diff options
938 files changed, 16922 insertions, 8822 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index 28462217e5de..7fee81095774 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -12,171 +12,107 @@ // See the License for the specific language governing permissions and // limitations under the License. -aconfig_srcjars = [ - // !!! KEEP THIS LIST ALPHABETICAL !!! - ":aconfig_mediacodec_flags_java_lib{.generated_srcjars}", - ":android.adaptiveauth.flags-aconfig-java{.generated_srcjars}", - ":android.app.flags-aconfig-java{.generated_srcjars}", - ":android.app.smartspace.flags-aconfig-java{.generated_srcjars}", - ":android.app.usage.flags-aconfig-java{.generated_srcjars}", - ":android.app.wearable.flags-aconfig-java{.generated_srcjars}", - ":android.appwidget.flags-aconfig-java{.generated_srcjars}", - ":android.chre.flags-aconfig-java{.generated_srcjars}", - ":android.companion.flags-aconfig-java{.generated_srcjars}", - ":android.companion.virtual.flags-aconfig-java{.generated_srcjars}", - ":android.companion.virtualdevice.flags-aconfig-java{.generated_srcjars}", - ":android.content.flags-aconfig-java{.generated_srcjars}", - ":android.content.pm.flags-aconfig-java{.generated_srcjars}", - ":android.content.res.flags-aconfig-java{.generated_srcjars}", - ":android.crashrecovery.flags-aconfig-java{.generated_srcjars}", - ":android.credentials.flags-aconfig-java{.generated_srcjars}", - ":android.database.sqlite-aconfig-java{.generated_srcjars}", - ":android.hardware.biometrics.flags-aconfig-java{.generated_srcjars}", - ":android.hardware.flags-aconfig-java{.generated_srcjars}", - ":android.hardware.radio.flags-aconfig-java{.generated_srcjars}", - ":android.hardware.usb.flags-aconfig-java{.generated_srcjars}", - ":android.location.flags-aconfig-java{.generated_srcjars}", - ":android.media.codec-aconfig-java{.generated_srcjars}", - ":android.media.tv.flags-aconfig-java{.generated_srcjars}", - ":android.multiuser.flags-aconfig-java{.generated_srcjars}", - ":android.net.platform.flags-aconfig-java{.generated_srcjars}", - ":android.net.vcn.flags-aconfig-java{.generated_srcjars}", - ":android.net.wifi.flags-aconfig-java{.generated_srcjars}", - ":android.nfc.flags-aconfig-java{.generated_srcjars}", - ":android.os.flags-aconfig-java{.generated_srcjars}", - ":android.os.vibrator.flags-aconfig-java{.generated_srcjars}", - ":android.permission.flags-aconfig-java{.generated_srcjars}", - ":android.provider.flags-aconfig-java{.generated_srcjars}", - ":android.security.flags-aconfig-java{.generated_srcjars}", - ":android.server.app.flags-aconfig-java{.generated_srcjars}", - ":android.service.autofill.flags-aconfig-java{.generated_srcjars}", - ":android.service.chooser.flags-aconfig-java{.generated_srcjars}", - ":android.service.controls.flags-aconfig-java{.generated_srcjars}", - ":android.service.dreams.flags-aconfig-java{.generated_srcjars}", - ":android.service.notification.flags-aconfig-java{.generated_srcjars}", - ":android.service.appprediction.flags-aconfig-java{.generated_srcjars}", - ":android.service.voice.flags-aconfig-java{.generated_srcjars}", - ":android.speech.flags-aconfig-java{.generated_srcjars}", - ":android.systemserver.flags-aconfig-java{.generated_srcjars}", - ":android.tracing.flags-aconfig-java{.generated_srcjars}", - ":android.view.accessibility.flags-aconfig-java{.generated_srcjars}", - ":android.view.contentcapture.flags-aconfig-java{.generated_srcjars}", - ":android.view.contentprotection.flags-aconfig-java{.generated_srcjars}", - ":android.view.flags-aconfig-java{.generated_srcjars}", - ":android.view.inputmethod.flags-aconfig-java{.generated_srcjars}", - ":android.webkit.flags-aconfig-java{.generated_srcjars}", - ":android.widget.flags-aconfig-java{.generated_srcjars}", - ":audio-framework-aconfig", - ":backup_flags_lib{.generated_srcjars}", - ":camera_platform_flags_core_java_lib{.generated_srcjars}", - ":com.android.hardware.input-aconfig-java{.generated_srcjars}", - ":com.android.input.flags-aconfig-java{.generated_srcjars}", - ":com.android.internal.foldables.flags-aconfig-java{.generated_srcjars}", - ":com.android.internal.pm.pkg.component.flags-aconfig-java{.generated_srcjars}", - ":com.android.media.flags.bettertogether-aconfig-java{.generated_srcjars}", - ":com.android.media.flags.editing-aconfig-java{.generated_srcjars}", - ":com.android.media.flags.projection-aconfig-java{.generated_srcjars}", - ":com.android.net.thread.flags-aconfig-java{.generated_srcjars}", - ":com.android.server.flags.services-aconfig-java{.generated_srcjars}", - ":com.android.text.flags-aconfig-java{.generated_srcjars}", - ":com.android.window.flags.window-aconfig-java{.generated_srcjars}", - ":device_policy_aconfig_flags_lib{.generated_srcjars}", - ":display_flags_lib{.generated_srcjars}", - ":framework-jobscheduler-job.flags-aconfig-java{.generated_srcjars}", - ":framework_graphics_flags_java_lib{.generated_srcjars}", - ":hwui_flags_java_lib{.generated_srcjars}", - ":power_flags_lib{.generated_srcjars}", - ":sdk_sandbox_flags_lib{.generated_srcjars}", - ":surfaceflinger_flags_java_lib{.generated_srcjars}", - ":telecom_flags_core_java_lib{.generated_srcjars}", - ":telephony_flags_core_java_lib{.generated_srcjars}", - // !!! KEEP THIS LIST ALPHABETICAL !!! -] - -stubs_defaults { +aconfig_declarations_group { name: "framework-minus-apex-aconfig-declarations", - aconfig_declarations: [ - "android.app.flags-aconfig", - "android.app.smartspace.flags-aconfig", - "android.app.usage.flags-aconfig", - "android.appwidget.flags-aconfig", - "android.companion.flags-aconfig", - "android.companion.virtual.flags-aconfig", - "android.content.pm.flags-aconfig", - "android.content.res.flags-aconfig", - "android.crashrecovery.flags-aconfig", - "android.credentials.flags-aconfig", - "android.database.sqlite-aconfig", - "android.hardware.biometrics.flags-aconfig", - "android.hardware.flags-aconfig", - "android.hardware.radio.flags-aconfig", - "android.hardware.usb.flags-aconfig", - "android.location.flags-aconfig", - "android.media.audio-aconfig", - "android.media.audiopolicy-aconfig", - "android.media.midi-aconfig", - "android.media.tv.flags-aconfig", - "android.multiuser.flags-aconfig", - "android.net.platform.flags-aconfig", - "android.net.vcn.flags-aconfig", - "android.net.wifi.flags-aconfig", - "android.nfc.flags-aconfig", - "android.os.flags-aconfig", - "android.os.vibrator.flags-aconfig", - "android.permission.flags-aconfig", - "android.provider.flags-aconfig", - "android.security.flags-aconfig", - "android.server.app.flags-aconfig", - "android.service.appprediction.flags-aconfig", - "android.service.autofill.flags-aconfig", - "android.service.chooser.flags-aconfig", - "android.service.controls.flags-aconfig", - "android.service.dreams.flags-aconfig", - "android.service.notification.flags-aconfig", - "android.service.voice.flags-aconfig", - "android.speech.flags-aconfig", - "android.tracing.flags-aconfig", - "android.view.accessibility.flags-aconfig", - "android.view.contentcapture.flags-aconfig", - "android.view.contentprotection.flags-aconfig", - "android.view.flags-aconfig", - "android.view.inputmethod.flags-aconfig", - "android.webkit.flags-aconfig", - "android.widget.flags-aconfig", - "camera_platform_flags", - "chre_flags", - "com.android.hardware.input.input-aconfig", - "com.android.input.flags-aconfig", - "com.android.media.flags.bettertogether-aconfig", - "com.android.net.thread.flags-aconfig", - "com.android.server.flags.services-aconfig", - "com.android.text.flags-aconfig", - "com.android.window.flags.window-aconfig", - "device_policy_aconfig_flags", - "display_flags", - "fold_lock_setting_flags", - "framework-jobscheduler-job.flags-aconfig", - "framework_graphics_flags", - "hwui_flags", - "power_flags", - "sdk_sandbox_flags", - "surfaceflinger_flags", - "telecom_flags", - "telephony_flags", + aconfig_declarations_groups: [ + "audio-framework-aconfig", + ], + java_aconfig_libraries: [ + // !!! KEEP THIS LIST ALPHABETICAL !!! + "aconfig_mediacodec_flags_java_lib", + "android.adaptiveauth.flags-aconfig-java", + "android.app.flags-aconfig-java", + "android.app.smartspace.flags-aconfig-java", + "android.app.usage.flags-aconfig-java", + "android.app.wearable.flags-aconfig-java", + "android.appwidget.flags-aconfig-java", + "android.chre.flags-aconfig-java", + "android.companion.flags-aconfig-java", + "android.companion.virtual.flags-aconfig-java", + "android.companion.virtualdevice.flags-aconfig-java", + "android.content.flags-aconfig-java", + "android.content.pm.flags-aconfig-java", + "android.content.res.flags-aconfig-java", + "android.crashrecovery.flags-aconfig-java", + "android.credentials.flags-aconfig-java", + "android.database.sqlite-aconfig-java", + "android.hardware.biometrics.flags-aconfig-java", + "android.hardware.flags-aconfig-java", + "android.hardware.radio.flags-aconfig-java", + "android.hardware.usb.flags-aconfig-java", + "android.location.flags-aconfig-java", + "android.media.codec-aconfig-java", + "android.media.tv.flags-aconfig-java", + "android.multiuser.flags-aconfig-java", + "android.net.platform.flags-aconfig-java", + "android.net.vcn.flags-aconfig-java", + "android.net.wifi.flags-aconfig-java", + "android.nfc.flags-aconfig-java", + "android.os.flags-aconfig-java", + "android.os.vibrator.flags-aconfig-java", + "android.permission.flags-aconfig-java", + "android.provider.flags-aconfig-java", + "android.security.flags-aconfig-java", + "android.server.app.flags-aconfig-java", + "android.service.autofill.flags-aconfig-java", + "android.service.chooser.flags-aconfig-java", + "android.service.controls.flags-aconfig-java", + "android.service.dreams.flags-aconfig-java", + "android.service.notification.flags-aconfig-java", + "android.service.appprediction.flags-aconfig-java", + "android.service.voice.flags-aconfig-java", + "android.speech.flags-aconfig-java", + "android.systemserver.flags-aconfig-java", + "android.tracing.flags-aconfig-java", + "android.view.accessibility.flags-aconfig-java", + "android.view.contentcapture.flags-aconfig-java", + "android.view.contentprotection.flags-aconfig-java", + "android.view.flags-aconfig-java", + "android.view.inputmethod.flags-aconfig-java", + "android.webkit.flags-aconfig-java", + "android.widget.flags-aconfig-java", + "backup_flags_lib", + "camera_platform_flags_core_java_lib", + "com.android.hardware.input-aconfig-java", + "com.android.input.flags-aconfig-java", + "com.android.internal.foldables.flags-aconfig-java", + "com.android.internal.pm.pkg.component.flags-aconfig-java", + "com.android.media.flags.bettertogether-aconfig-java", + "com.android.media.flags.editing-aconfig-java", + "com.android.media.flags.projection-aconfig-java", + "com.android.net.thread.flags-aconfig-java", + "com.android.server.flags.services-aconfig-java", + "com.android.text.flags-aconfig-java", + "com.android.window.flags.window-aconfig-java", + "device_policy_aconfig_flags_lib", + "display_flags_lib", + "framework-jobscheduler-job.flags-aconfig-java", + "framework_graphics_flags_java_lib", + "hwui_flags_java_lib", + "power_flags_lib", + "sdk_sandbox_flags_lib", + "surfaceflinger_flags_java_lib", + "telecom_flags_core_java_lib", + "telephony_flags_core_java_lib", + // !!! KEEP THIS LIST ALPHABETICAL !!! ], } filegroup { name: "framework-minus-apex-aconfig-srcjars", - srcs: aconfig_srcjars, + srcs: [ + ":framework-minus-apex-aconfig-declarations{.srcjars}", + ], } // Aconfig declarations and libraries for the core framework java_defaults { name: "framework-minus-apex-aconfig-libraries", // Add java_aconfig_libraries to here to add them to the core framework - srcs: aconfig_srcjars, // Add aconfig-annotations-lib as a dependency for the optimization + srcs: [ + ":framework-minus-apex-aconfig-declarations{.srcjars}", + ], libs: ["aconfig-annotations-lib"], } diff --git a/Android.bp b/Android.bp index e12f74fcd7ca..870df5a5723e 100644 --- a/Android.bp +++ b/Android.bp @@ -508,6 +508,8 @@ java_library { lint: { baseline_filename: "lint-baseline.xml", }, + // For jarjar repackaging + jarjar_prefix: "com.android.internal.hidden_from_bootclasspath", } java_library { diff --git a/WEAR_OWNERS b/WEAR_OWNERS index da8c83ebcc98..4ffb239e24ce 100644 --- a/WEAR_OWNERS +++ b/WEAR_OWNERS @@ -11,3 +11,4 @@ rwmyers@google.com nalmalki@google.com shijianli@google.com latkin@google.com +djsollen@google.com 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 f819f15b430f..bd00c03741f3 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -3852,7 +3852,7 @@ public class JobSchedulerService extends com.android.server.SystemService // the other jobs that will use this network. if (DEBUG) { Slog.d(TAG, "maybeQueueReadyJobsForExecutionLocked: piggybacking " - + batchedJobs.size() + " jobs on " + network + + (batchedJobs.size() - unbatchedJobCount) + " jobs on " + network + " because of unbatched job"); } jobsToRun.addAll(batchedJobs); @@ -3892,8 +3892,12 @@ public class JobSchedulerService extends com.android.server.SystemService // Some job is going to use the CPU anyway. Might as well run all the other // CPU-only jobs. if (DEBUG) { + final Integer unbatchedJobCountObj = mUnbatchedJobCount.get(null); + final int unbatchedJobCount = + unbatchedJobCountObj == null ? 0 : unbatchedJobCountObj; Slog.d(TAG, "maybeQueueReadyJobsForExecutionLocked: piggybacking " - + batchedNonNetworkedJobs.size() + " non-network jobs"); + + (batchedNonNetworkedJobs.size() - unbatchedJobCount) + + " non-network jobs"); } jobsToRun.addAll(batchedNonNetworkedJobs); } else if (batchedNonNetworkedJobs.size() >= minReadyCount) { 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 6ed42ec990ea..3219f7e5ce20 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 @@ -21,6 +21,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; +import static android.net.NetworkCapabilities.TRANSPORT_SATELLITE; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; @@ -139,8 +140,9 @@ public final class ConnectivityController extends RestrictingController implemen static final SparseIntArray sNetworkTransportAffinities = new SparseIntArray(); static { sNetworkTransportAffinities.put(TRANSPORT_CELLULAR, TRANSPORT_AFFINITY_AVOID); - sNetworkTransportAffinities.put(TRANSPORT_WIFI, TRANSPORT_AFFINITY_PREFER); sNetworkTransportAffinities.put(TRANSPORT_ETHERNET, TRANSPORT_AFFINITY_PREFER); + sNetworkTransportAffinities.put(TRANSPORT_SATELLITE, TRANSPORT_AFFINITY_AVOID); + sNetworkTransportAffinities.put(TRANSPORT_WIFI, TRANSPORT_AFFINITY_PREFER); } private final CcConfig mCcConfig; diff --git a/api/Android.bp b/api/Android.bp index 9d2147c32760..eeb76fbd81ef 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -302,7 +302,7 @@ packages_to_document = [ // classpath (or sources) somehow. stubs_defaults { name: "android-non-updatable-stubs-defaults", - defaults: ["framework-minus-apex-aconfig-declarations"], + aconfig_declarations: ["framework-minus-apex-aconfig-declarations"], srcs: [":android-non-updatable-stub-sources"], sdk_version: "none", system_modules: "none", diff --git a/boot/hiddenapi/hiddenapi-unsupported.txt b/boot/hiddenapi/hiddenapi-unsupported.txt index 26dc7003a828..adcc3df2d7fe 100644 --- a/boot/hiddenapi/hiddenapi-unsupported.txt +++ b/boot/hiddenapi/hiddenapi-unsupported.txt @@ -133,8 +133,6 @@ Landroid/hardware/input/IInputManager$Stub;->asInterface(Landroid/os/IBinder;)La Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService; Landroid/hardware/usb/IUsbManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/location/ICountryListener$Stub;-><init>()V -Landroid/location/IGeocodeProvider$Stub;-><init>()V -Landroid/location/IGeocodeProvider$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/IGeocodeProvider; Landroid/location/ILocationListener$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/location/ILocationListener$Stub$Proxy;->mRemote:Landroid/os/IBinder; Landroid/location/ILocationListener$Stub;-><init>()V diff --git a/core/TEST_MAPPING b/core/TEST_MAPPING index f1e4d0ee4906..fd571c95f568 100644 --- a/core/TEST_MAPPING +++ b/core/TEST_MAPPING @@ -20,15 +20,5 @@ "core/tests/coretests/src/com/android/internal/inputmethod/.*" ] } - ], - "postsubmit": [ - { - "name": "CtsContactKeysManagerTestCases", - "options": [ - { - "include-filter": "android.provider.cts.contactkeys." - } - ] - } - ] + ] } diff --git a/core/api/current.txt b/core/api/current.txt index 2f8a0a426bf8..e8a342d0c411 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -144,10 +144,12 @@ package android { field public static final String MANAGE_DEVICE_POLICY_AUDIO_OUTPUT = "android.permission.MANAGE_DEVICE_POLICY_AUDIO_OUTPUT"; field public static final String MANAGE_DEVICE_POLICY_AUTOFILL = "android.permission.MANAGE_DEVICE_POLICY_AUTOFILL"; field public static final String MANAGE_DEVICE_POLICY_BACKUP_SERVICE = "android.permission.MANAGE_DEVICE_POLICY_BACKUP_SERVICE"; + field @FlaggedApi("android.app.admin.flags.dedicated_device_control_api_enabled") public static final String MANAGE_DEVICE_POLICY_BLOCK_UNINSTALL = "android.permission.MANAGE_DEVICE_POLICY_BLOCK_UNINSTALL"; field public static final String MANAGE_DEVICE_POLICY_BLUETOOTH = "android.permission.MANAGE_DEVICE_POLICY_BLUETOOTH"; field public static final String MANAGE_DEVICE_POLICY_BUGREPORT = "android.permission.MANAGE_DEVICE_POLICY_BUGREPORT"; field public static final String MANAGE_DEVICE_POLICY_CALLS = "android.permission.MANAGE_DEVICE_POLICY_CALLS"; field public static final String MANAGE_DEVICE_POLICY_CAMERA = "android.permission.MANAGE_DEVICE_POLICY_CAMERA"; + field @FlaggedApi("android.app.admin.flags.dedicated_device_control_api_enabled") public static final String MANAGE_DEVICE_POLICY_CAMERA_TOGGLE = "android.permission.MANAGE_DEVICE_POLICY_CAMERA_TOGGLE"; field public static final String MANAGE_DEVICE_POLICY_CERTIFICATES = "android.permission.MANAGE_DEVICE_POLICY_CERTIFICATES"; field public static final String MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE = "android.permission.MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE"; field @FlaggedApi("android.view.contentprotection.flags.manage_device_policy_enabled") public static final String MANAGE_DEVICE_POLICY_CONTENT_PROTECTION = "android.permission.MANAGE_DEVICE_POLICY_CONTENT_PROTECTION"; @@ -169,6 +171,7 @@ package android { field @FlaggedApi("android.app.admin.flags.esim_management_enabled") public static final String MANAGE_DEVICE_POLICY_MANAGED_SUBSCRIPTIONS = "android.permission.MANAGE_DEVICE_POLICY_MANAGED_SUBSCRIPTIONS"; field public static final String MANAGE_DEVICE_POLICY_METERED_DATA = "android.permission.MANAGE_DEVICE_POLICY_METERED_DATA"; field public static final String MANAGE_DEVICE_POLICY_MICROPHONE = "android.permission.MANAGE_DEVICE_POLICY_MICROPHONE"; + field @FlaggedApi("android.app.admin.flags.dedicated_device_control_api_enabled") public static final String MANAGE_DEVICE_POLICY_MICROPHONE_TOGGLE = "android.permission.MANAGE_DEVICE_POLICY_MICROPHONE_TOGGLE"; field public static final String MANAGE_DEVICE_POLICY_MOBILE_NETWORK = "android.permission.MANAGE_DEVICE_POLICY_MOBILE_NETWORK"; field public static final String MANAGE_DEVICE_POLICY_MODIFY_USERS = "android.permission.MANAGE_DEVICE_POLICY_MODIFY_USERS"; field public static final String MANAGE_DEVICE_POLICY_MTE = "android.permission.MANAGE_DEVICE_POLICY_MTE"; @@ -454,6 +457,7 @@ package android { field public static final int allowBackup = 16843392; // 0x1010280 field public static final int allowClearUserData = 16842757; // 0x1010005 field public static final int allowClickWhenDisabled = 16844312; // 0x1010618 + field @FlaggedApi("android.security.asm_restrictions_enabled") public static final int allowCrossUidActivitySwitchFromBelow; field public static final int allowEmbedded = 16843765; // 0x10103f5 field public static final int allowGameAngleDriver = 16844376; // 0x1010658 field public static final int allowGameDownscaling = 16844377; // 0x1010659 @@ -687,6 +691,7 @@ package android { field public static final int defaultHeight = 16844021; // 0x10104f5 field @FlaggedApi("android.content.res.default_locale") public static final int defaultLocale; field public static final int defaultToDeviceProtectedStorage = 16844036; // 0x1010504 + field @FlaggedApi("android.nfc.Flags.FLAG_OBSERVE_MODE") public static final int defaultToObserveMode; field public static final int defaultValue = 16843245; // 0x10101ed field public static final int defaultWidth = 16844020; // 0x10104f4 field public static final int delay = 16843212; // 0x10101cc @@ -1491,6 +1496,7 @@ package android { field @Deprecated public static final int sharedUserLabel = 16843361; // 0x1010261 field public static final int sharedUserMaxSdkVersion = 16844365; // 0x101064d field public static final int shell = 16844180; // 0x1010594 + field @FlaggedApi("com.android.text.flags.use_bounds_for_width") public static final int shiftDrawingOffsetForStartOverhang; field public static final int shortcutDisabledMessage = 16844075; // 0x101052b field public static final int shortcutId = 16844072; // 0x1010528 field public static final int shortcutLongLabel = 16844074; // 0x101052a @@ -1887,6 +1893,7 @@ package android { field public static final int windowFullscreen = 16843277; // 0x101020d field public static final int windowHideAnimation = 16842935; // 0x10100b7 field public static final int windowIsFloating = 16842839; // 0x1010057 + field @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public static final int windowIsFrameRatePowerSavingsBalanced; field public static final int windowIsTranslucent = 16842840; // 0x1010058 field public static final int windowLayoutAffinity = 16844313; // 0x1010619 field public static final int windowLayoutInDisplayCutoutMode = 16844166; // 0x1010586 @@ -4423,12 +4430,14 @@ package android.app { method @Deprecated public void finishFromChild(android.app.Activity); method @Nullable public android.app.ActionBar getActionBar(); method public final android.app.Application getApplication(); + method @FlaggedApi("android.security.content_uri_permission_apis") @Nullable public android.app.ComponentCaller getCaller(); method @Nullable public android.content.ComponentName getCallingActivity(); method @Nullable public String getCallingPackage(); method public int getChangingConfigurations(); method public android.content.ComponentName getComponentName(); method public android.transition.Scene getContentScene(); method public android.transition.TransitionManager getContentTransitionManager(); + method @FlaggedApi("android.security.content_uri_permission_apis") @NonNull public android.app.ComponentCaller getCurrentCaller(); method @Nullable public android.view.View getCurrentFocus(); method @Deprecated public android.app.FragmentManager getFragmentManager(); method @FlaggedApi("android.security.content_uri_permission_apis") @NonNull public android.app.ComponentCaller getInitialCaller(); @@ -4480,6 +4489,7 @@ package android.app { method @CallSuper public void onActionModeStarted(android.view.ActionMode); method public void onActivityReenter(int, android.content.Intent); method protected void onActivityResult(int, int, android.content.Intent); + method @FlaggedApi("android.security.content_uri_permission_apis") public void onActivityResult(int, int, @NonNull android.content.Intent, @NonNull android.app.ComponentCaller); method @Deprecated public void onAttachFragment(android.app.Fragment); method public void onAttachedToWindow(); method @Deprecated public void onBackPressed(); @@ -4521,6 +4531,7 @@ package android.app { method public boolean onNavigateUp(); method @Deprecated public boolean onNavigateUpFromChild(android.app.Activity); method protected void onNewIntent(android.content.Intent); + method @FlaggedApi("android.security.content_uri_permission_apis") public void onNewIntent(@NonNull android.content.Intent, @NonNull android.app.ComponentCaller); method public boolean onOptionsItemSelected(@NonNull android.view.MenuItem); method public void onOptionsMenuClosed(android.view.Menu); method public void onPanelClosed(int, @NonNull android.view.Menu); @@ -4608,6 +4619,7 @@ package android.app { method public void setImmersive(boolean); method public void setInheritShowWhenLocked(boolean); method public void setIntent(android.content.Intent); + method @FlaggedApi("android.security.content_uri_permission_apis") public void setIntent(@Nullable android.content.Intent, @Nullable android.app.ComponentCaller); method public void setLocusContext(@Nullable android.content.LocusId, @Nullable android.os.Bundle); method public final void setMediaController(android.media.session.MediaController); method public void setPictureInPictureParams(@NonNull android.app.PictureInPictureParams); @@ -5459,11 +5471,15 @@ package android.app { method public int getDeferralPolicy(); method @Nullable public String getDeliveryGroupMatchingKey(); method public int getDeliveryGroupPolicy(); + method @FlaggedApi("android.app.bcast_event_timestamps") public long getEventTriggerTimestampMillis(); + method @FlaggedApi("android.app.bcast_event_timestamps") public long getRemoteEventTriggerTimestampMillis(); method public boolean isShareIdentityEnabled(); method @NonNull public static android.app.BroadcastOptions makeBasic(); method @NonNull public android.app.BroadcastOptions setDeferralPolicy(int); method @NonNull public android.app.BroadcastOptions setDeliveryGroupMatchingKey(@NonNull String, @NonNull String); method @NonNull public android.app.BroadcastOptions setDeliveryGroupPolicy(int); + method @FlaggedApi("android.app.bcast_event_timestamps") public void setEventTriggerTimestampMillis(long); + method @FlaggedApi("android.app.bcast_event_timestamps") public void setRemoteEventTriggerTimestampMillis(long); method @NonNull public android.app.BroadcastOptions setShareIdentityEnabled(boolean); method @NonNull public android.os.Bundle toBundle(); field public static final int DEFERRAL_POLICY_DEFAULT = 0; // 0x0 @@ -6091,6 +6107,7 @@ package android.app { method public void callActivityOnCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle); method public void callActivityOnDestroy(android.app.Activity); method public void callActivityOnNewIntent(android.app.Activity, android.content.Intent); + method @FlaggedApi("android.security.content_uri_permission_apis") public void callActivityOnNewIntent(@NonNull android.app.Activity, @NonNull android.content.Intent, @NonNull android.app.ComponentCaller); method public void callActivityOnPause(android.app.Activity); method public void callActivityOnPictureInPictureRequested(@NonNull android.app.Activity); method public void callActivityOnPostCreate(@NonNull android.app.Activity, @Nullable android.os.Bundle); @@ -8113,6 +8130,7 @@ package android.app.admin { method public boolean isLogoutEnabled(); method public boolean isManagedProfile(@NonNull android.content.ComponentName); method public boolean isMasterVolumeMuted(@NonNull android.content.ComponentName); + method @FlaggedApi("android.app.admin.flags.is_mte_policy_enforced") public static boolean isMtePolicyEnforced(); method public boolean isNetworkLoggingEnabled(@Nullable android.content.ComponentName); method public boolean isOrganizationOwnedDeviceWithManagedProfile(); method public boolean isOverrideApnEnabled(@NonNull android.content.ComponentName); @@ -15684,6 +15702,7 @@ package android.graphics { method public boolean clipOutRect(@NonNull android.graphics.Rect); method public boolean clipOutRect(float, float, float, float); method public boolean clipOutRect(int, int, int, int); + method @FlaggedApi("com.android.graphics.hwui.flags.clip_shader") public void clipOutShader(@NonNull android.graphics.Shader); method @Deprecated public boolean clipPath(@NonNull android.graphics.Path, @NonNull android.graphics.Region.Op); method public boolean clipPath(@NonNull android.graphics.Path); method @Deprecated public boolean clipRect(@NonNull android.graphics.RectF, @NonNull android.graphics.Region.Op); @@ -15693,6 +15712,7 @@ package android.graphics { method @Deprecated public boolean clipRect(float, float, float, float, @NonNull android.graphics.Region.Op); method public boolean clipRect(float, float, float, float); method public boolean clipRect(int, int, int, int); + method @FlaggedApi("com.android.graphics.hwui.flags.clip_shader") public void clipShader(@NonNull android.graphics.Shader); method public void concat(@Nullable android.graphics.Matrix); method @FlaggedApi("com.android.graphics.hwui.flags.matrix_44") public void concat44(@Nullable android.graphics.Matrix44); method public void disableZ(); @@ -18037,24 +18057,6 @@ package android.graphics.pdf { method public android.graphics.pdf.PdfDocument.PageInfo.Builder setContentRect(android.graphics.Rect); } - public final class PdfRenderer implements java.lang.AutoCloseable { - ctor public PdfRenderer(@NonNull android.os.ParcelFileDescriptor) throws java.io.IOException; - method public void close(); - method public int getPageCount(); - method public android.graphics.pdf.PdfRenderer.Page openPage(int); - method public boolean shouldScaleForPrinting(); - } - - public final class PdfRenderer.Page implements java.lang.AutoCloseable { - method public void close(); - method public int getHeight(); - method public int getIndex(); - method public int getWidth(); - method public void render(@NonNull android.graphics.Bitmap, @Nullable android.graphics.Rect, @Nullable android.graphics.Matrix, int); - field public static final int RENDER_MODE_FOR_DISPLAY = 1; // 0x1 - field public static final int RENDER_MODE_FOR_PRINT = 2; // 0x2 - } - } package android.graphics.text { @@ -18578,6 +18580,7 @@ package android.hardware { @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public final class OverlayProperties implements android.os.Parcelable { method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public int describeContents(); + method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public boolean isCombinationSupported(int, int); method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public boolean isMixedColorSpacesSupported(); method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public void writeToParcel(@NonNull android.os.Parcel, int); field @FlaggedApi("android.hardware.flags.overlayproperties_class_api") @NonNull public static final android.os.Parcelable.Creator<android.hardware.OverlayProperties> CREATOR; @@ -19311,6 +19314,7 @@ package android.hardware.camera2 { public abstract static class CameraExtensionSession.ExtensionCaptureCallback { ctor public CameraExtensionSession.ExtensionCaptureCallback(); method public void onCaptureFailed(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureFailed(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest, int); method public void onCaptureProcessProgressed(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest, @IntRange(from=0, to=100) int); method public void onCaptureProcessStarted(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest); method public void onCaptureResultAvailable(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest, @NonNull android.hardware.camera2.TotalCaptureResult); @@ -20002,11 +20006,14 @@ package android.hardware.camera2.params { public final class ExtensionSessionConfiguration { ctor public ExtensionSessionConfiguration(int, @NonNull java.util.List<android.hardware.camera2.params.OutputConfiguration>, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraExtensionSession.StateCallback); + method @FlaggedApi("com.android.internal.camera.flags.extension_10_bit") public void clearColorSpace(); + method @FlaggedApi("com.android.internal.camera.flags.extension_10_bit") @Nullable public android.graphics.ColorSpace getColorSpace(); method @NonNull public java.util.concurrent.Executor getExecutor(); method public int getExtension(); method @NonNull public java.util.List<android.hardware.camera2.params.OutputConfiguration> getOutputConfigurations(); method @Nullable public android.hardware.camera2.params.OutputConfiguration getPostviewOutputConfiguration(); method @NonNull public android.hardware.camera2.CameraExtensionSession.StateCallback getStateCallback(); + method @FlaggedApi("com.android.internal.camera.flags.extension_10_bit") public void setColorSpace(@NonNull android.graphics.ColorSpace.Named); method public void setPostviewOutputConfiguration(@Nullable android.hardware.camera2.params.OutputConfiguration); } @@ -22731,7 +22738,6 @@ package android.media { public final class MediaCodec.QueueRequest { method public void queue(); - method @FlaggedApi("com.android.media.codec.flags.large_audio_frame") @NonNull public android.media.MediaCodec.QueueRequest setBufferInfos(@NonNull java.util.ArrayDeque<android.media.MediaCodec.BufferInfo>); method @NonNull public android.media.MediaCodec.QueueRequest setByteBufferParameter(@NonNull String, @NonNull java.nio.ByteBuffer); method @NonNull public android.media.MediaCodec.QueueRequest setEncryptedLinearBlock(@NonNull android.media.MediaCodec.LinearBlock, int, int, @NonNull android.media.MediaCodec.CryptoInfo); method @NonNull public android.media.MediaCodec.QueueRequest setFlags(int); @@ -22741,6 +22747,7 @@ package android.media { method @NonNull public android.media.MediaCodec.QueueRequest setLinearBlock(@NonNull android.media.MediaCodec.LinearBlock, int, int); method @NonNull public android.media.MediaCodec.QueueRequest setLongParameter(@NonNull String, long); method @FlaggedApi("com.android.media.codec.flags.large_audio_frame") @NonNull public android.media.MediaCodec.QueueRequest setMultiFrameEncryptedLinearBlock(@NonNull android.media.MediaCodec.LinearBlock, @NonNull java.util.ArrayDeque<android.media.MediaCodec.BufferInfo>, @NonNull java.util.ArrayDeque<android.media.MediaCodec.CryptoInfo>); + method @FlaggedApi("com.android.media.codec.flags.large_audio_frame") @NonNull public android.media.MediaCodec.QueueRequest setMultiFrameLinearBlock(@NonNull android.media.MediaCodec.LinearBlock, @NonNull java.util.ArrayDeque<android.media.MediaCodec.BufferInfo>); method @NonNull public android.media.MediaCodec.QueueRequest setPresentationTimeUs(long); method @NonNull public android.media.MediaCodec.QueueRequest setStringParameter(@NonNull String, @NonNull String); } @@ -22749,12 +22756,16 @@ package android.media { method @NonNull public String getCanonicalName(); method public android.media.MediaCodecInfo.CodecCapabilities getCapabilitiesForType(String); method @NonNull public String getName(); + method @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public int getSecurityModel(); method public String[] getSupportedTypes(); method public boolean isAlias(); method public boolean isEncoder(); method public boolean isHardwareAccelerated(); method public boolean isSoftwareOnly(); method public boolean isVendor(); + field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_MEMORY_SAFE = 1; // 0x1 + field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_SANDBOXED = 0; // 0x0 + field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 2; // 0x2 } public static final class MediaCodecInfo.AudioCapabilities { @@ -23583,6 +23594,9 @@ package android.media { field public static final int COLOR_TRANSFER_LINEAR = 1; // 0x1 field public static final int COLOR_TRANSFER_SDR_VIDEO = 3; // 0x3 field public static final int COLOR_TRANSFER_ST2084 = 6; // 0x6 + field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_MEMORY_SAFE = 2; // 0x2 + field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_SANDBOXED = 1; // 0x1 + field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 4; // 0x4 field public static final String KEY_AAC_DRC_ALBUM_MODE = "aac-drc-album-mode"; field public static final String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level"; field public static final String KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level"; @@ -23664,6 +23678,7 @@ package android.media { field public static final String KEY_REPEAT_PREVIOUS_FRAME_AFTER = "repeat-previous-frame-after"; field public static final String KEY_ROTATION = "rotation-degrees"; field public static final String KEY_SAMPLE_RATE = "sample-rate"; + field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final String KEY_SECURITY_MODEL = "security-model"; field public static final String KEY_SLICE_HEIGHT = "slice-height"; field public static final String KEY_SLOW_MOTION_MARKERS = "slow-motion-markers"; field public static final String KEY_STRIDE = "stride"; @@ -24552,6 +24567,7 @@ package android.media { method @FlaggedApi("com.android.media.flags.enable_screen_off_scanning") @NonNull public android.media.MediaRouter2.ScanToken requestScan(@NonNull android.media.MediaRouter2.ScanRequest); method public void setOnGetControllerHintsListener(@Nullable android.media.MediaRouter2.OnGetControllerHintsListener); method public void setRouteListingPreference(@Nullable android.media.RouteListingPreference); + method @FlaggedApi("com.android.media.flags.enable_privileged_routing_for_media_routing_control") @RequiresPermission(anyOf={android.Manifest.permission.MEDIA_CONTENT_CONTROL, android.Manifest.permission.MEDIA_ROUTING_CONTROL}) public void setRouteVolume(@NonNull android.media.MediaRoute2Info, int); method public boolean showSystemOutputSwitcher(); method public void stop(); method public void transferTo(@NonNull android.media.MediaRoute2Info); @@ -26068,7 +26084,6 @@ package android.media.metrics { method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.media.metrics.MediaItemInfo> CREATOR; field public static final long DATA_TYPE_AUDIO = 4L; // 0x4L - field public static final long DATA_TYPE_CUE_POINTS = 128L; // 0x80L field public static final long DATA_TYPE_DEPTH = 16L; // 0x10L field public static final long DATA_TYPE_GAIN_MAP = 32L; // 0x20L field public static final long DATA_TYPE_GAPLESS = 256L; // 0x100L @@ -26077,6 +26092,7 @@ package android.media.metrics { field public static final long DATA_TYPE_IMAGE = 1L; // 0x1L field public static final long DATA_TYPE_METADATA = 8L; // 0x8L field public static final long DATA_TYPE_SPATIAL_AUDIO = 512L; // 0x200L + field public static final long DATA_TYPE_SPEED_SETTING_CUE_POINTS = 128L; // 0x80L field public static final long DATA_TYPE_VIDEO = 2L; // 0x2L field public static final int SOURCE_TYPE_CAMERA = 2; // 0x2 field public static final int SOURCE_TYPE_EDITING_SESSION = 3; // 0x3 @@ -42390,6 +42406,7 @@ package android.telecom { field public static final int SUPPORTS_SET_INACTIVE = 2; // 0x2 field public static final int SUPPORTS_STREAM = 4; // 0x4 field public static final int SUPPORTS_TRANSFER = 8; // 0x8 + field @FlaggedApi("com.android.server.telecom.flags.transactional_video_state") public static final int SUPPORTS_VIDEO_CALLING = 16; // 0x10 field public static final int VIDEO_CALL = 2; // 0x2 } @@ -42425,6 +42442,7 @@ package android.telecom { method @NonNull public android.os.ParcelUuid getCallId(); method public void requestCallEndpointChange(@NonNull android.telecom.CallEndpoint, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>); method @FlaggedApi("com.android.server.telecom.flags.set_mute_state") public void requestMuteState(boolean, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>); + method @FlaggedApi("com.android.server.telecom.flags.transactional_video_state") public void requestVideoState(int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>); method public void sendEvent(@NonNull String, @NonNull android.os.Bundle); method public void setActive(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>); method public void setInactive(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>); @@ -42473,6 +42491,7 @@ package android.telecom { method public void onCallStreamingFailed(int); method public void onEvent(@NonNull String, @NonNull android.os.Bundle); method public void onMuteStateChanged(boolean); + method @FlaggedApi("com.android.server.telecom.flags.transactional_video_state") public default void onVideoStateChanged(int); } public final class CallException extends java.lang.RuntimeException implements android.os.Parcelable { @@ -45776,6 +45795,7 @@ package android.telephony { method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<android.telephony.SubscriptionInfo> getSubscriptionsInGroup(@NonNull android.os.ParcelUuid); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isActiveSubscriptionId(int); method public boolean isNetworkRoaming(int); + method @FlaggedApi("com.android.internal.telephony.flags.subscription_user_association_query") @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isSubscriptionAssociatedWithUser(int); method public static boolean isUsableSubscriptionId(int); method public static boolean isValidSubscriptionId(int); method public void removeOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); @@ -47525,6 +47545,7 @@ package android.text { method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") @NonNull public android.text.DynamicLayout.Builder setLineBreakConfig(@NonNull android.graphics.text.LineBreakConfig); method @NonNull public android.text.DynamicLayout.Builder setLineSpacing(float, @FloatRange(from=0.0) float); method @FlaggedApi("com.android.text.flags.fix_line_height_for_locale") @NonNull public android.text.DynamicLayout.Builder setMinimumFontMetrics(@Nullable android.graphics.Paint.FontMetrics); + method @FlaggedApi("com.android.text.flags.use_bounds_for_width") @NonNull public android.text.DynamicLayout.Builder setShiftDrawingOffsetForStartOverhang(boolean); method @NonNull public android.text.DynamicLayout.Builder setTextDirection(@NonNull android.text.TextDirectionHeuristic); method @FlaggedApi("com.android.text.flags.use_bounds_for_width") @NonNull public android.text.DynamicLayout.Builder setUseBoundsForWidth(boolean); method @NonNull public android.text.DynamicLayout.Builder setUseLineSpacingFromFallbacks(boolean); @@ -47728,6 +47749,7 @@ package android.text { method @FlaggedApi("com.android.text.flags.use_bounds_for_width") @Nullable public final int[] getRightIndents(); method public float getSecondaryHorizontal(int); method public void getSelectionPath(int, int, android.graphics.Path); + method @FlaggedApi("com.android.text.flags.use_bounds_for_width") public boolean getShiftDrawingOffsetForStartOverhang(); method public final float getSpacingAdd(); method public final float getSpacingMultiplier(); method @NonNull public final CharSequence getText(); @@ -47784,6 +47806,7 @@ package android.text { method @NonNull public android.text.Layout.Builder setMaxLines(@IntRange(from=1) int); method @FlaggedApi("com.android.text.flags.fix_line_height_for_locale") @NonNull public android.text.Layout.Builder setMinimumFontMetrics(@Nullable android.graphics.Paint.FontMetrics); method @NonNull public android.text.Layout.Builder setRightIndents(@Nullable int[]); + method @FlaggedApi("com.android.text.flags.use_bounds_for_width") @NonNull public android.text.Layout.Builder setShiftDrawingOffsetForStartOverhang(boolean); method @NonNull public android.text.Layout.Builder setTextDirectionHeuristic(@NonNull android.text.TextDirectionHeuristic); method @FlaggedApi("com.android.text.flags.use_bounds_for_width") @NonNull public android.text.Layout.Builder setUseBoundsForWidth(boolean); } @@ -48055,6 +48078,7 @@ package android.text { method @NonNull public android.text.StaticLayout.Builder setLineSpacing(float, @FloatRange(from=0.0) float); method @NonNull public android.text.StaticLayout.Builder setMaxLines(@IntRange(from=0) int); method @FlaggedApi("com.android.text.flags.fix_line_height_for_locale") @NonNull public android.text.StaticLayout.Builder setMinimumFontMetrics(@Nullable android.graphics.Paint.FontMetrics); + method @FlaggedApi("com.android.text.flags.use_bounds_for_width") @NonNull public android.text.StaticLayout.Builder setShiftDrawingOffsetForStartOverhang(boolean); method public android.text.StaticLayout.Builder setText(CharSequence); method @NonNull public android.text.StaticLayout.Builder setTextDirection(@NonNull android.text.TextDirectionHeuristic); method @FlaggedApi("com.android.text.flags.use_bounds_for_width") @NonNull public android.text.StaticLayout.Builder setUseBoundsForWidth(boolean); @@ -50564,7 +50588,6 @@ package android.view { method public default void removeOnBufferTransformHintChangedListener(@NonNull android.view.AttachedSurfaceControl.OnBufferTransformHintChangedListener); method public default void setChildBoundingInsets(@NonNull android.graphics.Rect); method public default void setTouchableRegion(@Nullable android.graphics.Region); - method @FlaggedApi("com.android.window.flags.transfer_gesture_to_embedded") public default boolean transferHostTouchGestureToEmbedded(@NonNull android.view.SurfaceControlViewHost.SurfacePackage); } @UiThread public static interface AttachedSurfaceControl.OnBufferTransformHintChangedListener { @@ -52283,6 +52306,7 @@ package android.view { public static final class SurfaceControlViewHost.SurfacePackage implements android.os.Parcelable { ctor public SurfaceControlViewHost.SurfacePackage(@NonNull android.view.SurfaceControlViewHost.SurfacePackage); method public int describeContents(); + method @FlaggedApi("com.android.window.flags.surface_control_input_receiver") @Nullable public android.window.InputTransferToken getInputTransferToken(); method @NonNull public android.view.SurfaceControl getSurfaceControl(); method public void notifyConfigurationChanged(@NonNull android.content.res.Configuration); method public void notifyDetachedFromWindow(); @@ -53244,7 +53268,7 @@ package android.view { field protected static final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET; field protected static final int[] PRESSED_STATE_SET; field protected static final int[] PRESSED_WINDOW_FOCUSED_STATE_SET; - field @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public static final float REQUESTED_FRAME_RATE_CATEGORY_DEFAULT = 0.0f; + field @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public static final float REQUESTED_FRAME_RATE_CATEGORY_DEFAULT = (0.0f/0.0f); field @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public static final float REQUESTED_FRAME_RATE_CATEGORY_HIGH = -4.0f; field @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public static final float REQUESTED_FRAME_RATE_CATEGORY_LOW = -2.0f; field @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public static final float REQUESTED_FRAME_RATE_CATEGORY_NORMAL = -3.0f; @@ -54063,6 +54087,7 @@ package android.view { method public abstract void invalidatePanelMenu(int); method public final boolean isActive(); method public abstract boolean isFloating(); + method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public boolean isFrameRatePowerSavingsBalanced(); method public boolean isNavigationBarContrastEnforced(); method public abstract boolean isShortcutKey(int, android.view.KeyEvent); method @Deprecated public boolean isStatusBarContrastEnforced(); @@ -54112,6 +54137,7 @@ package android.view { method public void setFlags(int, int); method public void setFormat(int); method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRateBoostOnTouchEnabled(boolean); + method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRatePowerSavingsBalanced(boolean); method public void setGravity(int); method @RequiresPermission(android.Manifest.permission.HIDE_OVERLAY_WINDOWS) public final void setHideOverlayWindows(boolean); method public void setIcon(@DrawableRes int); @@ -54419,15 +54445,17 @@ package android.view { method @Deprecated public android.view.Display getDefaultDisplay(); method @NonNull public default android.view.WindowMetrics getMaximumWindowMetrics(); method public default boolean isCrossWindowBlurEnabled(); - method @FlaggedApi("com.android.window.flags.surface_control_input_receiver") public default void registerBatchedSurfaceControlInputReceiver(int, @NonNull android.window.InputTransferToken, @NonNull android.view.SurfaceControl, @NonNull android.view.Choreographer, @NonNull android.view.SurfaceControlInputReceiver); + method @FlaggedApi("com.android.window.flags.surface_control_input_receiver") @NonNull public default android.window.InputTransferToken registerBatchedSurfaceControlInputReceiver(int, @NonNull android.window.InputTransferToken, @NonNull android.view.SurfaceControl, @NonNull android.view.Choreographer, @NonNull android.view.SurfaceControlInputReceiver); method @FlaggedApi("com.android.window.flags.trusted_presentation_listener_for_window") public default void registerTrustedPresentationListener(@NonNull android.os.IBinder, @NonNull android.window.TrustedPresentationThresholds, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); - method @FlaggedApi("com.android.window.flags.surface_control_input_receiver") public default void registerUnbatchedSurfaceControlInputReceiver(int, @NonNull android.window.InputTransferToken, @NonNull android.view.SurfaceControl, @NonNull android.os.Looper, @NonNull android.view.SurfaceControlInputReceiver); + method @FlaggedApi("com.android.window.flags.surface_control_input_receiver") @NonNull public default android.window.InputTransferToken registerUnbatchedSurfaceControlInputReceiver(int, @NonNull android.window.InputTransferToken, @NonNull android.view.SurfaceControl, @NonNull android.os.Looper, @NonNull android.view.SurfaceControlInputReceiver); method public default void removeCrossWindowBlurEnabledListener(@NonNull java.util.function.Consumer<java.lang.Boolean>); method public default void removeProposedRotationListener(@NonNull java.util.function.IntConsumer); method @FlaggedApi("com.android.window.flags.screen_recording_callbacks") @RequiresPermission(android.Manifest.permission.DETECT_SCREEN_RECORDING) public default void removeScreenRecordingCallback(@NonNull java.util.function.Consumer<java.lang.Integer>); method public void removeViewImmediate(android.view.View); + method @FlaggedApi("com.android.window.flags.surface_control_input_receiver") public default boolean transferTouchGesture(@NonNull android.window.InputTransferToken, @NonNull android.window.InputTransferToken); method @FlaggedApi("com.android.window.flags.surface_control_input_receiver") public default void unregisterSurfaceControlInputReceiver(@NonNull android.view.SurfaceControl); method @FlaggedApi("com.android.window.flags.trusted_presentation_listener_for_window") public default void unregisterTrustedPresentationListener(@NonNull java.util.function.Consumer<java.lang.Boolean>); + field @FlaggedApi("com.android.window.flags.cover_display_opt_in") public static final int COMPAT_SMALL_COVER_SCREEN_OPT_IN = 1; // 0x1 field public static final String PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE = "android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE"; field public static final String PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED = "android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED"; field @FlaggedApi("com.android.window.flags.untrusted_embedding_state_sharing") public static final String PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING = "android.window.PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING"; @@ -54440,6 +54468,7 @@ package android.view { field public static final String PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE = "android.window.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE"; field @FlaggedApi("com.android.window.flags.app_compat_properties_api") public static final String PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES = "android.window.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES"; field public static final String PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS = "android.window.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS"; + field @FlaggedApi("com.android.window.flags.cover_display_opt_in") public static final String PROPERTY_COMPAT_ALLOW_SMALL_COVER_SCREEN = "android.window.PROPERTY_COMPAT_ALLOW_SMALL_COVER_SCREEN"; field @FlaggedApi("com.android.window.flags.app_compat_properties_api") public static final String PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE = "android.window.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE"; field @FlaggedApi("com.android.window.flags.app_compat_properties_api") public static final String PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE = "android.window.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE"; field public static final String PROPERTY_COMPAT_ENABLE_FAKE_FOCUS = "android.window.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS"; @@ -54480,6 +54509,7 @@ package android.view { method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public boolean getFrameRateBoostOnTouchEnabled(); method public final CharSequence getTitle(); method public boolean isFitInsetsIgnoringVisibility(); + method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public boolean isFrameRatePowerSavingsBalanced(); method public boolean isHdrConversionEnabled(); method public static boolean mayUseInputMethod(int); method public void setBlurBehindRadius(@IntRange(from=0) int); @@ -54490,6 +54520,7 @@ package android.view { method public void setFitInsetsSides(int); method public void setFitInsetsTypes(int); method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRateBoostOnTouchEnabled(boolean); + method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRatePowerSavingsBalanced(boolean); method public void setHdrConversionEnabled(boolean); method public final void setTitle(CharSequence); method public void setWallpaperTouchEventsEnabled(boolean); @@ -60221,6 +60252,7 @@ package android.widget { } @FlaggedApi("android.appwidget.flags.draw_data_parcel") public static final class RemoteViews.DrawInstructions { + method @FlaggedApi("android.appwidget.flags.draw_data_parcel") public static long getSupportedVersion(); } @FlaggedApi("android.appwidget.flags.draw_data_parcel") public static final class RemoteViews.DrawInstructions.Builder { @@ -60873,6 +60905,7 @@ package android.widget { method public float getShadowDx(); method public float getShadowDy(); method public float getShadowRadius(); + method @FlaggedApi("com.android.text.flags.use_bounds_for_width") public boolean getShiftDrawingOffsetForStartOverhang(); method public final boolean getShowSoftInputOnFocus(); method public CharSequence getText(); method @NonNull public android.view.textclassifier.TextClassifier getTextClassifier(); @@ -61009,6 +61042,7 @@ package android.widget { method public void setSearchResultHighlights(@Nullable int...); method public void setSelectAllOnFocus(boolean); method public void setShadowLayer(float, float, float, int); + method @FlaggedApi("com.android.text.flags.use_bounds_for_width") public void setShiftDrawingOffsetForStartOverhang(boolean); method public final void setShowSoftInputOnFocus(boolean); method public void setSingleLine(); method public void setSingleLine(boolean); diff --git a/core/api/lint-baseline.txt b/core/api/lint-baseline.txt index 9b8ab9bbb8e9..1b0da055038d 100644 --- a/core/api/lint-baseline.txt +++ b/core/api/lint-baseline.txt @@ -1461,6 +1461,7 @@ UnflaggedApi: android.graphics.text.PositionedGlyphs#getItalicOverride(int): New API must be flagged with @FlaggedApi: method android.graphics.text.PositionedGlyphs.getItalicOverride(int) UnflaggedApi: android.graphics.text.PositionedGlyphs#getWeightOverride(int): New API must be flagged with @FlaggedApi: method android.graphics.text.PositionedGlyphs.getWeightOverride(int) + UnflaggedApi: android.hardware.camera2.ExtensionCaptureRequest: New API must be flagged with @FlaggedApi: class android.hardware.camera2.ExtensionCaptureRequest UnflaggedApi: android.hardware.camera2.ExtensionCaptureRequest#ExtensionCaptureRequest(): diff --git a/core/api/system-current.txt b/core/api/system-current.txt index f93eab5b38ca..c144728a435c 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -195,6 +195,8 @@ package android { field public static final String MANAGE_DEFAULT_APPLICATIONS = "android.permission.MANAGE_DEFAULT_APPLICATIONS"; field public static final String MANAGE_DEVICE_ADMINS = "android.permission.MANAGE_DEVICE_ADMINS"; field public static final String MANAGE_DEVICE_POLICY_APP_EXEMPTIONS = "android.permission.MANAGE_DEVICE_POLICY_APP_EXEMPTIONS"; + field @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") public static final String MANAGE_DEVICE_POLICY_AUDIT_LOGGING = "android.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING"; + field @FlaggedApi("android.app.admin.flags.device_theft_api_enabled") public static final String MANAGE_DEVICE_POLICY_THEFT_DETECTION = "android.permission.MANAGE_DEVICE_POLICY_THEFT_DETECTION"; field @FlaggedApi("android.permission.flags.enhanced_confirmation_mode_apis_enabled") public static final String MANAGE_ENHANCED_CONFIRMATION_STATES = "android.permission.MANAGE_ENHANCED_CONFIRMATION_STATES"; field public static final String MANAGE_ETHERNET_NETWORKS = "android.permission.MANAGE_ETHERNET_NETWORKS"; field public static final String MANAGE_FACTORY_RESET_PROTECTION = "android.permission.MANAGE_FACTORY_RESET_PROTECTION"; @@ -203,7 +205,6 @@ package android { field public static final String MANAGE_HOTWORD_DETECTION = "android.permission.MANAGE_HOTWORD_DETECTION"; field public static final String MANAGE_IPSEC_TUNNELS = "android.permission.MANAGE_IPSEC_TUNNELS"; field public static final String MANAGE_LOW_POWER_STANDBY = "android.permission.MANAGE_LOW_POWER_STANDBY"; - field @FlaggedApi("com.android.media.flags.limit_manage_media_projection") public static final String MANAGE_MEDIA_PROJECTION = "android.permission.MANAGE_MEDIA_PROJECTION"; field public static final String MANAGE_MUSIC_RECOGNITION = "android.permission.MANAGE_MUSIC_RECOGNITION"; field public static final String MANAGE_NOTIFICATION_LISTENERS = "android.permission.MANAGE_NOTIFICATION_LISTENERS"; field public static final String MANAGE_ONE_TIME_PERMISSION_SESSIONS = "android.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS"; @@ -366,7 +367,7 @@ package android { field public static final String SET_VOLUME_KEY_LONG_PRESS_LISTENER = "android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER"; field public static final String SET_WALLPAPER_COMPONENT = "android.permission.SET_WALLPAPER_COMPONENT"; field public static final String SET_WALLPAPER_DIM_AMOUNT = "android.permission.SET_WALLPAPER_DIM_AMOUNT"; - field @FlaggedApi("android.service.chooser.support_nfc_resolver") public static final String SHOW_CUSTOMIZED_RESOLVER = "android.permission.SHOW_CUSTOMIZED_RESOLVER"; + field @FlaggedApi("android.nfc.enable_nfc_mainline") public static final String SHOW_CUSTOMIZED_RESOLVER = "android.permission.SHOW_CUSTOMIZED_RESOLVER"; field public static final String SHOW_KEYGUARD_MESSAGE = "android.permission.SHOW_KEYGUARD_MESSAGE"; field public static final String SHUTDOWN = "android.permission.SHUTDOWN"; field public static final String SIGNAL_REBOOT_READINESS = "android.permission.SIGNAL_REBOOT_READINESS"; @@ -594,6 +595,7 @@ package android.app { field public static final int FOREGROUND_SERVICE_API_TYPE_MICROPHONE = 6; // 0x6 field public static final int FOREGROUND_SERVICE_API_TYPE_PHONE_CALL = 7; // 0x7 field public static final int FOREGROUND_SERVICE_API_TYPE_USB = 8; // 0x8 + field @FlaggedApi("android.media.audio.foreground_audio_control") public static final int PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL = 64; // 0x40 field public static final int PROCESS_CAPABILITY_FOREGROUND_CAMERA = 2; // 0x2 field public static final int PROCESS_CAPABILITY_FOREGROUND_LOCATION = 1; // 0x1 field public static final int PROCESS_CAPABILITY_FOREGROUND_MICROPHONE = 4; // 0x4 @@ -624,6 +626,8 @@ package android.app { method public static String[] getOpStrs(); method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...); method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[]); + method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[], @NonNull String); + method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.permission.PermissionGroupUsage> getPermissionGroupUsageForPrivacyIndicator(boolean); method public static int opToDefaultMode(@NonNull String); method @Nullable public static String opToPermission(@NonNull String); method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(@NonNull String, int, @Nullable String, int); @@ -1288,6 +1292,10 @@ package android.app.admin { field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.DevicePolicyDrawableResource> CREATOR; } + public final class DevicePolicyIdentifiers { + field @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") public static final String AUDIT_LOGGING_POLICY = "auditLogging"; + } + public class DevicePolicyKeyguardService extends android.app.Service { ctor public DevicePolicyKeyguardService(); method @Nullable public void dismiss(); @@ -1316,12 +1324,14 @@ package android.app.admin { method @Nullable public android.content.ComponentName getProfileOwner() throws java.lang.IllegalArgumentException; method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS}) public String getProfileOwnerNameAsUser(int) throws java.lang.IllegalArgumentException; method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS}) public int getUserProvisioningState(); + method @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) public boolean isAuditLogEnabled(); method public boolean isDeviceManaged(); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isDeviceProvisioned(); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isDeviceProvisioningConfigApplied(); method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public boolean isDpcDownloaded(); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS}) public boolean isManagedKiosk(); method public boolean isSecondaryLockscreenEnabled(@NonNull android.os.UserHandle); + method @FlaggedApi("android.app.admin.flags.device_theft_api_enabled") @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_THEFT_DETECTION) public boolean isTheftDetectionTriggered(); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS}) public boolean isUnattendedManagedKiosk(); method @RequiresPermission("android.permission.NOTIFY_PENDING_SYSTEM_UPDATE") public void notifyPendingSystemUpdate(long); method @RequiresPermission("android.permission.NOTIFY_PENDING_SYSTEM_UPDATE") public void notifyPendingSystemUpdate(long, boolean); @@ -1330,6 +1340,8 @@ package android.app.admin { method @RequiresPermission(android.Manifest.permission.TRIGGER_LOST_MODE) public void sendLostModeLocationUpdate(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS) public boolean setActiveProfileOwner(@NonNull android.content.ComponentName, String) throws java.lang.IllegalArgumentException; method @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_APP_EXEMPTIONS) public void setApplicationExemptions(@NonNull String, @NonNull java.util.Set<java.lang.Integer>) throws android.content.pm.PackageManager.NameNotFoundException; + method @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) public void setAuditLogEnabled(boolean); + method @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) public void setAuditLogEventCallback(@NonNull java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.util.List<android.app.admin.SecurityLog.SecurityEvent>>); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setDeviceProvisioningConfigApplied(); method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setDpcDownloaded(boolean); method @FlaggedApi("android.app.admin.flags.device_policy_size_tracking_enabled") @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setMaxPolicyStorageLimit(int); @@ -3683,6 +3695,7 @@ package android.content { field public static final String ACTION_INSTANT_APP_RESOLVER_SETTINGS = "android.intent.action.INSTANT_APP_RESOLVER_SETTINGS"; field @Deprecated public static final String ACTION_INTENT_FILTER_NEEDS_VERIFICATION = "android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION"; field public static final String ACTION_LOAD_DATA = "android.intent.action.LOAD_DATA"; + field @FlaggedApi("android.security.frp_enforcement") public static final String ACTION_MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED = "android.intent.action.MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED"; field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_MANAGE_APP_PERMISSION = "android.intent.action.MANAGE_APP_PERMISSION"; field @Deprecated public static final String ACTION_MANAGE_APP_PERMISSIONS = "android.intent.action.MANAGE_APP_PERMISSIONS"; field @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public static final String ACTION_MANAGE_DEFAULT_APP = "android.intent.action.MANAGE_DEFAULT_APP"; @@ -4755,9 +4768,13 @@ package android.hardware.camera2.extension { @FlaggedApi("com.android.internal.camera.flags.concert_mode") public final class CameraOutputSurface { ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") public CameraOutputSurface(@NonNull android.view.Surface, @NonNull android.util.Size); + method @FlaggedApi("com.android.internal.camera.flags.extension_10_bit") public int getColorSpace(); + method @FlaggedApi("com.android.internal.camera.flags.extension_10_bit") public long getDynamicRangeProfile(); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int getImageFormat(); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public android.util.Size getSize(); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public android.view.Surface getSurface(); + method @FlaggedApi("com.android.internal.camera.flags.extension_10_bit") public void setColorSpace(int); + method @FlaggedApi("com.android.internal.camera.flags.extension_10_bit") public void setDynamicRangeProfile(long); } @FlaggedApi("com.android.internal.camera.flags.concert_mode") public class CharacteristicsMap { @@ -4810,8 +4827,8 @@ package android.hardware.camera2.extension { } @FlaggedApi("com.android.internal.camera.flags.concert_mode") public static interface SessionProcessor.CaptureCallback { - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureCompleted(long, int, @NonNull android.hardware.camera2.CaptureResult); - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureFailed(int); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureCompleted(long, int, @NonNull java.util.Map<android.hardware.camera2.CaptureResult.Key,java.lang.Object>); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureFailed(int, int); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureProcessStarted(int); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureSequenceAborted(int); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureSequenceCompleted(int); @@ -7108,7 +7125,6 @@ package android.media { public final class MediaRouter2 { method @NonNull public java.util.List<android.media.MediaRoute2Info> getAllRoutes(); method @Nullable public String getClientPackageName(); - method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void setRouteVolume(@NonNull android.media.MediaRoute2Info, int); method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void startScan(); method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void stopScan(); method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void transfer(@NonNull android.media.MediaRouter2.RoutingController, @NonNull android.media.MediaRoute2Info); @@ -10238,6 +10254,7 @@ package android.nfc.cardemulation { ctor @FlaggedApi("android.nfc.enable_nfc_mainline") public ApduServiceInfo(@NonNull android.content.pm.PackageManager, @NonNull android.content.pm.ResolveInfo, boolean) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void addPollingLoopFilter(@NonNull String); method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void addPollingLoopFilterToAutoTransact(@NonNull String); + method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean defaultToObserveMode(); method @FlaggedApi("android.nfc.enable_nfc_mainline") public int describeContents(); method @FlaggedApi("android.nfc.enable_nfc_mainline") public void dump(@NonNull android.os.ParcelFileDescriptor, @NonNull java.io.PrintWriter, @NonNull String[]); method @FlaggedApi("android.nfc.enable_nfc_mainline") public void dumpDebug(@NonNull android.util.proto.ProtoOutputStream); @@ -10267,6 +10284,7 @@ package android.nfc.cardemulation { method @FlaggedApi("android.nfc.enable_nfc_mainline") public boolean requiresUnlock(); method @FlaggedApi("android.nfc.enable_nfc_mainline") public void resetOffHostSecureElement(); method @FlaggedApi("android.nfc.enable_nfc_mainline") public void setCategoryOtherServiceEnabled(boolean); + method @FlaggedApi("android.nfc.nfc_observe_mode") public void setDefaultToObserveMode(boolean); method @FlaggedApi("android.nfc.enable_nfc_mainline") public void setDynamicAidGroup(@NonNull android.nfc.cardemulation.AidGroup); method @FlaggedApi("android.nfc.enable_nfc_mainline") public void setOffHostSecureElement(@NonNull String); method @FlaggedApi("android.nfc.enable_nfc_mainline") public void writeToParcel(@NonNull android.os.Parcel, int); @@ -11332,6 +11350,7 @@ package android.permission { method public long getLastAccessTimeMillis(); method @NonNull public String getPackageName(); method @NonNull public String getPermissionGroupName(); + method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") @NonNull public String getPersistentDeviceId(); method @Nullable public CharSequence getProxyLabel(); method public int getUid(); method public boolean isActive(); @@ -12309,14 +12328,6 @@ package android.service.carrier { } -package android.service.chooser { - - @FlaggedApi("android.service.chooser.support_nfc_resolver") public class CustomChoosers { - method @FlaggedApi("android.service.chooser.support_nfc_resolver") @NonNull public static android.content.Intent createNfcResolverIntent(@NonNull android.content.Intent, @Nullable CharSequence, @NonNull java.util.List<android.content.pm.ResolveInfo>); - } - -} - package android.service.cloudsearch { public abstract class CloudSearchService extends android.app.Service { @@ -13370,43 +13381,6 @@ package android.service.voice { method @NonNull public android.service.voice.HotwordRejectedResult.Builder setConfidenceLevel(int); } - @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public final class HotwordTrainingAudio implements android.os.Parcelable { - method public int describeContents(); - method @NonNull public android.media.AudioFormat getAudioFormat(); - method @NonNull public int getAudioType(); - method @NonNull public byte[] getHotwordAudio(); - method public int getHotwordOffsetMillis(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.HotwordTrainingAudio> CREATOR; - field public static final int HOTWORD_OFFSET_UNSET = -1; // 0xffffffff - } - - @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public static final class HotwordTrainingAudio.Builder { - ctor public HotwordTrainingAudio.Builder(@NonNull byte[], @NonNull android.media.AudioFormat); - method @NonNull public android.service.voice.HotwordTrainingAudio build(); - method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setAudioFormat(@NonNull android.media.AudioFormat); - method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setAudioType(@NonNull int); - method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setHotwordAudio(@NonNull byte[]); - method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setHotwordOffsetMillis(int); - } - - @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public final class HotwordTrainingData implements android.os.Parcelable { - method public int describeContents(); - method public static int getMaxTrainingDataBytes(); - method public int getTimeoutStage(); - method @NonNull public java.util.List<android.service.voice.HotwordTrainingAudio> getTrainingAudioList(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.HotwordTrainingData> CREATOR; - } - - @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public static final class HotwordTrainingData.Builder { - ctor public HotwordTrainingData.Builder(); - method @NonNull public android.service.voice.HotwordTrainingData.Builder addTrainingAudio(@NonNull android.service.voice.HotwordTrainingAudio); - method @NonNull public android.service.voice.HotwordTrainingData build(); - method @NonNull public android.service.voice.HotwordTrainingData.Builder setTimeoutStage(int); - method @NonNull public android.service.voice.HotwordTrainingData.Builder setTrainingAudioList(@NonNull java.util.List<android.service.voice.HotwordTrainingAudio>); - } - public interface SandboxedDetectionInitializer { method public static int getMaxCustomInitializationStatus(); method public void onUpdateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory, long, @Nullable java.util.function.IntConsumer); @@ -14350,9 +14324,9 @@ package android.telephony { @FlaggedApi("com.android.internal.telephony.flags.use_oem_domain_selection_service") public abstract class DomainSelectionService extends android.app.Service { ctor public DomainSelectionService(); + method @NonNull public java.util.concurrent.Executor getCreateExecutor(); method public void onBarringInfoUpdated(int, int, @NonNull android.telephony.BarringInfo); method @Nullable public final android.os.IBinder onBind(@Nullable android.content.Intent); - method @NonNull public java.util.concurrent.Executor onCreateExecutor(); method public abstract void onDomainSelection(@NonNull android.telephony.DomainSelectionService.SelectionAttributes, @NonNull android.telephony.TransportSelectorCallback); method public void onServiceStateUpdated(int, int, @NonNull android.telephony.ServiceState); field public static final int SCAN_TYPE_FULL_SERVICE = 2; // 0x2 @@ -15132,6 +15106,7 @@ package android.telephony { method @Deprecated public boolean getDataEnabled(int); method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getDefaultRespondViaMessageApplication(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getDeviceSoftwareVersion(int); + method @FlaggedApi("android.permission.flags.get_emergency_role_holder_api_enabled") @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getEmergencyAssistancePackage(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt index a6505c8b6093..ca9fab815167 100644 --- a/core/api/system-lint-baseline.txt +++ b/core/api/system-lint-baseline.txt @@ -535,6 +535,10 @@ ListenerLast: android.telephony.satellite.SatelliteManager#stopSatelliteTransmis Listeners should always be at end of argument list (method `stopSatelliteTransmissionUpdates`) +MethodNameUnits: android.hardware.camera2.extension.CameraOutputSurface#getColorSpace(): + Expected method name units to be `Bytes`, was `Space` in `getColorSpace` + + MissingGetterMatchingBuilder: android.service.voice.HotwordTrainingData.Builder#addTrainingAudio(android.service.voice.HotwordTrainingAudio): android.service.voice.HotwordTrainingData does not declare a `getTrainingAudios()` method matching method android.service.voice.HotwordTrainingData.Builder.addTrainingAudio(android.service.voice.HotwordTrainingAudio) MissingGetterMatchingBuilder: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallViaAudioProcessing(boolean): diff --git a/core/java/android/adaptiveauth/flags.aconfig b/core/java/android/adaptiveauth/flags.aconfig index 39e46bbdfa6a..de4e607b50f1 100644 --- a/core/java/android/adaptiveauth/flags.aconfig +++ b/core/java/android/adaptiveauth/flags.aconfig @@ -1,6 +1,13 @@ package: "android.adaptiveauth" flag { + name: "enable_adaptive_auth" + namespace: "biometrics" + description: "Feature flag for enabling the new adaptive auth service" + bug: "285053096" +} + +flag { name: "report_biometric_auth_attempts" namespace: "biometrics" description: "Control the usage of the biometric auth signal in adaptive auth" diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 23fe731701b6..251f82320ae5 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -844,7 +844,32 @@ public class Activity extends ContextThemeWrapper private IBinder mToken; private IBinder mAssistToken; private IBinder mShareableActivityToken; + + /** Initial caller of the activity. Can be retrieved from {@link #getInitialCaller} */ private ComponentCaller mInitialCaller; + /** + * Caller associated with the Intent from {@link #getIntent}. Can be retrieved from + * {@link #getCaller}. + * + * <p>The value of this field depends on how the activity set its intent: + * - If via {@link #setIntent(Intent)}, the caller will be {@code null}. + * - If via {@link #setIntent(Intent, ComponentCaller)}, the caller will be set to the passed + * caller. + */ + private ComponentCaller mCaller; + /** + * Caller associated with an Intent within {@link #onNewIntent} and {@link #onActivityResult}. + * Can be retrieved from either of these methods: + * - {@link #getCurrentCaller} + * - By overriding {@link #onNewIntent(Intent, ComponentCaller)} and getting the second argument + * - By overriding {@link #onActivityResult(int, int, Intent, ComponentCaller)} and getting the + * fourth argument + * + * <p>The value of this field will be {@code null} outside of {@link #onNewIntent} and + * {@link #onActivityResult}. + */ + private ComponentCaller mCurrentCaller; + @UnsupportedAppUsage private int mIdent; @UnsupportedAppUsage @@ -1117,23 +1142,71 @@ public class Activity extends ContextThemeWrapper private static native String getDlWarning(); - /** Return the intent that started this activity. */ + /** + * Returns the intent that started this activity. + * + * <p>To keep the Intent instance for future use, call {@link #setIntent(Intent)}, and use + * this method to retrieve it. + */ public Intent getIntent() { return mIntent; } /** - * Change the intent returned by {@link #getIntent}. This holds a - * reference to the given intent; it does not copy it. Often used in - * conjunction with {@link #onNewIntent}. + * Changes the intent returned by {@link #getIntent}. This holds a + * reference to the given intent; it does not copy it. Often used in + * conjunction with {@link #onNewIntent(Intent)}. * - * @param newIntent The new Intent object to return from getIntent + * @param newIntent The new Intent object to return from {@link #getIntent} * * @see #getIntent - * @see #onNewIntent + * @see #onNewIntent(Intent) */ public void setIntent(Intent newIntent) { + internalSetIntent(newIntent, /* newCaller */ null); + } + + /** + * Returns the ComponentCaller instance of the app that launched this activity with the intent + * from {@link #getIntent()}. To keep the value of the ComponentCaller instance for new intents, + * call {@link #setIntent(Intent, ComponentCaller)} instead of {@link #setIntent(Intent)}. + * + * @return {@link ComponentCaller} instance corresponding to the intent from + * {@link #getIntent()}, or {@code null} if the activity was not launched with that + * intent + * + * @see ComponentCaller + * @see #getIntent + * @see #setIntent(Intent, ComponentCaller) + */ + @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS) + public @Nullable ComponentCaller getCaller() { + return mCaller; + } + + /** + * Changes the intent returned by {@link #getIntent}, and ComponentCaller returned by + * {@link #getCaller}. This holds references to the given intent, and ComponentCaller; it does + * not copy them. Often used in conjunction with {@link #onNewIntent(Intent)}. To retrieve the + * caller from {@link #onNewIntent(Intent)}, use {@link #getCurrentCaller}, otherwise override + * {@link #onNewIntent(Intent, ComponentCaller)}. + * + * @param newIntent The new Intent object to return from {@link #getIntent} + * @param newCaller The new {@link ComponentCaller} object to return from + * {@link #getCaller} + * + * @see #getIntent + * @see #onNewIntent(Intent, ComponentCaller) + * @see #getCaller + */ + @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS) + public void setIntent(@Nullable Intent newIntent, @Nullable ComponentCaller newCaller) { + internalSetIntent(newIntent, newCaller); + } + + private void internalSetIntent(Intent newIntent, ComponentCaller newCaller) { mIntent = newIntent; + mCaller = newCaller; } /** @@ -2284,18 +2357,42 @@ public class Activity extends ContextThemeWrapper * sometime later when activity becomes active again. * * <p>Note that {@link #getIntent} still returns the original Intent. You - * can use {@link #setIntent} to update it to this new Intent. + * can use {@link #setIntent(Intent)} to update it to this new Intent. * - * @param intent The new intent that was started for the activity. + * @param intent The new intent that was used to start the activity * * @see #getIntent - * @see #setIntent + * @see #setIntent(Intent) * @see #onResume */ protected void onNewIntent(Intent intent) { } /** + * Same as {@link #onNewIntent(Intent)}, but with an extra parameter for the ComponentCaller + * instance associated with the app that sent the intent. + * + * <p>If you want to retrieve the caller without overriding this method, call + * {@link #getCurrentCaller} inside your existing {@link #onNewIntent(Intent)}. + * + * <p>Note that you should only override one {@link #onNewIntent} method. + * + * @param intent The new intent that was used to start the activity + * @param caller The {@link ComponentCaller} instance associated with the app that sent the + * intent + * + * @see ComponentCaller + * @see #onNewIntent(Intent) + * @see #getCurrentCaller + * @see #setIntent(Intent, ComponentCaller) + * @see #getCaller + */ + @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS) + public void onNewIntent(@NonNull Intent intent, @NonNull ComponentCaller caller) { + onNewIntent(intent); + } + + /** * The hook for {@link ActivityThread} to save the state of this activity. * * Calls {@link #onSaveInstanceState(android.os.Bundle)} @@ -7044,6 +7141,37 @@ public class Activity extends ContextThemeWrapper } /** + * Returns the ComponentCaller instance of the app that re-launched this activity with a new + * intent via {@link #onNewIntent} or {@link #onActivityResult}. + * + * <p>Note that this method only works within the {@link #onNewIntent} and + * {@link #onActivityResult} methods. If you call this method outside {@link #onNewIntent} and + * {@link #onActivityResult}, it will throw an {@link IllegalStateException}. + * + * <p>You can also retrieve the caller if you override + * {@link #onNewIntent(Intent, ComponentCaller)} or + * {@link #onActivityResult(int, int, Intent, ComponentCaller)}. + * + * <p>To keep the ComponentCaller instance for future use, call + * {@link #setIntent(Intent, ComponentCaller)}, and use {@link #getCaller} to retrieve it. + * + * @return {@link ComponentCaller} instance + * @throws IllegalStateException if the caller is {@code null}, indicating the method was called + * outside {@link #onNewIntent} + * @see ComponentCaller + * @see #setIntent(Intent, ComponentCaller) + * @see #getCaller + */ + @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS) + public @NonNull ComponentCaller getCurrentCaller() { + if (mCurrentCaller == null) { + throw new IllegalStateException("The caller is null because #getCurrentCaller should be" + + " called within #onNewIntent method"); + } + return mCurrentCaller; + } + + /** * Control whether this activity's main window is visible. This is intended * only for the special case of an activity that is not going to show a * UI itself, but can't just finish prior to onResume() because it needs @@ -7303,6 +7431,31 @@ public class Activity extends ContextThemeWrapper } /** + * Same as {@link #onActivityResult(int, int, Intent)}, but with an extra parameter for the + * ComponentCaller instance associated with the app that sent the result. + * + * <p>If you want to retrieve the caller without overriding this method, call + * {@link #getCurrentCaller} inside your existing {@link #onActivityResult(int, int, Intent)}. + * + * <p>Note that you should only override one {@link #onActivityResult} method. + * + * @param requestCode The integer request code originally supplied to + * startActivityForResult(), allowing you to identify who this + * result came from. + * @param resultCode The integer result code returned by the child activity + * through its setResult(). + * @param data An Intent, which can return result data to the caller + * (various data can be attached to Intent "extras"). + * @param caller The {@link ComponentCaller} instance associated with the app that sent the + * intent. + */ + @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS) + public void onActivityResult(int requestCode, int resultCode, @NonNull Intent data, + @NonNull ComponentCaller caller) { + onActivityResult(requestCode, resultCode, data); + } + + /** * Called when an activity you launched with an activity transition exposes this * Activity through a returning activity transition, giving you the resultCode * and any additional data from it. This method will only be called if the activity @@ -8740,6 +8893,7 @@ public class Activity extends ContextThemeWrapper if (android.security.Flags.contentUriPermissionApis()) { mInitialCaller = new ComponentCaller(getActivityToken(), initialCallerInfoAccessToken); + mCaller = mInitialCaller; } } @@ -8815,6 +8969,16 @@ public class Activity extends ContextThemeWrapper Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); } + @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS) + final void performNewIntent(@NonNull Intent intent, @NonNull ComponentCaller caller) { + Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performNewIntent"); + mCanEnterPictureInPicture = true; + mCurrentCaller = caller; + onNewIntent(intent, caller); + mCurrentCaller = null; + Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); + } + final void performStart(String reason) { if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) { Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performStart:" @@ -9135,15 +9299,36 @@ public class Activity extends ContextThemeWrapper } } + void dispatchActivityResult(String who, int requestCode, int resultCode, Intent data, + ComponentCaller caller, String reason) { + internalDispatchActivityResult(who, requestCode, resultCode, data, caller, reason); + } + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void dispatchActivityResult(String who, int requestCode, int resultCode, Intent data, String reason) { + if (android.security.Flags.contentUriPermissionApis()) { + internalDispatchActivityResult(who, requestCode, resultCode, data, + new ComponentCaller(getActivityToken(), /* callerToken */ null), reason); + } else { + internalDispatchActivityResult(who, requestCode, resultCode, data, null, reason); + } + } + + private void internalDispatchActivityResult(String who, int requestCode, int resultCode, + Intent data, ComponentCaller caller, String reason) { if (false) Log.v( TAG, "Dispatching result: who=" + who + ", reqCode=" + requestCode + ", resCode=" + resultCode + ", data=" + data); mFragments.noteStateNotSaved(); if (who == null) { - onActivityResult(requestCode, resultCode, data); + if (android.security.Flags.contentUriPermissionApis()) { + mCurrentCaller = caller; + onActivityResult(requestCode, resultCode, data, caller); + mCurrentCaller = null; + } else { + onActivityResult(requestCode, resultCode, data); + } } else if (who.startsWith(REQUEST_PERMISSIONS_WHO_PREFIX)) { who = who.substring(REQUEST_PERMISSIONS_WHO_PREFIX.length()); if (TextUtils.isEmpty(who)) { diff --git a/core/java/android/app/ActivityClient.java b/core/java/android/app/ActivityClient.java index a59f04bf4f3a..10dc3c6c1360 100644 --- a/core/java/android/app/ActivityClient.java +++ b/core/java/android/app/ActivityClient.java @@ -299,6 +299,26 @@ public class ActivityClient { } } + /** Returns the uid of the app that launched the activity. */ + public int getActivityCallerUid(IBinder activityToken, IBinder callerToken) { + try { + return getActivityClientController().getActivityCallerUid(activityToken, + callerToken); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** Returns the package of the app that launched the activity. */ + public String getActivityCallerPackage(IBinder activityToken, IBinder callerToken) { + try { + return getActivityClientController().getActivityCallerPackage(activityToken, + callerToken); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** Checks if the app that launched the activity has access to the URI. */ public int checkActivityCallerContentUriPermission(IBinder activityToken, IBinder callerToken, Uri uri, int modeFlags) { diff --git a/core/java/android/app/ActivityGroup.java b/core/java/android/app/ActivityGroup.java index cb06eea2059e..21c67edc607e 100644 --- a/core/java/android/app/ActivityGroup.java +++ b/core/java/android/app/ActivityGroup.java @@ -111,7 +111,7 @@ public class ActivityGroup extends Activity { @Override void dispatchActivityResult(String who, int requestCode, int resultCode, - Intent data, String reason) { + Intent data, ComponentCaller caller, String reason) { if (who != null) { Activity act = mLocalActivityManager.getActivity(who); /* @@ -125,7 +125,7 @@ public class ActivityGroup extends Activity { return; } } - super.dispatchActivityResult(who, requestCode, resultCode, data, reason); + super.dispatchActivityResult(who, requestCode, resultCode, data, caller, reason); } } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index a8d183a1d6dd..237d31c67fe2 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.activityTypeToString; import static android.app.WindowConfiguration.windowingModeToString; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; +import static android.media.audio.Flags.FLAG_FOREGROUND_AUDIO_CONTROL; import android.Manifest; import android.annotation.ColorInt; @@ -794,6 +795,7 @@ public class ActivityManager { PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK, PROCESS_CAPABILITY_BFSL, PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK, + PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL, }) @Retention(RetentionPolicy.SOURCE) public @interface ProcessCapability {} @@ -943,6 +945,14 @@ public class ActivityManager { public static final int PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK = 1 << 5; /** + * @hide + * Process can access volume APIs and can request audio focus with GAIN. + */ + @FlaggedApi(FLAG_FOREGROUND_AUDIO_CONTROL) + @SystemApi + public static final int PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL = 1 << 6; + + /** * @hide all capabilities, the ORing of all flags in {@link ProcessCapability}. * * Don't expose it as TestApi -- we may add new capabilities any time, which could @@ -953,7 +963,8 @@ public class ActivityManager { | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK | PROCESS_CAPABILITY_BFSL - | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK; + | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK + | PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; /** * All implicit capabilities. There are capabilities that process automatically have. @@ -975,6 +986,7 @@ public class ActivityManager { pw.print((caps & PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0 ? 'N' : '-'); pw.print((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-'); pw.print((caps & PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0 ? 'U' : '-'); + pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL) != 0 ? 'A' : '-'); } /** @hide */ @@ -986,6 +998,7 @@ public class ActivityManager { sb.append((caps & PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0 ? 'N' : '-'); sb.append((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-'); sb.append((caps & PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0 ? 'U' : '-'); + sb.append((caps & PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL) != 0 ? 'A' : '-'); } /** diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index e14bf68bde53..2a2c5f05f122 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -20,6 +20,7 @@ import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIO import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_RECEIVER_FOREGROUND; import static android.view.Display.INVALID_DISPLAY; @@ -1849,7 +1850,7 @@ public class ActivityOptions extends ComponentOptions { public int getPendingIntentLaunchFlags() { // b/243794108: Ignore all flags except the new task flag, to be reconsidered in b/254490217 return mPendingIntentLaunchFlags & - (FLAG_ACTIVITY_NEW_TASK | FLAG_RECEIVER_FOREGROUND); + (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK | FLAG_RECEIVER_FOREGROUND); } /** diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index b25d5ebf61a0..926e297a1098 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3758,7 +3758,7 @@ public final class ActivityThread extends ClientTransactionHandler if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id + " req=" + requestCode + " res=" + resultCode + " data=" + data); final ArrayList<ResultInfo> list = new ArrayList<>(); - list.add(new ResultInfo(id, requestCode, resultCode, data)); + list.add(new ResultInfo(id, requestCode, resultCode, data, activityToken)); final ClientTransaction clientTransaction = ClientTransaction.obtain(mAppThread); final ActivityResultItem activityResultItem = ActivityResultItem.obtain( activityToken, list); @@ -4203,7 +4203,12 @@ public final class ActivityThread extends ClientTransactionHandler intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo), r.activity.getAttributionSource()); r.activity.mFragments.noteStateNotSaved(); - mInstrumentation.callActivityOnNewIntent(r.activity, intent); + if (android.security.Flags.contentUriPermissionApis()) { + ComponentCaller caller = new ComponentCaller(r.token, intent.mCallerToken); + mInstrumentation.callActivityOnNewIntent(r.activity, intent, caller); + } else { + mInstrumentation.callActivityOnNewIntent(r.activity, intent); + } } } @@ -5794,8 +5799,14 @@ public final class ActivityThread extends ClientTransactionHandler } if (DEBUG_RESULTS) Slog.v(TAG, "Delivering result to activity " + r + " : " + ri); - r.activity.dispatchActivityResult(ri.mResultWho, - ri.mRequestCode, ri.mResultCode, ri.mData, reason); + if (android.security.Flags.contentUriPermissionApis()) { + ComponentCaller caller = new ComponentCaller(r.token, ri.mCallerToken); + r.activity.dispatchActivityResult(ri.mResultWho, + ri.mRequestCode, ri.mResultCode, ri.mData, caller, reason); + } else { + r.activity.dispatchActivityResult(ri.mResultWho, + ri.mRequestCode, ri.mResultCode, ri.mData, reason); + } } catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { throw new RuntimeException( diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 2100425a6771..16c7753c7f46 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -16,7 +16,9 @@ package android.app; + import static android.location.flags.Flags.FLAG_LOCATION_BYPASS; +import static android.media.audio.Flags.foregroundAudioControl; import static android.permission.flags.Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER; import static android.view.contentprotection.flags.Flags.FLAG_CREATE_ACCESSIBILITY_OVERLAY_APP_OP_ENABLED; import static android.view.contentprotection.flags.Flags.FLAG_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER_APP_OP_ENABLED; @@ -70,6 +72,8 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; +import android.permission.PermissionGroupUsage; +import android.permission.PermissionUsageHelper; import android.provider.DeviceConfig; import android.util.ArrayMap; import android.util.ArraySet; @@ -224,6 +228,7 @@ public class AppOpsManager { private static Boolean sFullLog = null; final Context mContext; + private PermissionUsageHelper mUsageHelper; @UnsupportedAppUsage final IAppOpsService mService; @@ -3229,6 +3234,10 @@ public class AppOpsManager { * @hide */ public static @Mode int opToDefaultMode(int op) { + if (op == OP_TAKE_AUDIO_FOCUS && foregroundAudioControl()) { + // when removing the flag, change the entry in sAppOpInfos for OP_TAKE_AUDIO_FOCUS + return AppOpsManager.MODE_FOREGROUND; + } return sAppOpInfos[op].defaultMode; } @@ -7759,6 +7768,44 @@ public class AppOpsManager { } /** + * Retrieve current operation state for all applications for a device. + * + * The mode of the ops returned are set for the package but may not reflect their effective + * state due to UID policy or because it's controlled by a different global op. + * + * Use {@link #unsafeCheckOp(String, int, String)}} or + * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed. + * + * @param ops The set of operations you are interested in, or null if you want all of them. + * @param persistentDeviceId The device that the ops are attributed to. + * + * @hide + */ + @SystemApi + @FlaggedApi(android.permission.flags.Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) + @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) + public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops, + @NonNull String persistentDeviceId) { + final int[] opCodes; + if (ops != null) { + final int opCount = ops.length; + opCodes = new int[opCount]; + for (int i = 0; i < opCount; i++) { + opCodes[i] = sOpStrToOp.get(ops[i]); + } + } else { + opCodes = null; + } + final List<AppOpsManager.PackageOps> result; + try { + result = mService.getPackagesForOpsForDevice(opCodes, persistentDeviceId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + return (result != null) ? result : Collections.emptyList(); + } + + /** * Retrieve current operation state for all applications. * * The mode of the ops returned are set for the package but may not reflect their effective @@ -7774,7 +7821,8 @@ public class AppOpsManager { @UnsupportedAppUsage public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) { try { - return mService.getPackagesForOps(ops); + return mService.getPackagesForOpsForDevice(ops, + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -9940,6 +9988,30 @@ public class AppOpsManager { appOpsNotedForAttribution.set(op); } + /** + * Get recent op usage data for CAMERA, MICROPHONE and LOCATION from all connected devices + * to power privacy indicator. + * + * @param includeMicrophoneUsage whether to retrieve microphone usage + * @return A list of permission groups currently or recently used by all apps by all users in + * the current profile group. + * + * @hide + */ + @SystemApi + @NonNull + @FlaggedApi(android.permission.flags.Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) + @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS) + public List<PermissionGroupUsage> getPermissionGroupUsageForPrivacyIndicator( + boolean includeMicrophoneUsage) { + // Lazily initialize the usage helper + if (mUsageHelper == null) { + mUsageHelper = new PermissionUsageHelper(mContext); + } + + return mUsageHelper.getOpUsageDataForAllDevices(includeMicrophoneUsage); + } + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(value = { diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java index f727ee5a95fe..1b5b0fc5d917 100644 --- a/core/java/android/app/BroadcastOptions.java +++ b/core/java/android/app/BroadcastOptions.java @@ -16,6 +16,8 @@ package android.app; +import android.annotation.CurrentTimeMillisLong; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; @@ -65,6 +67,8 @@ public class BroadcastOptions extends ComponentOptions { private @Nullable BundleMerger mDeliveryGroupExtrasMerger; private @Nullable IntentFilter mDeliveryGroupMatchingFilter; private @DeferralPolicy int mDeferralPolicy; + private @CurrentTimeMillisLong long mEventTriggerTimestampMillis; + private @CurrentTimeMillisLong long mRemoteEventTriggerTimestampMillis; /** @hide */ @IntDef(flag = true, prefix = { "FLAG_" }, value = { @@ -190,6 +194,18 @@ public class BroadcastOptions extends ComponentOptions { "android:broadcast.idForResponseEvent"; /** + * Corresponds to {@link #setEventTriggerTimestampMillis(long)}. + */ + private static final String KEY_EVENT_TRIGGER_TIMESTAMP = + "android:broadcast.eventTriggerTimestamp"; + + /** + * Corresponds to {@link #setRemoteEventTriggerTimestampMillis(long)}. + */ + private static final String KEY_REMOTE_EVENT_TRIGGER_TIMESTAMP = + "android:broadcast.remoteEventTriggerTimestamp"; + + /** * Corresponds to {@link #setDeliveryGroupPolicy(int)}. */ private static final String KEY_DELIVERY_GROUP_POLICY = @@ -341,6 +357,8 @@ public class BroadcastOptions extends ComponentOptions { mRequireNoneOfPermissions = opts.getStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS); mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID); mIdForResponseEvent = opts.getLong(KEY_ID_FOR_RESPONSE_EVENT); + mEventTriggerTimestampMillis = opts.getLong(KEY_EVENT_TRIGGER_TIMESTAMP); + mRemoteEventTriggerTimestampMillis = opts.getLong(KEY_REMOTE_EVENT_TRIGGER_TIMESTAMP); mDeliveryGroupPolicy = opts.getInt(KEY_DELIVERY_GROUP_POLICY, DELIVERY_GROUP_POLICY_ALL); mDeliveryGroupMatchingNamespaceFragment = opts.getString(KEY_DELIVERY_GROUP_NAMESPACE); @@ -787,6 +805,60 @@ public class BroadcastOptions extends ComponentOptions { } /** + * Set the timestamp for the event that triggered this broadcast, in + * {@link System#currentTimeMillis()} timebase. + * + * <p> For instance, if this broadcast is for a push message, then this timestamp + * could correspond to when the device received the message. + * + * @param timestampMillis the timestamp in {@link System#currentTimeMillis()} timebase that + * correspond to the event that triggered this broadcast. + */ + @FlaggedApi(android.app.Flags.FLAG_BCAST_EVENT_TIMESTAMPS) + public void setEventTriggerTimestampMillis(@CurrentTimeMillisLong long timestampMillis) { + mEventTriggerTimestampMillis = timestampMillis; + } + + /** + * Return the timestamp for the event that triggered this broadcast, in + * {@link System#currentTimeMillis()} timebase. + * + * @return the timestamp in {@link System#currentTimeMillis()} timebase that was previously + * set using {@link #setEventTriggerTimestampMillis(long)}. + */ + @FlaggedApi(android.app.Flags.FLAG_BCAST_EVENT_TIMESTAMPS) + public @CurrentTimeMillisLong long getEventTriggerTimestampMillis() { + return mEventTriggerTimestampMillis; + } + + /** + * Set the timestamp for the remote event, if any, that triggered this broadcast, in + * {@link System#currentTimeMillis()} timebase. + * + * <p> For instance, if this broadcast is for a push message, then this timestamp + * could correspond to when the message originated remotely. + * + * @param timestampMillis the timestamp in {@link System#currentTimeMillis()} timebase that + * correspond to the remote event that triggered this broadcast. + */ + @FlaggedApi(android.app.Flags.FLAG_BCAST_EVENT_TIMESTAMPS) + public void setRemoteEventTriggerTimestampMillis(@CurrentTimeMillisLong long timestampMillis) { + mRemoteEventTriggerTimestampMillis = timestampMillis; + } + + /** + * Return the timestamp for the remote event that triggered this broadcast, in + * {@link System#currentTimeMillis()} timebase. + * + * @return the timestamp in {@link System#currentTimeMillis()} timebase that was previously + * set using {@link #setRemoteEventTriggerTimestampMillis(long)}}. + */ + @FlaggedApi(android.app.Flags.FLAG_BCAST_EVENT_TIMESTAMPS) + public @CurrentTimeMillisLong long getRemoteEventTriggerTimestampMillis() { + return mRemoteEventTriggerTimestampMillis; + } + + /** * Sets deferral policy for this broadcast that specifies how this broadcast * can be deferred for delivery at some future point. */ @@ -1120,6 +1192,12 @@ public class BroadcastOptions extends ComponentOptions { if (mIdForResponseEvent != 0) { b.putLong(KEY_ID_FOR_RESPONSE_EVENT, mIdForResponseEvent); } + if (mEventTriggerTimestampMillis > 0) { + b.putLong(KEY_EVENT_TRIGGER_TIMESTAMP, mEventTriggerTimestampMillis); + } + if (mRemoteEventTriggerTimestampMillis > 0) { + b.putLong(KEY_REMOTE_EVENT_TRIGGER_TIMESTAMP, mRemoteEventTriggerTimestampMillis); + } if (mDeliveryGroupPolicy != DELIVERY_GROUP_POLICY_ALL) { b.putInt(KEY_DELIVERY_GROUP_POLICY, mDeliveryGroupPolicy); } diff --git a/core/java/android/app/ComponentCaller.java b/core/java/android/app/ComponentCaller.java index 44e8a0a3a20c..14bc0038883a 100644 --- a/core/java/android/app/ComponentCaller.java +++ b/core/java/android/app/ComponentCaller.java @@ -17,6 +17,7 @@ package android.app; import android.annotation.FlaggedApi; +import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Intent; import android.content.pm.PackageManager; @@ -24,8 +25,6 @@ import android.net.Uri; import android.os.IBinder; import android.os.Process; -import androidx.annotation.NonNull; - import java.util.Objects; /** @@ -45,7 +44,7 @@ public final class ComponentCaller { /** * @hide */ - public ComponentCaller(@NonNull IBinder activityToken, @Nullable IBinder callerToken) { + public ComponentCaller(@Nullable IBinder activityToken, @Nullable IBinder callerToken) { mActivityToken = activityToken; mCallerToken = callerToken; } @@ -83,7 +82,7 @@ public final class ComponentCaller { * @see Activity#getLaunchedFromUid() */ public int getUid() { - return ActivityClient.getInstance().getLaunchedFromUid(mActivityToken); + return ActivityClient.getInstance().getActivityCallerUid(mActivityToken, mCallerToken); } /** @@ -121,7 +120,7 @@ public final class ComponentCaller { */ @Nullable public String getPackage() { - return ActivityClient.getInstance().getLaunchedFromPackage(mActivityToken); + return ActivityClient.getInstance().getActivityCallerPackage(mActivityToken, mCallerToken); } /** diff --git a/core/java/android/app/IActivityClientController.aidl b/core/java/android/app/IActivityClientController.aidl index 05fee72b7e61..9c8fea15c712 100644 --- a/core/java/android/app/IActivityClientController.aidl +++ b/core/java/android/app/IActivityClientController.aidl @@ -90,7 +90,9 @@ interface IActivityClientController { ComponentName getCallingActivity(in IBinder token); String getCallingPackage(in IBinder token); int getLaunchedFromUid(in IBinder token); + int getActivityCallerUid(in IBinder activityToken, in IBinder callerToken); String getLaunchedFromPackage(in IBinder token); + String getActivityCallerPackage(in IBinder activityToken, in IBinder callerToken); int checkActivityCallerContentUriPermission(in IBinder activityToken, in IBinder callerToken, in Uri uri, int modeFlags, int userId); diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index 454d60534476..be7199b9a0fc 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -16,6 +16,7 @@ package android.app; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -1624,26 +1625,75 @@ public class Instrumentation { * @param intent The new intent being received. */ public void callActivityOnNewIntent(Activity activity, Intent intent) { - activity.performNewIntent(intent); + if (android.security.Flags.contentUriPermissionApis()) { + activity.performNewIntent(intent, new ComponentCaller(activity.getActivityToken(), + /* callerToken */ null)); + } else { + activity.performNewIntent(intent); + } + } + + /** + * Same as {@link #callActivityOnNewIntent(Activity, Intent)}, but with an extra parameter for + * the {@link ComponentCaller} instance associated with the app that sent the intent. + * + * @param activity The activity receiving a new Intent. + * @param intent The new intent being received. + * @param caller The {@link ComponentCaller} instance that launched the activity with the new + * intent. + */ + @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS) + public void callActivityOnNewIntent(@NonNull Activity activity, @NonNull Intent intent, + @NonNull ComponentCaller caller) { + activity.performNewIntent(intent, caller); } /** * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public void callActivityOnNewIntent(Activity activity, ReferrerIntent intent) { + @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS) + public void callActivityOnNewIntent(Activity activity, ReferrerIntent intent, + @NonNull ComponentCaller caller) { + internalCallActivityOnNewIntent(activity, intent, caller); + } + + @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS) + private void internalCallActivityOnNewIntent(Activity activity, ReferrerIntent intent, + @NonNull ComponentCaller caller) { final String oldReferrer = activity.mReferrer; try { if (intent != null) { activity.mReferrer = intent.mReferrer; } - callActivityOnNewIntent(activity, intent != null ? new Intent(intent) : null); + Intent newIntent = intent != null ? new Intent(intent) : null; + callActivityOnNewIntent(activity, newIntent, caller); } finally { activity.mReferrer = oldReferrer; } } /** + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + public void callActivityOnNewIntent(Activity activity, ReferrerIntent intent) { + if (android.security.Flags.contentUriPermissionApis()) { + internalCallActivityOnNewIntent(activity, intent, new ComponentCaller( + activity.getActivityToken(), /* callerToken */ null)); + } else { + final String oldReferrer = activity.mReferrer; + try { + if (intent != null) { + activity.mReferrer = intent.mReferrer; + } + callActivityOnNewIntent(activity, intent != null ? new Intent(intent) : null); + } finally { + activity.mReferrer = oldReferrer; + } + } + } + + /** * Perform calling of an activity's {@link Activity#onStart} * method. The default implementation simply calls through to that method. * diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS index f92ff83919c7..da0cc01e363d 100644 --- a/core/java/android/app/OWNERS +++ b/core/java/android/app/OWNERS @@ -31,6 +31,7 @@ per-file Service* = file:/services/core/java/com/android/server/am/OWNERS per-file SystemServiceRegistry.java = file:/services/core/java/com/android/server/am/OWNERS per-file *UserSwitchObserver* = file:/services/core/java/com/android/server/am/OWNERS per-file *UiAutomation* = file:/services/accessibility/OWNERS +per-file *UiAutomation* = file:/core/java/android/permission/OWNERS per-file GameManager* = file:/GAME_MANAGER_OWNERS per-file GameMode* = file:/GAME_MANAGER_OWNERS per-file GameState* = file:/GAME_MANAGER_OWNERS diff --git a/core/java/android/app/ResultInfo.java b/core/java/android/app/ResultInfo.java index 535f69f0e264..213c38c71543 100644 --- a/core/java/android/app/ResultInfo.java +++ b/core/java/android/app/ResultInfo.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Build; +import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -36,14 +37,21 @@ public class ResultInfo implements Parcelable { public final int mResultCode; @UnsupportedAppUsage public final Intent mData; + public final IBinder mCallerToken; @UnsupportedAppUsage public ResultInfo(String resultWho, int requestCode, int resultCode, Intent data) { + this(resultWho, requestCode, resultCode, data, /* callerToken */ null); + } + + public ResultInfo(String resultWho, int requestCode, int resultCode, + Intent data, IBinder callerToken) { mResultWho = resultWho; mRequestCode = requestCode; mResultCode = resultCode; mData = data; + mCallerToken = callerToken; } public String toString() { @@ -65,6 +73,7 @@ public class ResultInfo implements Parcelable { } else { out.writeInt(0); } + out.writeStrongBinder(mCallerToken); } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @@ -88,6 +97,7 @@ public class ResultInfo implements Parcelable { } else { mData = null; } + mCallerToken = in.readStrongBinder(); } @Override @@ -100,7 +110,8 @@ public class ResultInfo implements Parcelable { : mData.filterEquals(other.mData); return intentsEqual && Objects.equals(mResultWho, other.mResultWho) && mResultCode == other.mResultCode - && mRequestCode == other.mRequestCode; + && mRequestCode == other.mRequestCode + && mCallerToken == other.mCallerToken; } @Override @@ -112,6 +123,7 @@ public class ResultInfo implements Parcelable { if (mData != null) { result = 31 * result + mData.filterHashCode(); } + result = 31 * result + Objects.hashCode(mCallerToken); return result; } } diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig index ff23f09f78a5..350b1edf2129 100644 --- a/core/java/android/app/activity_manager.aconfig +++ b/core/java/android/app/activity_manager.aconfig @@ -34,3 +34,10 @@ flag { description: "Add a new callback in Service to indicate a FGS has reached its timeout." bug: "317799821" } + +flag { + name: "bcast_event_timestamps" + namespace: "backstage_power" + description: "Add APIs for clients to provide broadcast event trigger timestamps" + bug: "325136414" +} diff --git a/core/java/android/app/admin/DevicePolicyIdentifiers.java b/core/java/android/app/admin/DevicePolicyIdentifiers.java index a884ab0c4099..3c56aaf33ef3 100644 --- a/core/java/android/app/admin/DevicePolicyIdentifiers.java +++ b/core/java/android/app/admin/DevicePolicyIdentifiers.java @@ -20,6 +20,7 @@ import static android.app.admin.flags.Flags.FLAG_SECURITY_LOG_V2_ENABLED; import android.annotation.FlaggedApi; import android.annotation.NonNull; +import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.admin.flags.Flags; import android.os.UserManager; @@ -53,6 +54,15 @@ public final class DevicePolicyIdentifiers { public static final String SECURITY_LOGGING_POLICY = "securityLogging"; /** + * String identifier for {@link DevicePolicyManager#setAuditLogEnabled}. + * + * @hide + */ + @FlaggedApi(FLAG_SECURITY_LOG_V2_ENABLED) + @SystemApi + public static final String AUDIT_LOGGING_POLICY = "auditLogging"; + + /** * String identifier for {@link DevicePolicyManager#setLockTaskPackages}. */ public static final String LOCK_TASK_POLICY = "lockTask"; diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 34fb754b745f..a6fda9d23aca 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -45,6 +45,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SECURITY_LOGGING; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_STATUS_BAR; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SUPPORT_MESSAGE; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_THEFT_DETECTION; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIPE_DATA; @@ -54,7 +55,9 @@ import static android.Manifest.permission.SET_TIME; import static android.Manifest.permission.SET_TIME_ZONE; import static android.app.admin.flags.Flags.FLAG_ESIM_MANAGEMENT_ENABLED; import static android.app.admin.flags.Flags.FLAG_DEVICE_POLICY_SIZE_TRACKING_ENABLED; +import static android.app.admin.flags.Flags.FLAG_SECURITY_LOG_V2_ENABLED; import static android.app.admin.flags.Flags.onboardingBugreportV2Enabled; +import static android.app.admin.flags.Flags.FLAG_IS_MTE_POLICY_ENFORCED; import static android.content.Intent.LOCAL_FLAG_FROM_SYSTEM; import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; @@ -153,6 +156,7 @@ import com.android.internal.os.BackgroundThread; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; import com.android.org.conscrypt.TrustedCertificateStore; +import com.android.internal.os.Zygote; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; @@ -230,7 +234,6 @@ public class DevicePolicyManager { private final boolean mParentInstance; private final DevicePolicyResourcesManager mResourcesManager; - /** @hide */ public DevicePolicyManager(Context context, IDevicePolicyManager service) { this(context, service, false); @@ -4117,6 +4120,19 @@ public class DevicePolicyManager { return MTE_NOT_CONTROLLED_BY_POLICY; } + /** + * Get the current MTE state of the device. + * + * <a href="https://source.android.com/docs/security/test/memory-safety/arm-mte"> + * Learn more about MTE</a> + * + * @return whether MTE is currently enabled on the device. + */ + @FlaggedApi(FLAG_IS_MTE_POLICY_ENFORCED) + public static boolean isMtePolicyEnforced() { + return Zygote.nativeSupportsMemoryTagging(); + } + /** Indicates that content protection is not controlled by policy, allowing user to choose. */ @FlaggedApi(android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED) public static final int CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY = 0; @@ -14043,6 +14059,74 @@ public class DevicePolicyManager { } /** + * Controls whether audit logging is enabled. + * + * @hide + */ + @SystemApi + @FlaggedApi(FLAG_SECURITY_LOG_V2_ENABLED) + @RequiresPermission(permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) + public void setAuditLogEnabled(boolean enabled) { + throwIfParentInstance("setAuditLogEnabled"); + try { + mService.setAuditLogEnabled(mContext.getPackageName(), true); + } catch (RemoteException re) { + re.rethrowFromSystemServer(); + } + } + + /** + * @return Whether audit logging is enabled. + * + * @hide + */ + @SystemApi + @FlaggedApi(FLAG_SECURITY_LOG_V2_ENABLED) + @RequiresPermission(permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) + public boolean isAuditLogEnabled() { + throwIfParentInstance("isAuditLogEnabled"); + try { + return mService.isAuditLogEnabled(mContext.getPackageName()); + } catch (RemoteException re) { + re.rethrowFromSystemServer(); + // unreachable + return false; + } + } + + /** + * Sets audit log event callback. Only one callback per UID is active at any time, when a new + * callback is set, the previous one is forgotten. Should only be called when audit log policy + * is enforced by the caller. Disabling the policy clears the callback. Each time a new callback + * is set, it will first be invoked with all the audit log events available at the time. + * + * @param callback callback to invoke when new audit log events become available or {@code null} + * to clear the callback. + * @hide + */ + @SystemApi + @FlaggedApi(FLAG_SECURITY_LOG_V2_ENABLED) + @RequiresPermission(permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) + public void setAuditLogEventCallback( + @NonNull @CallbackExecutor Executor executor, + @Nullable Consumer<List<SecurityEvent>> callback) { + throwIfParentInstance("setAuditLogEventCallback"); + final IAuditLogEventsCallback wrappedCallback = callback == null + ? null + : new IAuditLogEventsCallback.Stub() { + @Override + public void onNewAuditLogEvents(List<SecurityEvent> events) { + executor.execute(() -> callback.accept(events)); + } + }; + try { + mService.setAuditLogEventsCallback(mContext.getPackageName(), wrappedCallback); + } catch (RemoteException re) { + re.rethrowFromSystemServer(); + } + } + + /** * Called by device owner or profile owner of an organization-owned managed profile to retrieve * all new security logging entries since the last call to this API after device boots. * @@ -17044,6 +17128,26 @@ public class DevicePolicyManager { } /** + * + * Returns whether the device considers itself to be potentially stolen. + * @hide + */ + @SystemApi + @RequiresPermission(value = MANAGE_DEVICE_POLICY_THEFT_DETECTION) + @FlaggedApi(Flags.FLAG_DEVICE_THEFT_API_ENABLED) + public boolean isTheftDetectionTriggered() { + throwIfParentInstance("isTheftDetectionTriggered"); + if (mService == null) { + return false; + } + try { + return mService.isTheftDetectionTriggered(mContext.getPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Returns a {@link DevicePolicyResourcesManager} containing the required APIs to set, reset, * and get device policy related resources. */ diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java index 07ee8de587f8..1aee9fe57466 100644 --- a/core/java/android/app/admin/DevicePolicyManagerInternal.java +++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java @@ -338,4 +338,9 @@ public abstract class DevicePolicyManagerInternal { * Enforces resolved security logging policy, should only be invoked from device policy engine. */ public abstract void enforceSecurityLoggingPolicy(boolean enabled); + + /** + * Enforces resolved audit logging policy, should only be invoked from device policy engine. + */ + public abstract void enforceAuditLoggingPolicy(boolean enabled); } diff --git a/core/java/android/app/admin/IAuditLogEventsCallback.aidl b/core/java/android/app/admin/IAuditLogEventsCallback.aidl new file mode 100644 index 000000000000..ab871178a9b9 --- /dev/null +++ b/core/java/android/app/admin/IAuditLogEventsCallback.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.admin; + +import android.app.admin.SecurityLog; + +/** @hide */ +oneway interface IAuditLogEventsCallback { + void onNewAuditLogEvents(in List<SecurityLog.SecurityEvent> events); +}
\ No newline at end of file diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index f2466acc59bf..3a7a891c7995 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -32,6 +32,7 @@ import android.app.admin.SystemUpdatePolicy; import android.app.admin.PackagePolicy; import android.app.admin.PasswordMetrics; import android.app.admin.FactoryResetProtectionPolicy; +import android.app.admin.IAuditLogEventsCallback; import android.app.admin.ManagedProfileProvisioningParams; import android.app.admin.FullyManagedDeviceProvisioningParams; import android.app.admin.ManagedSubscriptionsPolicy; @@ -441,6 +442,10 @@ interface IDevicePolicyManager { long forceNetworkLogs(); long forceSecurityLogs(); + void setAuditLogEnabled(String callerPackage, boolean enabled); + boolean isAuditLogEnabled(String callerPackage); + void setAuditLogEventsCallback(String callerPackage, in IAuditLogEventsCallback callback); + boolean isUninstallInQueue(String packageName); void uninstallPackageWithActiveAdmins(String packageName); @@ -576,6 +581,8 @@ interface IDevicePolicyManager { void setWifiSsidPolicy(String callerPackageName, in WifiSsidPolicy policy); WifiSsidPolicy getWifiSsidPolicy(String callerPackageName); + boolean isTheftDetectionTriggered(String callerPackageName); + List<UserHandle> listForegroundAffiliatedUsers(); void setDrawables(in List<DevicePolicyDrawableResource> drawables); void resetDrawables(in List<String> drawableIds); diff --git a/location/java/android/location/GeocoderParams.aidl b/core/java/android/app/admin/SecurityLog.aidl index 2484e207dae7..e5ae2df8c21b 100644 --- a/location/java/android/location/GeocoderParams.aidl +++ b/core/java/android/app/admin/SecurityLog.aidl @@ -1,11 +1,11 @@ /* - * Copyright (C) 2010, The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,6 +14,7 @@ * limitations under the License. */ -package android.location; +package android.app.admin; -parcelable GeocoderParams; +/** @hide */ +parcelable SecurityLog.SecurityEvent;
\ No newline at end of file diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig index 726ddad37cfb..cbd8e5b2ec3e 100644 --- a/core/java/android/app/admin/flags/flags.aconfig +++ b/core/java/android/app/admin/flags/flags.aconfig @@ -139,3 +139,10 @@ flag { description: "Add Headless DO support." bug: "289515470" } + +flag { + name: "is_mte_policy_enforced" + namespace: "enterprise" + description: "Allow to query whether MTE is enabled or not to check for compliance for enterprise policy" + bug: "322777918" +} diff --git a/core/java/android/app/ondeviceintelligence/OWNERS b/core/java/android/app/ondeviceintelligence/OWNERS new file mode 100644 index 000000000000..6932ba23a8ac --- /dev/null +++ b/core/java/android/app/ondeviceintelligence/OWNERS @@ -0,0 +1,7 @@ +# Bug component: 1363385 + +sandeepbandaru@google.com +shivanker@google.com +hackz@google.com +volnov@google.com + diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java index d74399274a60..91baa4ea1eeb 100644 --- a/core/java/android/companion/CompanionDeviceManager.java +++ b/core/java/android/companion/CompanionDeviceManager.java @@ -707,7 +707,9 @@ public final class CompanionDeviceManager { * Only components from the same {@link ComponentName#getPackageName package} as the calling app * are allowed. * - * Your app must have an association with a device before calling this API + * Your app must have an association with a device before calling this API. + * + * Side-loaded apps must allow restricted settings before requesting notification access. * * <p>Calling this API requires a uses-feature * {@link PackageManager#FEATURE_COMPANION_DEVICE_SETUP} declaration in the manifest</p> @@ -721,6 +723,9 @@ public final class CompanionDeviceManager { IntentSender intentSender = mService .requestNotificationAccess(component, mContext.getUserId()) .getIntentSender(); + if (intentSender == null) { + return; + } mContext.startIntentSender(intentSender, null, 0, 0, 0, ActivityOptions.makeBasic().setPendingIntentBackgroundActivityStartMode( ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED).toBundle()); diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index e8031a374310..0bcbb8e1868c 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -19,6 +19,7 @@ package android.content; import static android.app.sdksandbox.SdkSandboxManager.ACTION_START_SANDBOXED_ACTIVITY; import static android.content.ContentProvider.maybeAddUserId; import static android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE; +import static android.security.Flags.FLAG_FRP_ENFORCEMENT; import static android.service.chooser.Flags.FLAG_ENABLE_SHARESHEET_METADATA_EXTRA; import android.Manifest; @@ -3902,6 +3903,26 @@ public class Intent implements Parcelable, Cloneable { "android.intent.action.ACTION_IDLE_MAINTENANCE_END"; /** + * Broadcast Action: A broadcast sent to the main user when the main user changes their + * Lock Screen Knowledge Factor, either because they changed the current value, or because + * they added or removed it. + * + * <p class="note">At present, this intent is only broadcast to listeners with the + * CONFIGURE_FACTORY_RESET_PROTECTION signature|privileged permiession.</p> + * + * <p class="note">This is a protected intent that can only be sent by the system.</p> + * + * @hide + */ + @FlaggedApi(FLAG_FRP_ENFORCEMENT) + @SystemApi + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @BroadcastBehavior(protectedBroadcast = true) + public static final String + ACTION_MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED = + "android.intent.action.MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED"; + + /** * Broadcast Action: a remote intent is to be broadcasted. * * A remote intent is used for remote RPC between devices. The remote intent diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index a8dba5182e90..cae4fab0099c 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -1565,6 +1565,14 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { private Boolean requestRawExternalStorageAccess; /** + * If {@code false}, this app does not allow its activities to be replaced by another app. + * Is set from application manifest application tag's allowCrossUidActivitySwitchFromBelow + * attribute. + * @hide + */ + public boolean allowCrossUidActivitySwitchFromBelow = true; + + /** * Represents the default policy. The actual policy used will depend on other properties of * the application, e.g. the target SDK version. * @hide @@ -1760,6 +1768,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { + Integer.toHexString(localeConfigRes)); } pw.println(prefix + "enableOnBackInvokedCallback=" + isOnBackInvokedCallbackEnabled()); + pw.println(prefix + "allowCrossUidActivitySwitchFromBelow=" + + allowCrossUidActivitySwitchFromBelow); + } pw.println(prefix + "createTimestamp=" + createTimestamp); if (mKnownActivityEmbeddingCerts != null) { @@ -1877,6 +1888,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { proto.write(ApplicationInfoProto.Detail.NATIVE_HEAP_ZERO_INIT, nativeHeapZeroInitialized); } + proto.write(ApplicationInfoProto.Detail.ALLOW_CROSS_UID_ACTIVITY_SWITCH_FROM_BELOW, + allowCrossUidActivitySwitchFromBelow); proto.end(detailToken); } if (!ArrayUtils.isEmpty(mKnownActivityEmbeddingCerts)) { @@ -2002,6 +2015,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { nativeHeapZeroInitialized = orig.nativeHeapZeroInitialized; requestRawExternalStorageAccess = orig.requestRawExternalStorageAccess; localeConfigRes = orig.localeConfigRes; + allowCrossUidActivitySwitchFromBelow = orig.allowCrossUidActivitySwitchFromBelow; createTimestamp = SystemClock.uptimeMillis(); } @@ -2106,6 +2120,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } } dest.writeInt(localeConfigRes); + dest.writeInt(allowCrossUidActivitySwitchFromBelow ? 1 : 0); + sForStringSet.parcel(mKnownActivityEmbeddingCerts, dest, flags); } @@ -2204,6 +2220,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } } localeConfigRes = source.readInt(); + allowCrossUidActivitySwitchFromBelow = source.readInt() != 0; + mKnownActivityEmbeddingCerts = sForStringSet.unparcel(source); if (mKnownActivityEmbeddingCerts.isEmpty()) { mKnownActivityEmbeddingCerts = null; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 49c8a7cad57a..2a673530578a 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -2554,6 +2554,15 @@ public abstract class PackageManager { public static final int INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST = -130; /** + * Installation failed return code: if the system failed to install the package that + * {@link android.R.attr#multiArch} is true in its manifest because its packaged + * native code did not match all of the natively ABIs supported by the system. + * + * @hide + */ + public static final int INSTALL_FAILED_MULTI_ARCH_NOT_MATCH_ALL_NATIVE_ABIS = -131; + + /** * App minimum aspect ratio set by the user which will override app-defined aspect ratio. * * @hide @@ -10452,6 +10461,8 @@ public abstract class PackageManager { case INSTALL_FAILED_SESSION_INVALID: return "INSTALL_FAILED_SESSION_INVALID"; case INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST: return "INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST"; + case INSTALL_FAILED_MULTI_ARCH_NOT_MATCH_ALL_NATIVE_ABIS: + return "INSTALL_FAILED_MULTI_ARCH_NOT_MATCH_ALL_NATIVE_ABIS"; default: return Integer.toString(status); } } diff --git a/core/java/android/hardware/OverlayProperties.java b/core/java/android/hardware/OverlayProperties.java index 72586b2b22cb..88089eed50f4 100644 --- a/core/java/android/hardware/OverlayProperties.java +++ b/core/java/android/hardware/OverlayProperties.java @@ -71,17 +71,36 @@ public final class OverlayProperties implements Parcelable { /** * @return True if the device can support fp16, false otherwise. + * TODO: Move this to isCombinationSupported once the flag flips * @hide */ public boolean isFp16SupportedForHdr() { if (mNativeObject == 0) { return false; } - return nSupportFp16ForHdr(mNativeObject); + return nIsCombinationSupported( + mNativeObject, DataSpace.DATASPACE_SCRGB, HardwareBuffer.RGBA_FP16); } /** - * Indicates that hw composition of two or more overlays + * Indicates that hardware composition of a buffer encoded with the provided {@link DataSpace} + * and {@link HardwareBuffer.Format} is supported on the device. + * + * @return True if the device can support efficiently compositing the content described by the + * dataspace and format. False if GPOU composition fallback is otherwise required. + */ + @FlaggedApi(Flags.FLAG_OVERLAYPROPERTIES_CLASS_API) + public boolean isCombinationSupported(@DataSpace.ColorDataSpace int dataspace, + @HardwareBuffer.Format int format) { + if (mNativeObject == 0) { + return false; + } + + return nIsCombinationSupported(mNativeObject, dataspace, format); + } + + /** + * Indicates that hardware composition of two or more overlays * with different colorspaces is supported on the device. * * @return True if the device can support mixed colorspaces efficiently, @@ -131,6 +150,8 @@ public final class OverlayProperties implements Parcelable { private static native long nCreateDefault(); private static native boolean nSupportFp16ForHdr(long nativeObject); private static native boolean nSupportMixedColorSpaces(long nativeObject); + private static native boolean nIsCombinationSupported( + long nativeObject, int dataspace, int format); private static native void nWriteOverlayPropertiesToParcel(long nativeObject, Parcel dest); private static native long nReadOverlayPropertiesFromParcel(Parcel in); } diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java index f6b22edaafb1..76c20ce2184a 100644 --- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java @@ -808,13 +808,11 @@ public final class CameraExtensionCharacteristics { extender.init(mCameraId, mCharacteristicsMapNative); CameraMetadataNative metadata = extender.getAvailableCharacteristicsKeyValues(mCameraId); - CameraCharacteristics fallbackCharacteristics = mCharacteristicsMap.get(mCameraId); if (metadata == null) { - return fallbackCharacteristics.get(key); + return null; } CameraCharacteristics characteristics = new CameraCharacteristics(metadata); - T value = characteristics.get(key); - return value == null ? fallbackCharacteristics.get(key) : value; + return characteristics.get(key); } } catch (RemoteException e) { Log.e(TAG, "Failed to query the extension for the specified key! Extension " diff --git a/core/java/android/hardware/camera2/CameraExtensionSession.java b/core/java/android/hardware/camera2/CameraExtensionSession.java index 21fead980cdd..2d9433e31ab2 100644 --- a/core/java/android/hardware/camera2/CameraExtensionSession.java +++ b/core/java/android/hardware/camera2/CameraExtensionSession.java @@ -16,11 +16,14 @@ package android.hardware.camera2; +import android.annotation.FlaggedApi; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.camera2.utils.HashCodeHelpers; +import com.android.internal.camera.flags.Flags; + import java.util.concurrent.Executor; /** @@ -132,6 +135,34 @@ public abstract class CameraExtensionSession implements AutoCloseable { } /** + * This method is called instead of + * {@link #onCaptureProcessStarted} when the camera device failed + * to produce the required input for the device-specific extension. The + * cause could be a failed camera capture request, a failed + * capture result or dropped camera frame. More information about + * the reason is included in the 'failure' argument. + * + * <p>Other requests are unaffected, and some or all image buffers + * from the capture may have been pushed to their respective output + * streams.</p> + * + * <p>The default implementation of this method does nothing.</p> + * + * @param session the session received during + * {@link StateCallback#onConfigured(CameraExtensionSession)} + * @param request The request that was given to the CameraDevice + * @param failure The capture failure reason + * + * @see #capture + * @see #setRepeatingRequest + */ + @FlaggedApi(Flags.FLAG_CONCERT_MODE) + public void onCaptureFailed(@NonNull CameraExtensionSession session, + @NonNull CaptureRequest request, @CaptureFailure.FailureReason int failure) { + // default empty implementation + } + + /** * This method is called independently of the others in * ExtensionCaptureCallback, when a capture sequence finishes. * diff --git a/core/java/android/hardware/camera2/extension/CameraOutputSurface.java b/core/java/android/hardware/camera2/extension/CameraOutputSurface.java index b4fe7fe1f0d1..53f56bc9f896 100644 --- a/core/java/android/hardware/camera2/extension/CameraOutputSurface.java +++ b/core/java/android/hardware/camera2/extension/CameraOutputSurface.java @@ -18,8 +18,11 @@ package android.hardware.camera2.extension; import android.annotation.FlaggedApi; import android.annotation.NonNull; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.graphics.ImageFormat; +import android.hardware.camera2.params.ColorSpaceProfiles; +import android.hardware.camera2.params.DynamicRangeProfiles; import android.hardware.camera2.utils.SurfaceUtils; import android.util.Size; import android.view.Surface; @@ -65,6 +68,8 @@ public final class CameraOutputSurface { mOutputSurface.size = new android.hardware.camera2.extension.Size(); mOutputSurface.size.width = size.getWidth(); mOutputSurface.size.height = size.getHeight(); + mOutputSurface.dynamicRangeProfile = DynamicRangeProfiles.STANDARD; + mOutputSurface.colorSpace = ColorSpaceProfiles.UNSPECIFIED; } /** @@ -95,4 +100,48 @@ public final class CameraOutputSurface { public @ImageFormat.Format int getImageFormat() { return mOutputSurface.imageFormat; } + + /** + * Return the dynamic range profile. The default + * dynamicRangeProfile is + * {@link android.hardware.camera2.params.DynamicRangeProfiles.STANDARD} + * unless specified by CameraOutputSurface.setDynamicRangeProfile. + */ + @FlaggedApi(Flags.FLAG_EXTENSION_10_BIT) + public @DynamicRangeProfiles.Profile long getDynamicRangeProfile() { + return mOutputSurface.dynamicRangeProfile; + } + + /** + * Return the color space. The default colorSpace is + * {@link android.hardware.camera2.params.ColorSpaceProfiles.UNSPECIFIED} + * unless specified by CameraOutputSurface.setColorSpace. + */ + @SuppressLint("MethodNameUnits") + @FlaggedApi(Flags.FLAG_EXTENSION_10_BIT) + public int getColorSpace() { + return mOutputSurface.colorSpace; + } + + /** + * Set the dynamic range profile. The default dynamicRangeProfile + * will be {@link android.hardware.camera2.params.DynamicRangeProfiles.STANDARD} + * unless explicitly set using this method. + */ + @FlaggedApi(Flags.FLAG_EXTENSION_10_BIT) + public void setDynamicRangeProfile( + @DynamicRangeProfiles.Profile long dynamicRangeProfile) { + mOutputSurface.dynamicRangeProfile = dynamicRangeProfile; + } + + /** + * Set the color space. The default colorSpace + * will be + * {@link android.hardware.camera2.params.ColorSpaceProfiles.UNSPECIFIED} + * unless explicitly set using this method. + */ + @FlaggedApi(Flags.FLAG_EXTENSION_10_BIT) + public void setColorSpace(int colorSpace) { + mOutputSurface.colorSpace = colorSpace; + } } diff --git a/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl b/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl index 02a4690c3b77..b1f10ee103c1 100644 --- a/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl +++ b/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl @@ -15,6 +15,7 @@ */ package android.hardware.camera2.extension; +import android.hardware.camera2.extension.CaptureFailure; import android.hardware.camera2.extension.Request; import android.hardware.camera2.impl.CameraMetadataNative; @@ -28,4 +29,5 @@ interface ICaptureCallback void onCaptureSequenceAborted(int captureSequenceId); void onCaptureCompleted(long shutterTimestamp, int requestId, in CameraMetadataNative results); void onCaptureProcessProgressed(int progress); + void onCaptureProcessFailed(int captureSequenceId, int captureFailureReason); } diff --git a/core/java/android/hardware/camera2/extension/OutputSurface.aidl b/core/java/android/hardware/camera2/extension/OutputSurface.aidl index 841537918f65..02e160cdd8dd 100644 --- a/core/java/android/hardware/camera2/extension/OutputSurface.aidl +++ b/core/java/android/hardware/camera2/extension/OutputSurface.aidl @@ -24,4 +24,6 @@ parcelable OutputSurface Surface surface; Size size; int imageFormat; + long dynamicRangeProfile; + int colorSpace; } diff --git a/core/java/android/hardware/camera2/extension/SessionProcessor.java b/core/java/android/hardware/camera2/extension/SessionProcessor.java index e7cc5303fc18..2e428e5aa5f9 100644 --- a/core/java/android/hardware/camera2/extension/SessionProcessor.java +++ b/core/java/android/hardware/camera2/extension/SessionProcessor.java @@ -20,6 +20,7 @@ import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.SystemApi; import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CaptureFailure; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; import android.hardware.camera2.impl.CameraExtensionUtils.HandlerExecutor; @@ -132,13 +133,14 @@ public abstract class SessionProcessor { * This method is called instead of * {@link #onCaptureProcessStarted} when the camera device failed * to produce the required input for the device-specific - * extension. The cause could be a failed camera capture request, - * a failed capture result or dropped camera frame. + * extension. The callback allows clients to be notified + * about failure reason. * * @param captureSequenceId id of the current capture sequence + * @param failure The capture failure reason */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - void onCaptureFailed(int captureSequenceId); + void onCaptureFailed(int captureSequenceId, @CaptureFailure.FailureReason int failure); /** * This method is called independently of the others in the @@ -181,8 +183,8 @@ public abstract class SessionProcessor { * capture results. This is the return value of * either {@link #startRepeating} or {@link * #startMultiFrameCapture}. - * @param results The supported capture results. Do note - * that if results 'android.jpeg.quality' and + * @param results Key value map of the supported capture results. + * Do note that if results 'android.jpeg.quality' and * android.jpeg.orientation' are present in the * process capture input results, then the values * must also be passed as part of this callback. @@ -192,7 +194,7 @@ public abstract class SessionProcessor { */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) void onCaptureCompleted(long shutterTimestamp, int requestId, - @NonNull CaptureResult results); + @NonNull Map<CaptureResult.Key, Object> results); } /** @@ -412,7 +414,7 @@ public abstract class SessionProcessor { public int startRepeating(ICaptureCallback callback) throws RemoteException { return SessionProcessor.this.startRepeating( new HandlerExecutor(new Handler(Looper.getMainLooper())), - new CaptureCallbackImpl(callback)); + new CaptureCallbackImpl(callback, mVendorId)); } @Override @@ -425,7 +427,7 @@ public abstract class SessionProcessor { throws RemoteException { return SessionProcessor.this.startMultiFrameCapture( new HandlerExecutor(new Handler(Looper.getMainLooper())), - new CaptureCallbackImpl(callback)); + new CaptureCallbackImpl(callback, mVendorId)); } @Override @@ -438,7 +440,7 @@ public abstract class SessionProcessor { throws RemoteException { return SessionProcessor.this.startTrigger(captureRequest, new HandlerExecutor(new Handler(Looper.getMainLooper())), - new CaptureCallbackImpl(callback)); + new CaptureCallbackImpl(callback, mVendorId)); } @Override @@ -450,9 +452,11 @@ public abstract class SessionProcessor { private static final class CaptureCallbackImpl implements CaptureCallback { private final ICaptureCallback mCaptureCallback; + private long mVendorId = -1; - CaptureCallbackImpl(@NonNull ICaptureCallback cb) { + CaptureCallbackImpl(@NonNull ICaptureCallback cb, long vendorId) { mCaptureCallback = cb; + mVendorId = vendorId; } @Override @@ -474,9 +478,9 @@ public abstract class SessionProcessor { } @Override - public void onCaptureFailed(int captureSequenceId) { + public void onCaptureFailed(int captureSequenceId, int failure) { try { - mCaptureCallback.onCaptureFailed(captureSequenceId); + mCaptureCallback.onCaptureProcessFailed(captureSequenceId, failure); } catch (RemoteException e) { Log.e(TAG, "Failed to notify capture failure start due to remote exception!"); } @@ -502,10 +506,14 @@ public abstract class SessionProcessor { @Override public void onCaptureCompleted(long shutterTimestamp, int requestId, - @androidx.annotation.NonNull CaptureResult results) { + Map<CaptureResult.Key, Object> results) { + CameraMetadataNative captureResults = new CameraMetadataNative(); + captureResults.setVendorId(mVendorId); + for (Map.Entry<CaptureResult.Key, Object> entry : results.entrySet()) { + captureResults.set(entry.getKey(), entry.getValue()); + } try { - mCaptureCallback.onCaptureCompleted(shutterTimestamp, requestId, - results.getNativeCopy()); + mCaptureCallback.onCaptureCompleted(shutterTimestamp, requestId, captureResults); } catch (RemoteException e) { Log.e(TAG, "Failed to notify capture complete due to remote exception!"); } diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java index b2032fa3db81..a7d6caf9d9df 100644 --- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java @@ -66,6 +66,8 @@ import android.util.Log; import android.util.Size; import android.view.Surface; +import com.android.internal.camera.flags.Flags; + import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -779,6 +781,22 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } @Override + public void onCaptureProcessFailed(int captureSequenceId, int captureFailureReason) { + if (Flags.concertMode()) { + final long ident = Binder.clearCallingIdentity(); + try { + mClientExecutor.execute( + () -> mClientCallbacks.onCaptureFailed( + CameraAdvancedExtensionSessionImpl.this, mClientRequest, + captureFailureReason + )); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } + + @Override public void onCaptureSequenceCompleted(int captureSequenceId) { final long ident = Binder.clearCallingIdentity(); try { diff --git a/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java b/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java index 0e6c1b39271c..69a6e9b0ab32 100644 --- a/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java +++ b/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java @@ -15,15 +15,20 @@ */ package android.hardware.camera2.params; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; - +import android.annotation.SuppressLint; +import android.graphics.ColorSpace; +import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraExtensionCharacteristics.Extension; import android.hardware.camera2.CameraExtensionSession; import java.util.List; import java.util.concurrent.Executor; +import com.android.internal.camera.flags.Flags; + /** * A class that aggregates all supported arguments for * {@link CameraExtensionSession} initialization. @@ -36,6 +41,7 @@ public final class ExtensionSessionConfiguration { private OutputConfiguration mPostviewOutput = null; private Executor mExecutor = null; private CameraExtensionSession.StateCallback mCallback = null; + private int mColorSpace; /** * Create a new ExtensionSessionConfiguration @@ -118,4 +124,55 @@ public final class ExtensionSessionConfiguration { Executor getExecutor() { return mExecutor; } + + /** + * Set a specific device-supported color space. + * + * <p>Clients can choose from any profile advertised as supported in + * {@link CameraCharacteristics#REQUEST_AVAILABLE_COLOR_SPACE_PROFILES} + * queried using {@link ColorSpaceProfiles#getSupportedColorSpaces}. + * When set, the colorSpace will override the default color spaces of the output targets, + * or the color space implied by the dataSpace passed into an {@link ImageReader}'s + * constructor.</p> + */ + @FlaggedApi(Flags.FLAG_EXTENSION_10_BIT) + public void setColorSpace(@NonNull ColorSpace.Named colorSpace) { + mColorSpace = colorSpace.ordinal(); + for (OutputConfiguration outputConfiguration : mOutputs) { + outputConfiguration.setColorSpace(colorSpace); + } + if (mPostviewOutput != null) { + mPostviewOutput.setColorSpace(colorSpace); + } + } + + /** + * Clear the color space, such that the default color space will be used. + */ + @FlaggedApi(Flags.FLAG_EXTENSION_10_BIT) + public void clearColorSpace() { + mColorSpace = ColorSpaceProfiles.UNSPECIFIED; + for (OutputConfiguration outputConfiguration : mOutputs) { + outputConfiguration.clearColorSpace(); + } + if (mPostviewOutput != null) { + mPostviewOutput.clearColorSpace(); + } + } + + /** + * Return the current color space. + * + * @return the currently set color space, or null + * if not set + */ + @FlaggedApi(Flags.FLAG_EXTENSION_10_BIT) + @SuppressLint("MethodNameUnits") + public @Nullable ColorSpace getColorSpace() { + if (mColorSpace != ColorSpaceProfiles.UNSPECIFIED) { + return ColorSpace.get(ColorSpace.Named.values()[mColorSpace]); + } else { + return null; + } + } } diff --git a/core/java/android/permission/PermissionGroupUsage.java b/core/java/android/permission/PermissionGroupUsage.java index 49b7463533e4..6895d3c67f06 100644 --- a/core/java/android/permission/PermissionGroupUsage.java +++ b/core/java/android/permission/PermissionGroupUsage.java @@ -17,6 +17,7 @@ package android.permission; import android.annotation.CurrentTimeMillisLong; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -26,8 +27,8 @@ import com.android.internal.util.DataClass; /** * Represents the usage of a permission group by an app. Supports package name, user, permission - * group, whether or not the access is running or recent, whether the access is tied to a phone - * call, and an optional special attribution tag, label and proxy label. + * group, persistent device Id, whether or not the access is running or recent, whether the access + * is tied to a phone call, and an optional special attribution tag, label and proxy label. * * @hide */ @@ -48,6 +49,7 @@ public final class PermissionGroupUsage implements Parcelable { private final @Nullable CharSequence mAttributionTag; private final @Nullable CharSequence mAttributionLabel; private final @Nullable CharSequence mProxyLabel; + private final @NonNull String mPersistentDeviceId; @@ -79,7 +81,8 @@ public final class PermissionGroupUsage implements Parcelable { boolean phoneCall, @Nullable CharSequence attributionTag, @Nullable CharSequence attributionLabel, - @Nullable CharSequence proxyLabel) { + @Nullable CharSequence proxyLabel, + @NonNull String persistentDeviceId) { this.mPackageName = packageName; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mPackageName); @@ -93,6 +96,9 @@ public final class PermissionGroupUsage implements Parcelable { this.mAttributionTag = attributionTag; this.mAttributionLabel = attributionLabel; this.mProxyLabel = proxyLabel; + this.mPersistentDeviceId = persistentDeviceId; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mPersistentDeviceId); // onConstructed(); // You can define this method to get a callback } @@ -170,6 +176,12 @@ public final class PermissionGroupUsage implements Parcelable { return mProxyLabel; } + @DataClass.Generated.Member + @FlaggedApi(android.permission.flags.Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) + public @NonNull String getPersistentDeviceId() { + return mPersistentDeviceId; + } + @Override @DataClass.Generated.Member public String toString() { @@ -185,7 +197,8 @@ public final class PermissionGroupUsage implements Parcelable { "phoneCall = " + mPhoneCall + ", " + "attributionTag = " + mAttributionTag + ", " + "attributionLabel = " + mAttributionLabel + ", " + - "proxyLabel = " + mProxyLabel + + "proxyLabel = " + mProxyLabel + ", " + + "persistentDeviceId = " + mPersistentDeviceId + " }"; } @@ -210,7 +223,8 @@ public final class PermissionGroupUsage implements Parcelable { && mPhoneCall == that.mPhoneCall && java.util.Objects.equals(mAttributionTag, that.mAttributionTag) && java.util.Objects.equals(mAttributionLabel, that.mAttributionLabel) - && java.util.Objects.equals(mProxyLabel, that.mProxyLabel); + && java.util.Objects.equals(mProxyLabel, that.mProxyLabel) + && java.util.Objects.equals(mPersistentDeviceId, that.mPersistentDeviceId); } @Override @@ -229,6 +243,7 @@ public final class PermissionGroupUsage implements Parcelable { _hash = 31 * _hash + java.util.Objects.hashCode(mAttributionTag); _hash = 31 * _hash + java.util.Objects.hashCode(mAttributionLabel); _hash = 31 * _hash + java.util.Objects.hashCode(mProxyLabel); + _hash = 31 * _hash + java.util.Objects.hashCode(mPersistentDeviceId); return _hash; } @@ -252,6 +267,7 @@ public final class PermissionGroupUsage implements Parcelable { if (mAttributionTag != null) dest.writeCharSequence(mAttributionTag); if (mAttributionLabel != null) dest.writeCharSequence(mAttributionLabel); if (mProxyLabel != null) dest.writeCharSequence(mProxyLabel); + dest.writeString(mPersistentDeviceId); } @Override @@ -275,6 +291,7 @@ public final class PermissionGroupUsage implements Parcelable { CharSequence attributionTag = (flg & 0x40) == 0 ? null : (CharSequence) in.readCharSequence(); CharSequence attributionLabel = (flg & 0x80) == 0 ? null : (CharSequence) in.readCharSequence(); CharSequence proxyLabel = (flg & 0x100) == 0 ? null : (CharSequence) in.readCharSequence(); + String persistentDeviceId = in.readString(); this.mPackageName = packageName; com.android.internal.util.AnnotationValidations.validate( @@ -289,6 +306,9 @@ public final class PermissionGroupUsage implements Parcelable { this.mAttributionTag = attributionTag; this.mAttributionLabel = attributionLabel; this.mProxyLabel = proxyLabel; + this.mPersistentDeviceId = persistentDeviceId; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mPersistentDeviceId); // onConstructed(); // You can define this method to get a callback } @@ -308,10 +328,10 @@ public final class PermissionGroupUsage implements Parcelable { }; @DataClass.Generated( - time = 1645067417023L, + time = 1706285211875L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/permission/PermissionGroupUsage.java", - inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final int mUid\nprivate final long mLastAccessTimeMillis\nprivate final @android.annotation.NonNull java.lang.String mPermissionGroupName\nprivate final boolean mActive\nprivate final boolean mPhoneCall\nprivate final @android.annotation.Nullable java.lang.CharSequence mAttributionTag\nprivate final @android.annotation.Nullable java.lang.CharSequence mAttributionLabel\nprivate final @android.annotation.Nullable java.lang.CharSequence mProxyLabel\nclass PermissionGroupUsage extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genEqualsHashCode=true, genToString=true)") + inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final int mUid\nprivate final long mLastAccessTimeMillis\nprivate final @android.annotation.NonNull java.lang.String mPermissionGroupName\nprivate final boolean mActive\nprivate final boolean mPhoneCall\nprivate final @android.annotation.Nullable java.lang.CharSequence mAttributionTag\nprivate final @android.annotation.Nullable java.lang.CharSequence mAttributionLabel\nprivate final @android.annotation.Nullable java.lang.CharSequence mProxyLabel\nprivate final @android.annotation.NonNull java.lang.String mPersistentDeviceId\nclass PermissionGroupUsage extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genEqualsHashCode=true, genToString=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index e6b8102764eb..fd52c769e408 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -1329,7 +1329,9 @@ public final class PermissionManager { public List<PermissionGroupUsage> getIndicatorAppOpUsageData(boolean micMuted) { // Lazily initialize the usage helper initializeUsageHelper(); - return mUsageHelper.getOpUsageData(micMuted); + boolean includeMicrophoneUsage = !micMuted; + return mUsageHelper.getOpUsageDataByDevice(includeMicrophoneUsage, + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); } /** diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java index 1f798baf1bd6..460b4dd9b86c 100644 --- a/core/java/android/permission/PermissionUsageHelper.java +++ b/core/java/android/permission/PermissionUsageHelper.java @@ -41,6 +41,8 @@ import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_AC import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AppOpsManager; +import android.companion.virtual.VirtualDevice; +import android.companion.virtual.VirtualDeviceManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.Attribution; @@ -52,10 +54,12 @@ import android.location.LocationManager; import android.media.AudioManager; import android.os.Process; import android.os.UserHandle; +import android.permission.flags.Flags; import android.provider.DeviceConfig; import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.Slog; import com.android.internal.annotations.GuardedBy; @@ -75,6 +79,8 @@ import java.util.Objects; public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedListener, AppOpsManager.OnOpStartedListener { + private static final String LOG_TAG = PermissionUsageHelper.class.getName(); + /** * Whether to show the mic and camera icons. */ @@ -159,6 +165,7 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis private ArrayMap<UserHandle, Context> mUserContexts; private PackageManager mPkgManager; private AppOpsManager mAppOpsManager; + private VirtualDeviceManager mVirtualDeviceManager; @GuardedBy("mAttributionChains") private final ArrayMap<Integer, ArrayList<AccessChainLink>> mAttributionChains = new ArrayMap<>(); @@ -172,6 +179,7 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis mContext = context; mPkgManager = context.getPackageManager(); mAppOpsManager = context.getSystemService(AppOpsManager.class); + mVirtualDeviceManager = context.getSystemService(VirtualDeviceManager.class); mUserContexts = new ArrayMap<>(); mUserContexts.put(Process.myUserHandle(), mContext); // TODO ntmyren: make this listen for flag enable/disable changes @@ -280,9 +288,11 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis } /** - * @see PermissionManager.getIndicatorAppOpUsageData + * Return Op usage for CAMERA, LOCATION AND MICROPHONE for all packages for a device. + * The returned data is to power privacy indicator. */ - public @NonNull List<PermissionGroupUsage> getOpUsageData(boolean isMicMuted) { + public @NonNull List<PermissionGroupUsage> getOpUsageDataByDevice( + boolean includeMicrophoneUsage, String deviceId) { List<PermissionGroupUsage> usages = new ArrayList<>(); if (!shouldShowIndicators()) { @@ -293,11 +303,11 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis if (shouldShowLocationIndicator()) { ops.addAll(LOCATION_OPS); } - if (!isMicMuted) { + if (includeMicrophoneUsage) { ops.addAll(MIC_OPS); } - Map<String, List<OpUsage>> rawUsages = getOpUsages(ops); + Map<String, List<OpUsage>> rawUsages = getOpUsagesByDevice(ops, deviceId); ArrayList<String> usedPermGroups = new ArrayList<>(rawUsages.keySet()); @@ -349,13 +359,40 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis new PermissionGroupUsage(usage.packageName, usage.uid, usage.lastAccessTime, permGroup, usage.isRunning, isPhone, usage.attributionTag, attributionLabel, - usagesWithLabels.valueAt(usageNum))); + usagesWithLabels.valueAt(usageNum), + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT)); } } return usages; } + /** + * Return Op usage for CAMERA, LOCATION AND MICROPHONE for all packages and all connected + * devices. + * The returned data is to power privacy indicator. + */ + public @NonNull List<PermissionGroupUsage> getOpUsageDataForAllDevices( + boolean includeMicrophoneUsage) { + List<PermissionGroupUsage> allUsages = new ArrayList<>(); + List<VirtualDevice> virtualDevices = mVirtualDeviceManager.getVirtualDevices(); + ArraySet<String> persistentDeviceIds = new ArraySet<>(); + + for (int num = 0; num < virtualDevices.size(); num++) { + persistentDeviceIds.add(virtualDevices.get(num).getPersistentDeviceId()); + } + persistentDeviceIds.add(VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); + + for (int index = 0; index < persistentDeviceIds.size(); index++) { + allUsages.addAll( + getOpUsageDataByDevice(includeMicrophoneUsage, + persistentDeviceIds.valueAt(index))); + } + + return allUsages; + } + + private void updateSubattributionLabelsMap(List<OpUsage> usages, ArrayMap<String, Map<String, String>> subAttributionLabelsMap) { if (usages == null || usages.isEmpty()) { @@ -443,12 +480,24 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis * running/recent info, if the usage is a phone call, per permission group. * * @param opNames a list of op names to get usage for + * @param deviceId which device to get op usage for * @return A map of permission group -> list of usages that are recent or running */ - private Map<String, List<OpUsage>> getOpUsages(List<String> opNames) { + private Map<String, List<OpUsage>> getOpUsagesByDevice(List<String> opNames, String deviceId) { List<AppOpsManager.PackageOps> ops; try { - ops = mAppOpsManager.getPackagesForOps(opNames.toArray(new String[opNames.size()])); + if (Flags.deviceAwarePermissionApisEnabled()) { + ops = mAppOpsManager.getPackagesForOps(opNames.toArray(new String[opNames.size()]), + deviceId); + } else if (!Objects.equals(deviceId, + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT)) { + Slog.w(LOG_TAG, + "device_aware_permission_apis_enabled flag not enabled when deviceId is " + + "not default"); + return Collections.emptyMap(); + } else { + ops = mAppOpsManager.getPackagesForOps(opNames.toArray(new String[opNames.size()])); + } } catch (NullPointerException e) { // older builds might not support all the app-ops requested return Collections.emptyMap(); diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig index 9d7fb7018d52..9218cb8f497d 100644 --- a/core/java/android/permission/flags.aconfig +++ b/core/java/android/permission/flags.aconfig @@ -96,9 +96,37 @@ flag { } flag { + name: "sensitive_notification_app_protection" + namespace: "permissions" + description: "This flag controls the sensitive notification app protections while screen sharing" + bug: "312784351" + # Referenced in WM where WM starts before DeviceConfig + is_fixed_read_only: true +} + +flag { name: "device_aware_permissions_enabled" is_fixed_read_only: true namespace: "permissions" description: "When the flag is off no permissions can be device aware" bug: "274852670" -}
\ No newline at end of file +} + +flag { + name: "get_emergency_role_holder_api_enabled" + is_fixed_read_only: true + namespace: "permissions" + description: "Enables the getEmergencyRoleHolder API." + bug: "323157319" +} + +flag { + name: "new_permission_gid_enabled" + is_fixed_read_only: true + namespace: "permissions" + description: "Enable new permission GID implementation" + bug: "325137277" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/core/java/android/service/chooser/CustomChoosers.java b/core/java/android/service/chooser/CustomChoosers.java deleted file mode 100644 index 5b89432b956d..000000000000 --- a/core/java/android/service/chooser/CustomChoosers.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.service.chooser; - -import android.annotation.FlaggedApi; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.content.Intent; -import android.content.pm.ResolveInfo; - -import java.util.ArrayList; -import java.util.List; - -/** - * Static helper methods that privileged clients can use to initiate Share sessions with extra - * customization options that aren't usually available in the stock "Resolver/Chooser" flows. - * - * @hide - */ -@FlaggedApi(Flags.FLAG_SUPPORT_NFC_RESOLVER) -@SystemApi -public class CustomChoosers { - /** - * Intent action to start a Share session with additional customization options. Clients should - * use the helper methods in this class to configure their customized share intents, and should - * avoid using this action to construct their own intents directly. - */ - private static final String ACTION_SHOW_CUSTOMIZED_RESOLVER = - "android.service.chooser.action.SHOW_CUSTOMIZED_RESOLVER"; - - /** - * "Extras" key for an ArrayList of {@link ResolveInfo} records which are to be shown as the - * targets in the customized share session. - * - * @hide - */ - public static final String EXTRA_RESOLVE_INFOS = "android.service.chooser.extra.RESOLVE_INFOS"; - - /** - * Build an {@link Intent} to dispatch a "Chooser flow" that picks a target resolution for the - * specified {@code target} intent, styling the Chooser UI according to the specified - * customization parameters. - * - * @param target The ambiguous intent that should be resolved to a specific target selected - * via the Chooser flow. - * @param title An optional "headline" string to display at the top of the Chooser UI, or null - * to use the system default. - * @param resolutionList Explicit resolution info for targets that should be shown in the - * dispatched Share UI. - * - * @hide - */ - @FlaggedApi(Flags.FLAG_SUPPORT_NFC_RESOLVER) - @SystemApi - @NonNull - public static Intent createNfcResolverIntent( - @NonNull Intent target, - @Nullable CharSequence title, - @NonNull List<ResolveInfo> resolutionList) { - Intent resolverIntent = new Intent(ACTION_SHOW_CUSTOMIZED_RESOLVER); - resolverIntent.putExtra(Intent.EXTRA_INTENT, target); - resolverIntent.putExtra(Intent.EXTRA_TITLE, title); - resolverIntent.putParcelableArrayListExtra( - EXTRA_RESOLVE_INFOS, new ArrayList<>(resolutionList)); - return resolverIntent; - } - - private CustomChoosers() {} -} diff --git a/core/java/android/service/chooser/flags.aconfig b/core/java/android/service/chooser/flags.aconfig index add575b23792..00236dfa7876 100644 --- a/core/java/android/service/chooser/flags.aconfig +++ b/core/java/android/service/chooser/flags.aconfig @@ -15,13 +15,6 @@ flag { } flag { - name: "support_nfc_resolver" - namespace: "systemui" - description: "This flag controls the new NFC 'resolver' activity" - bug: "268089816" -} - -flag { name: "chooser_payload_toggling" namespace: "intentresolver" description: "This flag controls content toggling in Chooser" diff --git a/core/java/android/service/ondeviceintelligence/OWNERS b/core/java/android/service/ondeviceintelligence/OWNERS new file mode 100644 index 000000000000..09774f78d712 --- /dev/null +++ b/core/java/android/service/ondeviceintelligence/OWNERS @@ -0,0 +1 @@ +file:/core/java/android/app/ondeviceintelligence/OWNERS diff --git a/core/java/android/service/voice/HotwordTrainingAudio.java b/core/java/android/service/voice/HotwordTrainingAudio.java deleted file mode 100644 index 916fa36b2339..000000000000 --- a/core/java/android/service/voice/HotwordTrainingAudio.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.service.voice; - -import android.annotation.FlaggedApi; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SuppressLint; -import android.annotation.SystemApi; -import android.media.AudioFormat; -import android.os.Parcel; -import android.os.Parcelable; -import android.service.voice.flags.Flags; - -import com.android.internal.util.DataClass; - -import java.util.Objects; - -/** - * Represents audio supporting hotword model training. - * - * @hide - */ -@FlaggedApi(Flags.FLAG_ALLOW_TRAINING_DATA_EGRESS_FROM_HDS) -@DataClass( - genConstructor = false, - genBuilder = true, - genEqualsHashCode = true, - genHiddenConstDefs = true, - genParcelable = true, - genToString = true -) -@SystemApi -public final class HotwordTrainingAudio implements Parcelable { - /** Represents unset value for the hotword offset. */ - public static final int HOTWORD_OFFSET_UNSET = -1; - - /** - * Buffer of hotword audio data for training models. The data format is expected to match - * {@link #getAudioFormat()}. - */ - @NonNull - private final byte[] mHotwordAudio; - - private String hotwordAudioToString() { - return "length=" + mHotwordAudio.length; - } - - /** - * The {@link AudioFormat} of the {@link HotwordTrainingAudio#mHotwordAudio}. - */ - @NonNull - private final AudioFormat mAudioFormat; - - /** - * App-defined identifier to distinguish hotword training audio instances. - * <p> Returns -1 if unset. */ - @NonNull - private final int mAudioType; - - private static int defaultAudioType() { - return -1; - } - - /** - * App-defined offset in milliseconds relative to start of - * {@link HotwordTrainingAudio#mHotwordAudio}. Default value is - * {@link HotwordTrainingAudio#HOTWORD_OFFSET_UNSET}. - */ - private int mHotwordOffsetMillis = HOTWORD_OFFSET_UNSET; - - @DataClass.Suppress("setHotwordAudio") - abstract static class BaseBuilder { - - /** - * Buffer of hotword audio data for training models. The data format is expected to match - * {@link #getAudioFormat()}. - */ - @SuppressLint("UnflaggedApi") - public @NonNull HotwordTrainingAudio.Builder setHotwordAudio(@NonNull byte[] value) { - Objects.requireNonNull(value, "value should not be null"); - final HotwordTrainingAudio.Builder builder = (HotwordTrainingAudio.Builder) this; - // If the code gen flag in build() is changed, we must update the flag e.g. 0x1 here. - builder.mBuilderFieldsSet |= 0x1; - builder.mHotwordAudio = value; - return builder; - } - } - - - - // Code below generated by codegen v1.0.23. - // - // DO NOT MODIFY! - // CHECKSTYLE:OFF Generated code - // - // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/voice/HotwordTrainingAudio.java - // - // To exclude the generated code from IntelliJ auto-formatting enable (one-time): - // Settings > Editor > Code Style > Formatter Control - //@formatter:off - - - @DataClass.Generated.Member - /* package-private */ HotwordTrainingAudio( - @NonNull byte[] hotwordAudio, - @NonNull AudioFormat audioFormat, - @NonNull int audioType, - int hotwordOffsetMillis) { - this.mHotwordAudio = hotwordAudio; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mHotwordAudio); - this.mAudioFormat = audioFormat; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mAudioFormat); - this.mAudioType = audioType; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mAudioType); - this.mHotwordOffsetMillis = hotwordOffsetMillis; - - // onConstructed(); // You can define this method to get a callback - } - - /** - * Buffer of hotword audio data for training models. The data format is expected to match - * {@link #getAudioFormat()}. - */ - @DataClass.Generated.Member - public @NonNull byte[] getHotwordAudio() { - return mHotwordAudio; - } - - /** - * The {@link AudioFormat} of the {@link HotwordTrainingAudio#mHotwordAudio}. - */ - @DataClass.Generated.Member - public @NonNull AudioFormat getAudioFormat() { - return mAudioFormat; - } - - /** - * App-defined identifier to distinguish hotword training audio instances. - * <p> Returns -1 if unset. - */ - @DataClass.Generated.Member - public @NonNull int getAudioType() { - return mAudioType; - } - - /** - * App-defined offset in milliseconds relative to start of - * {@link HotwordTrainingAudio#mHotwordAudio}. Default value is - * {@link HotwordTrainingAudio#HOTWORD_OFFSET_UNSET}. - */ - @DataClass.Generated.Member - public int getHotwordOffsetMillis() { - return mHotwordOffsetMillis; - } - - @Override - @DataClass.Generated.Member - public String toString() { - // You can override field toString logic by defining methods like: - // String fieldNameToString() { ... } - - return "HotwordTrainingAudio { " + - "hotwordAudio = " + hotwordAudioToString() + ", " + - "audioFormat = " + mAudioFormat + ", " + - "audioType = " + mAudioType + ", " + - "hotwordOffsetMillis = " + mHotwordOffsetMillis + - " }"; - } - - @Override - @DataClass.Generated.Member - public boolean equals(@Nullable Object o) { - // You can override field equality logic by defining either of the methods like: - // boolean fieldNameEquals(HotwordTrainingAudio other) { ... } - // boolean fieldNameEquals(FieldType otherValue) { ... } - - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - @SuppressWarnings("unchecked") - HotwordTrainingAudio that = (HotwordTrainingAudio) o; - //noinspection PointlessBooleanExpression - return true - && java.util.Arrays.equals(mHotwordAudio, that.mHotwordAudio) - && Objects.equals(mAudioFormat, that.mAudioFormat) - && mAudioType == that.mAudioType - && mHotwordOffsetMillis == that.mHotwordOffsetMillis; - } - - @Override - @DataClass.Generated.Member - public int hashCode() { - // You can override field hashCode logic by defining methods like: - // int fieldNameHashCode() { ... } - - int _hash = 1; - _hash = 31 * _hash + java.util.Arrays.hashCode(mHotwordAudio); - _hash = 31 * _hash + Objects.hashCode(mAudioFormat); - _hash = 31 * _hash + mAudioType; - _hash = 31 * _hash + mHotwordOffsetMillis; - return _hash; - } - - @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.writeByteArray(mHotwordAudio); - dest.writeTypedObject(mAudioFormat, flags); - dest.writeInt(mAudioType); - dest.writeInt(mHotwordOffsetMillis); - } - - @Override - @DataClass.Generated.Member - public int describeContents() { return 0; } - - /** @hide */ - @SuppressWarnings({"unchecked", "RedundantCast"}) - @DataClass.Generated.Member - /* package-private */ HotwordTrainingAudio(@NonNull Parcel in) { - // You can override field unparcelling by defining methods like: - // static FieldType unparcelFieldName(Parcel in) { ... } - - byte[] hotwordAudio = in.createByteArray(); - AudioFormat audioFormat = (AudioFormat) in.readTypedObject(AudioFormat.CREATOR); - int audioType = in.readInt(); - int hotwordOffsetMillis = in.readInt(); - - this.mHotwordAudio = hotwordAudio; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mHotwordAudio); - this.mAudioFormat = audioFormat; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mAudioFormat); - this.mAudioType = audioType; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mAudioType); - this.mHotwordOffsetMillis = hotwordOffsetMillis; - - // onConstructed(); // You can define this method to get a callback - } - - @DataClass.Generated.Member - public static final @NonNull Parcelable.Creator<HotwordTrainingAudio> CREATOR - = new Parcelable.Creator<HotwordTrainingAudio>() { - @Override - public HotwordTrainingAudio[] newArray(int size) { - return new HotwordTrainingAudio[size]; - } - - @Override - public HotwordTrainingAudio createFromParcel(@NonNull Parcel in) { - return new HotwordTrainingAudio(in); - } - }; - - /** - * A builder for {@link HotwordTrainingAudio} - */ - @FlaggedApi(Flags.FLAG_ALLOW_TRAINING_DATA_EGRESS_FROM_HDS) - @SuppressWarnings("WeakerAccess") - @DataClass.Generated.Member - public static final class Builder extends BaseBuilder { - - private @NonNull byte[] mHotwordAudio; - private @NonNull AudioFormat mAudioFormat; - private @NonNull int mAudioType; - private int mHotwordOffsetMillis; - - private long mBuilderFieldsSet = 0L; - - /** - * Creates a new Builder. - * - * @param hotwordAudio - * Buffer of hotword audio data for training models. The data format is expected to match - * {@link #getAudioFormat()}. - * @param audioFormat - * The {@link AudioFormat} of the {@link HotwordTrainingAudio#mHotwordAudio}. - */ - public Builder( - @NonNull byte[] hotwordAudio, - @NonNull AudioFormat audioFormat) { - mHotwordAudio = hotwordAudio; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mHotwordAudio); - mAudioFormat = audioFormat; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mAudioFormat); - } - - /** - * The {@link AudioFormat} of the {@link HotwordTrainingAudio#mHotwordAudio}. - */ - @DataClass.Generated.Member - public @NonNull Builder setAudioFormat(@NonNull AudioFormat value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x2; - mAudioFormat = value; - return this; - } - - /** - * App-defined identifier to distinguish hotword training audio instances. - * <p> Returns -1 if unset. - */ - @DataClass.Generated.Member - public @NonNull Builder setAudioType(@NonNull int value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x4; - mAudioType = value; - return this; - } - - /** - * App-defined offset in milliseconds relative to start of - * {@link HotwordTrainingAudio#mHotwordAudio}. Default value is - * {@link HotwordTrainingAudio#HOTWORD_OFFSET_UNSET}. - */ - @DataClass.Generated.Member - public @NonNull Builder setHotwordOffsetMillis(int value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x8; - mHotwordOffsetMillis = value; - return this; - } - - /** Builds the instance. This builder should not be touched after calling this! */ - public @NonNull HotwordTrainingAudio build() { - checkNotUsed(); - mBuilderFieldsSet |= 0x10; // Mark builder used - - if ((mBuilderFieldsSet & 0x4) == 0) { - mAudioType = defaultAudioType(); - } - if ((mBuilderFieldsSet & 0x8) == 0) { - mHotwordOffsetMillis = HOTWORD_OFFSET_UNSET; - } - HotwordTrainingAudio o = new HotwordTrainingAudio( - mHotwordAudio, - mAudioFormat, - mAudioType, - mHotwordOffsetMillis); - return o; - } - - private void checkNotUsed() { - if ((mBuilderFieldsSet & 0x10) != 0) { - throw new IllegalStateException( - "This Builder should not be reused. Use a new Builder instance instead"); - } - } - } - - @DataClass.Generated( - time = 1697827049629L, - codegenVersion = "1.0.23", - sourceFile = "frameworks/base/core/java/android/service/voice/HotwordTrainingAudio.java", - inputSignatures = "public static final int HOTWORD_OFFSET_UNSET\nprivate final @android.annotation.NonNull byte[] mHotwordAudio\nprivate final @android.annotation.NonNull android.media.AudioFormat mAudioFormat\nprivate final @android.annotation.NonNull int mAudioType\nprivate int mHotwordOffsetMillis\nprivate java.lang.String hotwordAudioToString()\nprivate static int defaultAudioType()\nclass HotwordTrainingAudio extends java.lang.Object implements [android.os.Parcelable]\npublic @android.annotation.SuppressLint @android.annotation.NonNull android.service.voice.HotwordTrainingAudio.Builder setHotwordAudio(byte[])\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)\npublic @android.annotation.SuppressLint @android.annotation.NonNull android.service.voice.HotwordTrainingAudio.Builder setHotwordAudio(byte[])\nclass BaseBuilder extends java.lang.Object implements []") - @Deprecated - private void __metadata() {} - - - //@formatter:on - // End of generated code - -} diff --git a/core/java/android/service/voice/HotwordTrainingData.java b/core/java/android/service/voice/HotwordTrainingData.java deleted file mode 100644 index aa6dab3629b4..000000000000 --- a/core/java/android/service/voice/HotwordTrainingData.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.service.voice; - -import android.annotation.FlaggedApi; -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; -import android.service.voice.flags.Flags; -import android.text.TextUtils; - -import com.android.internal.util.DataClass; -import com.android.internal.util.Preconditions; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Contains training data related to hotword detection service. - * - * <p>The constructed object's size must be within - * {@link HotwordTrainingData#getMaxTrainingDataBytes()} or an - * {@link IllegalArgumentException} will be thrown on construction. Size of the object is calculated - * by converting object to a {@link Parcel} and using the {@link Parcel#dataSize()}. - * - * @hide - */ -@DataClass( - genConstructor = false, - genBuilder = true, - genEqualsHashCode = true, - genHiddenConstDefs = true, - genParcelable = true, - genToString = true) -@SystemApi -@FlaggedApi(Flags.FLAG_ALLOW_TRAINING_DATA_EGRESS_FROM_HDS) -public final class HotwordTrainingData implements Parcelable { - /** Max size for hotword training data in bytes. */ - public static int getMaxTrainingDataBytes() { - return 1024 * 1024; // 1 MB; - } - - /** The list containing hotword audio that is useful for training. */ - @NonNull - @DataClass.PluralOf("trainingAudio") - private final List<HotwordTrainingAudio> mTrainingAudioList; - - private static List<HotwordTrainingAudio> defaultTrainingAudioList() { - return Collections.emptyList(); - } - - /** App-defined stage when hotword model timed-out while running. - * <p> Returns -1 if unset. */ - private final int mTimeoutStage; - - private static int defaultTimeoutStage() { - return -1; - } - - private void onConstructed() { - // Verify size of object is within limit. - Parcel parcel = Parcel.obtain(); - parcel.writeValue(this); - int dataSizeBytes = parcel.dataSize(); - parcel.recycle(); - Preconditions.checkArgument( - dataSizeBytes < getMaxTrainingDataBytes(), - TextUtils.formatSimple( - "Hotword training data of size %s exceeds size limit of %s bytes!", - dataSizeBytes, getMaxTrainingDataBytes())); - } - - - - // Code below generated by codegen v1.0.23. - // - // DO NOT MODIFY! - // CHECKSTYLE:OFF Generated code - // - // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/voice/HotwordTrainingData.java - // - // To exclude the generated code from IntelliJ auto-formatting enable (one-time): - // Settings > Editor > Code Style > Formatter Control - //@formatter:off - - - @DataClass.Generated.Member - /* package-private */ HotwordTrainingData( - @NonNull List<HotwordTrainingAudio> trainingAudioList, - int timeoutStage) { - this.mTrainingAudioList = trainingAudioList; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mTrainingAudioList); - this.mTimeoutStage = timeoutStage; - - onConstructed(); - } - - /** - * The list containing hotword audio that is useful for training. - */ - @DataClass.Generated.Member - public @NonNull List<HotwordTrainingAudio> getTrainingAudioList() { - return mTrainingAudioList; - } - - /** - * App-defined stage when hotword model timed-out while running. - * <p> Returns -1 if unset. - */ - @DataClass.Generated.Member - public int getTimeoutStage() { - return mTimeoutStage; - } - - @Override - @DataClass.Generated.Member - public String toString() { - // You can override field toString logic by defining methods like: - // String fieldNameToString() { ... } - - return "HotwordTrainingData { " + - "trainingAudioList = " + mTrainingAudioList + ", " + - "timeoutStage = " + mTimeoutStage + - " }"; - } - - @Override - @DataClass.Generated.Member - public boolean equals(@android.annotation.Nullable Object o) { - // You can override field equality logic by defining either of the methods like: - // boolean fieldNameEquals(HotwordTrainingData other) { ... } - // boolean fieldNameEquals(FieldType otherValue) { ... } - - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - @SuppressWarnings("unchecked") - HotwordTrainingData that = (HotwordTrainingData) o; - //noinspection PointlessBooleanExpression - return true - && java.util.Objects.equals(mTrainingAudioList, that.mTrainingAudioList) - && mTimeoutStage == that.mTimeoutStage; - } - - @Override - @DataClass.Generated.Member - public int hashCode() { - // You can override field hashCode logic by defining methods like: - // int fieldNameHashCode() { ... } - - int _hash = 1; - _hash = 31 * _hash + java.util.Objects.hashCode(mTrainingAudioList); - _hash = 31 * _hash + mTimeoutStage; - return _hash; - } - - @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.writeParcelableList(mTrainingAudioList, flags); - dest.writeInt(mTimeoutStage); - } - - @Override - @DataClass.Generated.Member - public int describeContents() { return 0; } - - /** @hide */ - @SuppressWarnings({"unchecked", "RedundantCast"}) - @DataClass.Generated.Member - /* package-private */ HotwordTrainingData(@NonNull Parcel in) { - // You can override field unparcelling by defining methods like: - // static FieldType unparcelFieldName(Parcel in) { ... } - - List<HotwordTrainingAudio> trainingAudioList = new ArrayList<>(); - in.readParcelableList(trainingAudioList, HotwordTrainingAudio.class.getClassLoader()); - int timeoutStage = in.readInt(); - - this.mTrainingAudioList = trainingAudioList; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mTrainingAudioList); - this.mTimeoutStage = timeoutStage; - - onConstructed(); - } - - @DataClass.Generated.Member - public static final @NonNull Parcelable.Creator<HotwordTrainingData> CREATOR - = new Parcelable.Creator<HotwordTrainingData>() { - @Override - public HotwordTrainingData[] newArray(int size) { - return new HotwordTrainingData[size]; - } - - @Override - public HotwordTrainingData createFromParcel(@NonNull Parcel in) { - return new HotwordTrainingData(in); - } - }; - - /** - * A builder for {@link HotwordTrainingData} - */ - @FlaggedApi(Flags.FLAG_ALLOW_TRAINING_DATA_EGRESS_FROM_HDS) - @SuppressWarnings("WeakerAccess") - @DataClass.Generated.Member - public static final class Builder { - - private @NonNull List<HotwordTrainingAudio> mTrainingAudioList; - private int mTimeoutStage; - - private long mBuilderFieldsSet = 0L; - - public Builder() { - } - - /** - * The list containing hotword audio that is useful for training. - */ - @DataClass.Generated.Member - public @NonNull Builder setTrainingAudioList(@NonNull List<HotwordTrainingAudio> value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x1; - mTrainingAudioList = value; - return this; - } - - /** @see #setTrainingAudioList */ - @DataClass.Generated.Member - public @NonNull Builder addTrainingAudio(@NonNull HotwordTrainingAudio value) { - if (mTrainingAudioList == null) setTrainingAudioList(new ArrayList<>()); - mTrainingAudioList.add(value); - return this; - } - - /** - * App-defined stage when hotword model timed-out while running. - * <p> Returns -1 if unset. - */ - @DataClass.Generated.Member - public @NonNull Builder setTimeoutStage(int value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x2; - mTimeoutStage = value; - return this; - } - - /** Builds the instance. This builder should not be touched after calling this! */ - public @NonNull HotwordTrainingData build() { - checkNotUsed(); - mBuilderFieldsSet |= 0x4; // Mark builder used - - if ((mBuilderFieldsSet & 0x1) == 0) { - mTrainingAudioList = defaultTrainingAudioList(); - } - if ((mBuilderFieldsSet & 0x2) == 0) { - mTimeoutStage = defaultTimeoutStage(); - } - HotwordTrainingData o = new HotwordTrainingData( - mTrainingAudioList, - mTimeoutStage); - return o; - } - - private void checkNotUsed() { - if ((mBuilderFieldsSet & 0x4) != 0) { - throw new IllegalStateException( - "This Builder should not be reused. Use a new Builder instance instead"); - } - } - } - - @DataClass.Generated( - time = 1697826948280L, - codegenVersion = "1.0.23", - sourceFile = "frameworks/base/core/java/android/service/voice/HotwordTrainingData.java", - inputSignatures = "private final @android.annotation.NonNull @com.android.internal.util.DataClass.PluralOf(\"trainingAudio\") java.util.List<android.service.voice.HotwordTrainingAudio> mTrainingAudioList\nprivate final int mTimeoutStage\npublic static int getMaxTrainingDataBytes()\nprivate static java.util.List<android.service.voice.HotwordTrainingAudio> defaultTrainingAudioList()\nprivate static int defaultTimeoutStage()\nprivate void onConstructed()\nclass HotwordTrainingData extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)") - @Deprecated - private void __metadata() {} - - - //@formatter:on - // End of generated code - -} diff --git a/core/java/android/text/BoringLayout.java b/core/java/android/text/BoringLayout.java index 2028c4057c01..9db8aa167498 100644 --- a/core/java/android/text/BoringLayout.java +++ b/core/java/android/text/BoringLayout.java @@ -273,7 +273,7 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback outerwidth /* ellipsizedWidth */, null /* ellipsize */, 1 /* maxLines */, BREAK_STRATEGY_SIMPLE, HYPHENATION_FREQUENCY_NONE, null /* leftIndents */, null /* rightIndents */, JUSTIFICATION_MODE_NONE, LineBreakConfig.NONE, false, - null); + false /* shiftDrawingOffsetForStartOverhang */, null); mEllipsizedWidth = outerwidth; mEllipsizedStart = 0; @@ -346,7 +346,8 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback ellipsizedWidth, ellipsize, 1 /* maxLines */, BREAK_STRATEGY_SIMPLE, HYPHENATION_FREQUENCY_NONE, null /* leftIndents */, null /* rightIndents */, JUSTIFICATION_MODE_NONE, - LineBreakConfig.NONE, metrics, false /* useBoundsForWidth */, null); + LineBreakConfig.NONE, metrics, false /* useBoundsForWidth */, + false /* shiftDrawingOffsetForStartOverhang */, null); } /** @hide */ @@ -363,12 +364,14 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback TextUtils.TruncateAt ellipsize, Metrics metrics, boolean useBoundsForWidth, + boolean shiftDrawingOffsetForStartOverhang, @Nullable Paint.FontMetrics minimumFontMetrics) { this(text, paint, width, align, TextDirectionHeuristics.LTR, spacingMult, spacingAdd, includePad, fallbackLineSpacing, ellipsizedWidth, ellipsize, 1 /* maxLines */, Layout.BREAK_STRATEGY_SIMPLE, Layout.HYPHENATION_FREQUENCY_NONE, null, null, Layout.JUSTIFICATION_MODE_NONE, - LineBreakConfig.NONE, metrics, useBoundsForWidth, minimumFontMetrics); + LineBreakConfig.NONE, metrics, useBoundsForWidth, + shiftDrawingOffsetForStartOverhang, minimumFontMetrics); } /* package */ BoringLayout( @@ -392,12 +395,14 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback LineBreakConfig lineBreakConfig, Metrics metrics, boolean useBoundsForWidth, + boolean shiftDrawingOffsetForStartOverhang, @Nullable Paint.FontMetrics minimumFontMetrics) { super(text, paint, width, align, textDir, spacingMult, spacingAdd, includePad, fallbackLineSpacing, ellipsizedWidth, ellipsize, maxLines, breakStrategy, hyphenationFrequency, leftIndents, rightIndents, justificationMode, - lineBreakConfig, useBoundsForWidth, minimumFontMetrics); + lineBreakConfig, useBoundsForWidth, shiftDrawingOffsetForStartOverhang, + minimumFontMetrics); boolean trust; @@ -712,7 +717,7 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback int cursorOffset) { if (mDirect != null && highlight == null) { float leftShift = 0; - if (getUseBoundsForWidth()) { + if (getUseBoundsForWidth() && getShiftDrawingOffsetForStartOverhang()) { RectF drawingRect = computeDrawingBoundingBox(); if (drawingRect.left < 0) { leftShift = -drawingRect.left; diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java index 928604983b70..cce4f7bf7b1f 100644 --- a/core/java/android/text/DynamicLayout.java +++ b/core/java/android/text/DynamicLayout.java @@ -25,6 +25,7 @@ import android.annotation.FloatRange; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SuppressLint; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Paint; import android.graphics.Rect; @@ -317,6 +318,35 @@ public class DynamicLayout extends Layout { } /** + * Set true for shifting the drawing x offset for showing overhang at the start position. + * + * This flag is ignored if the {@link #getUseBoundsForWidth()} is false. + * + * If this value is false, the Layout draws text from the zero even if there is a glyph + * stroke in a region where the x coordinate is negative. + * + * If this value is true, the Layout draws text with shifting the x coordinate of the + * drawing bounding box. + * + * This value is false by default. + * + * @param shiftDrawingOffsetForStartOverhang true for shifting the drawing offset for + * showing the stroke that is in the region where + * the x coordinate is negative. + * @see #setUseBoundsForWidth(boolean) + * @see #getUseBoundsForWidth() + */ + @NonNull + // The corresponding getter is getShiftDrawingOffsetForStartOverhang() + @SuppressLint("MissingGetterMatchingBuilder") + @FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH) + public Builder setShiftDrawingOffsetForStartOverhang( + boolean shiftDrawingOffsetForStartOverhang) { + mShiftDrawingOffsetForStartOverhang = shiftDrawingOffsetForStartOverhang; + return this; + } + + /** * Set the minimum font metrics used for line spacing. * * <p> @@ -386,6 +416,7 @@ public class DynamicLayout extends Layout { private int mEllipsizedWidth; private LineBreakConfig mLineBreakConfig = LineBreakConfig.NONE; private boolean mUseBoundsForWidth; + private boolean mShiftDrawingOffsetForStartOverhang; private @Nullable Paint.FontMetrics mMinimumFontMetrics; private final Paint.FontMetricsInt mFontMetricsInt = new Paint.FontMetricsInt(); @@ -462,7 +493,8 @@ public class DynamicLayout extends Layout { false /* fallbackLineSpacing */, ellipsizedWidth, ellipsize, Integer.MAX_VALUE /* maxLines */, breakStrategy, hyphenationFrequency, null /* leftIndents */, null /* rightIndents */, justificationMode, - lineBreakConfig, false /* useBoundsForWidth */, null /* minimumFontMetrics */); + lineBreakConfig, false /* useBoundsForWidth */, false, + null /* minimumFontMetrics */); final Builder b = Builder.obtain(base, paint, width) .setAlignment(align) @@ -488,7 +520,8 @@ public class DynamicLayout extends Layout { b.mIncludePad, b.mFallbackLineSpacing, b.mEllipsizedWidth, b.mEllipsize, Integer.MAX_VALUE /* maxLines */, b.mBreakStrategy, b.mHyphenationFrequency, null /* leftIndents */, null /* rightIndents */, b.mJustificationMode, - b.mLineBreakConfig, b.mUseBoundsForWidth, b.mMinimumFontMetrics); + b.mLineBreakConfig, b.mUseBoundsForWidth, b.mShiftDrawingOffsetForStartOverhang, + b.mMinimumFontMetrics); mDisplay = b.mDisplay; mIncludePad = b.mIncludePad; @@ -516,6 +549,7 @@ public class DynamicLayout extends Layout { mBase = b.mBase; mFallbackLineSpacing = b.mFallbackLineSpacing; mUseBoundsForWidth = b.mUseBoundsForWidth; + mShiftDrawingOffsetForStartOverhang = b.mShiftDrawingOffsetForStartOverhang; mMinimumFontMetrics = b.mMinimumFontMetrics; if (b.mEllipsize != null) { mInts = new PackedIntVector(COLUMNS_ELLIPSIZE); @@ -713,6 +747,7 @@ public class DynamicLayout extends Layout { .setAddLastLineLineSpacing(!islast) .setIncludePad(false) .setUseBoundsForWidth(mUseBoundsForWidth) + .setShiftDrawingOffsetForStartOverhang(mShiftDrawingOffsetForStartOverhang) .setMinimumFontMetrics(mMinimumFontMetrics) .setCalculateBounds(true); @@ -1392,6 +1427,7 @@ public class DynamicLayout extends Layout { private Rect mTempRect = new Rect(); private boolean mUseBoundsForWidth; + private boolean mShiftDrawingOffsetForStartOverhang; @Nullable Paint.FontMetrics mMinimumFontMetrics; @UnsupportedAppUsage diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index e5d199ad8e46..8e52af3fb57b 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -44,6 +44,7 @@ import android.text.style.LineBackgroundSpan; import android.text.style.ParagraphStyle; import android.text.style.ReplacementSpan; import android.text.style.TabStopSpan; +import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; @@ -299,7 +300,7 @@ public abstract class Layout { this(text, paint, width, align, TextDirectionHeuristics.FIRSTSTRONG_LTR, spacingMult, spacingAdd, false, false, 0, null, Integer.MAX_VALUE, BREAK_STRATEGY_SIMPLE, HYPHENATION_FREQUENCY_NONE, null, null, - JUSTIFICATION_MODE_NONE, LineBreakConfig.NONE, false, null); + JUSTIFICATION_MODE_NONE, LineBreakConfig.NONE, false, false, null); } /** @@ -349,6 +350,7 @@ public abstract class Layout { int justificationMode, LineBreakConfig lineBreakConfig, boolean useBoundsForWidth, + boolean shiftDrawingOffsetForStartOverhang, Paint.FontMetrics minimumFontMetrics ) { @@ -384,6 +386,7 @@ public abstract class Layout { mJustificationMode = justificationMode; mLineBreakConfig = lineBreakConfig; mUseBoundsForWidth = useBoundsForWidth; + mShiftDrawingOffsetForStartOverhang = shiftDrawingOffsetForStartOverhang; mMinimumFontMetrics = minimumFontMetrics; } @@ -465,7 +468,7 @@ public abstract class Layout { @Nullable Paint selectionPaint, int cursorOffsetVertical) { float leftShift = 0; - if (mUseBoundsForWidth) { + if (mUseBoundsForWidth && mShiftDrawingOffsetForStartOverhang) { RectF drawingRect = computeDrawingBoundingBox(); if (drawingRect.left < 0) { leftShift = -drawingRect.left; @@ -3414,6 +3417,7 @@ public abstract class Layout { private int mJustificationMode; private LineBreakConfig mLineBreakConfig; private boolean mUseBoundsForWidth; + private boolean mShiftDrawingOffsetForStartOverhang; private @Nullable Paint.FontMetrics mMinimumFontMetrics; private TextLine.LineInfo mLineInfo = null; @@ -3873,6 +3877,35 @@ public abstract class Layout { } /** + * Set true for shifting the drawing x offset for showing overhang at the start position. + * + * This flag is ignored if the {@link #getUseBoundsForWidth()} is false. + * + * If this value is false, the Layout draws text from the zero even if there is a glyph + * stroke in a region where the x coordinate is negative. + * + * If this value is true, the Layout draws text with shifting the x coordinate of the + * drawing bounding box. + * + * This value is false by default. + * + * @param shiftDrawingOffsetForStartOverhang true for shifting the drawing offset for + * showing the stroke that is in the region where + * the x coordinate is negative. + * @see #setUseBoundsForWidth(boolean) + * @see #getUseBoundsForWidth() + */ + @NonNull + // The corresponding getter is getShiftDrawingOffsetForStartOverhang() + @SuppressLint("MissingGetterMatchingBuilder") + @FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH) + public Builder setShiftDrawingOffsetForStartOverhang( + boolean shiftDrawingOffsetForStartOverhang) { + mShiftDrawingOffsetForStartOverhang = shiftDrawingOffsetForStartOverhang; + return this; + } + + /** * Set the minimum font metrics used for line spacing. * * <p> @@ -3948,6 +3981,7 @@ public abstract class Layout { .setJustificationMode(mJustificationMode) .setLineBreakConfig(mLineBreakConfig) .setUseBoundsForWidth(mUseBoundsForWidth) + .setShiftDrawingOffsetForStartOverhang(mShiftDrawingOffsetForStartOverhang) .build(); } else { return new BoringLayout( @@ -3955,7 +3989,7 @@ public abstract class Layout { mIncludePad, mFallbackLineSpacing, mEllipsizedWidth, mEllipsize, mMaxLines, mBreakStrategy, mHyphenationFrequency, mLeftIndents, mRightIndents, mJustificationMode, mLineBreakConfig, metrics, mUseBoundsForWidth, - mMinimumFontMetrics); + mShiftDrawingOffsetForStartOverhang, mMinimumFontMetrics); } } @@ -3980,6 +4014,7 @@ public abstract class Layout { private int mJustificationMode = JUSTIFICATION_MODE_NONE; private LineBreakConfig mLineBreakConfig = LineBreakConfig.NONE; private boolean mUseBoundsForWidth; + private boolean mShiftDrawingOffsetForStartOverhang; private Paint.FontMetrics mMinimumFontMetrics; } @@ -4294,6 +4329,20 @@ public abstract class Layout { } /** + * Returns true if shifting drawing offset for start overhang. + * + * @return True if shifting drawing offset for start overhang. + * @see android.widget.TextView#setShiftDrawingOffsetForStartOverhang(boolean) + * @see TextView#getShiftDrawingOffsetForStartOverhang() + * @see StaticLayout.Builder#setShiftDrawingOffsetForStartOverhang(boolean) + * @see DynamicLayout.Builder#setShiftDrawingOffsetForStartOverhang(boolean) + */ + @FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH) + public boolean getShiftDrawingOffsetForStartOverhang() { + return mShiftDrawingOffsetForStartOverhang; + } + + /** * Get the minimum font metrics used for line spacing. * * @see android.widget.TextView#setMinimumFontMetrics(Paint.FontMetrics) diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 5986238d3035..3dd3a9ea8baf 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -24,6 +24,7 @@ import android.annotation.FloatRange; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SuppressLint; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Paint; import android.graphics.RectF; @@ -454,6 +455,35 @@ public class StaticLayout extends Layout { } /** + * Set true for shifting the drawing x offset for showing overhang at the start position. + * + * This flag is ignored if the {@link #getUseBoundsForWidth()} is false. + * + * If this value is false, the Layout draws text from the zero even if there is a glyph + * stroke in a region where the x coordinate is negative. + * + * If this value is true, the Layout draws text with shifting the x coordinate of the + * drawing bounding box. + * + * This value is false by default. + * + * @param shiftDrawingOffsetForStartOverhang true for shifting the drawing offset for + * showing the stroke that is in the region where + * the x coordinate is negative. + * @see #setUseBoundsForWidth(boolean) + * @see #getUseBoundsForWidth() + */ + @NonNull + // The corresponding getter is getShiftDrawingOffsetForStartOverhang() + @SuppressLint("MissingGetterMatchingBuilder") + @FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH) + public Builder setShiftDrawingOffsetForStartOverhang( + boolean shiftDrawingOffsetForStartOverhang) { + mShiftDrawingOffsetForStartOverhang = shiftDrawingOffsetForStartOverhang; + return this; + } + + /** * Internal API that tells underlying line breaker that calculating bounding boxes even if * the line break is performed with advances. This is useful for DynamicLayout internal * implementation because it uses bounding box as well as advances. @@ -566,6 +596,7 @@ public class StaticLayout extends Layout { private boolean mAddLastLineLineSpacing; private LineBreakConfig mLineBreakConfig = LineBreakConfig.NONE; private boolean mUseBoundsForWidth; + private boolean mShiftDrawingOffsetForStartOverhang; private boolean mCalculateBounds; @Nullable private Paint.FontMetrics mMinimumFontMetrics; @@ -599,6 +630,7 @@ public class StaticLayout extends Layout { JUSTIFICATION_MODE_NONE, null, // lineBreakConfig, false, // useBoundsForWidth + false, // shiftDrawingOffsetForStartOverhang null // minimumFontMetrics ); @@ -677,7 +709,7 @@ public class StaticLayout extends Layout { b.mIncludePad, b.mFallbackLineSpacing, b.mEllipsizedWidth, b.mEllipsize, b.mMaxLines, b.mBreakStrategy, b.mHyphenationFrequency, b.mLeftIndents, b.mRightIndents, b.mJustificationMode, b.mLineBreakConfig, b.mUseBoundsForWidth, - b.mMinimumFontMetrics); + b.mShiftDrawingOffsetForStartOverhang, b.mMinimumFontMetrics); mColumns = columnSize; if (b.mEllipsize != null) { diff --git a/core/java/android/view/AttachedSurfaceControl.java b/core/java/android/view/AttachedSurfaceControl.java index 9413f5c0868e..5406cf557410 100644 --- a/core/java/android/view/AttachedSurfaceControl.java +++ b/core/java/android/view/AttachedSurfaceControl.java @@ -192,7 +192,7 @@ public interface AttachedSurfaceControl { * {@link WindowManager#registerUnbatchedSurfaceControlInputReceiver(int, InputTransferToken, * SurfaceControl, Looper, SurfaceControlInputReceiver)} * - * @return The SurfaceControlViewHost link token. + * @return The {@link InputTransferToken} for the {@link AttachedSurfaceControl} * @throws IllegalStateException if the {@link AttachedSurfaceControl} was created with no * registered input */ @@ -202,38 +202,4 @@ public interface AttachedSurfaceControl { throw new UnsupportedOperationException("The getInputTransferToken needs to be " + "implemented before making this call."); } - - /** - * Transfer the currently in progress touch gesture from the host to the requested - * {@link SurfaceControlViewHost.SurfacePackage}. This requires that the - * SurfaceControlViewHost was created with the current host's inputToken. - * <p> - * When the touch is transferred, the window currently receiving touch gets an ACTION_CANCEL - * and does not receive any further input events for this gesture. - * <p> - * The transferred-to window receives an ACTION_DOWN event and then the remainder of the - * input events for this gesture. It does not receive any of the previous events of this gesture - * that the originating window received. - * <p> - * The "transferTouch" API only works for the current gesture. When a new gesture arrives, - * input dispatcher will do a new round of hit testing. So, if the "host" window is still the - * first thing that's being touched, then it will receive the new gesture again. It will - * again be up to the host to transfer this new gesture to the embedded. - * <p> - * Once the transferred-to window receives the gesture, it can choose to give up this gesture - * and send it to another window that it's linked to (it can't be an arbitrary window for - * security reasons) using the same transferTouch API. Only the window currently receiving - * touch is allowed to transfer the gesture. - * - * @param surfacePackage The SurfacePackage to transfer the gesture to. - * @return Whether the touch stream was transferred. - * @see SurfaceControlViewHost#transferTouchGestureToHost() for the reverse to transfer touch - * gesture from the embedded to the host. - */ - @FlaggedApi(Flags.FLAG_TRANSFER_GESTURE_TO_EMBEDDED) - default boolean transferHostTouchGestureToEmbedded( - @NonNull SurfaceControlViewHost.SurfacePackage surfacePackage) { - throw new UnsupportedOperationException( - "transferHostTouchGestureToEmbedded is unimplemented"); - } } diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java index eb289204e481..676b903472c5 100644 --- a/core/java/android/view/HandwritingInitiator.java +++ b/core/java/android/view/HandwritingInitiator.java @@ -23,6 +23,9 @@ import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; +import android.text.TextUtils; +import android.view.inputmethod.ConnectionlessHandwritingCallback; +import android.view.inputmethod.CursorAnchorInfo; import android.view.inputmethod.Flags; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; @@ -225,15 +228,7 @@ public class HandwritingInitiator { } startHandwriting(candidateView); } else if (candidateView.getHandwritingDelegatorCallback() != null) { - String delegatePackageName = - candidateView.getAllowedHandwritingDelegatePackageName(); - if (delegatePackageName == null) { - delegatePackageName = candidateView.getContext().getOpPackageName(); - } - mImm.prepareStylusHandwritingDelegation( - candidateView, delegatePackageName); - candidateView.getHandwritingDelegatorCallback().run(); - mState.mHasPreparedHandwritingDelegation = true; + prepareDelegation(candidateView); } else { if (!mInitiateWithoutConnection) { mState.mPendingConnectedView = new WeakReference<>(candidateView); @@ -375,7 +370,7 @@ public class HandwritingInitiator { // A new view just gain focus. By default, we should show hover icon for it. mShowHoverIconForConnectedView = true; } - if (!fromTouchEvent) { + if (!fromTouchEvent && view.isHandwritingDelegate()) { tryAcceptStylusHandwritingDelegation(view); } return true; @@ -393,15 +388,33 @@ public class HandwritingInitiator { } } + private void prepareDelegation(View view) { + String delegatePackageName = view.getAllowedHandwritingDelegatePackageName(); + if (delegatePackageName == null) { + delegatePackageName = view.getContext().getOpPackageName(); + } + if (mImm.isConnectionlessStylusHandwritingAvailable()) { + // No other view should have focus during the connectionless handwriting session, as + // this could cause user confusion about the input target for the session. + view.getViewRootImpl().getView().clearFocus(); + mImm.startConnectionlessStylusHandwritingForDelegation( + view, getCursorAnchorInfoForConnectionless(view), delegatePackageName, + view::post, new DelegationCallback(view, delegatePackageName)); + mState.mHasInitiatedHandwriting = true; + mState.mShouldInitHandwriting = false; + } else { + mImm.prepareStylusHandwritingDelegation(view, delegatePackageName); + view.getHandwritingDelegatorCallback().run(); + mState.mHasPreparedHandwritingDelegation = true; + } + } + /** * Starts a stylus handwriting session for the delegate view, if {@link * InputMethodManager#prepareStylusHandwritingDelegation} was previously called. */ @VisibleForTesting public boolean tryAcceptStylusHandwritingDelegation(@NonNull View view) { - if (!view.isHandwritingDelegate() || (mState != null && mState.mHasInitiatedHandwriting)) { - return false; - } String delegatorPackageName = view.getAllowedHandwritingDelegatorPackageName(); if (delegatorPackageName == null) { @@ -807,6 +820,59 @@ public class HandwritingInitiator { && view.shouldInitiateHandwriting(); } + private CursorAnchorInfo getCursorAnchorInfoForConnectionless(View view) { + CursorAnchorInfo.Builder builder = new CursorAnchorInfo.Builder(); + // Fake editor views will usually display hint text. The hint text view can be used to + // populate the CursorAnchorInfo. + TextView textView = findFirstTextViewDescendent(view); + if (textView != null) { + textView.getCursorAnchorInfo(0, builder, mTempMatrix); + if (textView.getSelectionStart() < 0) { + // Insertion marker location is not populated if selection start is negative, so + // make a best guess. + float bottom = textView.getHeight() - textView.getExtendedPaddingBottom(); + builder.setInsertionMarkerLocation( + /* horizontalPosition= */ textView.getCompoundPaddingStart(), + /* lineTop= */ textView.getExtendedPaddingTop(), + /* lineBaseline= */ bottom, + /* lineBottom= */ bottom, + /* flags= */ 0); + } + } else { + // If there is no TextView descendent, just populate the insertion marker with the start + // edge of the view. + mTempMatrix.reset(); + view.transformMatrixToGlobal(mTempMatrix); + builder.setMatrix(mTempMatrix); + builder.setInsertionMarkerLocation( + /* horizontalPosition= */ view.isLayoutRtl() ? view.getWidth() : 0, + /* lineTop= */ 0, + /* lineBaseline= */ view.getHeight(), + /* lineBottom= */ view.getHeight(), + /* flags= */ 0); + } + return builder.build(); + } + + @Nullable + private static TextView findFirstTextViewDescendent(View view) { + if (view instanceof ViewGroup viewGroup) { + TextView textView; + for (int i = 0; i < viewGroup.getChildCount(); ++i) { + View child = viewGroup.getChildAt(i); + textView = (child instanceof TextView tv) + ? tv : findFirstTextViewDescendent(viewGroup.getChildAt(i)); + if (textView != null + && textView.isAggregatedVisible() + && (!TextUtils.isEmpty(textView.getText()) + || !TextUtils.isEmpty(textView.getHint()))) { + return textView; + } + } + } + return null; + } + /** * A class used to track the handwriting areas set by the Views. * @@ -931,4 +997,35 @@ public class HandwritingInitiator { return true; } } + + private class DelegationCallback implements ConnectionlessHandwritingCallback { + private final View mView; + private final String mDelegatePackageName; + + private DelegationCallback(View view, String delegatePackageName) { + mView = view; + mDelegatePackageName = delegatePackageName; + } + + @Override + public void onResult(@NonNull CharSequence text) { + mView.getHandwritingDelegatorCallback().run(); + } + + @Override + public void onError(int errorCode) { + switch (errorCode) { + case CONNECTIONLESS_HANDWRITING_ERROR_NO_TEXT_RECOGNIZED: + mView.getHandwritingDelegatorCallback().run(); + break; + case CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED: + // Fall back to the old delegation flow + mImm.prepareStylusHandwritingDelegation(mView, mDelegatePackageName); + mView.getHandwritingDelegatorCallback().run(); + mState.mHasInitiatedHandwriting = false; + mState.mHasPreparedHandwritingDelegation = true; + break; + } + } + } } diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 29cc8594deec..c475f6babbf1 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -1098,4 +1098,7 @@ interface IWindowManager * (ie. not handled by any window which can handle the drag). */ void setUnhandledDragListener(IUnhandledDragListener listener); + + boolean transferTouchGesture(in InputTransferToken transferFromToken, + in InputTransferToken transferToToken); } diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 55e49f8f3ad9..d68a47c54d4b 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -370,11 +370,6 @@ interface IWindowSession { */ boolean cancelDraw(IWindow window); - boolean transferEmbeddedTouchFocusToHost(IWindow embeddedWindow); - - boolean transferHostTouchGestureToEmbedded(IWindow hostWindow, - in InputTransferToken transferTouchToken); - /** * Moves the focus to the adjacent window if there is one in the given direction. This can only * move the focus to the window in the same leaf task. diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java index 1dd9cbb76a9f..6f757df66d42 100644 --- a/core/java/android/view/SurfaceControlViewHost.java +++ b/core/java/android/view/SurfaceControlViewHost.java @@ -293,12 +293,13 @@ public class SurfaceControlViewHost { /** * Gets an {@link InputTransferToken} which can be used to request focus on the embedded * surface or to transfer touch gesture to the embedded surface. - * @return the InputTransferToken associated with {@link SurfacePackage} - * @see AttachedSurfaceControl#transferHostTouchGestureToEmbedded(SurfacePackage) * - * @hide + * @return the InputTransferToken associated with {@link SurfacePackage} or {@code null} if + * the embedded hasn't set up its view or doesn't have input. + * @see WindowManager#transferTouchGesture(InputTransferToken, InputTransferToken) */ @Nullable + @FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) public InputTransferToken getInputTransferToken() { return mInputTransferToken; } @@ -577,9 +578,9 @@ public class SurfaceControlViewHost { } /** - * Transfer the currently in progress touch gesture to the parent - * (if any) of this SurfaceControlViewHost. This requires that the - * SurfaceControlViewHost was created with an associated hostInputToken. + * Transfer the currently in progress touch gesture to the parent (if any) of this + * SurfaceControlViewHost. This requires that the SurfaceControlViewHost was created with an + * associated host {@link InputTransferToken}. * * @return Whether the touch stream was transferred. */ @@ -587,13 +588,14 @@ public class SurfaceControlViewHost { if (mViewRoot == null) { return false; } - - final IWindowSession realWm = WindowManagerGlobal.getWindowSession(); - try { - return realWm.transferEmbeddedTouchFocusToHost(mViewRoot.mWindow); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); + final WindowManager wm = + (WindowManager) mViewRoot.mContext.getSystemService(Context.WINDOW_SERVICE); + InputTransferToken embeddedToken = getInputTransferToken(); + InputTransferToken hostToken = mWm.mHostInputTransferToken; + if (embeddedToken == null || hostToken == null) { + Log.w(TAG, "Failed to transferTouchGestureToHost. Host or embedded token is null"); + return false; } - return false; + return wm.transferTouchGesture(getInputTransferToken(), mWm.mHostInputTransferToken); } } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 25ade62078fd..8cbfdcb12846 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5629,7 +5629,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // The preferred frame rate of the view that is mainly used for // touch boosting, view velocity handling, and TextureView. - private float mPreferredFrameRate = Float.NaN; + private float mPreferredFrameRate = REQUESTED_FRAME_RATE_CATEGORY_DEFAULT; private int mInfrequentUpdateCount = 0; private long mLastUpdateTimeMillis = 0; @@ -5638,7 +5638,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private int mLastFrameRateCategory = FRAME_RATE_CATEGORY_HIGH; @FlaggedApi(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) - public static final float REQUESTED_FRAME_RATE_CATEGORY_DEFAULT = 0; + public static final float REQUESTED_FRAME_RATE_CATEGORY_DEFAULT = Float.NaN; @FlaggedApi(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) public static final float REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE = -1; @FlaggedApi(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) @@ -33457,7 +33457,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mInfrequentUpdateCount == INFREQUENT_UPDATE_COUNTS) { return FRAME_RATE_CATEGORY_NORMAL; } - return mLastFrameRateCategory; } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 657c8e644f3a..75deceb5826f 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -27,6 +27,8 @@ import static android.view.InputDevice.SOURCE_CLASS_NONE; import static android.view.InsetsSource.ID_IME; import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH; import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT; +import static android.view.Surface.FRAME_RATE_CATEGORY_LOW; +import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL; import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE; import static android.view.View.PFLAG_DRAW_ANIMATION; import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN; @@ -1020,6 +1022,11 @@ public final class ViewRootImpl implements ViewParent, // Used to check if there is a message in the message queue // for idleness handling. private boolean mHasIdledMessage = false; + // Used to allow developers to opt out Toolkit dVRR feature. + // This feature allows device to adjust refresh rate + // as needed and can be useful for power saving. + // Should not enable the dVRR feature if the value is false. + private boolean mIsFrameRatePowerSavingsBalanced = true; // time for touch boost period. private static final int FRAME_RATE_TOUCH_BOOST_TIME = 3000; // time for checking idle status periodically. @@ -1031,6 +1038,15 @@ public final class ViewRootImpl implements ViewParent, private static final int FRAME_RATE_SETTING_REEVALUATE_TIME = 100; /* + * The variables below are used to update frame rate category + */ + private static final int FRAME_RATE_CATEGORY_COUNT = 5; + private int mFrameRateCategoryHighCount = 0; + private int mFrameRateCategoryHighHintCount = 0; + private int mFrameRateCategoryNormalCount = 0; + private int mFrameRateCategoryLowCount = 0; + + /* * the variables below are used to determine whther a dVRR feature should be enabled */ @@ -2522,8 +2538,10 @@ public final class ViewRootImpl implements ViewParent, // Set the frame rate selection strategy to FRAME_RATE_SELECTION_STRATEGY_SELF // This strategy ensures that the frame rate specifications do not cascade down to // the descendant layers. This is particularly important for applications like Chrome, - // where child surfaces should adhere to default behavior instead of no preference - if (sToolkitSetFrameRateReadOnlyFlagValue) { + // where child surfaces should adhere to default behavior instead of no preference. + // This issue only happens when ViewRootImpl calls setFrameRateCategory. This is + // no longer needed if the dVRR feature is disabled. + if (shouldEnableDvrr()) { try { mFrameRateTransaction.setFrameRateSelectionStrategy(sc, sc.FRAME_RATE_SELECTION_STRATEGY_SELF).applyAsyncUnsafe(); @@ -3247,7 +3265,7 @@ public final class ViewRootImpl implements ViewParent, destroyHardwareResources(); } - if (sToolkitSetFrameRateReadOnlyFlagValue && viewVisibility == View.VISIBLE) { + if (shouldEnableDvrr() && viewVisibility == View.VISIBLE) { // Boost frame rate when the viewVisibility becomes true. // This is mainly for lanuchers that lanuch new windows. boostFrameRate(FRAME_RATE_TOUCH_BOOST_TIME); @@ -3962,7 +3980,7 @@ public final class ViewRootImpl implements ViewParent, } } - if (sToolkitSetFrameRateReadOnlyFlagValue) { + if (shouldEnableDvrr()) { // Boost the frame rate when the ViewRootImpl first becomes available. boostFrameRate(FRAME_RATE_TOUCH_BOOST_TIME); } @@ -4084,7 +4102,14 @@ public final class ViewRootImpl implements ViewParent, // when the values are applicable. setPreferredFrameRate(mPreferredFrameRate); setPreferredFrameRateCategory(mPreferredFrameRateCategory); + mFrameRateCategoryHighCount = mFrameRateCategoryHighCount > 0 + ? mFrameRateCategoryHighCount - 1 : mFrameRateCategoryHighCount; + mFrameRateCategoryNormalCount = mFrameRateCategoryNormalCount > 0 + ? mFrameRateCategoryNormalCount - 1 : mFrameRateCategoryNormalCount; + mFrameRateCategoryLowCount = mFrameRateCategoryLowCount > 0 + ? mFrameRateCategoryLowCount - 1 : mFrameRateCategoryLowCount; mPreferredFrameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE; + mPreferredFrameRate = -1; } private void createSyncIfNeeded() { @@ -5169,7 +5194,10 @@ public final class ViewRootImpl implements ViewParent, // Force recalculation of transparent regions if (accessibilityFocusDirty) { - requestLayout(); + final Rect bounds = mAttachInfo.mTmpInvalRect; + if (getAccessibilityFocusedRect(bounds)) { + requestLayout(); + } } mAttachInfo.mDrawingTime = @@ -12296,7 +12324,8 @@ public final class ViewRootImpl implements ViewParent, } try { - if (mLastPreferredFrameRate != preferredFrameRate) { + if (mLastPreferredFrameRate != preferredFrameRate + && preferredFrameRate >= 0) { if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.traceBegin( Trace.TRACE_TAG_VIEW, "ViewRootImpl#setFrameRate " @@ -12321,12 +12350,12 @@ public final class ViewRootImpl implements ViewParent, private boolean shouldSetFrameRateCategory() { // use toolkitSetFrameRate flag to gate the change - return mSurface.isValid() && sToolkitSetFrameRateReadOnlyFlagValue; + return mSurface.isValid() && shouldEnableDvrr(); } private boolean shouldSetFrameRate() { // use toolkitSetFrameRate flag to gate the change - return sToolkitSetFrameRateReadOnlyFlagValue; + return mSurface.isValid() && mPreferredFrameRate > 0 && shouldEnableDvrr(); } private boolean shouldTouchBoost(int motionEventAction, int windowType) { @@ -12335,7 +12364,7 @@ public final class ViewRootImpl implements ViewParent, || motionEventAction == MotionEvent.ACTION_UP; boolean undesiredType = windowType == TYPE_INPUT_METHOD && mShouldSuppressBoostOnTyping; // use toolkitSetFrameRate flag to gate the change - return desiredAction && !undesiredType && sToolkitSetFrameRateReadOnlyFlagValue + return desiredAction && !undesiredType && shouldEnableDvrr() && getFrameRateBoostOnTouchEnabled(); } @@ -12346,7 +12375,25 @@ public final class ViewRootImpl implements ViewParent, */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) public void votePreferredFrameRateCategory(int frameRateCategory) { - mPreferredFrameRateCategory = Math.max(mPreferredFrameRateCategory, frameRateCategory); + if (frameRateCategory == FRAME_RATE_CATEGORY_HIGH) { + mFrameRateCategoryHighCount = FRAME_RATE_CATEGORY_COUNT; + } else if (frameRateCategory == FRAME_RATE_CATEGORY_HIGH_HINT) { + mFrameRateCategoryHighHintCount = FRAME_RATE_CATEGORY_COUNT; + } else if (frameRateCategory == FRAME_RATE_CATEGORY_NORMAL) { + mFrameRateCategoryNormalCount = FRAME_RATE_CATEGORY_COUNT; + } else if (frameRateCategory == FRAME_RATE_CATEGORY_LOW) { + mFrameRateCategoryLowCount = FRAME_RATE_CATEGORY_COUNT; + } + + if (mFrameRateCategoryHighCount > 0) { + mPreferredFrameRateCategory = FRAME_RATE_CATEGORY_HIGH; + } else if (mFrameRateCategoryHighHintCount > 0) { + mPreferredFrameRateCategory = FRAME_RATE_CATEGORY_HIGH_HINT; + } else if (mFrameRateCategoryNormalCount > 0) { + mPreferredFrameRateCategory = FRAME_RATE_CATEGORY_NORMAL; + } else if (mFrameRateCategoryLowCount > 0) { + mPreferredFrameRateCategory = FRAME_RATE_CATEGORY_LOW; + } mHasInvalidation = true; } @@ -12368,13 +12415,7 @@ public final class ViewRootImpl implements ViewParent, return; } - if (mPreferredFrameRate == 0) { - mPreferredFrameRate = frameRate; - } else if (frameRate > 60 || mPreferredFrameRate > 60) { - mPreferredFrameRate = Math.max(mPreferredFrameRate, frameRate); - } else if (mPreferredFrameRate != frameRate) { - mPreferredFrameRate = 60; - } + mPreferredFrameRate = Math.max(mPreferredFrameRate, frameRate); mHasInvalidation = true; mHandler.removeMessages(MSG_FRAME_RATE_SETTING); @@ -12403,7 +12444,7 @@ public final class ViewRootImpl implements ViewParent, */ @VisibleForTesting public float getPreferredFrameRate() { - return mPreferredFrameRate; + return mPreferredFrameRate >= 0 ? mPreferredFrameRate : mLastPreferredFrameRate; } /** @@ -12431,19 +12472,6 @@ public final class ViewRootImpl implements ViewParent, boostTimeOut); } - @Override - public boolean transferHostTouchGestureToEmbedded( - @NonNull SurfaceControlViewHost.SurfacePackage surfacePackage) { - final IWindowSession realWm = WindowManagerGlobal.getWindowSession(); - try { - return realWm.transferHostTouchGestureToEmbedded(mWindow, - surfacePackage.getInputTransferToken()); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); - } - return false; - } - /** * Set the default back key callback for windowless window, to forward the back key event * to host app. @@ -12458,4 +12486,27 @@ public final class ViewRootImpl implements ViewParent, // Record the largest view of percentage to the display size. mLargestChildPercentage = Math.max(percentage, mLargestChildPercentage); } + + /** + * Get the value of mIsFrameRatePowerSavingsBalanced + * Can be used to checked if toolkit dVRR feature is enabled. The default value is true. + */ + @VisibleForTesting + public boolean isFrameRatePowerSavingsBalanced() { + return mIsFrameRatePowerSavingsBalanced; + } + + /** + * Set the value of mIsFrameRatePowerSavingsBalanced + * Can be used to checked if toolkit dVRR feature is enabled. + */ + public void setFrameRatePowerSavingsBalanced(boolean enabled) { + if (sToolkitSetFrameRateReadOnlyFlagValue) { + mIsFrameRatePowerSavingsBalanced = enabled; + } + } + + private boolean shouldEnableDvrr() { + return sToolkitSetFrameRateReadOnlyFlagValue && mIsFrameRatePowerSavingsBalanced; + } } diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 4ba4ee3ffff7..6b427fc00766 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -1409,6 +1409,42 @@ public abstract class Window { } /** + * Set whether frameratepowersavingsbalance is enabled for this Window. + * This allows device to adjust refresh rate + * as needed and can be useful for power saving. + * + * @param enabled whether the frameratepowersavingsbalance is enabled. + * @see #isFrameRatePowerSavingsBalanced() + * @see WindowManager.LayoutParams#setFrameRatePowerSavingsBalanced(boolean) + */ + @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public void setFrameRatePowerSavingsBalanced(boolean enabled) { + if (sToolkitSetFrameRateReadOnlyFlagValue) { + final WindowManager.LayoutParams attrs = getAttributes(); + attrs.setFrameRatePowerSavingsBalanced(enabled); + dispatchWindowAttributesChanged(attrs); + } + } + + /** + * Get whether frameratepowersavingsbalance is enabled for this Window. + * This allows device to adjust refresh rate + * as needed and can be useful for power saving. + * {@link #setFrameRateBoostOnTouchEnabled(boolean)} + * + * @return whether the frameratepowersavingsbalance is enabled. + * @see #setFrameRatePowerSavingsBalanced(boolean) + * @see WindowManager.LayoutParams#isFrameRatePowerSavingsBalanced() + */ + @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public boolean isFrameRatePowerSavingsBalanced() { + if (sToolkitSetFrameRateReadOnlyFlagValue) { + return getAttributes().isFrameRatePowerSavingsBalanced(); + } + return false; + } + + /** * If {@code isPreferred} is true, this method requests that the connected display does minimal * post processing when this window is visible on the screen. Otherwise, it requests that the * display switches back to standard image processing. diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 0302a0df35c0..64846d082601 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1548,6 +1548,48 @@ public interface WindowManager extends ViewManager { "android.window.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI"; /** + * Application or Activity level + * {@link android.content.pm.PackageManager.Property PackageManager.Property} to provide any + * preferences for showing all or specific Activities on small cover displays of foldable + * style devices. + * + * <p>The only supported value for the property is {@link #COMPAT_SMALL_COVER_SCREEN_OPT_IN}. + * + * <p><b>Syntax:</b> + * <pre> + * <application> + * <property + * android:name="android.window.PROPERTY_COMPAT_ALLOW_SMALL_COVER_SCREEN" + * android:value=1 <!-- COMPAT_COVER_SCREEN_OPT_IN -->/> + * </application> + * </pre> + */ + @FlaggedApi(Flags.FLAG_COVER_DISPLAY_OPT_IN) + String PROPERTY_COMPAT_ALLOW_SMALL_COVER_SCREEN = + "android.window.PROPERTY_COMPAT_ALLOW_SMALL_COVER_SCREEN"; + + /** + * Value applicable for the {@link #PROPERTY_COMPAT_ALLOW_SMALL_COVER_SCREEN} property to + * provide a signal to the system that an application or its specific activities explicitly + * opt into being displayed on small foldable device cover screens that measure at least 1.5 + * inches for the shorter dimension and at least 2.4 inches for the longer dimension. + */ + @CompatSmallScreenPolicy + @FlaggedApi(Flags.FLAG_COVER_DISPLAY_OPT_IN) + int COMPAT_SMALL_COVER_SCREEN_OPT_IN = 1; + + /** + * @hide + */ + @IntDef({ + COMPAT_SMALL_COVER_SCREEN_OPT_IN, + }) + @Retention(RetentionPolicy.SOURCE) + @interface CompatSmallScreenPolicy {} + + + + /** * Request for app's keyboard shortcuts to be retrieved asynchronously. * * @param receiver The callback to be triggered when the result is ready. @@ -4397,6 +4439,7 @@ public interface WindowManager extends ViewManager { * For variable refresh rate project. */ private boolean mFrameRateBoostOnTouch = true; + private boolean mIsFrameRatePowerSavingsBalanced = true; private static boolean sToolkitSetFrameRateReadOnlyFlagValue = android.view.flags.Flags.toolkitSetFrameRateReadOnly(); @@ -4861,6 +4904,36 @@ public interface WindowManager extends ViewManager { } /** + * Set the value whether frameratepowersavingsbalance is enabled for this Window. + * This allows device to adjust refresh rate + * as needed and can be useful for power saving. + * + * @param enabled Whether we should enable frameratepowersavingsbalance. + */ + @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public void setFrameRatePowerSavingsBalanced(boolean enabled) { + if (sToolkitSetFrameRateReadOnlyFlagValue) { + mIsFrameRatePowerSavingsBalanced = enabled; + } + } + + /** + * Get the value whether frameratepowersavingsbalance is enabled for this Window. + * This allows device to adjust refresh rate + * as needed and can be useful for power saving. + * by {@link #setFrameRatePowerSavingsBalanced(boolean)} + * + * @return Whether we should enable frameratepowersavingsbalance. + */ + @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public boolean isFrameRatePowerSavingsBalanced() { + if (sToolkitSetFrameRateReadOnlyFlagValue) { + return mIsFrameRatePowerSavingsBalanced; + } + return true; + } + + /** * <p> * Blurs the screen behind the window. The effect is similar to that of {@link #dimAmount}, * but instead of dimmed, the content behind the window will be blurred (or combined with @@ -5013,6 +5086,7 @@ public interface WindowManager extends ViewManager { out.writeFloat(mDesiredHdrHeadroom); if (sToolkitSetFrameRateReadOnlyFlagValue) { out.writeBoolean(mFrameRateBoostOnTouch); + out.writeBoolean(mIsFrameRatePowerSavingsBalanced); } } @@ -5088,6 +5162,7 @@ public interface WindowManager extends ViewManager { mDesiredHdrHeadroom = in.readFloat(); if (sToolkitSetFrameRateReadOnlyFlagValue) { mFrameRateBoostOnTouch = in.readBoolean(); + mIsFrameRatePowerSavingsBalanced = in.readBoolean(); } } @@ -5431,6 +5506,12 @@ public interface WindowManager extends ViewManager { changes |= LAYOUT_CHANGED; } + if (sToolkitSetFrameRateReadOnlyFlagValue + && mIsFrameRatePowerSavingsBalanced != o.mIsFrameRatePowerSavingsBalanced) { + mIsFrameRatePowerSavingsBalanced = o.mIsFrameRatePowerSavingsBalanced; + changes |= LAYOUT_CHANGED; + } + return changes; } @@ -5658,6 +5739,11 @@ public interface WindowManager extends ViewManager { sb.append(prefix).append(" frameRateBoostOnTouch="); sb.append(mFrameRateBoostOnTouch); } + if (sToolkitSetFrameRateReadOnlyFlagValue && mIsFrameRatePowerSavingsBalanced) { + sb.append(System.lineSeparator()); + sb.append(prefix).append(" dvrrWindowFrameRateHint="); + sb.append(mIsFrameRatePowerSavingsBalanced); + } if (paramsForRotation != null && paramsForRotation.length != 0) { sb.append(System.lineSeparator()); sb.append(prefix).append(" paramsForRotation:"); @@ -6098,7 +6184,7 @@ public interface WindowManager extends ViewManager { * receive batched input event. For those events that are batched, the invocation will happen * once per {@link Choreographer} frame, and other input events will be delivered immediately. * This is different from - * { #registerUnbatchedSurfaceControlInputReceiver(int, InputTransferToken, SurfaceControl, + * {@link #registerUnbatchedSurfaceControlInputReceiver(int, InputTransferToken, SurfaceControl, * Looper, SurfaceControlInputReceiver)} in that the input events are received batched. The * caller must invoke {@link #unregisterSurfaceControlInputReceiver(SurfaceControl)} to clean up * the resources when no longer needing to use the {@link SurfaceControlInputReceiver} @@ -6115,12 +6201,15 @@ public interface WindowManager extends ViewManager { * rendering Choreographer. * @param receiver The SurfaceControlInputReceiver that will receive the input * events + * @return Returns the {@link InputTransferToken} that can be used to transfer touch gesture + * to or from other windows. */ @FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) - default void registerBatchedSurfaceControlInputReceiver(int displayId, + @NonNull + default InputTransferToken registerBatchedSurfaceControlInputReceiver(int displayId, @NonNull InputTransferToken hostInputTransferToken, - @NonNull SurfaceControl surfaceControl, - @NonNull Choreographer choreographer, @NonNull SurfaceControlInputReceiver receiver) { + @NonNull SurfaceControl surfaceControl, @NonNull Choreographer choreographer, + @NonNull SurfaceControlInputReceiver receiver) { throw new UnsupportedOperationException( "registerBatchedSurfaceControlInputReceiver is not implemented"); } @@ -6145,9 +6234,12 @@ public interface WindowManager extends ViewManager { * @param looper The looper to use when invoking callbacks. * @param receiver The SurfaceControlInputReceiver that will receive the input * events. + * @return Returns the {@link InputTransferToken} that can be used to transfer touch gesture + * to or from other windows. */ @FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) - default void registerUnbatchedSurfaceControlInputReceiver(int displayId, + @NonNull + default InputTransferToken registerUnbatchedSurfaceControlInputReceiver(int displayId, @NonNull InputTransferToken hostInputTransferToken, @NonNull SurfaceControl surfaceControl, @NonNull Looper looper, @NonNull SurfaceControlInputReceiver receiver) { @@ -6161,10 +6253,9 @@ public interface WindowManager extends ViewManager { * <p> * Must be called on the same {@link Looper} thread to which was passed to the * {@link #registerBatchedSurfaceControlInputReceiver(int, InputTransferToken, SurfaceControl, - * Choreographer, - * SurfaceControlInputReceiver)} or - * {@link #registerUnbatchedSurfaceControlInputReceiver(int, InputTransferToken, SurfaceControl, Looper, - * SurfaceControlInputReceiver)} + * Choreographer, SurfaceControlInputReceiver)} or + * {@link #registerUnbatchedSurfaceControlInputReceiver(int, InputTransferToken, SurfaceControl, + * Looper, SurfaceControlInputReceiver)} * * @param surfaceControl The SurfaceControl to remove and unregister the input channel for. */ @@ -6175,12 +6266,12 @@ public interface WindowManager extends ViewManager { } /** - * Returns the input client token for the {@link SurfaceControl}. This will only return non null - * if the SurfaceControl was registered for input via - * { #registerBatchedSurfaceControlInputReceiver(int, IBinder, SurfaceControl, Choreographer, - * SurfaceControlInputReceiver)} or - * {@link #registerUnbatchedSurfaceControlInputReceiver(int, InputTransferToken, SurfaceControl, Looper, - * SurfaceControlInputReceiver)}. + * Returns the input client token for the {@link SurfaceControl}. This will only return non + * null if the SurfaceControl was registered for input via + * {@link #registerBatchedSurfaceControlInputReceiver(int, InputTransferToken, SurfaceControl, + * Choreographer, SurfaceControlInputReceiver)} or + * {@link #registerUnbatchedSurfaceControlInputReceiver(int, InputTransferToken, + * SurfaceControl, Looper, SurfaceControlInputReceiver)}. * <p> * This is helpful for testing to ensure the test waits for the layer to be registered with * SurfaceFlinger and Input before proceeding with the test. @@ -6196,6 +6287,70 @@ public interface WindowManager extends ViewManager { } /** + * Transfer the currently in progress touch gesture from the transferFromToken to the + * transferToToken. + * <p><br> + * This requires that the fromToken and toToken are associated with each other. The association + * can be done different ways, depending on how the embedded window is created. + * <ul> + * <li> + * Creating a {@link SurfaceControlViewHost} and passing the host's + * {@link InputTransferToken} for + * {@link SurfaceControlViewHost#SurfaceControlViewHost(Context, Display, InputTransferToken)}. + * </li> + * <li> + * Registering a SurfaceControl for input and passing the host's token to either + * {@link #registerBatchedSurfaceControlInputReceiver(int, InputTransferToken, SurfaceControl, + * Choreographer, SurfaceControlInputReceiver)} or + * {@link #registerUnbatchedSurfaceControlInputReceiver(int, InputTransferToken, + * SurfaceControl, Looper, SurfaceControlInputReceiver)}. + * </li> + * </ul> + * <p> + * The host is likely to be an {@link AttachedSurfaceControl} so the host token can be + * retrieved via {@link AttachedSurfaceControl#getInputTransferToken()}. + * <p><br> + * Only the window currently receiving touch is allowed to transfer the gesture so if the caller + * attempts to transfer touch gesture from a token that doesn't have touch, it will fail the + * transfer. + * <p><br> + * When the host wants to transfer touch gesture to the embedded, it can retrieve the embedded + * token via {@link SurfaceControlViewHost.SurfacePackage#getInputTransferToken()} or use the + * value returned from either + * {@link #registerBatchedSurfaceControlInputReceiver(int, InputTransferToken, SurfaceControl, + * Choreographer, SurfaceControlInputReceiver)} or + * {@link #registerUnbatchedSurfaceControlInputReceiver(int, InputTransferToken, SurfaceControl, + * Looper, SurfaceControlInputReceiver)} and pass its own token as the transferFromToken. + * <p> + * When the embedded wants to transfer touch gesture to the host, it can pass in its own + * token as the transferFromToken and use the associated host's {@link InputTransferToken} as + * the transferToToken + * <p><br> + * When the touch is transferred, the window currently receiving touch gets an ACTION_CANCEL + * and does not receive any further input events for this gesture. + * <p> + * The transferred-to window receives an ACTION_DOWN event and then the remainder of the input + * events for this gesture. It does not receive any of the previous events of this gesture that + * the originating window received. + * <p> + * The transferTouchGesture API only works for the current gesture. When a new gesture + * arrives, input dispatcher will do a new round of hit testing. So, if the host window is + * still the first thing that's being touched, then it will receive the new gesture again. It + * will again be up to the host to transfer this new gesture to the embedded. + * + * @param transferFromToken the InputTransferToken for the currently active gesture + * @param transferToToken the InputTransferToken to transfer the gesture to. + * @return Whether the touch stream was transferred. + * @see android.view.SurfaceControlViewHost.SurfacePackage#getInputTransferToken() + * @see AttachedSurfaceControl#getInputTransferToken() + */ + @FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) + default boolean transferTouchGesture(@NonNull InputTransferToken transferFromToken, + @NonNull InputTransferToken transferToToken) { + throw new UnsupportedOperationException("transferTouchGesture is not implemented"); + } + + /** * @hide */ default @NonNull IBinder getDefaultToken() { diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 142896346bde..c6d0454fbcfd 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -839,14 +839,15 @@ public final class WindowManagerGlobal { mTrustedPresentationListener.removeListener(listener); } - void registerBatchedSurfaceControlInputReceiver(int displayId, + InputTransferToken registerBatchedSurfaceControlInputReceiver(int displayId, @NonNull InputTransferToken hostToken, @NonNull SurfaceControl surfaceControl, @NonNull Choreographer choreographer, @NonNull SurfaceControlInputReceiver receiver) { IBinder clientToken = new Binder(); + InputTransferToken inputTransferToken = new InputTransferToken(); InputChannel inputChannel = new InputChannel(); try { WindowManagerGlobal.getWindowSession().grantInputChannel(displayId, surfaceControl, - clientToken, hostToken, 0, 0, TYPE_APPLICATION, 0, null, null, + clientToken, hostToken, 0, 0, TYPE_APPLICATION, 0, null, inputTransferToken, surfaceControl.getName(), inputChannel); } catch (RemoteException e) { Log.e(TAG, "Failed to create input channel", e); @@ -865,16 +866,18 @@ public final class WindowManagerGlobal { } })); } + return inputTransferToken; } - void registerUnbatchedSurfaceControlInputReceiver(int displayId, + InputTransferToken registerUnbatchedSurfaceControlInputReceiver(int displayId, @NonNull InputTransferToken hostToken, @NonNull SurfaceControl surfaceControl, @NonNull Looper looper, @NonNull SurfaceControlInputReceiver receiver) { IBinder clientToken = new Binder(); + InputTransferToken inputTransferToken = new InputTransferToken(); InputChannel inputChannel = new InputChannel(); try { WindowManagerGlobal.getWindowSession().grantInputChannel(displayId, surfaceControl, - clientToken, hostToken, 0, 0, TYPE_APPLICATION, 0, null, null, + clientToken, hostToken, 0, 0, TYPE_APPLICATION, 0, null, inputTransferToken, surfaceControl.getName(), inputChannel); } catch (RemoteException e) { Log.e(TAG, "Failed to create input channel", e); @@ -892,9 +895,10 @@ public final class WindowManagerGlobal { } })); } + return inputTransferToken; } - void unregisterSurfaceControlInputReceiver(SurfaceControl surfaceControl) { + void unregisterSurfaceControlInputReceiver(@NonNull SurfaceControl surfaceControl) { SurfaceControlInputReceiverInfo surfaceControlInputReceiverInfo; synchronized (mSurfaceControlInputReceivers) { surfaceControlInputReceiverInfo = mSurfaceControlInputReceivers.removeReturnOld( @@ -916,7 +920,7 @@ public final class WindowManagerGlobal { surfaceControlInputReceiverInfo.mInputEventReceiver.dispose(); } - IBinder getSurfaceControlInputClientToken(SurfaceControl surfaceControl) { + IBinder getSurfaceControlInputClientToken(@NonNull SurfaceControl surfaceControl) { SurfaceControlInputReceiverInfo surfaceControlInputReceiverInfo; synchronized (mSurfaceControlInputReceivers) { surfaceControlInputReceiverInfo = mSurfaceControlInputReceivers.get( @@ -930,6 +934,17 @@ public final class WindowManagerGlobal { return surfaceControlInputReceiverInfo.mClientToken; } + boolean transferTouchGesture(@NonNull InputTransferToken transferFromToken, + @NonNull InputTransferToken transferToToken) { + try { + return getWindowManagerService().transferTouchGesture(transferFromToken, + transferToToken); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + return false; + } + private final class TrustedPresentationListener extends ITrustedPresentationListener.Stub { private static int sId = 0; diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index 1e3d0624a95b..df4fed6a45f1 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -533,36 +533,56 @@ public final class WindowManagerImpl implements WindowManager { mGlobal.unregisterTrustedPresentationListener(listener); } + @NonNull @Override - public void registerBatchedSurfaceControlInputReceiver(int displayId, + public InputTransferToken registerBatchedSurfaceControlInputReceiver(int displayId, @NonNull InputTransferToken hostInputTransferToken, @NonNull SurfaceControl surfaceControl, @NonNull Choreographer choreographer, @NonNull SurfaceControlInputReceiver receiver) { - mGlobal.registerBatchedSurfaceControlInputReceiver(displayId, hostInputTransferToken, + Objects.requireNonNull(hostInputTransferToken); + Objects.requireNonNull(surfaceControl); + Objects.requireNonNull(choreographer); + Objects.requireNonNull(receiver); + return mGlobal.registerBatchedSurfaceControlInputReceiver(displayId, hostInputTransferToken, surfaceControl, choreographer, receiver); } + @NonNull @Override - public void registerUnbatchedSurfaceControlInputReceiver(int displayId, + public InputTransferToken registerUnbatchedSurfaceControlInputReceiver(int displayId, @NonNull InputTransferToken hostInputTransferToken, @NonNull SurfaceControl surfaceControl, @NonNull Looper looper, @NonNull SurfaceControlInputReceiver receiver) { - mGlobal.registerUnbatchedSurfaceControlInputReceiver(displayId, hostInputTransferToken, - surfaceControl, looper, receiver); + Objects.requireNonNull(hostInputTransferToken); + Objects.requireNonNull(surfaceControl); + Objects.requireNonNull(looper); + Objects.requireNonNull(receiver); + return mGlobal.registerUnbatchedSurfaceControlInputReceiver(displayId, + hostInputTransferToken, surfaceControl, looper, receiver); } @Override public void unregisterSurfaceControlInputReceiver(@NonNull SurfaceControl surfaceControl) { + Objects.requireNonNull(surfaceControl); mGlobal.unregisterSurfaceControlInputReceiver(surfaceControl); } @Override @Nullable public IBinder getSurfaceControlInputClientToken(@NonNull SurfaceControl surfaceControl) { + Objects.requireNonNull(surfaceControl); return mGlobal.getSurfaceControlInputClientToken(surfaceControl); } @Override + public boolean transferTouchGesture(@NonNull InputTransferToken transferFromToken, + @NonNull InputTransferToken transferToToken) { + Objects.requireNonNull(transferFromToken); + Objects.requireNonNull(transferToToken); + return mGlobal.transferTouchGesture(transferFromToken, transferToToken); + } + + @Override public @ScreenRecordingState int addScreenRecordingCallback( @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<@ScreenRecordingState Integer> callback) { diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 3f1ae51ef25e..2b2c50725749 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -651,21 +651,6 @@ public class WindowlessWindowManager implements IWindowSession { } @Override - public boolean transferEmbeddedTouchFocusToHost(IWindow window) { - Log.e(TAG, "Received request to transferEmbeddedTouch focus on WindowlessWindowManager" + - " we shouldn't get here!"); - return false; - } - - @Override - public boolean transferHostTouchGestureToEmbedded(IWindow hostWindow, - InputTransferToken embeddedInputToken) { - Log.e(TAG, "Received request to transferHostTouchGestureToEmbedded on" - + " WindowlessWindowManager. We shouldn't get here!"); - return false; - } - - @Override public boolean moveFocusToAdjacentWindow(IWindow fromWindow, @FocusDirection int direction) { Log.e(TAG, "Received request to moveFocusToAdjacentWindow on" + " WindowlessWindowManager. We shouldn't get here!"); diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java index 57a3b765641d..8a407c3252f0 100644 --- a/core/java/android/view/animation/AnimationUtils.java +++ b/core/java/android/view/animation/AnimationUtils.java @@ -185,7 +185,7 @@ public class AnimationUtils { @FlaggedApi(FLAG_EXPECTED_PRESENTATION_TIME_READ_ONLY) public static long getExpectedPresentationTimeNanos() { if (!sExpectedPresentationTimeFlagValue) { - return SystemClock.uptimeMillis(); + return SystemClock.uptimeMillis() * TimeUtils.NANOS_PER_MS; } AnimationState state = sAnimationState.get(); diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 5bf1b5ba6cec..13dc4efb374d 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -112,6 +112,7 @@ import android.widget.CompoundButton.OnCheckedChangeListener; import com.android.internal.R; import com.android.internal.util.Preconditions; import com.android.internal.widget.IRemoteViewsFactory; +import com.android.internal.widget.remotecompose.core.operations.Theme; import com.android.internal.widget.remotecompose.player.RemoteComposeDocument; import com.android.internal.widget.remotecompose.player.RemoteComposePlayer; @@ -3902,7 +3903,6 @@ public class RemoteViews implements Parcelable, Filter { throws ActionException { if (drawDataParcel() && mInstructions != null && root instanceof RemoteComposePlayer player) { - player.setTag(mInstructions); final List<byte[]> bytes = mInstructions.mInstructions; if (bytes.isEmpty()) { return; @@ -6082,20 +6082,24 @@ public class RemoteViews implements Parcelable, Filter { if (applyThemeResId != 0) { inflationContext = new ContextThemeWrapper(inflationContext, applyThemeResId); } + View v; // If the RemoteViews contains draw instructions, just use it instead. if (rv.hasDrawInstructions()) { - return new RemoteComposePlayer(inflationContext); - } - LayoutInflater inflater = LayoutInflater.from(context); + final RemoteComposePlayer player = new RemoteComposePlayer(inflationContext); + player.setDebug(Build.IS_USERDEBUG || Build.IS_ENG ? 1 : 0); + v = player; + } else { + LayoutInflater inflater = LayoutInflater.from(context); - // Clone inflater so we load resources from correct context and - // we don't add a filter to the static version returned by getSystemService. - inflater = inflater.cloneInContext(inflationContext); - inflater.setFilter(shouldUseStaticFilter() ? INFLATER_FILTER : this); - if (mLayoutInflaterFactory2 != null) { - inflater.setFactory2(mLayoutInflaterFactory2); + // Clone inflater so we load resources from correct context and + // we don't add a filter to the static version returned by getSystemService. + inflater = inflater.cloneInContext(inflationContext); + inflater.setFilter(shouldUseStaticFilter() ? INFLATER_FILTER : this); + if (mLayoutInflaterFactory2 != null) { + inflater.setFactory2(mLayoutInflaterFactory2); + } + v = inflater.inflate(rv.getLayoutId(), parent, false); } - View v = inflater.inflate(rv.getLayoutId(), parent, false); if (mViewId != View.NO_ID) { v.setId(mViewId); v.setTagInternal(R.id.remote_views_override_id, mViewId); @@ -6441,6 +6445,10 @@ public class RemoteViews implements Parcelable, Filter { if (params.handler == null) { params.handler = DEFAULT_INTERACTION_HANDLER; } + if (v instanceof RemoteComposePlayer player) { + player.setTheme(v.getResources().getConfiguration().isNightModeActive() + ? Theme.DARK : Theme.LIGHT); + } if (mActions != null) { final int count = mActions.size(); for (int i = 0; i < count; i++) { @@ -7565,6 +7573,8 @@ public class RemoteViews implements Parcelable, Filter { @FlaggedApi(FLAG_DRAW_DATA_PARCEL) public static final class DrawInstructions { + private static final long VERSION = 1L; + @NonNull final List<byte[]> mInstructions; @@ -7599,6 +7609,7 @@ public class RemoteViews implements Parcelable, Filter { } return new DrawInstructions(instructions); } + private static void writeToParcel(@Nullable final DrawInstructions drawInstructions, @NonNull final Parcel dest, final int flags) { if (drawInstructions == null) { @@ -7614,6 +7625,14 @@ public class RemoteViews implements Parcelable, Filter { } /** + * Version number of {@link DrawInstructions} currently supported. + */ + @FlaggedApi(FLAG_DRAW_DATA_PARCEL) + public static long getSupportedVersion() { + return VERSION; + } + + /** * Builder class for {@link DrawInstructions} objects. */ @FlaggedApi(FLAG_DRAW_DATA_PARCEL) diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 57e4e6a2fa5b..172146215257 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -181,6 +181,7 @@ import android.view.PointerIcon; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewDebug; +import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.ViewHierarchyEncoder; import android.view.ViewParent; @@ -866,6 +867,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private final boolean mUseTextPaddingForUiTranslation; private boolean mUseBoundsForWidth; + private boolean mShiftDrawingOffsetForStartOverhang; @Nullable private Paint.FontMetrics mMinimumFontMetrics; @Nullable private Paint.FontMetrics mLocalePreferredFontMetrics; private boolean mUseLocalePreferredLineHeightForMinimum; @@ -1621,6 +1623,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener hasUseBoundForWidthValue = true; break; case com.android.internal.R.styleable + .TextView_shiftDrawingOffsetForStartOverhang: + mShiftDrawingOffsetForStartOverhang = a.getBoolean(attr, false); + break; + case com.android.internal.R.styleable .TextView_useLocalePreferredLineHeightForMinimum: mUseLocalePreferredLineHeightForMinimum = a.getBoolean(attr, false); break; @@ -4922,6 +4928,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * @param useBoundsForWidth true for using bounding box for width. false for using advances for * width. * @see #getUseBoundsForWidth() + * @see #setShiftDrawingOffsetForStartOverhang(boolean) + * @see #getShiftDrawingOffsetForStartOverhang() */ @FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH) public void setUseBoundsForWidth(boolean useBoundsForWidth) { @@ -4939,6 +4947,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * Returns true if using bounding box as a width, false for using advance as a width. * * @see #setUseBoundsForWidth(boolean) + * @see #setShiftDrawingOffsetForStartOverhang(boolean) + * @see #getShiftDrawingOffsetForStartOverhang() * @return True if using bounding box for width, false if using advance for width. */ @FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH) @@ -4947,6 +4957,53 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** + * Set true for shifting the drawing x offset for showing overhang at the start position. + * + * This flag is ignored if the {@link #getUseBoundsForWidth()} is false. + * + * If this value is false, the TextView draws text from the zero even if there is a glyph stroke + * in a region where the x coordinate is negative. TextView clips the stroke in the region where + * the X coordinate is negative unless the parents has {@link ViewGroup#getClipChildren()} to + * true. This is useful for aligning multiple TextViews vertically. + * + * If this value is true, the TextView draws text with shifting the x coordinate of the drawing + * bounding box. This prevents the clipping even if the parents doesn't have + * {@link ViewGroup#getClipChildren()} to true. + * + * This value is false by default. + * + * @param shiftDrawingOffsetForStartOverhang true for shifting the drawing offset for showing + * the stroke that is in the region whre the x + * coorinate is negative. + * @see #setUseBoundsForWidth(boolean) + * @see #getUseBoundsForWidth() + */ + @FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH) + public void setShiftDrawingOffsetForStartOverhang(boolean shiftDrawingOffsetForStartOverhang) { + if (mShiftDrawingOffsetForStartOverhang != shiftDrawingOffsetForStartOverhang) { + mShiftDrawingOffsetForStartOverhang = shiftDrawingOffsetForStartOverhang; + if (mLayout != null) { + nullLayouts(); + requestLayout(); + invalidate(); + } + } + } + + /** + * Returns true if shifting the drawing x offset for start overhang. + * + * @see #setShiftDrawingOffsetForStartOverhang(boolean) + * @see #setUseBoundsForWidth(boolean) + * @see #getUseBoundsForWidth() + * @return True if shifting the drawing x offset for start overhang. + */ + @FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH) + public boolean getShiftDrawingOffsetForStartOverhang() { + return mShiftDrawingOffsetForStartOverhang; + } + + /** * Set the minimum font metrics used for line spacing. * * <p> @@ -5456,6 +5513,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_fontVariationSettings */ + @android.view.RemotableViewMethod public boolean setFontVariationSettings(@Nullable String fontVariationSettings) { final String existingSettings = mTextPaint.getFontVariationSettings(); if (fontVariationSettings == existingSettings @@ -11001,6 +11059,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener null, boring, mUseBoundsForWidth, + mShiftDrawingOffsetForStartOverhang, getResolvedMinimumFontMetrics()); } @@ -11028,6 +11087,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener effectiveEllipsize, boring, mUseBoundsForWidth, + mShiftDrawingOffsetForStartOverhang, getResolvedMinimumFontMetrics()); } } diff --git a/core/java/android/window/InputTransferToken.java b/core/java/android/window/InputTransferToken.java index bed0e0e8a225..e572853e5d5d 100644 --- a/core/java/android/window/InputTransferToken.java +++ b/core/java/android/window/InputTransferToken.java @@ -20,8 +20,12 @@ import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.os.Binder; import android.os.IBinder; +import android.os.Looper; import android.os.Parcel; import android.os.Parcelable; +import android.view.Choreographer; +import android.view.SurfaceControl; +import android.view.SurfaceControlInputReceiver; import android.view.SurfaceControlViewHost; import com.android.window.flags.Flags; @@ -31,6 +35,19 @@ import java.util.Objects; /** * A token that can be used to request focus on or to transfer touch gesture to a * {@link SurfaceControlViewHost} or {@link android.view.SurfaceControl} that has an input channel. + * <p> + * The {@link android.view.SurfaceControl} needs to have been registered for input via + * {@link android.view.WindowManager#registerUnbatchedSurfaceControlInputReceiver(int, + * InputTransferToken, SurfaceControl, Looper, SurfaceControlInputReceiver)} or + * {@link android.view.WindowManager#registerBatchedSurfaceControlInputReceiver(int, + * InputTransferToken, SurfaceControl, Choreographer, SurfaceControlInputReceiver)} and the + * returned token can be used to call + * {@link android.view.WindowManager#transferTouchGesture(InputTransferToken, InputTransferToken)} + * <p> + * For {@link SurfaceControlViewHost}, the token can be retrieved via + * {@link SurfaceControlViewHost.SurfacePackage#getInputTransferToken()} + * + * @see android.view.WindowManager#transferTouchGesture(InputTransferToken, InputTransferToken) */ @FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) public final class InputTransferToken implements Parcelable { diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig index 3ffa27451557..8b3bd974b3fa 100644 --- a/core/java/android/window/flags/window_surfaces.aconfig +++ b/core/java/android/window/flags/window_surfaces.aconfig @@ -20,13 +20,6 @@ flag { flag { namespace: "window_surfaces" - name: "transfer_gesture_to_embedded" - description: "Enable public API for Window Surfaces" - bug: "287076178" -} - -flag { - namespace: "window_surfaces" name: "delete_capture_display" description: "Delete uses of ScreenCapture#captureDisplay" is_fixed_read_only: true diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig index bc63881163f0..ce74848705e4 100644 --- a/core/java/android/window/flags/windowing_sdk.aconfig +++ b/core/java/android/window/flags/windowing_sdk.aconfig @@ -69,4 +69,12 @@ flag { name: "embedded_activity_back_nav_flag" description: "Refines embedded activity back navigation behavior" bug: "293642394" +} + +flag { + namespace: "windowing_sdk" + name: "cover_display_opt_in" + description: "Properties to allow apps and activities to opt-in to cover display rendering" + bug: "312530526" + is_fixed_read_only: true }
\ No newline at end of file diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index 3a321e5c26f7..3ec70649294b 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -162,4 +162,5 @@ interface IAppOpsService { int attributionFlags, int attributionChainId); void finishOperationForDevice(IBinder clientId, int code, int uid, String packageName, @nullable String attributionTag, int virtualDeviceId); + List<AppOpsManager.PackageOps> getPackagesForOpsForDevice(in int[] ops, String persistentDeviceId); } diff --git a/core/java/com/android/internal/app/NfcResolverActivity.java b/core/java/com/android/internal/app/NfcResolverActivity.java index 402192abaf0a..78427fe91088 100644 --- a/core/java/com/android/internal/app/NfcResolverActivity.java +++ b/core/java/com/android/internal/app/NfcResolverActivity.java @@ -16,25 +16,25 @@ package com.android.internal.app; -import static android.service.chooser.CustomChoosers.EXTRA_RESOLVE_INFOS; -import static android.service.chooser.Flags.supportNfcResolver; +import static android.nfc.Flags.enableNfcMainline; import android.content.Intent; import android.content.pm.ResolveInfo; +import android.nfc.NfcAdapter; import android.os.Bundle; import java.util.ArrayList; /** * Caller-customizable variant of {@link ResolverActivity} to support the - * {@link CustomChoosers#showNfcResolver()} API. + * NFC resolver intent. */ public class NfcResolverActivity extends ResolverActivity { @Override @SuppressWarnings("MissingSuperCall") // Called indirectly via `super_onCreate()`. protected void onCreate(Bundle savedInstanceState) { - if (!supportNfcResolver()) { + if (!enableNfcMainline()) { super_onCreate(savedInstanceState); finish(); return; @@ -43,7 +43,8 @@ public class NfcResolverActivity extends ResolverActivity { Intent intent = getIntent(); Intent target = intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent.class); ArrayList<ResolveInfo> rList = - intent.getParcelableArrayListExtra(EXTRA_RESOLVE_INFOS, ResolveInfo.class); + intent.getParcelableArrayListExtra( + NfcAdapter.EXTRA_RESOLVE_INFOS, ResolveInfo.class); CharSequence title = intent.getExtras().getCharSequence( Intent.EXTRA_TITLE, getResources().getText(com.android.internal.R.string.chooseActivity)); diff --git a/core/java/com/android/internal/content/ReferrerIntent.java b/core/java/com/android/internal/content/ReferrerIntent.java index 6af03dd29899..2c68203d9cae 100644 --- a/core/java/com/android/internal/content/ReferrerIntent.java +++ b/core/java/com/android/internal/content/ReferrerIntent.java @@ -18,6 +18,7 @@ package com.android.internal.content; import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; +import android.os.IBinder; import android.os.Parcel; import java.util.Objects; @@ -29,20 +30,29 @@ public class ReferrerIntent extends Intent { @UnsupportedAppUsage public final String mReferrer; + public final IBinder mCallerToken; + @UnsupportedAppUsage public ReferrerIntent(Intent baseIntent, String referrer) { + this(baseIntent, referrer, /* callerToken */ null); + } + + public ReferrerIntent(Intent baseIntent, String referrer, IBinder callerToken) { super(baseIntent); mReferrer = referrer; + mCallerToken = callerToken; } public void writeToParcel(Parcel dest, int parcelableFlags) { super.writeToParcel(dest, parcelableFlags); dest.writeString(mReferrer); + dest.writeStrongBinder(mCallerToken); } ReferrerIntent(Parcel in) { readFromParcel(in); mReferrer = in.readString(); + mCallerToken = in.readStrongBinder(); } public static final Creator<ReferrerIntent> CREATOR = new Creator<ReferrerIntent>() { @@ -60,7 +70,8 @@ public class ReferrerIntent extends Intent { return false; } final ReferrerIntent other = (ReferrerIntent) obj; - return filterEquals(other) && Objects.equals(mReferrer, other.mReferrer); + return filterEquals(other) && Objects.equals(mReferrer, other.mReferrer) + && Objects.equals(mCallerToken, other.mCallerToken); } @Override @@ -68,6 +79,7 @@ public class ReferrerIntent extends Intent { int result = 17; result = 31 * result + filterHashCode(); result = 31 * result + Objects.hashCode(mReferrer); + result = 31 * result + Objects.hashCode(mCallerToken); return result; } } diff --git a/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java b/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java index d433ca3246b6..73df5e8e7b1b 100644 --- a/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java +++ b/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java @@ -408,6 +408,7 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, // Derived fields private long mLongVersionCode; private int mLocaleConfigRes; + private boolean mAllowCrossUidActivitySwitchFromBelow; private List<AndroidPackageSplit> mSplits; @@ -1542,6 +1543,11 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, } @Override + public boolean isAllowCrossUidActivitySwitchFromBelow() { + return mAllowCrossUidActivitySwitchFromBelow; + } + + @Override public boolean hasPreserveLegacyExternalStorage() { return getBoolean(Booleans.PRESERVE_LEGACY_EXTERNAL_STORAGE); } @@ -2199,6 +2205,12 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, } @Override + public ParsingPackage setAllowCrossUidActivitySwitchFromBelow(boolean value) { + mAllowCrossUidActivitySwitchFromBelow = value; + return this; + } + + @Override public PackageImpl setResourceOverlay(boolean value) { return setBoolean(Booleans.OVERLAY, value); } @@ -2656,6 +2668,7 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, if (!mKnownActivityEmbeddingCerts.isEmpty()) { appInfo.setKnownActivityEmbeddingCerts(mKnownActivityEmbeddingCerts); } + appInfo.allowCrossUidActivitySwitchFromBelow = mAllowCrossUidActivitySwitchFromBelow; return appInfo; } @@ -3250,6 +3263,7 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, dest.writeInt(this.uid); dest.writeLong(this.mBooleans); dest.writeLong(this.mBooleans2); + dest.writeBoolean(this.mAllowCrossUidActivitySwitchFromBelow); } public PackageImpl(Parcel in) { @@ -3411,6 +3425,7 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, this.uid = in.readInt(); this.mBooleans = in.readLong(); this.mBooleans2 = in.readLong(); + this.mAllowCrossUidActivitySwitchFromBelow = in.readBoolean(); assignDerivedFields(); assignDerivedFields2(); diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java index ef106e0268a6..5d185af17d48 100644 --- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java +++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java @@ -374,6 +374,9 @@ public interface ParsingPackage { ParsingPackage setZygotePreloadName(String zygotePreloadName); + ParsingPackage setAllowCrossUidActivitySwitchFromBelow( + boolean allowCrossUidActivitySwitchFromBelow); + ParsingPackage sortActivities(); ParsingPackage sortReceivers(); @@ -518,6 +521,8 @@ public interface ParsingPackage { @Nullable String getZygotePreloadName(); + boolean isAllowCrossUidActivitySwitchFromBelow(); + boolean isBackupAllowed(); boolean isTaskReparentingAllowed(); diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java index e0fdbc68a41f..2e6053d3d904 100644 --- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java +++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java @@ -2374,8 +2374,10 @@ public class ParsingPackageUtils { .setRestrictedAccountType(string(R.styleable.AndroidManifestApplication_restrictedAccountType, sa)) .setZygotePreloadName(string(R.styleable.AndroidManifestApplication_zygotePreloadName, sa)) // Non-Config String - .setPermission(nonConfigString(0, R.styleable.AndroidManifestApplication_permission, sa)); - // CHECKSTYLE:on + .setPermission(nonConfigString(0, R.styleable.AndroidManifestApplication_permission, sa)) + .setAllowCrossUidActivitySwitchFromBelow(bool(true, R.styleable.AndroidManifestApplication_allowCrossUidActivitySwitchFromBelow, sa)); + + // CHECKSTYLE:on //@formatter:on } diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 523924566dd7..0dd01e48db0a 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -363,6 +363,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private boolean mUseDecorContext = false; + private boolean mIsFrameRatePowerSavingsBalanced = true; + /** @see ViewRootImpl#mActivityConfigCallback */ private ActivityConfigCallback mActivityConfigCallback; @@ -2211,6 +2213,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { void onViewRootImplSet(ViewRootImpl viewRoot) { viewRoot.setActivityConfigCallback(mActivityConfigCallback); viewRoot.getOnBackInvokedDispatcher().updateContext(getContext()); + viewRoot.setFrameRatePowerSavingsBalanced(mIsFrameRatePowerSavingsBalanced); mProxyOnBackInvokedDispatcher.setActualDispatcher(viewRoot.getOnBackInvokedDispatcher()); applyDecorFitsSystemWindows(); } @@ -2559,6 +2562,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { if (a.getBoolean(R.styleable.Window_windowActivityTransitions, false)) { requestFeature(FEATURE_ACTIVITY_TRANSITIONS); } + if (a.hasValue(R.styleable.Window_windowIsFrameRatePowerSavingsBalanced)) { + mIsFrameRatePowerSavingsBalanced = + a.getBoolean(R.styleable.Window_windowIsFrameRatePowerSavingsBalanced, true); + } mIsTranslucent = a.getBoolean(R.styleable.Window_windowIsTranslucent, false); diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index b5b3a48dacb7..e46b8d7c5fae 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -1615,7 +1615,8 @@ public class LockPatternUtils { STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN, STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT, - SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED}) + SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED, + SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST}) @Retention(RetentionPolicy.SOURCE) public @interface StrongAuthFlags {} @@ -1641,7 +1642,8 @@ public class LockPatternUtils { /** * Strong authentication is required because the user has been locked out after too many - * attempts. + * attempts using primary auth methods (i.e. PIN/pattern/password) from the lock screen, + * Android Settings, and BiometricPrompt where user authentication is required. */ public static final int STRONG_AUTH_REQUIRED_AFTER_LOCKOUT = 0x8; @@ -1674,12 +1676,23 @@ public class LockPatternUtils { public static final int SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED = 0x100; /** + * Some authentication is required because adaptive auth has requested to lock device due to + * repeated failed primary auth (i.e. PIN/pattern/password) or biometric auth attempts which + * can come from Android Settings or BiometricPrompt where user authentication is required, + * in addition to from the lock screen. When a risk is determined, adaptive auth will + * proactively prompt the lock screen and will require users to re-enter the device with + * either primary auth or biometric auth (if not prohibited by other flags). + */ + public static final int SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST = 0x200; + + /** * Strong auth flags that do not prevent biometric methods from being accepted as auth. * If any other flags are set, biometric authentication is disabled. */ private static final int ALLOWING_BIOMETRIC = STRONG_AUTH_NOT_REQUIRED | SOME_AUTH_REQUIRED_AFTER_USER_REQUEST - | SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED; + | SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED + | SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST; private final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray(); private final H mHandler; diff --git a/core/java/com/android/server/pm/pkg/AndroidPackage.java b/core/java/com/android/server/pm/pkg/AndroidPackage.java index 096f246b1bab..d430fe32a64e 100644 --- a/core/java/com/android/server/pm/pkg/AndroidPackage.java +++ b/core/java/com/android/server/pm/pkg/AndroidPackage.java @@ -1507,4 +1507,11 @@ public interface AndroidPackage { * @hide */ boolean isVisibleToInstantApps(); + + /** + * @see ApplicationInfo#allowCrossUidActivitySwitchFromBelow + * @see R.styleable#AndroidManifestApplication_allowCrossUidActivitySwitchFromBelow + * @hide + */ + boolean isAllowCrossUidActivitySwitchFromBelow(); } diff --git a/core/jni/android_hardware_OverlayProperties.cpp b/core/jni/android_hardware_OverlayProperties.cpp index f6fe3dd842da..96494b16cc21 100644 --- a/core/jni/android_hardware_OverlayProperties.cpp +++ b/core/jni/android_hardware_OverlayProperties.cpp @@ -35,7 +35,6 @@ static struct { jclass clazz; jmethodID ctor; } gOverlayPropertiesClassInfo; - // ---------------------------------------------------------------------------- // OverlayProperties lifecycle // ---------------------------------------------------------------------------- @@ -52,21 +51,21 @@ static jlong android_hardware_OverlayProperties_getDestructor(JNIEnv*, jclass) { // Accessors // ---------------------------------------------------------------------------- -static jboolean android_hardware_OverlayProperties_supportFp16ForHdr(JNIEnv* env, jobject thiz, - jlong nativeObject) { +static jboolean android_hardware_OverlayProperties_isCombinationSupported(JNIEnv* env, jobject thiz, + jlong nativeObject, + jint dataspace, + jint format) { gui::OverlayProperties* properties = reinterpret_cast<gui::OverlayProperties*>(nativeObject); if (properties != nullptr) { for (const auto& i : properties->combinations) { - if (std::find(i.pixelFormats.begin(), i.pixelFormats.end(), - static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_FP16)) != + if (std::find(i.pixelFormats.begin(), i.pixelFormats.end(), format) != i.pixelFormats.end() && std::find(i.standards.begin(), i.standards.end(), - static_cast<int32_t>(HAL_DATASPACE_STANDARD_BT709)) != - i.standards.end() && + dataspace & HAL_DATASPACE_STANDARD_MASK) != i.standards.end() && std::find(i.transfers.begin(), i.transfers.end(), - static_cast<int32_t>(HAL_DATASPACE_TRANSFER_SRGB)) != i.transfers.end() && - std::find(i.ranges.begin(), i.ranges.end(), - static_cast<int32_t>(HAL_DATASPACE_RANGE_EXTENDED)) != i.ranges.end()) { + dataspace & HAL_DATASPACE_TRANSFER_MASK) != i.transfers.end() && + std::find(i.ranges.begin(), i.ranges.end(), dataspace & HAL_DATASPACE_RANGE_MASK) != + i.ranges.end()) { return true; } } @@ -88,7 +87,7 @@ static jlong android_hardware_OverlayProperties_createDefault(JNIEnv* env, jobje gui::OverlayProperties* overlayProperties = new gui::OverlayProperties; gui::OverlayProperties::SupportedBufferCombinations combination; combination.pixelFormats = {HAL_PIXEL_FORMAT_RGBA_8888}; - combination.standards = {HAL_DATASPACE_BT709}; + combination.standards = {HAL_DATASPACE_STANDARD_BT709}; combination.transfers = {HAL_DATASPACE_TRANSFER_SRGB}; combination.ranges = {HAL_DATASPACE_RANGE_FULL}; overlayProperties->combinations.emplace_back(combination); @@ -153,8 +152,8 @@ const char* const kClassPathName = "android/hardware/OverlayProperties"; // clang-format off static const JNINativeMethod gMethods[] = { { "nGetDestructor", "()J", (void*) android_hardware_OverlayProperties_getDestructor }, - { "nSupportFp16ForHdr", "(J)Z", - (void*) android_hardware_OverlayProperties_supportFp16ForHdr }, + { "nIsCombinationSupported", "(JII)Z", + (void*) android_hardware_OverlayProperties_isCombinationSupported }, { "nSupportMixedColorSpaces", "(J)Z", (void*) android_hardware_OverlayProperties_supportMixedColorSpaces }, { "nWriteOverlayPropertiesToParcel", "(JLandroid/os/Parcel;)V", @@ -172,6 +171,5 @@ int register_android_hardware_OverlayProperties(JNIEnv* env) { gOverlayPropertiesClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); gOverlayPropertiesClassInfo.ctor = GetMethodIDOrDie(env, gOverlayPropertiesClassInfo.clazz, "<init>", "(J)V"); - return err; } diff --git a/core/proto/android/content/package_item_info.proto b/core/proto/android/content/package_item_info.proto index b9905e8cf446..b7408a4da381 100644 --- a/core/proto/android/content/package_item_info.proto +++ b/core/proto/android/content/package_item_info.proto @@ -113,6 +113,7 @@ message ApplicationInfoProto { optional int32 enable_gwp_asan = 19; optional int32 enable_memtag = 20; optional bool native_heap_zero_init = 21; + optional bool allow_cross_uid_activity_switch_from_below = 22; } optional Detail detail = 17; repeated string overlay_paths = 18; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index fb82edc9166a..33af172789a5 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -836,6 +836,7 @@ <protected-broadcast android:name="android.intent.action.PROFILE_AVAILABLE" /> <protected-broadcast android:name="android.intent.action.PROFILE_UNAVAILABLE" /> <protected-broadcast android:name="android.app.action.CONSOLIDATED_NOTIFICATION_POLICY_CHANGED" /> + <protected-broadcast android:name="android.intent.action.MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED" /> <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> @@ -3689,6 +3690,14 @@ <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SECURITY_LOGGING" android:protectionLevel="internal|role" /> + <!-- Allows an application to use audit logging API. + @hide + @SystemApi + @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") + --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING" + android:protectionLevel="internal|role" /> + <!-- Allows an application to set policy related to system updates. <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call APIs protected by this permission on users different to the calling user. @@ -3792,6 +3801,14 @@ <permission android:name="android.permission.MANAGE_DEVICE_POLICY_LOCK" android:protectionLevel="internal|role" /> + <!-- Allows an application to manage policy related to theft detection. + @FlaggedApi("android.app.admin.flags.device_theft_api_enabled") + @hide + @SystemApi + --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_THEFT_DETECTION" + android:protectionLevel="internal|role" /> + <!-- Allows an application to manage policy related to system apps. <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call APIs protected by this permission on users different to the calling user. @@ -3829,6 +3846,24 @@ <permission android:name="android.permission.MANAGE_DEVICE_POLICY_MANAGED_SUBSCRIPTIONS" android:protectionLevel="internal|role" /> + <!-- Allows an application to manage policy related to block package uninstallation. + @FlaggedApi("android.app.admin.flags.dedicated_device_control_api_enabled") + --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_BLOCK_UNINSTALL" + android:protectionLevel="internal|role" /> + + <!-- Allows an application to manage policy related to camera toggle. + @FlaggedApi("android.app.admin.flags.dedicated_device_control_api_enabled") + --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_CAMERA_TOGGLE" + android:protectionLevel="internal|role" /> + + <!-- Allows an application to manage policy related to microphone toggle. + @FlaggedApi("android.app.admin.flags.dedicated_device_control_api_enabled") + --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_MICROPHONE_TOGGLE" + android:protectionLevel="internal|role" /> + <!-- Allows an application to set device policies outside the current user that are critical for securing data within the current user. <p>Holding this permission allows the use of other held MANAGE_DEVICE_POLICY_* @@ -6883,13 +6918,10 @@ <permission android:name="android.permission.ACCESS_DRM_CERTIFICATES" android:protectionLevel="signature|privileged" /> - <!-- Allows an application to manage media projection sessions, by showing the permission dialog - to the user and creating a new token for each capture session. - @FlaggedApi("com.android.media.flags.limit_manage_media_projection") - @SystemApi Only granted to apps holding role SYSTEM_UI. + <!-- Api Allows an application to manage media projection sessions. @hide This is not a third-party API (intended for system apps). --> <permission android:name="android.permission.MANAGE_MEDIA_PROJECTION" - android:protectionLevel="internal|role" /> + android:protectionLevel="signature" /> <!-- @SystemApi Allows an application to read install sessions @hide This is not a third-party API (intended for system apps). --> @@ -7664,7 +7696,7 @@ <!-- @SystemApi Allows the holder to launch an Intent Resolver flow with custom presentation and/or targets. - @FlaggedApi("android.service.chooser.support_nfc_resolver") + @FlaggedApi("android.nfc.enable_nfc_mainline") @hide --> <permission android:name="android.permission.SHOW_CUSTOMIZED_RESOLVER" android:protectionLevel="signature|privileged" /> @@ -8164,8 +8196,8 @@ android:multiprocess="true" android:permission="android.permission.SHOW_CUSTOMIZED_RESOLVER" android:exported="true"> - <intent-filter> - <action android:name="android.service.chooser.action.SHOW_CUSTOMIZED_RESOLVER" /> + <intent-filter android:priority="100" > + <action android:name="android.nfc.action.SHOW_NFC_RESOLVER" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index eebd765705ee..da67efee4842 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Vingerafdruk is gestaaf"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Gesig is gestaaf"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gesig is gestaaf; druk asseblief bevestig"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Vingerafdrukhardeware is nie beskikbaar nie."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Kan nie vingerafdruk opstel nie"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Vingerafdrukopstelling het uitgetel. Probeer weer."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Vingerafdrukhandeling is gekanselleer."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Vingerafdrukhandeling is deur gebruiker gekanselleer."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Te veel pogings. Gebruik eerder skermslot."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Te veel pogings. Gebruik eerder skermslot."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Kan nie vingerafdruk verwerk nie. Probeer weer."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukke is geregistreer nie."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Kan nie vingerafdruksensor gebruik nie. Besoek \'n verskaffer wat herstelwerk doen"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Hierdie toetstel het nie \'n vingerafdruksensor nie"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Aan/af-skakelaar is gedruk"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gebruik vingerafdruk"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index ea6efdb1c0c3..4a7f6f3b7976 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"የጣት አሻራ ትክክለኛነት ተረጋግጧል"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ፊት ተረጋግጧል"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ፊት ተረጋግጧል፣ እባክዎ አረጋግጥን ይጫኑ"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"የጣት አሻራ ሃርድዌር አይገኝም።"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"የጣት አሻራን ማዋቀር አልተቻለም"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"የጣት አሻራ ውቅረት ጊዜው አብቅቷል። እንደገና ይሞክሩ።"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"የጣት አሻራ ስርዓተ ክወና ተትቷል።"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"የጣት አሻራ ክወና በተጠቃሚ ተሰርዟል።"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"በጣም ብዙ ሙከራዎች። በምትኩ የማያ ገፅ መቆለፊያን ይጠቀሙ።"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"በጣም ብዙ ሙከራዎች። በምትኩ የማያ ገፅ መቆለፊያን ይጠቀሙ።"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"የጣት አሻራን ማሰናዳት አልተቻለም። እንደገና ይሞክሩ።"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ምንም የጣት አሻራዎች አልተመዘገቡም።"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"የጣት አሻራ ዳሳሽን መጠቀም አይቻልም። የጥገና አገልግሎት ሰጪን ይጎብኙ"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"የኃይል አዝራር ተጭኗል"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"የጣት አሻራ ይጠቀሙ"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 88adffabe394..b767c5704cef 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -670,18 +670,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"تم مصادقة بصمة الإصبع"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"تمّت مصادقة الوجه"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"تمّت مصادقة الوجه، يُرجى الضغط على \"تأكيد\"."</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"جهاز بصمة الإصبع غير متاح."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"يتعذّر إعداد بصمة الإصبع."</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"انتهت مهلة إعداد بصمة الإصبع. يُرجى إعادة المحاولة."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"تم إلغاء تشغيل بصمة الإصبع."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"تم إلغاء تشغيل بصمة الإصبع بواسطة المستخدم."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"تم إجراء عدد كبير جدًا من المحاولات. عليك استخدام قفل الشاشة بدلاً من ذلك."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"تم إجراء عدد كبير جدًا من المحاولات. عليك استخدام قفل الشاشة بدلاً من ذلك."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"تتعذّر معالجة بصمة الإصبع. يُرجى إعادة المحاولة."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ليست هناك بصمات إصبع مسجَّلة."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"لا يمكن استخدام أداة استشعار بصمة الإصبع. يُرجى التواصل مع مقدِّم خدمات إصلاح."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"لا يحتوي هذا الجهاز على جهاز استشعار بصمات الأصابع."</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"تم الضغط على زر التشغيل"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استخدام بصمة الإصبع"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 0be253222232..19d8357644d8 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"ফিংগাৰপ্ৰিণ্টৰ সত্যাপন কৰা হ’ল"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল, অনুগ্ৰহ কৰি ‘নিশ্চিত কৰক’ বুটামটো টিপক"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ নাই।"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ফিংগাৰপ্ৰিণ্ট ছেট আপ কৰিব নোৱাৰি"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ফিংগাৰপ্ৰিণ্ট ছেটআপ কৰাৰ সময় উকলি গৈছে। পুনৰ চেষ্টা কৰক।"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"ফিংগাৰপ্ৰিণ্ট কাৰ্য বাতিল কৰা হ’ল।"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ব্যৱহাৰকাৰীয়ে ফিংগাৰপ্ৰিণ্ট ক্ৰিয়া বাতিল কৰিছে।"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"অতি বেছিসংখ্যক প্ৰয়াস। ইয়াৰ সলনি স্ক্ৰীন লক ব্যৱহাৰ কৰক।"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"অতি বেছিসংখ্যক প্ৰয়াস। ইয়াৰ সলনি স্ক্ৰীন লক ব্যৱহাৰ কৰক।"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ফিংগাৰপ্ৰিণ্ট চিনাক্তকৰণ প্ৰক্ৰিয়া কৰিব পৰা নাই। পুনৰ চেষ্টা কৰক।"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনো ফিংগাৰপ্ৰিণ্ট যোগ কৰা নহ\'ল।"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰ ব্যৱহাৰ কৰিব নোৱাৰি। মেৰামতি সেৱা প্ৰদানকাৰী কোনো প্ৰতিষ্ঠানলৈ যাওক"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"পাৱাৰ বুটাম টিপা হৈছে"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 63efc6655555..b82ffdced01a 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Barmaq izi doğrulandı"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Üz doğrulandı"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Üz təsdiq edildi, təsdiq düyməsinə basın"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Barmaq izi üçün avadanlıq yoxdur."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Barmaq izini ayarlamaq mümkün deyil"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Barmaq izi ayarlama vaxtı bitib. Yenidən cəhd edin."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Barmaq izi əməliyyatı ləğv edildi."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Barmaq izi əməliyyatı istifadəçi tərəfindən ləğv edildi."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Həddindən çox cəhd edilib. Əvəzində ekran kilidindən istifadə edin."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Həddindən çox cəhd edilib. Əvəzində ekran kilidindən istifadə edin."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Barmaq izini emal etmək mümkün deyil. Yenidən cəhd edin."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Barmaq izi qeydə alınmayıb."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Barmaq izi sensorundan istifadə etmək mümkün deyil. Təmir provayderini ziyarət edin"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Bu cihazda barmaq izi sensoru yoxdur"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Qidalanma düyməsi basılıb"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmaq izini istifadə edin"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 2cb924efe50c..655d1d81efe3 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisak prsta je potvrđen"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Lice je potvrđeno"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je potvrđeno. Pritisnite Potvrdi"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardver za otiske prstiju nije dostupan."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Podešavanje otiska prsta nije uspelo"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Vreme za podešavanje otiska prsta je isteklo. Probajte ponovo."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Radnja sa otiskom prsta je otkazana."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Korisnik je otkazao radnju sa otiskom prsta."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Previše pokušaja. Koristite zaključavanje ekrana umesto toga."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Previše pokušaja. Koristite zaključavanje ekrana umesto toga."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Obrađivanje otiska prsta nije uspelo. Probajte ponovo."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registrovan nijedan otisak prsta."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Ne možete da koristite senzor za otisak prsta. Posetite dobavljača za popravke"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Ovaj uređaj nema senzor za otisak prsta"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Pritisnuto je dugme za uključivanje"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristite otisak prsta"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 8815ae2f5092..d36c7d1b8b66 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -668,18 +668,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Адбітак пальца распазнаны"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Твар распазнаны"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Твар распазнаны. Націсніце, каб пацвердзіць"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Апаратныя сродкі адбіткаў пальцаў недаступныя."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Не ўдалося захаваць адбітак пальца"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Наладжванне адбітка пальца не завершана. Паўтарыце спробу."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Аперацыя з адбіткамі пальцаў скасавана."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Аўтэнтыфікацыя па адбітках пальцаў скасавана карыстальнікам."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Занадта шмат спроб. Скарыстайце блакіроўку экрана."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Занадта шмат спроб. Скарыстайце блакіроўку экрана."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Не ўдалося апрацаваць адбітак пальца. Паўтарыце спробу."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Адбіткі пальцаў не зарэгістраваны."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не ўдалося скарыстаць сканер адбіткаў пальцаў. Звярніцеся ў сэрвісны цэнтр."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"На гэтай прыладзе няма сканера адбіткаў пальцаў"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Націснута кнопка сілкавання"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Выкарыстоўваць адбітак пальца"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index b427349c51f5..24d5d293d6f3 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечатъкът е удостоверен"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лицето е удостоверено"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицето е удостоверено. Моля, натиснете „Потвърждаване“"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Хардуерът за отпечатъци не е налице."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Не може да се настрои отпечатък"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Настройването на отпечатък не завърши навреме. Опитайте отново."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Операцията за отпечатък е анулирана."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Операцията за удостоверяване чрез отпечатък бе анулирана от потребителя."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Твърде много опити. Вместо това използвайте опция за заключване на екрана."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Твърде много опити. Вместо това използвайте опция за заключване на екрана."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Отпечатъкът не може да бъде обработен. Опитайте отново."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Няма регистрирани отпечатъци."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорът е временно деактивиран."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Сензорът за отпечатъци не може да се използва. Посетете оторизиран сервиз."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Това устройство няма сензор за отпечатъци"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Бутонът за захранване е натиснат"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Използване на отпечатък"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 8da77ae1f370..f7f63cc4cc6c 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"আঙ্গুলের ছাপ যাচাই করা হয়েছে"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ফেস যাচাই করা হয়েছে"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ফেস যাচাই করা হয়েছে, \'কনফার্ম করুন\' বোতাম প্রেস করুন"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"আঙ্গুলের ছাপ নেওয়ার হার্ডওয়্যার অনুপলব্ধ৷"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"আঙ্গুলের ছাপ সেট-আপ করতে পারছি না"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ফিঙ্গারপ্রিন্ট সেট-আপ করার সময় সীমা পেরিয়ে গেছে। আবার চেষ্টা করুন।"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"আঙ্গুলের ছাপ অপারেশন বাতিল করা হয়েছে৷"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ব্যবহারকারী আঙ্গুলের ছাপের অপারেশনটি বাতিল করেছেন।"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"অনেকবার চেষ্টা করেছেন। পরিবর্তে স্ক্রিন লক ব্যবহার করুন।"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"অনেকবার চেষ্টা করেছেন। পরিবর্তে স্ক্রিন লক ব্যবহার করুন।"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ফিঙ্গারপ্রিন্ট প্রসেস করা যায়নি। আবার চেষ্টা করুন।"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনও আঙ্গুলের ছাপ নথিভুক্ত করা হয়নি।"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইসে আঙ্গুলের ছাপ নেওয়ার সেন্সর নেই।"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"আঙ্গুলের ছাপের সেন্সর ব্যবহার করা যাচ্ছে না। একজন মেরামতি মিস্ত্রির কাছে যান"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"এই ডিভাইসে আঙ্গুলের ছাপের সেন্সর নেই"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"পাওয়ার বোতাম প্রেস করা হয়েছে"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"আঙ্গুলের ছাপ ব্যবহার করুন"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 819695f91e02..b433f7762dd1 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisak prsta je potvrđen"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Lice je provjereno"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je provjereno, pritisnite dugme za potvrdu"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardver za otisak prsta nije dostupan."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nije moguće postaviti otisak prsta"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Postavljanje otiska prsta je isteklo. Pokušajte ponovo."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Radnja s otiskom prsta je otkazana."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Korisnik je otkazao radnju s otiskom prsta."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Previše pokušaja. Umjesto toga koristite zaključavanje ekrana."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Previše pokušaja. Umjesto toga koristite zaključavanje ekrana."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nije moguće obraditi otisak prsta. Pokušajte ponovo."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije prijavljen nijedan otisak prsta."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Nije moguće koristiti senzor za otisak prsta. Posjetite pružaoca usluga za popravke"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Ovaj uređaj nema senzor za otisak prsta"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Dugme za uključivanje je pritisnuto"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristi otisak prsta"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 785fd27b0d19..f93d6bb9562f 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -667,18 +667,24 @@ <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 d\'empremtes digitals no està disponible."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"No es pot configurar l\'empremta digital"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Temps d\'espera esgotat per configurar 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> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"L\'usuari ha cancel·lat l\'operació d\'empremta digital."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Massa intents. Utilitza el bloqueig de pantalla."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Massa intents. Utilitza el bloqueig de pantalla."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"No es pot processar l\'empremta digital. Torna-ho a provar."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No s\'ha registrat cap empremta digital."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes digitals."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor està desactivat temporalment."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"No es pot utilitzar el sensor d\'empremtes digitals. Visita un proveïdor de reparacions."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Aquest dispositiu no té sensor d\'empremtes digitals"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"S\'ha premut el botó d\'engegada"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilitza l\'empremta digital"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index d95536280176..7edc6b46c623 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -668,18 +668,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisk byl ověřen"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Obličej byl ověřen"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Obličej byl ověřen, stiskněte tlačítko pro potvrzení"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Není k dispozici hardware ke snímání otisků prstů."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Otisk prstu se nepodařilo nastavit"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Časový limit nastavení otisku prstu vypršel. Zkuste to znovu."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operace otisku prstu byla zrušena."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Uživatel operaci s otiskem prstu zrušil."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Příliš mnoho pokusů. Použijte zámek obrazovky."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Příliš mnoho pokusů. Použijte zámek obrazovky."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Otisk prstu nelze zpracovat. Zkuste to znovu."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nejsou zaregistrovány žádné otisky prstů."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Snímač otisků prstů nelze použít. Navštivte servis"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Toto zařízení nemá snímač otisků prstů"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Bylo stisknut vypínač"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použít otisk prstu"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 65f4c6d9ad58..b5938fd09d96 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeraftrykket blev godkendt"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ansigtet er godkendt"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansigtet er godkendt. Tryk på Bekræft."</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardwaren til fingeraftryk er ikke tilgængelig."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Fingeraftrykket kan ikke gemmes"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Konfigurationen af fingeraftryk fik timeout. Prøv igen."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingeraftrykshandlingen blev annulleret."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingeraftrykshandlingen blev annulleret af brugeren."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Du har brugt for mange forsøg. Brug skærmlåsen i stedet."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Du har brugt for mange forsøg. Brug skærmlåsen i stedet."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Fingeraftrykket kan ikke behandles. Prøv igen."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Der er ikke registreret nogen fingeraftryk."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enhed har ingen fingeraftrykssensor."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidigt deaktiveret."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Fingeraftrykssensoren kan ikke bruges. Få den repareret"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Denne enhed har ingen fingeraftrykslæser"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Der blev trykket på afbryderknappen"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Brug fingeraftryk"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 286c1d6be80b..59c7d4a0d389 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerabdruck wurde authentifiziert"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Gesicht authentifiziert"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gesicht authentifiziert, bitte bestätigen"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerabdruckhardware nicht verfügbar"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Fingerabdruck konnte nicht eingerichtet werden"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Zeitüberschreitung bei Fingerabdruckeinrichtung. Versuch es noch einmal."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerabdruckvorgang abgebrochen"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Vorgang der Fingerabdruckauthentifizierung vom Nutzer abgebrochen."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Zu viele Versuche. Verwende stattdessen die Displaysperre."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Zu viele Versuche. Verwende stattdessen die Displaysperre."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Fingerabdruck kann nicht verarbeitet werden. Versuch es noch einmal."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Keine Fingerabdrücke erfasst."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Der Fingerabdrucksensor kann nicht verwendet werden. Suche einen Reparaturdienstleister auf."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Dieses Gerät hat keinen Fingerabdrucksensor"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Ein-/Aus-Taste wurde gedrückt"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Fingerabdruck verwenden"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 1de2bc6b9b39..762bd52bed0c 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Η ταυτότητα του δακτυλικού αποτυπώματος ελέγχθηκε"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Έγινε έλεγχος ταυτότητας προσώπου"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Έγινε έλεγχος ταυτότητας προσώπου, πατήστε \"Επιβεβαίωση\""</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Ο εξοπλισμός δακτυλικού αποτυπώματος δεν είναι διαθέσιμος."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Δεν είναι δυνατή η ρύθμιση του δακτυλικού αποτυπώματος"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Λήξη χρονικού ορίου ρύθμισης δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Η λειτουργία δακτυλικού αποτυπώματος ακυρώθηκε."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Η λειτουργία δακτυλικού αποτυπώματος ακυρώθηκε από τον χρήστη."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Υπερβολικά πολλές προσπάθειες. Χρησιμοποιήστε εναλλακτικά το κλείδωμα οθόνης."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Υπερβολικά πολλές προσπάθειες. Χρησιμοποιήστε εναλλακτικά το κλείδωμα οθόνης."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Δεν είναι δυνατή η επεξεργασία του δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Δεν έχουν καταχωριστεί δακτυλικά αποτυπώματα."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Δεν είναι δυνατή η χρήση του αισθητήρα δακτυλικών αποτυπωμάτων. Επισκεφτείτε έναν πάροχο υπηρεσιών επισκευής."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Το κουμπί λειτουργίας πατήθηκε"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Χρήση δακτυλικού αποτυπώματος"</string> @@ -1756,7 +1762,7 @@ <string name="user_switched" msgid="7249833311585228097">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Εναλλαγή σε <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Αποσύνδεση <xliff:g id="NAME">%1$s</xliff:g>…"</string> - <string name="owner_name" msgid="8713560351570795743">"Κάτοχος"</string> + <string name="owner_name" msgid="8713560351570795743">"Κάτοχο"</string> <string name="guest_name" msgid="8502103277839834324">"Επισκέπτης"</string> <string name="error_message_title" msgid="4082495589294631966">"Σφάλμα"</string> <string name="error_message_change_not_allowed" msgid="843159705042381454">"Αυτή η αλλαγή δεν επιτρέπεται από το διαχειριστή σας"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 0b752f69b619..719c4232a52d 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingerprint setup timed out. Try again."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation cancelled."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation cancelled by user."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Too many attempts. Use screen lock instead."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Too many attempts. Use screen lock instead."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Can’t process fingerprint. Try again."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"This device does not have a fingerprint sensor"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Power button pressed"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 0dbb2ef21795..e317067c53f9 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated, please press confirm"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingerprint setup timed out. Try again."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation canceled."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation canceled by user."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Too many attempts. Use screen lock instead."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Too many attempts. Use screen lock instead."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Can’t process fingerprint. Try again."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"This device does not have a fingerprint sensor"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Power button pressed"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 4a7ba92244f2..0e58b1d17615 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingerprint setup timed out. Try again."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation cancelled."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation cancelled by user."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Too many attempts. Use screen lock instead."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Too many attempts. Use screen lock instead."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Can’t process fingerprint. Try again."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"This device does not have a fingerprint sensor"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Power button pressed"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index a7332c66878d..3c6b6712b84b 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingerprint setup timed out. Try again."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation cancelled."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation cancelled by user."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Too many attempts. Use screen lock instead."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Too many attempts. Use screen lock instead."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Can’t process fingerprint. Try again."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"This device does not have a fingerprint sensor"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Power button pressed"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 8f709048d25a..34a020f4395a 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated, please press confirm"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingerprint setup timed out. Try again."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation canceled."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation canceled by user."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Too many attempts. Use screen lock instead."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Too many attempts. Use screen lock instead."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Can’t process fingerprint. Try again."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"This device does not have a fingerprint sensor"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Power button pressed"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index b6edfd7e852d..7fb0d1f446d1 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Se autenticó la huella dactilar"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Se autenticó el rostro"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Se autenticó el rostro; presiona Confirmar"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"El hardware para detectar huellas dactilares no está disponible."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"No se puede configurar la huella dactilar"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Se agotó el tiempo de espera para configurar la huella dactilar. Vuelve a intentarlo."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Se canceló la operación de huella dactilar."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"El usuario canceló la operación de huella dactilar."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Demasiados intentos. Utiliza el bloqueo de pantalla en su lugar."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Demasiados intentos. Utiliza el bloqueo de pantalla en su lugar."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"No se puede procesar la huella dactilar. Vuelve a intentarlo."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se registraron huellas digitales."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas dactilares."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Se inhabilitó temporalmente el sensor."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"No se puede usar el sensor de huellas dactilares. Consulta a un proveedor de reparaciones."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Este dispositivo no tiene sensor de huellas dactilares"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Se presionó el botón de encendido"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella dactilar"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index baa445e1eec3..7d0c4e0318f4 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Se ha autenticado la huella digital"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Cara autenticada"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Se ha autenticado la cara, pulsa para confirmar"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"El hardware de huella digital no está disponible."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"No se puede configurar la huella digital"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Tiempo de espera para configurar la huella digital agotado. Inténtalo de nuevo."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Se ha cancelado la operación de huella digital."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"El usuario ha cancelado la operación de huella digital."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Demasiados intentos. Usa el bloqueo de pantalla."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Demasiados intentos. Usa el bloqueo de pantalla."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"No se puede procesar la huella digital. Inténtalo de nuevo."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se ha registrado ninguna huella digital."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"No se puede usar el sensor de huellas digitales. Visita un proveedor de reparaciones."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"El dispositivo no tiene ningún sensor de huellas digitales"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Se ha pulsado el botón de encendido"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 3cb3605403c8..250341f07a82 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sõrmejälg autenditi"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Nägu on autenditud"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Nägu on autenditud, vajutage käsku Kinnita"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Sõrmejälje riistvara pole saadaval."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Sõrmejälge ei saa seadistada"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Sõrmejälje seadistamine aegus. Proovige uuesti."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Sõrmejälje toiming tühistati."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Kasutaja tühistas sõrmejälje kasutamise."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Liiga palju katseid. Kasutage selle asemel ekraanilukku."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Liiga palju katseid. Kasutage selle asemel ekraanilukku."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Sõrmejälge ei õnnestu töödelda. Proovige uuesti."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ühtegi sõrmejälge pole registreeritud."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Sõrmejäljeandurit ei saa kasutada. Külastage remonditeenuse pakkujat"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Selles seadmes pole sõrmejäljeandurit"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Vajutati toitenuppu"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Sõrmejälg <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sõrmejälje kasutamine"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 8e1e1864bc6f..3c5377989497 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autentifikatu da hatz-marka"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Autentifikatu da aurpegia"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Autentifikatu da aurpegia; sakatu Berretsi"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hatz-marken hardwarea ez dago erabilgarri."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Ezin da konfiguratu hatz-marka"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Hatz-marka konfiguratzeko denbora-muga gainditu da. Saiatu berriro."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Hatz-markaren eragiketa bertan behera utzi da."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Erabiltzaileak bertan behera utzi du hatz-marka bidezko eragiketa."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Saiakera gehiegi egin dira. Erabili pantailaren blokeoa."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Saiakera gehiegi egin dira. Erabili pantailaren blokeoa."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Ezin da prozesatu hatz-marka. Saiatu berriro."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ez da erregistratu hatz-markarik."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Ezin da erabili hatz-marken sentsorea. Jarri harremanetan konponketak egiten dituen hornitzaile batekin."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Gailu honek ez du hatz-marken sentsorerik"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Etengailua sakatu da"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. hatza"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Erabili hatz-marka"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index bba6a1b86db5..640f93f73563 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"اثر انگشت اصالتسنجی شد"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"چهره اصالتسنجی شد"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"چهره اصالتسنجی شد، لطفاً تأیید را فشار دهید"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"سختافزار اثرانگشت در دسترس نیست."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"اثر انگشت راهاندازی نشد"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"مهلت تنظیم اثر انگشت بهپایان رسید. دوباره امتحان کنید."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"عملکرد اثر انگشت لغو شد."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"کاربر عملیات اثر انگشت را لغو کرد"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"تلاشها از حد مجاز بیشتر شده است. بهجای آن از قفل صفحه استفاده کنید."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"تلاشهای بیشازحد. حالا از قفل صفحه استفاده کنید."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"اثر انگشت پردازش نشد. دوباره امتحان کنید."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"اثر انگشتی ثبت نشده است."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"حسگر بهطور موقت غیرفعال است."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"امکان استفاده از حسگر اثر انگشت وجود ندارد. به ارائهدهنده خدمات تعمیر مراجعه کنید"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"این دستگاه حسگر اثر انگشت ندارد"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"دکمه روشن/خاموش فشار داده شد"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استفاده از اثر انگشت"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 6650570af968..18b9ee2a5a64 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sormenjälki tunnistettu"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Kasvot tunnistettu"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Kasvot tunnistettu, valitse Vahvista"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Sormenjälkilaitteisto ei ole käytettävissä."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Sormenjälkeä ei voi ottaa käyttöön"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Sormenjäljen käyttöönotto aikakatkaistu. Yritä uudelleen."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Sormenjälkitoiminto peruutettiin."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Käyttäjä peruutti sormenjälkitoiminnon."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Liian monta yritystä. Käytä näytön lukituksen avaustapaa."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Liian monta yritystä. Käytä näytön lukituksen avaustapaa."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Sormenjälkeä ei voida käsitellä. Yritä uudelleen."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Sormenjälkiä ei ole otettu käyttöön."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Sormenjälkitunnistinta ei voi käyttää. Ota yhteys korjauspalveluun"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Laitteessa ei ole sormenjälkitunnistinta."</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Virtapainiketta on painettu"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Käytä sormenjälkeä"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index c6cda6598ee3..1eb9eb21c842 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Empreinte digitale authentifiée"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Visage authentifié"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Visage authentifié, veuillez appuyer sur le bouton Confirmer"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Lecteur d\'empreintes digitales indisponible."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Impossible de configurer l\'empreinte digitale"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Délai dépassé pour configurer l\'empreinte digitale. Réessayez."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Opération d\'empreinte digitale numérique annulée."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"L\'opération d\'empreinte digitale a été annulée par l\'utilisateur."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Trop de tentatives. Utilisez plutôt le verrouillage de l\'écran."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Trop de tentatives. Utilisez plutôt le verrouillage de l\'écran."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Empreinte digitale non traitable. Réessayez."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Impossible d\'utiliser le capteur d\'empreintes digitales. Consultez un fournisseur de services de réparation"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Cet appareil ne possède pas de capteur d\'empreintes digitales"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Vous avez appuyé sur l\'interrupteur"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index b15ca166b1b2..c349b1cf1774 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Empreinte digitale authentifiée"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Visage authentifié"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Visage authentifié, veuillez appuyer sur \"Confirmer\""</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Matériel d\'empreinte digitale indisponible."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Impossible de configurer l\'empreinte"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Délai de configuration de l\'empreinte dépassé. Réessayez."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Opération d\'empreinte digitale annulée."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Opération d\'authentification par empreinte digitale annulée par l\'utilisateur."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Trop de tentatives. Utilisez plutôt le verrouillage de l\'écran."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Trop de tentatives. Utilisez plutôt le verrouillage de l\'écran."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Impossible de reconnaître l\'empreinte digitale. Réessayez."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Impossible d\'utiliser le lecteur d\'empreinte digitale. Contactez un réparateur"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Bouton Marche/Arrêt appuyé"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index ec2833dec526..2cc80d5cf9a7 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autenticouse a impresión dixital"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Autenticouse a cara"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Autenticouse a cara, preme Confirmar"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impresión dixital non dispoñible."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Non se puido configurar a impresión dixital"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Esgotouse o tempo para configurar a impresión dixital. Téntao de novo."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Cancelouse a operación da impresión dixital."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"O usuario cancelou a operación da impresión dixital."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Houbo demasiados intentos. Mellor usa o bloqueo de pantalla."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Demasiados intentos. Mellor usa o bloqueo de pantalla."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Non se pode procesar a impresión dixital Téntao de novo."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Non se rexistraron impresións dixitais."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Non se puido usar o sensor de impresión dixital. Visita un provedor de reparacións"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Este dispositivo non ten sensor de impresión dixital"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Premeuse o botón de acendido"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar impresión dixital"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 5cb77d8fdfed..1ef8c4703205 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"ફિંગરપ્રિન્ટ પ્રમાણિત કરી"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ચહેરા પ્રમાણિત"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ચહેરા પ્રમાણિત, કૃપા કરીને કન્ફર્મ કરો"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ફિંગરપ્રિન્ટ હાર્ડવેર ઉપલબ્ધ નથી."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ફિંગરપ્રિન્ટનું સેટઅપ કરી શકતા નથી"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ફિંગરપ્રિન્ટનું સેટઅપ કરવાનો સમય સમાપ્ત થઈ ગયો. ફરી પ્રયાસ કરો."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"ફિંગરપ્રિન્ટ ઓપરેશન રદ કર્યું."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ફિંગરપ્રિન્ટ ચકાસવાની પ્રક્રિયા વપરાશકર્તાએ રદ કરી."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ઘણા બધા પ્રયાસો. તેને બદલે સ્ક્રીન લૉકનો ઉપયોગ કરો."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ઘણા બધા પ્રયાસો. વિકલ્પ તરીકે સ્ક્રીન લૉકનો ઉપયોગ કરો."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ફિંગરપ્રિન્ટની પ્રક્રિયા કરી શકતા નથી. ફરી પ્રયાસ કરો."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"કોઈ ફિંગરપ્રિન્ટની નોંધણી કરવામાં આવી નથી."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ફિંગરપ્રિન્ટ સેન્સરનો ઉપયોગ કરી શકાતો નથી. રિપેર કરવાની સેવા આપતા પ્રદાતાની મુલાકાત લો"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"પાવર બટન દબાવવામાં આવ્યું"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index d51146933785..bd49843657a7 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"फ़िंगरप्रिंट की पुष्टि हो गई"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"चेहरे की पहचान की गई"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"चेहरे की पहचान की गई, कृपया पुष्टि बटन दबाएं"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"फ़िंगरप्रिंट हार्डवेयर उपलब्ध नहीं है."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"फ़िंगरप्रिंट सेट अप नहीं किया जा सका"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"फ़िंगरप्रिंट सेटअप करने का समय खत्म हो गया. फिर से कोशिश करें."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"फ़िंगरप्रिंट ऑपरेशन रोक दिया गया."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"उपयोगकर्ता ने फिंगरप्रिंट की पुष्टि की कार्रवाई रद्द कर दी है."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"कई बार कोशिश की जा चुकी है. इसके बजाय, स्क्रीन लॉक का इस्तेमाल करें."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"इससे ज़्यादा बार कोशिश नहीं की जा सकती. इसके बजाय, स्क्रीन लॉक का इस्तेमाल करें."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"फ़िंगरप्रिंट की पहचान नहीं की जा सकी. फिर से कोशिश करें."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोई फ़िंगरप्रिंट रजिस्टर नहीं किया गया है."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फ़िंगरप्रिंट सेंसर इस्तेमाल नहीं किया जा सकता. रिपेयर की सेवा देने वाली कंपनी से संपर्क करें"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"पावर बटन दबाने की वजह से गड़बड़ी हुई"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फ़िंगरप्रिंट इस्तेमाल करें"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 636baa0be42b..f1e9bd6d0636 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autentificirano otiskom prsta"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Lice je autentificirano"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je autentificirano, pritisnite Potvrdi"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardver za otisak prsta nije dostupan."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Postavljanje otiska prsta nije uspjelo"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Vrijeme za postavljanje otiska prsta je isteklo. Pokušajte ponovo."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Radnja otiska prsta otkazana je."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Radnju s otiskom prsta otkazao je korisnik."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Previše pokušaja. Umjesto toga upotrijebite zaključavanje zaslona."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Previše pokušaja. Umjesto toga upotrijebite zaključavanje zaslona."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Obrada otiska prsta nije uspjela. Pokušajte ponovo."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registriran nijedan otisak prsta."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Senzor otiska prsta ne može se koristiti. Posjetite davatelja usluga popravaka"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Ovaj uređaj nema senzor otiska prsta"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Pritisnuta je tipka za uključivanje/isključivanje"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Upotreba otiska prsta"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 2c9f7cce21c6..26c607788ac1 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Ujjlenyomat hitelesítve"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Arc hitelesítve"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Arc hitelesítve; nyomja meg a Megerősítés lehetőséget"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Az ujjlenyomathoz szükséges hardver nem érhető el."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nem sikerült beállítani az ujjlenyomatot"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Lejárt az ujjlenyomat-beállítás időkorlátja. Próbálkozzon újra."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Ujjlenyomattal kapcsolatos művelet megszakítva"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Az ujjlenyomattal kapcsolatos műveletet a felhasználó megszakította."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Túl sokszor próbálkozott. Használja inkább a képernyőzárat."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Túl sok próbálkozás. Használja inkább a képernyőzárat."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nem sikerült feldolgozni az ujjlenyomatot. Próbálkozzon újra."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nincsenek regisztrált ujjlenyomatok."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Nem lehet használni az ujjlenyomat-érzékelőt. Keresse fel a szervizt."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Ez az eszköz nem rendelkezik ujjlenyomat-érzékelővel"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Bekapcsológomb megnyomva"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Ujjlenyomat használata"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 904f47c0246d..e82dc708de73 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Մատնահետքը նույնականացվեց"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Դեմքը ճանաչվեց"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Դեմքը ճանաչվեց: Սեղմեք «Հաստատել»:"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Մատնահետքի սարքն անհասանելի է:"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Հնարավոր չէ կարգավորել մատնահետքը"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Մատնահետքի կարգավորման ժամանակը սպառվել է։ Նորից փորձեք։"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Իսկորոշումը մատնահետքի միջոցով չեղարկվեց:"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Մատնահետքով նույնականացման գործողությունը չեղարկվել է օգտատիրոջ կողմից:"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Չափազանց շատ փորձեր են արվել։ Օգտագործեք էկրանի կողպումը։"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Չափազանց շատ փորձեր են արվել։ Օգտագործեք էկրանի կողպումը։"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Չի հաջողվում մշակել մատնահետքը։ Նորից փորձեք։"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Գրանցված մատնահետք չկա:"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Տվիչը ժամանակավորապես անջատված է:"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Մատնահետքերի սկաները հնարավոր չէ օգտագործել։ Այցելեք սպասարկման կենտրոն։"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Սարքը չունի մատնահետքի սկաներ"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Սեղմվել է սնուցման կոճակը"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Օգտագործել մատնահետք"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 9df1d3aaa9ec..52d1463c7e24 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sidik jari diautentikasi"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Wajah diautentikasi"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Wajah diautentikasi, silakan tekan konfirmasi"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware sidik jari tidak tersedia."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Tidak dapat menyiapkan sidik jari"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Waktu penyiapan sidik jari habis. Coba lagi."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operasi sidik jari dibatalkan."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operasi sidik jari dibatalkan oleh pengguna."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Terlalu banyak upaya gagal. Gunakan kunci layar."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Terlalu banyak upaya gagal. Gunakan kunci layar."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Tidak dapat memproses sidik jari. Coba lagi."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tidak ada sidik jari yang terdaftar."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Tidak dapat menggunakan sensor sidik jari. Kunjungi penyedia reparasi"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Perangkat ini tidak memiliki sensor sidik jari"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Tombol daya ditekan"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan sidik jari"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 5f0e0ed43c82..81e5a62d5c38 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingrafar staðfest"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Andlit staðfest"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Andlit staðfest, ýttu til að staðfesta"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingrafarsvélbúnaður ekki til staðar."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Ekki er hægt að setja upp fingrafar"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingrafarsuppsetning rann út á tíma. Reyndu aftur."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Hætt við fingrafarsaðgerð."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Notandi hætti við að nota fingrafar."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Of margar tilraunir. Notaðu skjálás í staðinn."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Of margar tilraunir. Notaðu skjálás í staðinn."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Ekki tekst að vinna úr fingrafari. Reyndu aftur."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Engin fingraför hafa verið skráð."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Ekki er hægt að nota fingrafaralesara. Þú verður að fara með hann á verkstæði"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Þetta tæki er ekki með fingrafaralesara"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Ýtt á aflrofa"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Nota fingrafar"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 014ac499a9d5..e5a8b2506366 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impronta autenticata"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Volto autenticato"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Volto autenticato, premi Conferma"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware per l\'impronta non disponibile."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Impossibile configurare l\'impronta"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Timeout configurazione impronta. Riprova."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operazione associata all\'impronta annullata."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operazione di autenticazione dell\'impronta annullata dall\'utente."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Troppi tentativi. Usa il blocco schermo."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Troppi tentativi. Usa il blocco schermo."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Impossibile elaborare l\'impronta. Riprova."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nessuna impronta digitale registrata."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Impossibile usare il sensore di impronte digitali. Contatta un fornitore di servizi di riparazione"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Questo dispositivo non è dotato di sensore di impronte"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Tasto di accensione premuto"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usa l\'impronta"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index daac1ca5f0bc..1e040c19bd89 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"טביעת האצבע אומתה"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"זיהוי הפנים בוצע"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"זיהוי הפנים בוצע. יש ללחוץ על אישור"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"החומרה לזיהוי טביעות אצבעות אינה זמינה."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"לא ניתן להגדיר טביעת אצבע"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"הזמן שהוקצב להגדרה של טביעת האצבע פג. יש לנסות שוב."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"פעולת טביעת האצבע בוטלה."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"פעולת טביעת האצבע בוטלה על ידי המשתמש."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"בוצעו יותר מדי ניסיונות. יש להשתמש בנעילת המסך במקום זאת."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"בוצעו יותר מדי ניסיונות. יש להשתמש בנעילת המסך במקום זאת."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"לא ניתן לעבד את טביעת האצבע. יש לנסות שוב."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"לא נסרקו טביעות אצבע."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר הזה אין חיישן טביעות אצבע."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"לא ניתן להשתמש בחיישן טביעות האצבע. צריך ליצור קשר עם ספק תיקונים"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"במכשיר הזה אין חיישן טביעות אצבע"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"לחצן ההפעלה נלחץ"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index c9005dc286d9..f4382c4e2505 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"指紋認証を完了しました"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"顔を認証しました"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"顔を認証しました。[確認] を押してください"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"指紋認証ハードウェアは使用できません。"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"指紋を設定できません"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"指紋の設定がタイムアウトしました。もう一度お試しください。"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"指紋の操作をキャンセルしました。"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"指紋の操作がユーザーによりキャンセルされました。"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"試行回数が上限を超えました。代わりに画面ロックを使用してください。"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"試行回数が上限を超えました。代わりに画面ロックを使用してください。"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"指紋を処理できません。もう一度お試しください。"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"指紋が登録されていません。"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"センサーが一時的に無効になっています。"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"指紋認証センサーを使用できません。修理業者に調整を依頼してください"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"このデバイスには指紋認証センサーがありません"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"電源ボタンが押されました"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"指紋 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"指紋の使用"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 8cd3c941e06c..35f885b913f3 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"თითის ანაბეჭდი ავტორიზებულია"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"სახე ავტორიზებულია"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"სახე ავტორიზებულია, დააჭირეთ დადასტურებას"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"თითის ანაბეჭდის აპარატურა არ არის ხელმისაწვდომი."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"თითის ანაბეჭდის დაყენება ვერ ხერხდება"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"თითის ანაბეჭდის დაყენების დრო ამოიწურა. ცადეთ ხელახლა."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"თითის ანაბეჭდის აღების ოპერაცია გაუქმდა."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"თითის ანაბეჭდის ოპერაცია გააუქმა მომხმარებელმა."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"მეტისმეტად ბევრი მცდელობა იყო. სანაცვლოდ გამოიყენეთ ეკრანის დაბლოკვა."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"მეტისმეტად ბევრი მცდელობა იყო. სანაცვლოდ გამოიყენეთ ეკრანის დაბლოკვა."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"თითის ანაბეჭდის დამუშავება შეუძლებელია. ცადეთ ხელახლა."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"თითის ანაბეჭდები რეგისტრირებული არ არის."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"თითის ანაბეჭდის სენსორის გამოყენება ვერ ხერხდება. ეწვიეთ შეკეთების სერვისის პროვაიდერს"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"ჩართვის ღილაკზე დაეჭირა"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"გამოიყენეთ თითის ანაბეჭდი"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index a8299b7cd6ab..1e7a73b7c57b 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -153,26 +153,16 @@ <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> <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Басқа нөмірге бағытталмады"</string> <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: қайта бағытталған жоқ."</string> - <!-- no translation found for scCellularNetworkSecurityTitle (90330018476923559) --> - <skip /> - <!-- no translation found for scCellularNetworkSecuritySummary (8659128412709908263) --> - <skip /> - <!-- no translation found for scIdentifierDisclosureIssueTitle (3737384845335568193) --> - <skip /> - <!-- no translation found for scIdentifierDisclosureIssueSummary (3870743771498510600) --> - <skip /> - <!-- no translation found for scNullCipherIssueEncryptedTitle (8426373579673205292) --> - <skip /> - <!-- no translation found for scNullCipherIssueEncryptedSummary (6437468449554283998) --> - <skip /> - <!-- no translation found for scNullCipherIssueNonEncryptedTitle (2069674849204163569) --> - <skip /> - <!-- no translation found for scNullCipherIssueNonEncryptedSummary (3577092996366374833) --> - <skip /> - <!-- no translation found for scNullCipherIssueActionSettings (8378372959891478470) --> - <skip /> - <!-- no translation found for scNullCipherIssueActionLearnMore (7896642417214757769) --> - <skip /> + <string name="scCellularNetworkSecurityTitle" msgid="90330018476923559">"Ұялы желі қауіпсіздігі"</string> + <string name="scCellularNetworkSecuritySummary" msgid="8659128412709908263">"Параметрлерді қарап шығу"</string> + <string name="scIdentifierDisclosureIssueTitle" msgid="3737384845335568193">"Құрылғы идентификаторы пайдаланылды"</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="3870743771498510600">"Желі (<xliff:g id="DISCLOSURE_NETWORK">%4$s</xliff:g> байланысы) құрылғының бірегей идентификаторын (IMSI) <xliff:g id="DISCLOSURE_WINDOW_START_TIME">%2$tr</xliff:g> және <xliff:g id="DISCLOSURE_WINDOW_END_TIME">%3$tr</xliff:g> аралығында <xliff:g id="DISCLOSURE_COUNT">%1$d</xliff:g> рет жазып алды."</string> + <string name="scNullCipherIssueEncryptedTitle" msgid="8426373579673205292">"\"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>\" желісіне қосылу шифрланды"</string> + <string name="scNullCipherIssueEncryptedSummary" msgid="6437468449554283998">"Қазір қауіпсіздеу ұялы желіге қосылып тұрсыз."</string> + <string name="scNullCipherIssueNonEncryptedTitle" msgid="2069674849204163569">"\"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>\" желісіне қосылу шифрланбаған"</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="3577092996366374833">"Шифрланбаған ұялы желіге қосылғансыз. Қоңырауларды, хабарлар мен деректерді басқалар қолға түсіруі мүмкін."</string> + <string name="scNullCipherIssueActionSettings" msgid="8378372959891478470">"Ұялы желі қауіпсіздігінің параметрлері"</string> + <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Толық ақпарат"</string> <string name="fcComplete" msgid="1080909484660507044">"Функция коды толық."</string> <string name="fcError" msgid="5325116502080221346">"Байланыс мәселесі немесе функция коды жарамсыз."</string> <string name="httpErrorOk" msgid="6206751415788256357">"Жарайды"</string> @@ -390,10 +380,8 @@ <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Ұялы таратылым хабарлары алынғаннан кейін, олардың бағытын өзгерту үшін қолданбаға ұялы таратылым модулімен байланыстыруға мүмкіндік береді. Ұялы таратылым ескертулері кей аймақтарда төтенше жағдайлар туралы хабарлау үшін беріледі. Төтенше жағдай туралы ұялы таратылым хабары алынғаннан кейін, зиянды қолданбалар құрылғы жұмысына кедергі келтіруі мүмкін."</string> <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"Қазіргі қоңырауларды басқару"</string> <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Қолданбаға құрылғыдағы қазіргі қоңыраулар туралы мәліметтерді көруге және басқаруға мүмкіндік береді."</string> - <!-- no translation found for permlab_accessLastKnownCellId (7638226620825665130) --> - <skip /> - <!-- no translation found for permdesc_accessLastKnownCellId (6664621339249308857) --> - <skip /> + <string name="permlab_accessLastKnownCellId" msgid="7638226620825665130">"Белгілі соңғы ұялы байланыс идентификаторын пайдалану."</string> + <string name="permdesc_accessLastKnownCellId" msgid="6664621339249308857">"Қолданба телефония қызметі берген белгілі соңғы ұялы байланыс идентификаторын пайдалануға рұқсат алады."</string> <string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"ұялы хабар тарату хабарларын оқу"</string> <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Қолданбаға ұялы таратылым хабарларын оқу мүмкіндігін береді. Ұялы таратылым дабылдары кейбір аймақтарда төтенше жағдай туралы ескерту үшін қолданылады. Төтенше ұялы хабарлар келгенде залалды қолданбалар құрылғының жұмысына кедергі жасауы мүмкін."</string> <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"жазылған ағындарды оқу"</string> @@ -565,10 +553,8 @@ <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Қолданбаға телефонның инфрақызыл қабылдағышын қолдану мүмкіндігін береді."</string> <string name="permlab_setWallpaper" msgid="6959514622698794511">"артқы фонды орнату"</string> <string name="permdesc_setWallpaper" msgid="2973996714129021397">"Қолданбаға жүйелік экранның артқы фонын орнатуға рұқсат береді."</string> - <!-- no translation found for permlab_accessHiddenProfile (8607094418491556823) --> - <skip /> - <!-- no translation found for permdesc_accessHiddenProfile (1543153202481009676) --> - <skip /> + <string name="permlab_accessHiddenProfile" msgid="8607094418491556823">"Жасырын профильдерге кіру"</string> + <string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"Қолданбаға жасырын профильдерге кіру рұқсатын береді."</string> <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"артқы фон өлшемін реттеу"</string> <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Қолданбаға жүйелік экранның артқы фонының өлшемі туралы кеңестерді орнатуға рұқсат береді."</string> <string name="permlab_setTimeZone" msgid="7922618798611542432">"уақыт аймағын реттеу"</string> @@ -680,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Саусақ ізі аутентификацияланды"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Бет танылды"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Бет танылды, \"Растау\" түймесін басыңыз"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Саусақ ізі жабдығы қолжетімді емес."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Саусақ ізін орнату мүмкін емес."</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Саусақ ізін реттеу уақыты өтіп кетті. Қайталап көріңіз."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Саусақ ізі операциясынан бас тартылған."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Пайдаланушы саусақ ізі операциясынан бас тартты."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Тым көп әрекет жасалды. Орнына экран құлпын пайдаланыңыз."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Тым көп әрекет жасалды. Орнына экран құлпын пайдаланыңыз."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Саусақ ізін өңдеу мүмкін емес. Қайталап көріңіз."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Саусақ іздері тіркелмеген."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Саусақ ізін оқу сканерін пайдалану мүмкін емес. Жөндеу қызметіне барыңыз."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Бұл құрылғыда саусақ ізін оқу сканері жоқ"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Қуат түймесі басулы."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-саусақ"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Саусақ ізін пайдалану"</string> @@ -837,10 +829,8 @@ <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Қолданбаға жиілігі 200 Гц-тен жоғары датчик деректерінің үлгісін таңдауға рұқсат береді."</string> <string name="permlab_updatePackagesWithoutUserAction" msgid="3363272609642618551">"қолданбаны автоматты түрде жаңарту"</string> <string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Бұған дейін орнатылған қолданбаның автоматты түрде жаңартылуына мүмкіндік береді."</string> - <!-- no translation found for permlab_writeVerificationStateE2eeContactKeys (3990742344778360457) --> - <skip /> - <!-- no translation found for permdesc_writeVerificationStateE2eeContactKeys (8453156829747427041) --> - <skip /> + <string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"тура шифрлаумен қорғалған және басқа қолданбаларға тиесілі контакт кілттерін тексеру күйлерін жаңарту"</string> + <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Қолданбаға тура шифрлаумен қорғалған және басқа қолданбаларға тиесілі контакт кілттерін тексеру күйлерін жаңартуға рұқсат береді."</string> <string name="policylab_limitPassword" msgid="4851829918814422199">"Құпия сөз ережелерін тағайындау"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"Экран бекітпесінің құпия сөздерінің және PIN кодтарының ұзындығын және оларда рұқсат етілген таңбаларды басқару."</string> <string name="policylab_watchLogin" msgid="7599669460083719504">"Экран құлпын ашу әрекеттерін бақылау"</string> @@ -2402,12 +2392,8 @@ <string name="profile_label_test" msgid="9168641926186071947">"Сынақ"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Жалпы"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for satellite_notification_title (4026338973463121526) --> - <skip /> - <!-- no translation found for satellite_notification_summary (5207364139430767162) --> - <skip /> - <!-- no translation found for satellite_notification_open_message (4149234979688273729) --> - <skip /> - <!-- no translation found for satellite_notification_how_it_works (3132069321977520519) --> - <skip /> + <string name="satellite_notification_title" msgid="4026338973463121526">"Жерсерік қызметіне автоматты түрде қосылды"</string> + <string name="satellite_notification_summary" msgid="5207364139430767162">"Мобильдік не Wi-Fi желісіне қосылмастан хабар жібере аласыз және ала аласыз."</string> + <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages қолданбасын ашу"</string> + <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Бұл қалай орындалады?"</string> </resources> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 27d9a06bc731..37a4f817fd13 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"បានផ្ទៀងផ្ទាត់ស្នាមម្រាមដៃ"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"បានផ្ទៀងផ្ទាត់មុខ"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"បានផ្ទៀងផ្ទាត់មុខ សូមចុចបញ្ជាក់"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ផ្នែករឹងស្នាមម្រាមដៃមិនមានទេ។"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"មិនអាចរៀបចំស្នាមម្រាមដៃបានទេ"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ការរៀបចំស្នាមម្រាមដៃបានអស់ម៉ោង។ សូមព្យាយាមម្ដងទៀត។"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"បានបោះបង់ប្រតិបត្តិការស្នាមម្រាមដៃ។"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ប្រតិបត្តិការស្នាមម្រាមដៃត្រូវបានបោះបង់ដោយអ្នកប្រើប្រាស់។"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ព្យាយាមច្រើនដងពេក។ សូមប្រើការចាក់សោអេក្រង់ជំនួសវិញ។"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ព្យាយាមច្រើនដងពេក។ សូមប្រើការចាក់សោអេក្រង់ជំនួសវិញ។"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"មិនអាចដំណើរការស្នាមម្រាមដៃបានទេ។ សូមព្យាយាមម្ដងទៀត។"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"មិនមានការចុះឈ្មោះស្នាមម្រាមដៃទេ។"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះមិនមានឧបករណ៍ចាប់ស្នាមម្រាមដៃទេ។"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទឧបករណ៍ចាប់សញ្ញាជាបណ្តោះអាសន្ន។"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"មិនអាចប្រើឧបករណ៍ចាប់ស្នាមម្រាមដៃបានទេ។ សូមទាក់ទងក្រុមហ៊ុនផ្ដល់ការជួសជុល"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"ឧបករណ៍នេះមិនមានឧបករណ៍ចាប់ស្នាមម្រាមដៃទេ"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"បានចុចប៊ូតុងថាមពល"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃទី <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ប្រើស្នាមម្រាមដៃ"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index b89a1868067e..db4bf180704a 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ಪ್ರಮಾಣೀಕರಣ ಮಾಡಲಾಗಿದೆ"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ, ದೃಢೀಕರಣವನ್ನು ಒತ್ತಿ"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಹಾರ್ಡ್ವೇರ್ ಲಭ್ಯವಿಲ್ಲ."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ಸೆಟಪ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆಟಪ್ ಮಾಡುವ ಅವಧಿ ಮುಗಿದಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ರದ್ದುಮಾಡಲಾಗಿದೆ."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ಬಳಕೆದಾರರು ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ರದ್ದುಪಡಿಸಿದ್ದಾರೆ."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಬದಲಾಗಿ ಸ್ಕ್ರೀನ್ಲಾಕ್ ಬಳಸಿ."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಬದಲಾಗಿ ಪರದೆಲಾಕ್ ಬಳಸಿ."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ಯಾವುದೇ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ನೋಂದಣಿ ಮಾಡಿಲ್ಲ."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ರಿಪೇರಿ ಮಾಡುವವರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"ಈ ಸಾಧನವು ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಹೊಂದಿಲ್ಲ"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"ಪವರ್ ಬಟನ್ ಒತ್ತಲಾಗಿದೆ"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಬಳಸಿ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index e7a04242eebe..e654eb2030f0 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"지문이 인증됨"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"얼굴이 인증되었습니다"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"얼굴이 인증되었습니다. 확인을 누르세요"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"지문 인식 하드웨어를 사용할 수 없습니다."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"지문을 설정할 수 없음"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"지문 설정 시간이 초과되었습니다. 다시 시도해 주세요."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"지문 인식 작업이 취소되었습니다."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"사용자가 지문 인식 작업을 취소했습니다."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"시도 횟수가 너무 많습니다. 화면 잠금을 대신 사용하세요."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"시도 횟수가 너무 많습니다. 화면 잠금을 대신 사용하세요."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"지문을 처리할 수 없습니다. 다시 시도해 주세요."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"등록된 지문이 없습니다."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"센서가 일시적으로 사용 중지되었습니다."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"지문 센서를 사용할 수 없습니다. 수리업체에 방문하세요."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"기기에 지문 센서가 없습니다."</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"전원 버튼을 눌렀습니다."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"지문 사용"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 91be9e419b96..39ecc0260d9c 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Манжа изи текшерилди"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Жүздүн аныктыгы текшерилди"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Жүздүн аныктыгы текшерилди, эми \"Ырастоону\" басыңыз"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Манжа изинин аппараттык камсыздоосу жеткиликтүү эмес."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Манжа изи жөндөлбөй жатат"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Манжа изин коюу убакыты бүтүп калды. Кайра аракет кылыңыз."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Манжа изи иш-аракети жокко чыгарылды."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Манжа изи операциясын колдонуучу жокко чыгарды."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Өтө көп жолу аракет кылдыңыз. Экранды кулпулоо функциясын колдонуңуз."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Өтө көп жолу аракет кылдыңыз. Экранды кулпулоо функциясын колдонуңуз."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Манжа изи иштетилген жок. Кайра аракет кылыңыз."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бир да манжа изи катталган эмес."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Манжа изинин сенсорун колдонууга болбойт. Тейлөө кызматына кайрылыңыз"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Бул түзмөктө манжа изинин сенсору жок"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Кубат баскычы басылды"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Манжа изин колдонуу"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 7d49b0522ab6..48d62d614976 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"ພິສູດຢືນຢັນລາຍນິ້ວມືແລ້ວ"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ພິສູດຢືນຢັນໃບໜ້າແລ້ວ"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ພິສູດຢືນຢັນໃບໜ້າແລ້ວ, ກະລຸນາກົດຢືນຢັນ"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ບໍ່ມີຮາດແວລາຍນີ້ວມືໃຫ້ຢູ່."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ບໍ່ສາມາດຕັ້ງຄ່າລາຍນິ້ວມືໄດ້"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ໝົດເວລາຕັ້ງຄ່າລາຍນິ້ວມື. ກະລຸນາລອງໃໝ່."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"ຍົກເລີກການດຳເນີນການລາຍນີ້ວມືແລ້ວ."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ຜູ້ໃຊ້ໄດ້ຍົກເລີກຄຳສັ່ງລາຍນິ້ວມືແລ້ວ."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ພະຍາຍາມຫຼາຍເທື່ອເກີນໄປ. ກະລຸນາໃຊ້ການລອກໜ້າຈໍແທນ."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ພະຍາຍາມຫຼາຍເທື່ອເກີນໄປ. ກະລຸນາໃຊ້ການລອກໜ້າຈໍແທນ."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ບໍ່ສາມາດປະມວນຜົນລາຍນິ້ວມືໄດ້. ກະລຸນາລອງໃໝ່."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ບໍ່ມີການລົງທະບຽນລາຍນິ້ວມື."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ບໍ່ສາມາດໃຊ້ເຊັນເຊີລາຍນິ້ວມືໄດ້. ກະລຸນາໄປຫາຜູ້ໃຫ້ບໍລິການສ້ອມແປງ"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"ກົດປຸ່ມເປີດປິດແລ້ວ"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ນີ້ວມື <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ໃຊ້ລາຍນິ້ວມື"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index bf750b9cbed7..38aa52a17b3e 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -668,18 +668,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Piršto antspaudas autentifikuotas"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Veidas autentifikuotas"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Veidas autentifikuotas, paspauskite patvirtinimo mygtuką"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Piršto antspaudo aparatinė įranga nepasiekiama."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nepavyko nustatyti kontrolinio kodo"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Baigėsi piršto atspaudo sąrankos skirtasis laikas. Bandykite dar kartą."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Piršto antspaudo operacija atšaukta."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Piršto antspaudo operaciją atšaukė naudotojas."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Per daug bandymų. Naudokite ekrano užraktą."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Per daug bandymų. Naudokite ekrano užraktą."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nepavyko apdoroti kontrolinio kodo. Bandykite dar kartą."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neužregistruota jokių kontrolinių kodų."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Negalima naudoti kontrolinio kodo jutiklio. Apsilankykite pas taisymo paslaugos teikėją"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Šiame įrenginyje nėra piršto antspaudo jutiklio"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Paspaustas maitinimo mygtukas"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Naudoti kontrolinį kodą"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index b554040891c2..165eccde23a4 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Pirksta nospiedums tika autentificēts."</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Seja autentificēta"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Seja ir autentificēta. Nospiediet pogu Apstiprināt."</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Nospieduma aparatūra nav pieejama."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nevar iestatīt pirksta nospiedumu"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Iestatot pirksta nospiedumu, iestājās noildze. Mēģiniet vēlreiz."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Nospieduma darbība neizdevās."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Lietotājs atcēla pirksta nospieduma darbību."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Pārāk daudz mēģinājumu. Izmantojiet ekrāna bloķēšanu."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Pārāk daudz mēģinājumu. Izmantojiet ekrāna bloķēšanu."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nevar apstrādāt pirksta nospiedumu. Mēģiniet vēlreiz."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nav reģistrēts neviens pirksta nospiedums."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Nevar izmantot pirksta nospieduma sensoru. Sazinieties ar remonta pakalpojumu sniedzēju."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Šajā ierīcē nav pirksta nospieduma sensora."</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Tika nospiesta barošanas poga"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Pirksta nospieduma izmantošana"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index ad2274142ee3..aa5645a30d4a 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечатокот е проверен"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лицето е проверено"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицето е проверено, притиснете го копчето „Потврди“"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Хардверот за отпечатоци не е достапен."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Не може да се постави отпечаток"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Времето за поставување отпечаток истече. Обидете се повторно."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Операцијата со отпечаток се откажа."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Корисникот ја откажа потврдата со отпечаток."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Премногу обиди. Користете заклучување екран."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Премногу обиди. Користете заклучување екран."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Не може да се обработи отпечатокот од прст. Обидете се повторно."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Не се запишани отпечатоци."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорот е привремено оневозможен."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не може да се користи сензорот за отпечатоци. Однесете го на поправка"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Уредов нема сензор за отпечатоци"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Притиснато е копчето за вклучување"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користи отпечаток"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index b91c8cfd1f24..0ef12814e3c9 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"ഫിംഗർപ്രിന്റ് പരിശോധിച്ചുറപ്പിച്ചു"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"മുഖം പരിശോധിച്ചുറപ്പിച്ചു"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"മുഖം പരിശോധിച്ചുറപ്പിച്ചു, സ്ഥിരീകരിക്കുക അമർത്തുക"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ഫിംഗർപ്രിന്റ് ഹാർഡ്വെയർ ലഭ്യമല്ല."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ഫിംഗർപ്രിന്റ് സജ്ജീകരിക്കാനാകില്ല"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ഫിംഗർപ്രിന്റ് സജ്ജീകരണം ടൈംഔട്ടായി. വീണ്ടും ശ്രമിക്കുക."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"ഫിംഗർപ്രിന്റ് പ്രവർത്തനം റദ്ദാക്കി."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ഉപയോക്താവ് റദ്ദാക്കിയ ഫിംഗർപ്രിന്റ് പ്രവർത്തനം."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"നിരവധി ശ്രമങ്ങൾ. പകരം സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"നിരവധി ശ്രമങ്ങൾ. പകരം സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ഫിംഗർപ്രിന്റ് പ്രോസസ് ചെയ്യാനാകില്ല. വീണ്ടും ശ്രമിക്കുക."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"വിരലടയാളങ്ങൾ എൻറോൾ ചെയ്തിട്ടില്ല."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"വിരലടയാള സെൻസർ ഉപയോഗിക്കാനാകുന്നില്ല. റിപ്പയർ കേന്ദ്രം സന്ദർശിക്കുക"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസർ ഇല്ല"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"പവർ ബട്ടൺ അമർത്തി"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ഫിംഗർ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index e17684a6ff0a..df4148ef296f 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Хурууны хээг нотолсон"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Царайг баталгаажууллаа"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Царайг баталгаажууллаа. Баталгаажуулах товчлуурыг дарна уу"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Хурууны хээний төхөөрөмж бэлэн бус байна."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Хурууны хээ тохируулах боломжгүй"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Хурууны хээний тохируулга завсарласан. Дахин оролдоно уу."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Хурууны хээний бүртгэл амжилтгүй боллоо."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Хэрэглэгч хурууны хээний баталгаажуулалтыг цуцалсан байна."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Хэт олон удаа оролдлоо. Оронд нь дэлгэцийн түгжээ ашиглана уу."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Хэт олон удаа оролдлоо. Оронд нь дэлгэцийн түгжээ ашиглана уу."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Хурууны хээг боловсруулах боломжгүй. Дахин оролдоно уу."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бүртгүүлсэн хурууны хээ алга."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Хурууны хээ мэдрэгч ашиглах боломжгүй. Засварын үйлчилгээ үзүүлэгчид зочилно уу"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Асаах/Унтраах товчийг дарсан"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Хурууны хээ ашиглах"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index ca26b71b3b2e..09c2ac3b2c48 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"फिंगरप्रिंट ऑथेंटिकेट केली आहे"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"चेहरा ऑथेंटिकेशन केलेला आहे"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"चेहरा ऑथेंटिकेशन केलेला आहे, कृपया कंफर्म प्रेस करा"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"फिंगरप्रिंट हार्डवेअर उपलब्ध नाही."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"फिंगरप्रिंट सेट करता आली नाही"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"फिंगरप्रिंट सेट करण्याची वेळ संपली आहे. पुन्हा प्रयत्न करा."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"फिंगरप्रिंट ऑपरेशन रद्द झाले."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"वापरकर्त्याने फिंगरप्रिंट ऑपरेशन रद्द केले."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"खूप जास्त प्रयत्न. त्याऐवजी स्क्रीन लॉक वापरा."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"खूप जास्त प्रयत्न. त्याऐवजी स्क्रीन लॉक वापरा."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"फिंगरप्रिंटवर प्रक्रिया करू शकत नाही. पुन्हा प्रयत्न करा."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोणत्याही फिंगरप्रिंटची नोंद झाली नाही"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"या डिव्हाइसमध्ये फिंगरप्रिंट सेन्सर नाही."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेन्सर तात्पुरता बंद केला आहे."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फिंगरप्रिंट सेन्सर वापरू शकत नाही. दुरुस्तीच्या सेवा पुरवठादाराला भेट द्या"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"या डिव्हाइसवर फिंगरप्रिंट सेन्सर नाही"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"पॉवर बटण दाबले"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिंट वापरा"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 5865a7493b47..5018aa8fddc7 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Cap jari disahkan"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Wajah disahkan"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Wajah disahkan, sila tekan sahkan"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Perkakasan cap jari tidak tersedia."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Tidak dapat menyediakan cap jari"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Persediaan cap jari telah tamat masa. Cuba lagi."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Pengendalian cap jari dibatalkan."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Pengendalian cap jari dibatalkan oleh pengguna."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Terlalu banyak percubaan. Gunakan kunci skrin."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Terlalu banyak percubaan. Gunakan kunci skrin."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Tidak dapat memproses cap jari. Cuba lagi."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tiada cap jari didaftarkan."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Tidak boleh menggunakan penderia cap jari. Lawati penyedia pembaikan"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Peranti ini tiada penderia cap jari"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Butang kuasa ditekan"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan cap jari"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index c77c8aac3b12..97121dd39f74 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"လက်ဗွေကို အထောက်အထား စိစစ်ပြီးပါပြီ"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ၊ အတည်ပြုရန်ကို နှိပ်ပါ"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"လက်ဗွေ စက်ပစ္စည်းမရနိုင်ပါ။"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"လက်ဗွေကို စနစ်ထည့်သွင်း၍ မရပါ"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"လက်ဗွေစနစ်ထည့်သွင်းချိန် ကုန်သွားပါပြီ။ ထပ်စမ်းကြည့်ပါ။"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"လက်ဗွေယူခြင်း ပယ်ဖျက်လိုက်သည်။"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"လက်ဗွေဖြင့် အထောက်အထားစိစစ်ခြင်းကို အသုံးပြုသူက ပယ်ဖျက်ထားသည်။"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ကြိုးပမ်းမှုအကြိမ်ရေ များလွန်းသည်။ ဖန်သားပြင်လော့ခ်ချခြင်းကို အစားထိုးသုံးပါ။"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ကြိုးပမ်းမှုအကြိမ်ရေ များလွန်းသည်။ ဖန်သားပြင်လော့ခ်ချခြင်းကို အစားထိုးသုံးပါ။"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"လက်ဗွေကို လုပ်ဆောင်နိုင်ခြင်းမရှိပါ။ ထပ်စမ်းကြည့်ပါ။"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"မည်သည့် လက်ဗွေကိုမျှ ထည့်သွင်းမထားပါ။"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"လက်ဗွေ အာရုံခံကိရိယာကို အသုံးပြု၍ မရပါ။ ပြုပြင်ရေး ဝန်ဆောင်မှုပေးသူထံသို့ သွားပါ"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"ဤစက်ပစ္စည်းတွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"ဖွင့်ပိတ်ခလုတ် နှိပ်ထားသည်"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"လက်ဗွေ သုံးခြင်း"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 2bed82e71808..ca6df0e02195 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeravtrykket er godkjent"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ansiktet er autentisert"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansiktet er autentisert. Trykk på Bekreft"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Maskinvare for fingeravtrykk er ikke tilgjengelig."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Kan ikke konfigurere fingeravtrykk"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Konfigureringen av fingeravtrykk er tidsavbrutt. Prøv på nytt."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingeravtrykk-operasjonen ble avbrutt."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingeravtrykk-operasjonen ble avbrutt av brukeren."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"For mange forsøk. Bruk skjermlås i stedet."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"For mange forsøk. Bruk skjermlås i stedet."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Kan ikke behandle fingeravtrykket. Prøv på nytt."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ingen fingeravtrykk er registrert."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Kan ikke bruke fingeravtrykkssensoren. Gå til en reparasjonsleverandør"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Denne enheten har ikke fingeravtrykkssensor"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Av/på-knappen ble trykket"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Bruk fingeravtrykk"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 6e4c0d200821..fd31ac4b6dbe 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"फिंगरप्रिन्ट प्रमाणीकरण गरियो"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"अनुहार प्रमाणीकरण गरियो"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"अनुहार प्रमाणीकरण गरियो, कृपया पुष्टि गर्नुहोस् थिच्नुहोस्"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"औँठाछाप हार्डवेयर उपलब्ध छैन।"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"फिंगरप्रिन्ट सेटअप गर्न सकिएन"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"फिंगरप्रिन्ट सेट अप गर्ने समय सकियो। फेरि प्रयास गर्नुहोस्।"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"फिंगरप्रिन्ट सञ्चालन रद्द गरियो।"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"प्रयोगकर्ताले फिंगरप्रिन्टसम्बन्धी कारबाही रद्द गर्नुभयो।"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"निकै धेरै पटक प्रयास गरिसकिएको छ। बरु स्क्रिन लक प्रयोग गर्नुहोस्।"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"निकै धेरै पटक प्रयास गरिसकिएको छ। बरु स्क्रिन लक प्रयोग गर्नुहोस्।"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"फिंगरप्रिन्ट पहिचान गर्ने प्रक्रिया अघि बढाउन सकिएन। फेरि प्रयास गर्नुहोस्।"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कुनै पनि फिंगरप्रिन्ट दर्ता गरिएको छैन।"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो डिभाइसमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फिंगरप्रिन्ट सेन्सर प्रयोग गर्न मिल्दैन। फिंगरप्रिन्ट सेन्सर मर्मत गर्ने सेवा प्रदायक कम्पनीमा सम्पर्क गर्नुहोस्"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"यो डिभाइसमा कुनै फिंगरप्रिन्ट सेन्सर छैन"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"पावर बटन थिचियो"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 2de4cb9acf39..e68947e8ed42 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Vingerafdruk geverifieerd"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Gezicht geverifieerd"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gezicht geverifieerd. Druk op Bevestigen."</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware voor vingerafdruk niet beschikbaar."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Kan vingerafdruk niet instellen"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Time-out bij instellen van vingerafdruk. Probeer het opnieuw."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Vingerafdrukbewerking geannuleerd."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Vingerafdrukverificatie geannuleerd door gebruiker."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Te veel pogingen. Gebruik in plaats daarvan de schermvergrendeling."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Te veel pogingen. Gebruik in plaats daarvan de schermvergrendeling."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Kan vingerafdruk niet verwerken. Probeer het opnieuw."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukken geregistreerd."</string> - <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 staat tijdelijk uit."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Kan vingerafdruksensor niet gebruiken. Ga naar een reparateur."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Dit apparaat heeft geen vingerafdruksensor"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Aan/uit-knop ingedrukt"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Vingerafdruk gebruiken"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 2a4a07ef9746..45b49d373588 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"ଟିପଚିହ୍ନ ପ୍ରମାଣିତ ହେଲା"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ମୁହଁ ଚିହ୍ନଟ ହୋଇଛି"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ମୁହଁ ଚିହ୍ନଟ ହୋଇଛି, ଦୟାକରି ସୁନିଶ୍ଚିତ ଦବାନ୍ତୁ"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ଟିପଚିହ୍ନ ହାର୍ଡୱେର୍ ଉପଲବ୍ଧ ନାହିଁ।"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ଟିପଚିହ୍ନକୁ ସେଟ୍ ଅପ୍ କରାଯାଇପାରିବ ନାହିଁ"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ସେଟଅପର ସମୟସୀମା ସମାପ୍ତ ହୋଇଯାଇଛି। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"ଟିପଚିହ୍ନ କାର୍ଯ୍ୟ ବାତିଲ୍ କରାଗଲା।"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ଉପଯୋଗକର୍ତ୍ତା ଟିପଚିହ୍ନ କାର୍ଯ୍ୟ ବାତିଲ୍ କରିଛନ୍ତି।"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ଅନେକଗୁଡ଼ିଏ ପ୍ରଚେଷ୍ଟା। ଏହା ପରିବର୍ତ୍ତେ ସ୍କ୍ରିନ ଲକ ବ୍ୟବହାର କରନ୍ତୁ।"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ଅନେକଗୁଡ଼ିଏ ପ୍ରଚେଷ୍ଟା। ଏହା ପରିବର୍ତ୍ତେ ସ୍କ୍ରିନ ଲକ ବ୍ୟବହାର କରନ୍ତୁ।"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ଟିପଚିହ୍ନକୁ ପ୍ରକ୍ରିୟାନ୍ୱିତ କରାଯାଇପାରିବ ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"କୌଣସି ଆଙ୍ଗୁଠି ଚିହ୍ନ ପଞ୍ଜୀକୃତ ହୋଇନାହିଁ।"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍ରେ ଟିପଚିହ୍ନ ସେନ୍ସର୍ ନାହିଁ।"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ। ଏକ ମରାମତି କେନ୍ଦ୍ରକୁ ଭିଜିଟ୍ କରନ୍ତୁ"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"ଏହି ଡିଭାଇସ୍ରେ ଟିପଚିହ୍ନ ସେନସର୍ ନାହିଁ"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"ପାୱାର ବଟନ ଦବାଯାଇଛି"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index db4c38e7349c..2abe228d6733 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ਚਿਹਰਾ ਪੁਸ਼ਟੀਕਰਨ"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ਚਿਹਰਾ ਪੁਸ਼ਟੀਕਰਨ, ਕਿਰਪਾ ਕਰਕੇ \'ਪੁਸ਼ਟੀ ਕਰੋ\' ਦਬਾਓ"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਾਰਡਵੇਅਰ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਸੈੱਟਅੱਪ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ ਸਮਾਂ ਸਮਾਪਤ ਹੋਇਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਓਪਰੇਸ਼ਨ ਰੱਦ ਕੀਤਾ ਗਿਆ।"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਓਪਰੇਸ਼ਨ ਵਰਤੋਂਕਾਰ ਵੱਲੋਂ ਰੱਦ ਕੀਤਾ ਗਿਆ।"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ਬਹੁਤ ਸਾਰੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਸਦੀ ਬਜਾਏ ਸਕ੍ਰੀਨ ਲਾਕ ਵਰਤੋ।"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ਬਹੁਤ ਸਾਰੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਸਦੀ ਬਜਾਏ ਸਕ੍ਰੀਨ ਲਾਕ ਵਰਤੋ।"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ਫਿੰਗਰਪ੍ਰਿੰਟ \'ਤੇ ਪ੍ਰਕਿਰਿਆ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ਕੋਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਰਜ ਨਹੀਂ ਕੀਤੇ ਗਏ।"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨਹੀਂ ਹੈ।"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ਸੈਂਸਰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਮੁਰੰਮਤ ਪ੍ਰਦਾਨਕ \'ਤੇ ਜਾਓ"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨਹੀਂ ਹੈ"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"\'ਪਾਵਰ\' ਬਟਨ ਦਬਾਇਆ ਗਿਆ"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 1dcc7393f0a9..06bff2aaad55 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -668,18 +668,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Uwierzytelniono odciskiem palca"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Twarz rozpoznana"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Twarz rozpoznana, kliknij Potwierdź"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Czytnik linii papilarnych nie jest dostępny."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nie można skonfigurować odcisku palca"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Upłynął limit czasu konfiguracji odcisku palca. Spróbuj ponownie."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Odczyt odcisku palca został anulowany."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Odczyt odcisku palca został anulowany przez użytkownika."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Zbyt wiele prób. Użyj blokady ekranu."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Zbyt wiele prób. Użyj blokady ekranu."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nie udało się przetworzyć odcisku palca. Spróbuj ponownie."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nie zarejestrowano odcisków palców."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Nie można użyć czytnika linii papilarnych. Odwiedź serwis."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"To urządzenie nie jest wyposażone w czytnik linii papilarnych"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Naciśnięto przycisk zasilania"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Używaj odcisku palca"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index b0a3adbed054..43cdfa205162 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Rosto autenticado"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impressão digital não disponível."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Não foi possível configurar a impressão digital"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Tempo de configuração esgotado. Tente de novo."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operação de impressão digital cancelada."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operação de impressão digital cancelada pelo usuário."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Excesso de tentativas. Use o bloqueio de tela."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Excesso de tentativas. Use o bloqueio de tela."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Não foi possível processar a impressão digital. Tente de novo."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Não foi possível usar o sensor de impressão digital. Entre em contato com uma assistência técnica"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Este dispositivo não tem um sensor de impressão digital"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Botão liga/desliga pressionado"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 735aa7c8f508..74df1872a970 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"A impressão digital foi autenticada."</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Rosto autenticado."</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado. Prima Confirmar."</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impressão digital não disponível."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Não é possível configurar a impressão digital"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"A configuração da impressão digital expirou. Tente novamente."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operação de impressão digital cancelada."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operação de impressão digital cancelada pelo utilizador."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Demasiadas tentativas. Em alternativa, use o bloqueio de ecrã."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Demasiadas tentativas. Em alternativa, use o bloqueio de ecrã."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Não é possível processar a impressão digital. Tente novamente."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registada."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Não é possível usar o sensor de impressões digitais. Visite um fornecedor de serviços de reparação"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Este dispositivo não tem sensor de impressões digitais."</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Botão ligar/desligar premido"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar a impressão digital"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index b0a3adbed054..43cdfa205162 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Rosto autenticado"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impressão digital não disponível."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Não foi possível configurar a impressão digital"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Tempo de configuração esgotado. Tente de novo."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operação de impressão digital cancelada."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operação de impressão digital cancelada pelo usuário."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Excesso de tentativas. Use o bloqueio de tela."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Excesso de tentativas. Use o bloqueio de tela."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Não foi possível processar a impressão digital. Tente de novo."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Não foi possível usar o sensor de impressão digital. Entre em contato com uma assistência técnica"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Este dispositivo não tem um sensor de impressão digital"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Botão liga/desliga pressionado"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 820ca895258a..67ade37b2756 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Amprentă autentificată"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Chip autentificat"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Chip autentificat, apasă pe Confirmă"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware-ul pentru amprentă nu este disponibil."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nu se poate configura amprenta"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Configurarea amprentei a expirat. Încearcă din nou."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operațiunea privind amprenta a fost anulată."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operațiunea privind amprenta a fost anulată de utilizator."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Prea multe încercări. Folosește blocarea ecranului."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Prea multe încercări. Folosește blocarea ecranului."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nu putem procesa amprenta. Încearcă din nou."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nu au fost înregistrate amprente."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Nu se poate folosi senzorul de amprentă. Vizitează un furnizor de servicii de reparații."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Acest dispozitiv nu are senzor de amprentă"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"A fost apăsat butonul de pornire"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Folosește amprenta"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 0c80e0ec709e..7e8df9ff23ff 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -668,18 +668,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечаток пальца проверен"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лицо распознано"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицо распознано, нажмите кнопку \"Подтвердить\""</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Сканер недоступен"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Не удалось сохранить отпечаток."</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Время настройки отпечатка пальца истекло. Повторите попытку."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Операция с отпечатком отменена."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Операция с отпечатком пальца отменена пользователем."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Слишком много попыток. Используйте другой способ разблокировки экрана."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Слишком много попыток. Используйте другой способ разблокировки экрана."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Не удалось распознать отпечаток пальца. Повторите попытку."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Нет отсканированных отпечатков пальцев"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сканер отпечатков пальцев временно отключен."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Невозможно использовать сканер отпечатков пальцев. Обратитесь в сервисный центр."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"На этом устройстве нет сканера отпечатков пальцев"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Нажата кнопка питания."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Использовать отпечаток пальца"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 0aa3200545cb..db7fb6d13b94 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"ඇඟිලි සලකුණ සත්යාපනය කරන ලදී"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"මුහුණ සත්යාපනය කරන ලදී"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"මුහුණ සත්යාපනය කරන ලදී, කරුණාකර තහවුරු කරන්න ඔබන්න"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ඇඟිලි සලකුණු දෘඪාංගය ලද නොහැකිය."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ඇඟිලි සලකුණ පිහිටුවිය නොහැකිය"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ඇඟිලි සලකුණු පිහිටුවීම කාලය නිමා විය. නැවත උත්සාහ කරන්න."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"ඇඟිලි සලකුණු මෙහෙයුම අවලංගු කරන ලදී."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"පරිශීලක විසින් ඇඟිලි සලකුණු මෙහෙයුම අවසන් කරන ලදී."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"උත්සාහ ගණන ඉතා වැඩියි. ඒ වෙනුවට තිර අගුල භාවිත කරන්න."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"උත්සාහ ගණන ඉතා වැඩියි. ඒ වෙනුවට තිර අගුල භාවිත කරන්න."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ඇඟිලි සලකුණ සැකසීමට නොහැක. නැවත උත්සාහ කරන්න."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ඇඟිලි සලකුණු ඇතුළත් කර නොමැත."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"මෙම උපාංගයේ ඇඟිලි සලකුණු සංවේදකයක් නොමැත."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"සංවේදකය තාවකාලිකව අබල කර ඇත."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ඇඟිලි සලකුණු සංවේදකය භාවිත කළ නොහැකිය. අළුත්වැඩියා සැපයුම්කරුවෙකු බලන්න"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"මෙම උපාංගයේ ඇඟිලි සලකුණු සංවේදකයක් නොමැත"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"බල බොත්තම ඔබා ඇත"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ඇඟිලි <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ඇඟිලි සලකුණ භාවිත කරන්න"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 2ddfbffe4b7c..e199235ac19a 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -668,18 +668,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Odtlačok prsta bol overený"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Tvár bola overená"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Tvár bola overená, stlačte tlačidlo potvrdenia"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardvér na snímanie odtlačku prsta nie je k dispozícii"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Odtlačok prsta sa nedá nastaviť"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Nastavenie odtlačku prsta vypršalo. Skúste to znova."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operácia týkajúca sa odtlačku prsta bola zrušená"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Overenie odtlačku prsta zrušil používateľ."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Príliš veľa pokusov. Použite radšej zámku obrazovky."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Príliš veľa pokusov. Použite radšej zámku obrazovky."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Odtlačok prsta sa nedá spracovať. Skúste to znova."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neregistrovali ste žiadne odtlačky prstov."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Senzor odtlačkov prstov nie je možné používať. Navštívte poskytovateľa opráv."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Toto zariadenie nemá senzor odtlačkov prstov"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Bol stlačený vypínač"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použiť odtlačok prsta"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 191570374251..305e3903397d 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -668,18 +668,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Pristnost prstnega odtisa je preverjena"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Pristnost obraza je potrjena"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Pristnost obraza je preverjena. Pritisnite gumb »Potrdi«."</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Strojna oprema za prstne odtise ni na voljo."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Prstnega odtisa ni mogoče nastaviti."</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Čas za nastavitev prstnega odtisa je potekel. Poskusite znova."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Dejanje s prstnim odtisom je bilo preklicano."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Dejanje s prstnim odtisom je preklical uporabnik."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Preveč poskusov. Odklenite z načinom za zaklepanje zaslona."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Preveč poskusov. Odklenite z zaklepanjem zaslona."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Prstnega odtisa ni mogoče obdelati. Poskusite znova."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ni registriranih prstnih odtisov."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Tipala prstnih odtisov ni mogoče uporabiti. Obiščite ponudnika popravil."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Ta naprava nima tipala prstnih odtisov"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Gumb za vklop je pritisnjen."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Uporaba prstnega odtisa"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 9b3935173de1..c6fdb8f9440c 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Gjurma e gishtit u vërtetua"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Fytyra u vërtetua"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Fytyra u vërtetua, shtyp \"Konfirmo\""</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardueri i gjurmës së gishtit nuk mundësohet."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nuk mund të konfigurohet gjurma e gishtit"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Konfigurimi i gjurmës së gishtit skadoi. Provo përsëri."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operacioni i gjurmës së gishtit u anulua."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Veprimi i gjurmës së gishtit u anulua nga përdoruesi."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Shumë përpjekje. Përdor më mirë kyçjen e ekranit."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Shumë përpjekje. Përdor më mirë kyçjen e ekranit."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Gjurma e gishtit nuk mund të përpunohet. Provo përsëri."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nuk ka asnjë gjurmë gishti të regjistruar."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Sensori i gjurmës së gishtit nuk mund të përdoret. Vizito një ofrues të shërbimit të riparimit"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Kjo pajisje nuk ka sensor të gjurmës së gishtit"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Butoni i energjisë u shtyp"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Përdor gjurmën e gishtit"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 8440b939466e..194e48957a02 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -667,18 +667,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отисак прста је потврђен"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лице је потврђено"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лице је потврђено. Притисните Потврди"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Хардвер за отиске прстију није доступан."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Подешавање отиска прста није успело"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Време за подешавање отиска прста је истекло. Пробајте поново."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Радња са отиском прста је отказана."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Корисник је отказао радњу са отиском прста."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Превише покушаја. Користите закључавање екрана уместо тога."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Превише покушаја. Користите закључавање екрана уместо тога."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Обрађивање отиска прста није успело. Пробајте поново."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Није регистрован ниједан отисак прста."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не можете да користите сензор за отисак прста. Посетите добављача за поправке"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Овај уређај нема сензор за отисак прста"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Притиснуто је дугме за укључивање"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користите отисак прста"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index cfd3aefbd932..25109b80a77a 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeravtrycket har autentiserats"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ansiktet har autentiserats"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansiktet har autentiserats. Tryck på Bekräfta"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Det finns ingen maskinvara för fingeravtryck."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Det gick inte att konfigurera fingeravtryck"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Tiden för fingeravtrycksinställning gick ut. Försök igen."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingeravtrycksåtgärden avbröts."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingeravtrycksåtgärden avbröts av användaren."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"För många försök. Använd låsskärmen i stället."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"För många försök. Använd låsskärmen i stället."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Det gick inte att bearbeta fingeravtrycket. Försök igen."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Inga fingeravtryck har registrerats."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Det går inte att använda fingeravtryckssensorn. Besök ett reparationsställe"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Enheten har ingen fingeravtryckssensor"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Av/på-knappen nedtryckt"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Använd ditt fingeravtryck"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index ff1a603c1d89..8819f2707593 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Imethibitisha alama ya kidole"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Uso umethibitishwa"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Uso umethibitishwa, tafadhali bonyeza thibitisha"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Maunzi ya alama ya kidole hayapatikani."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Imeshindwa kuweka mipangilio ya alama ya kidole"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Muda wa kuweka alama ya kidole umeisha. Jaribu tena."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Mchakato wa alama ya kidole umeghairiwa."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Mtumiaji ameghairi uthibitishaji wa alama ya kidole."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Umejaribu mara nyingi mno. Badala yake, tumia mbinu ya kufunga skrini."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Umejaribu mara nyingi mno. Badala yake, tumia mbinu ya kufunga skrini."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Imeshindwa kutambua alama ya kidole. Jaribu tena."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hakuna alama za vidole zilizojumuishwa."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Imeshindwa kutumia kitambua alama ya kidole. Tembelea mtoa huduma za urekebishaji"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Kifaa hiki hakina kitambua alama ya kidole"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Kitufe cha kuwasha au kuzima kimebonyezwa"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Kidole cha <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Tumia alama ya kidole"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 6074fdf606e1..24307fa95389 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"கைரேகை அங்கீகரிக்கப்பட்டது"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"முகம் அங்கீகரிக்கப்பட்டது"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"முகம் அங்கீகரிக்கப்பட்டது. ’உறுதிப்படுத்துக’ என்பதை அழுத்துக"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"கைரேகை வன்பொருள் இல்லை."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"கைரேகையை அமைக்க முடியவில்லை"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"கைரேகை அமைவுக்கான நேரம் முடிந்துவிட்டது. மீண்டும் முயலவும்."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"கைரேகை செயல்பாடு ரத்துசெய்யப்பட்டது."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"பயனர், கைரேகை உறுதிப்படுத்துதலை ரத்துசெய்தார்."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"பலமுறை முயன்றுவிட்டீர்கள். இதற்குப் பதிலாகத் திரைப்பூட்டைப் பயன்படுத்தவும்."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"பலமுறை முயன்றுவிட்டீர்கள். இதற்குப் பதிலாகத் திரைப்பூட்டைப் பயன்படுத்தவும்."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"கைரேகையைச் செயலாக்க முடியவில்லை. மீண்டும் முயலவும்."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"கைரேகைப் பதிவுகள் எதுவும் இல்லை."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"கைரேகை சென்சாரைப் பயன்படுத்த முடியவில்லை. பழுதுபார்ப்புச் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"பவர் பட்டன் அழுத்தப்பட்டுள்ளது"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"கைரேகையைப் பயன்படுத்து"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 3f729667ad04..28b7d2804681 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"వేలిముద్ర ప్రమాణీకరించబడింది"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ముఖం ప్రమాణీకరించబడింది"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ముఖం ప్రమాణీకరించబడింది, దయచేసి ధృవీకరించును నొక్కండి"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"వేలిముద్ర హార్డ్వేర్ అందుబాటులో లేదు."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"వేలిముద్రను సెటప్ చేయడం సాధ్యం కాదు"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"వేలిముద్ర సెటప్ సమయం ముగిసింది. మళ్లీ ట్రై చేయండి."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"వేలిముద్ర యాక్టివిటీ రద్దయింది."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"వేలిముద్ర చర్యని వినియోగదారు రద్దు చేశారు."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"చాలా ఎక్కువ సార్లు ప్రయత్నించారు. బదులుగా స్క్రీన్ లాక్ను ఉపయోగించండి."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"చాలా ఎక్కువ సార్లు ప్రయత్నించారు. బదులుగా స్క్రీన్ లాక్ను ఉపయోగించండి."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"వేలిముద్రను ప్రాసెస్ చేయడం సాధ్యపడదు. మళ్లీ ట్రై చేయండి."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"వేలిముద్రలు నమోదు చేయబడలేదు."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ ఎంపిక లేదు."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"వేలిముద్ర సెన్సార్ను ఉపయోగించడం సాధ్యం కాదు. రిపెయిర్ ప్రొవైడర్ను సందర్శించండి"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ లేదు"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Power button pressed"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>వ వేలు"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"వేలిముద్రను ఉపయోగించండి"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 2f8486ce2763..94fe59d18549 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -514,8 +514,8 @@ <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"แอปนี้ถ่ายภาพและวิดีโอด้วยกล้องได้ทุกเมื่อ"</string> <string name="permlab_systemCamera" msgid="3642917457796210580">"อนุญาตให้แอปพลิเคชันหรือบริการเข้าถึงกล้องของระบบเพื่อถ่ายภาพและวิดีโอ"</string> <string name="permdesc_systemCamera" msgid="5938360914419175986">"แอปของระบบหรือที่ได้รับสิทธิ์นี้จะถ่ายภาพและบันทึกวิดีโอโดยใช้กล้องของระบบได้ทุกเมื่อ แอปต้องมีสิทธิ์ android.permission.CAMERA ด้วย"</string> - <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"อนุญาตให้แอปพลิเคชันหรือบริการได้รับโค้ดเรียกกลับเมื่อมีการเปิดหรือปิดอุปกรณ์กล้อง"</string> - <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"แอปนี้จะได้รับโค้ดเรียกกลับเมื่อมีการปิดหรือเปิดอุปกรณ์กล้อง (โดยแอปพลิเคชันที่เปิด)"</string> + <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"อนุญาตให้แอปพลิเคชันหรือบริการได้รับ Callback เมื่อมีการเปิดหรือปิดอุปกรณ์กล้อง"</string> + <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"แอปนี้จะได้รับ Callback เมื่อมีการปิดหรือเปิดอุปกรณ์กล้อง (โดยแอปพลิเคชันที่เปิด)"</string> <string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"อนุญาตให้แอปพลิเคชันหรือบริการเข้าถึงกล้องในฐานะผู้ใช้ระบบแบบไม่มีส่วนหัว"</string> <string name="permdesc_cameraHeadlessSystemUser" msgid="6963163319710996412">"แอปนี้เข้าถึงกล้องในฐานะผู้ใช้ระบบแบบไม่มีส่วนหัว"</string> <string name="permlab_vibrate" msgid="8596800035791962017">"ควบคุมการสั่นเตือน"</string> @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"ตรวจสอบสิทธิ์ลายนิ้วมือแล้ว"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ตรวจสอบสิทธิ์ใบหน้าแล้ว"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ตรวจสอบสิทธิ์ใบหน้าแล้ว โปรดกดยืนยัน"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ฮาร์ดแวร์ลายนิ้วมือไม่พร้อมใช้งาน"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ตั้งค่าลายนิ้วมือไม่ได้"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"การตั้งค่าลายนิ้วมือหมดเวลา โปรดลองอีกครั้ง"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"ยกเลิกการทำงานของลายนิ้วมือ"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ผู้ใช้ยกเลิกการทำงานของลายนิ้วมือ"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ลองหลายครั้งเกินไป ใช้การล็อกหน้าจอแทน"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ลองหลายครั้งเกินไป ใช้การล็อกหน้าจอแทน"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ประมวลผลลายนิ้วมือไม่ได้ โปรดลองอีกครั้ง"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ไม่มีลายนิ้วมือที่ลงทะเบียน"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ใช้เซ็นเซอร์ลายนิ้วมือไม่ได้ โปรดติดต่อผู้ให้บริการซ่อม"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"กดปุ่มเปิด/ปิดแล้ว"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้วมือ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ใช้ลายนิ้วมือ"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 3cb5babd5fcb..57c6b2ab3b46 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Na-authenticate ang fingerprint"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Na-authenticate ang mukha"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Na-authenticate ang mukha, pakipindot ang kumpirmahin"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hindi available ang hardware na ginagamitan ng fingerprint."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Hindi ma-set up ang fingerprint"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Nag-time out ang pag-set up ng fingerprint. Subukan ulit."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Nakansela ang operasyong ginagamitan ng fingerprint."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Kinansela ng user ang operasyon sa fingerprint."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Masyadong maraming pagsubok. Gamitin na lang ang lock ng screen."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Masyadong maraming pagsubok. Gamitin na lang ang lock ng screen."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Hindi maproseso ang fingerprint. Subukan ulit."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Walang naka-enroll na fingerprint."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Hindi magamit ang sensor para sa fingerprint. Bumisita sa provider ng pag-aayos"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Walang sensor para sa fingerprint ang device na ito"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Napindot ang power button"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gumamit ng fingerprint"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 48beb9a0a8d7..af18dacc05c2 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Parmak izi kimlik doğrulaması yapıldı"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Yüz kimliği doğrulandı"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Yüz kimliği doğrulandı, lütfen onayla\'ya basın"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Parmak izi donanımı kullanılamıyor."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Parmak izi ayarlanamıyor"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Parmak izi kurulumu zaman aşımına uğradı. Tekrar deneyin."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Parmak izi işlemi iptal edildi."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Parmak izi işlemi kullanıcı tarafından iptal edildi."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Çok fazla deneme yapıldı. Bunun yerine ekran kilidini kullanın."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Çok fazla deneme yapıldı. Bunun yerine ekran kilidini kullanın."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Parmak izi işlenemiyor. Tekrar deneyin."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Parmak izi kaydedilmedi."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Parmak izi sensörü kullanılamıyor. Bir onarım hizmeti sağlayıcıyı ziyaret edin"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Bu cihazda parmak izi sensörü yok"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Güç düğmesine basıldı"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Parmak izi kullan"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 08051a76a1a6..5b645db69daa 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -668,18 +668,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Відбиток пальця автентифіковано"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Обличчя автентифіковано"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Обличчя автентифіковано. Натисніть \"Підтвердити\""</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Сканер відбитків пальців недоступний."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Не вдалося створити відбиток пальця"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Час очікування для налаштування відбитка пальця минув. Повторіть спробу."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Дію з відбитком пальця скасовано."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Користувач скасував дію з відбитком пальця."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Забагато спроб. Використайте натомість розблокування екрана."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Забагато спроб. Використайте натомість розблокування екрана."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Не вдалось обробити відбиток пальця. Повторіть спробу."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Відбитки пальців не зареєстровано."</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не вдається скористатися сканером відбитків пальців. Зверніться до постачальника послуг із ремонту."</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"На цьому пристрої немає сканера відбитків пальців"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Натиснуто кнопку живлення"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Доступ за відбитком пальця"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index ba8dfe376caf..1c9275293cca 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"فنگر پرنٹ کی تصدیق ہو گئی"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"چہرے کی تصدیق ہو گئی"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"چہرے کی تصدیق ہو گئی، براہ کرم \'تصدیق کریں\' کو دبائيں"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"فنگر پرنٹ ہارڈ ویئر دستیاب نہیں ہے۔"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"فنگر پرنٹ کو سیٹ اپ نہیں کیا جا سکا"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"فنگر پرنٹ کے سیٹ اپ کا وقت ختم ہو گیا۔ دوبارہ کوشش کریں۔"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"فنگر پرنٹ کی کارروائی منسوخ ہوگئی۔"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"صارف نے فنگر پرنٹ کی کارروائی منسوخ کر دی۔"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"کافی زیادہ کوششیں۔ اس کے بجائے اسکرین لاک کا استعمال کریں۔"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"کافی زیادہ کوششیں۔ اس کے بجائے اسکرین لاک کا استعمال کریں۔"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"فنگر پرنٹ پروسیس نہیں ہو سکتا۔ دوبارہ کوشش کریں۔"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"کوئی فنگر پرنٹ مندرج شدہ نہیں ہے۔"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"فنگر پرنٹ سینسر کا استعمال نہیں کر سکتے۔ ایک مرمت فراہم کنندہ کو ملاحظہ کریں"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"پاور بٹن دبایا گیا"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"فنگر پرنٹ استعمال کریں"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index b4c6a8d87735..828f391345f0 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Barmoq izi tekshirildi"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Yuzingiz aniqlandi"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Yuzingiz aniqlandi, tasdiqlash uchun bosing"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Barmoq izi skaneri ish holatida emas."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Barmoq izi sozlanmadi"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Barmoq izini sozlash vaqti tugadi. Qayta urining."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Barmoq izi tekshiruvi bekor qilindi."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Barmoq izi amali foydalanuvchi tomonidan bekor qilindi"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Juda koʻp urinildi. Ekran qulfi orqali urining."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Juda koʻp urinildi. Ekran qulfi orqali urining."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Barmoq izi tekshirilmadi. Qayta urining."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hech qanday barmoq izi qayd qilinmagan."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Barmoq izi skaneridan foydalanish imkonsiz. Xizmat koʻrsatish markaziga murojaat qiling"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Bu qurilmada barmoq izi skaneri yo‘q"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Quvvat tugmasi bosildi"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmoq izi ishlatish"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 61f134800c41..2e57cafaec1f 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Đã xác thực vân tay"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Đã xác thực khuôn mặt"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Đã xác thực khuôn mặt, vui lòng nhấn để xác nhận"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Phần cứng vân tay không khả dụng."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Không thể thiết lập vân tay"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Hết thời gian chờ thiết lập vân tay. Hãy thử lại."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Thao tác dùng dấu vân tay bị hủy."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Người dùng đã hủy thao tác dùng dấu vân tay."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Bạn đã thử quá nhiều lần. Hãy dùng phương thức khoá màn hình."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Bạn đã thử quá nhiều lần. Hãy dùng phương thức khoá màn hình."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Không xử lý được vân tay. Hãy thử lại."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Chưa đăng ký vân tay."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Không thể dùng cảm biến vân tay. Hãy liên hệ với một nhà cung cấp dịch vụ sửa chữa"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Thiết bị này không có cảm biến vân tay"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Đã nhấn nút nguồn"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Dùng vân tay"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 09e80eb8f7c0..0d49373867fb 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"已验证指纹"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"面孔已验证"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"面孔已验证,请按确认按钮"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"指纹硬件无法使用。"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"无法设置指纹"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"指纹设置已超时,请重试。"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"指纹操作已取消。"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"用户取消了指纹操作。"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"尝试次数过多,请通过屏幕锁定功能解锁。"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"尝试次数过多,请通过屏幕锁定功能解锁。"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"无法处理指纹,请重试。"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未注册任何指纹。"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"无法使用指纹传感器。请联系维修服务提供商"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"此设备没有指纹传感器"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"已按下电源按钮"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指纹"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 8743f8548a71..cce19905c2ff 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -153,15 +153,15 @@ <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> <string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:尚未轉接"</string> <string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:尚未轉接"</string> - <string name="scCellularNetworkSecurityTitle" msgid="90330018476923559">"行動網路安全性"</string> - <string name="scCellularNetworkSecuritySummary" msgid="8659128412709908263">"查看設定"</string> - <string name="scIdentifierDisclosureIssueTitle" msgid="3737384845335568193">"已存取裝置 ID"</string> - <string name="scIdentifierDisclosureIssueSummary" msgid="3870743771498510600">"<xliff:g id="DISCLOSURE_NETWORK">%4$s</xliff:g> 連線上的網路已記錄裝置的專屬 ID (IMSI),次數為 <xliff:g id="DISCLOSURE_COUNT">%1$d</xliff:g> 次;記錄區間為 <xliff:g id="DISCLOSURE_WINDOW_START_TIME">%2$tr</xliff:g>至 <xliff:g id="DISCLOSURE_WINDOW_END_TIME">%3$tr</xliff:g>。"</string> - <string name="scNullCipherIssueEncryptedTitle" msgid="8426373579673205292">"已連上加密的 <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> - <string name="scNullCipherIssueEncryptedSummary" msgid="6437468449554283998">"你現在已連上較安全的行動網路。"</string> - <string name="scNullCipherIssueNonEncryptedTitle" msgid="2069674849204163569">"已連上未加密的 <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> - <string name="scNullCipherIssueNonEncryptedSummary" msgid="3577092996366374833">"你已連上未加密的行動網路。通話、訊息和資料會容易遭到攔截。"</string> - <string name="scNullCipherIssueActionSettings" msgid="8378372959891478470">"行動網路安全性設定"</string> + <string name="scCellularNetworkSecurityTitle" msgid="90330018476923559">"流動網絡安全性"</string> + <string name="scCellularNetworkSecuritySummary" msgid="8659128412709908263">"檢查設定"</string> + <string name="scIdentifierDisclosureIssueTitle" msgid="3737384845335568193">"已存取裝置識別碼"</string> + <string name="scIdentifierDisclosureIssueSummary" msgid="3870743771498510600">"<xliff:g id="DISCLOSURE_NETWORK">%4$s</xliff:g> 連線上的網絡已記錄裝置的專屬識別碼 (IMSI),次數為 <xliff:g id="DISCLOSURE_COUNT">%1$d</xliff:g> 次;記錄區間為 <xliff:g id="DISCLOSURE_WINDOW_START_TIME">%2$tr</xliff:g>至<xliff:g id="DISCLOSURE_WINDOW_END_TIME">%3$tr</xliff:g>。"</string> + <string name="scNullCipherIssueEncryptedTitle" msgid="8426373579673205292">"已連線至加密的 <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueEncryptedSummary" msgid="6437468449554283998">"你現已連線至較安全的流動網絡。"</string> + <string name="scNullCipherIssueNonEncryptedTitle" msgid="2069674849204163569">"已連線至未加密的 <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string> + <string name="scNullCipherIssueNonEncryptedSummary" msgid="3577092996366374833">"你已連線至未加密的流動網絡。通話、訊息和資料會容易被攔截。"</string> + <string name="scNullCipherIssueActionSettings" msgid="8378372959891478470">"流動網絡安全性設定"</string> <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"瞭解詳情"</string> <string name="fcComplete" msgid="1080909484660507044">"功能碼輸入完成。"</string> <string name="fcError" msgid="5325116502080221346">"連線問題或功能碼無效。"</string> @@ -553,8 +553,8 @@ <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"允許應用程式使用手機的紅外線傳送器。"</string> <string name="permlab_setWallpaper" msgid="6959514622698794511">"設定桌布"</string> <string name="permdesc_setWallpaper" msgid="2973996714129021397">"允許應用程式設定系統桌布。"</string> - <string name="permlab_accessHiddenProfile" msgid="8607094418491556823">"存取隱藏的設定檔"</string> - <string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"允許應用程式存取隱藏的設定檔。"</string> + <string name="permlab_accessHiddenProfile" msgid="8607094418491556823">"存取已隱藏的設定檔"</string> + <string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"允許應用程式存取已隱藏的設定檔。"</string> <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"調整桌布大小"</string> <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"允許應用程式設定有關系統桌布大小的提示。"</string> <string name="permlab_setTimeZone" msgid="7922618798611542432">"設定時區"</string> @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"驗證咗指紋"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"面孔已經驗證"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"面孔已經驗證,請㩒一下 [確認]"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"無法使用指紋軟件。"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"無法設定指紋"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"指紋設定逾時,請再試一次。"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"指紋操作已取消。"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"使用者已取消指紋操作。"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"嘗試次數過多,請改用螢幕鎖定功能。"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"嘗試次數過多,請改用螢幕鎖定功能。"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"無法處理指紋,請再試一次。"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未註冊任何指紋"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"無法使用指紋感應器。請諮詢維修服務供應商"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"此裝置沒有指紋感應器"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"已按下開關按鈕"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string> @@ -823,8 +829,8 @@ <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"允許應用程式以大於 200 Hz 的頻率對感應器資料進行取樣"</string> <string name="permlab_updatePackagesWithoutUserAction" msgid="3363272609642618551">"更新應用程式,無需使用者操作"</string> <string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"允許擁有者更新先前安裝的應用程式,無需使用者操作"</string> - <string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"更新 E2EE 聯絡人金鑰的驗證狀態,這些金鑰為其他應用程式所有"</string> - <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"允許應用程式更新 E2EE 聯絡人金鑰的驗證狀態,這些金鑰為其他應用程式所有"</string> + <string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"更新其他應用程式擁有的點對點加密聯絡人密鑰的驗證狀態"</string> + <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"允許應用程式更新其他應用程式擁有的點對點加密聯絡人密鑰的驗證狀態"</string> <string name="policylab_limitPassword" msgid="4851829918814422199">"設定密碼規則"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"控制螢幕鎖定密碼和 PIN 所允許的長度和字元。"</string> <string name="policylab_watchLogin" msgid="7599669460083719504">"監控螢幕解鎖嘗試次數"</string> @@ -2386,8 +2392,8 @@ <string name="profile_label_test" msgid="9168641926186071947">"測試"</string> <string name="profile_label_communal" msgid="8743921499944800427">"共用"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <string name="satellite_notification_title" msgid="4026338973463121526">"已自動連上衛星"</string> - <string name="satellite_notification_summary" msgid="5207364139430767162">"你可以收發訊息,沒有行動/Wi-Fi 網路也無妨"</string> - <string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」應用程式"</string> + <string name="satellite_notification_title" msgid="4026338973463121526">"已自動連線至衛星"</string> + <string name="satellite_notification_summary" msgid="5207364139430767162">"你可在沒有流動/Wi-Fi 網絡的情況下收發訊息"</string> + <string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index ba257da04279..ff31b74fbea2 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"指紋驗證成功"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"臉孔驗證成功"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"臉孔驗證成功,請按下 [確認] 按鈕"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"指紋硬體無法使用。"</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"無法設定指紋"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"指紋設定逾時,請再試一次。"</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"指紋作業已取消。"</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"使用者已取消指紋驗證作業。"</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"嘗試次數過多,請改用螢幕鎖定功能。"</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"嘗試次數過多,請改用螢幕鎖定功能。"</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"無法處理指紋,請再試一次。"</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未登錄任何指紋。"</string> - <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string> - <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string> - <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"指紋感應器無法使用,請洽詢維修供應商"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"這個裝置沒有指紋感應器"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"已按下電源鍵"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 04c60cb5c1b8..5112da966e7f 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -666,18 +666,24 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"Izigxivizo zeminwe zigunyaziwe"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ubuso bufakazelwe ubuqiniso"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ukuqinisekiswa kobuso, sicela ucindezele okuthi qinisekisa"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Izingxenyekazi zekhompuyutha zezigxivizo zeminwe azitholakali."</string> + <!-- no translation found for fingerprint_error_hw_not_available (7755729484334001137) --> + <skip /> <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Ayikwazi ukusetha izigxivizo zeminwe"</string> <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Ukusethwa kwesigxivizo somunwe kuphelelwe yisikhathi Zama futhi."</string> - <string name="fingerprint_error_canceled" msgid="540026881380070750">"Ukusebenza kwezigxivizo zeminwe kukhanseliwe."</string> - <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Umsebenzi wezigxivizo zomunwe ukhanselwe umsebenzisi."</string> + <!-- no translation found for fingerprint_error_canceled (5541771463159727513) --> + <skip /> + <!-- no translation found for fingerprint_error_user_canceled (2017941773466506863) --> + <skip /> <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Imizamo eminingi kakhulu. Sebenzisa ukukhiya isikrini kunalokho."</string> <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Imizamo eminingi kakhulu. Sebenzisa ukukhiya isikrini kunalokho."</string> <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Ayikwazi ukucubungula isigxivizo somunwe. Zama futhi."</string> - <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Azikho izigxivizo zeminwe ezibhalisiwe."</string> - <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_error_bad_calibration" msgid="4385512597740168120">"Ayikwazi ukusebenzisa inzwa yesigxivizo somunwe. Vakashela umhlinzeki wokulungisa"</string> + <!-- no translation found for fingerprint_error_no_fingerprints (3144806556204061862) --> + <skip /> + <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Le divayisi ayinayo inzwa yezigxivizo zeminwe"</string> + <!-- no translation found for fingerprint_error_security_update_required (8440349108169661934) --> + <skip /> + <!-- no translation found for fingerprint_error_bad_calibration (6770614925736183528) --> + <skip /> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Inkinobho yamandla icindezelwe"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sebenzisa izigxivizo zeminwe"</string> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 4ee03deab6c2..c1fd61948e68 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2514,6 +2514,13 @@ <!-- The icon is shown unless the launching app specified SPLASH_SCREEN_STYLE_EMPTY --> <enum name="icon_preferred" value="1" /> </attr> + <!-- Offer Window the ability to opt out the UI Toolkit discrete variable refresh rate. + This feature allows device to adjust refresh rate as needed and + can be useful for power saving. + Set to false to reduce the frame rate optimizations on devices with + variable refresh rate screens. + The default is true. --> + <attr name="windowIsFrameRatePowerSavingsBalanced" format="boolean"/> <!-- Flag indicating whether this window would opt-out the edge-to-edge enforcement. @@ -5891,6 +5898,17 @@ use glyph bound's as a source of text width. --> <!-- @FlaggedApi("com.android.text.flags.use_bounds_for_width") --> <attr name="useBoundsForWidth" format="boolean" /> + + + <!-- Whether to shift the drawing offset for prevent clipping start drawing offset. + This value is ignored when the useBoundsForWidth attribute is false. + + If this value is false, the TextView draws text from the zero X coordinate. This is + useful for aligning multiple TextViews vertically. + If this value is true, the TextView shift the drawing offset not to clip the + stroke in the region where the X coordinate is negative. --> + <!-- @FlaggedApi("com.android.text.flags.use_bounds_for_width") --> + <attr name="shiftDrawingOffsetForStartOverhang" format="boolean" /> <!-- Whether to use the locale preferred line height for the minimum line height. This flag is useful for preventing jitter of entering letters into empty EditText. diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 734ff8db4944..b2e0be7c2201 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1919,6 +1919,12 @@ try to load its code when launching components. The default is true for normal behavior. --> <attr name="hasCode" format="boolean" /> + <!-- Specifies if activities can be launched on top of this application by activities from + other applications in the same task. If set to false, activity launches which would + replace this application with another when in the user's view will be blocked. + The default is true. --> + <!-- @FlaggedApi("android.security.asm_restrictions_enabled") --> + <attr name="allowCrossUidActivitySwitchFromBelow" format="boolean" /> <attr name="persistent" /> <attr name="persistentWhenFeatureAvailable" /> <attr name="requiredForAllUsers" /> diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml index dcb6bb0cd743..c797210345a2 100644 --- a/core/res/res/values/public-staging.xml +++ b/core/res/res/values/public-staging.xml @@ -159,6 +159,14 @@ <public name="contentSensitivity" /> <!-- @FlaggedApi("android.view.inputmethod.connectionless_handwriting") --> <public name="supportsConnectionlessStylusHandwriting" /> + <!-- @FlaggedApi("android.nfc.Flags.FLAG_OBSERVE_MODE") --> + <public name="defaultToObserveMode"/> + <!-- @FlaggedApi("android.security.asm_restrictions_enabled") --> + <public name="allowCrossUidActivitySwitchFromBelow"/> + <!-- @FlaggedApi("com.android.text.flags.use_bounds_for_width") --> + <public name="shiftDrawingOffsetForStartOverhang" /> + <!-- @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") --> + <public name="windowIsFrameRatePowerSavingsBalanced"/> </staging-public-group> <staging-public-group type="id" first-id="0x01bc0000"> diff --git a/core/tests/BroadcastRadioTests/TEST_MAPPING b/core/tests/BroadcastRadioTests/TEST_MAPPING index b085a27b25b8..563706374bf2 100644 --- a/core/tests/BroadcastRadioTests/TEST_MAPPING +++ b/core/tests/BroadcastRadioTests/TEST_MAPPING @@ -1,5 +1,5 @@ { - "postsubmit": [ + "presubmit": [ { "name": "BroadcastRadioTests" } diff --git a/core/tests/coretests/res/values/styles.xml b/core/tests/coretests/res/values/styles.xml index 32eebb35e0c3..78cd1e1e47e8 100644 --- a/core/tests/coretests/res/values/styles.xml +++ b/core/tests/coretests/res/values/styles.xml @@ -55,4 +55,10 @@ <style name="ViewDefaultBackground"> <item name="android:background">#00000000</item> </style> + <style name="IsFrameRatePowerSavingsBalancedDisabled"> + <item name="android:windowIsFrameRatePowerSavingsBalanced">false</item> + </style> + <style name="IsFrameRatePowerSavingsBalancedEnabled"> + <item name="android:windowIsFrameRatePowerSavingsBalanced">true</item> + </style> </resources> diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java index 2327b20bada6..48ef7e6f11a8 100644 --- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java +++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java @@ -40,6 +40,7 @@ import android.app.ActivityThread.ActivityClientRecord; import android.app.Application; import android.app.IApplicationThread; import android.app.PictureInPictureParams; +import android.app.PictureInPictureUiState; import android.app.ResourcesManager; import android.app.servertransaction.ActivityConfigurationChangeItem; import android.app.servertransaction.ActivityLifecycleItem; @@ -706,6 +707,9 @@ public class ActivityThreadTest { final TestActivity activity = mActivityTestRule.launchActivity(startIntent); final ActivityThread activityThread = activity.getActivityThread(); final ActivityClientRecord r = getActivityClientRecord(activity); + if (android.app.Flags.enablePipUiStateCallbackOnEntering()) { + activity.mPipUiStateLatch = new CountDownLatch(1); + } InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { activityThread.handlePictureInPictureRequested(r); @@ -940,6 +944,11 @@ public class ActivityThreadTest { * latch reaches 0. */ volatile CountDownLatch mConfigLatch; + /** + * A latch used to notify tests that we're about to wait for the + * onPictureInPictureUiStateChanged callback. + */ + volatile CountDownLatch mPipUiStateLatch; @Override protected void onCreate(Bundle savedInstanceState) { @@ -974,6 +983,14 @@ public class ActivityThreadTest { if (getIntent().getBooleanExtra(PIP_REQUESTED_OVERRIDE_ENTER, false)) { enterPictureInPictureMode(new PictureInPictureParams.Builder().build()); mPipEntered = true; + // Await for onPictureInPictureUiStateChanged callback if applicable + if (mPipUiStateLatch != null) { + try { + mPipUiStateLatch.await(TIMEOUT_SEC, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } + } return true; } else if (getIntent().getBooleanExtra(PIP_REQUESTED_OVERRIDE_SKIP, false)) { mPipEnterSkipped = true; @@ -982,6 +999,13 @@ public class ActivityThreadTest { return super.onPictureInPictureRequested(); } + @Override + public void onPictureInPictureUiStateChanged(PictureInPictureUiState pipState) { + if (mPipUiStateLatch != null && pipState.isEnteringPip()) { + mPipUiStateLatch.countDown(); + } + } + boolean pipRequested() { return mPipRequested; } diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java index 0657e4b9c619..038c00e3823c 100644 --- a/core/tests/coretests/src/android/view/ViewRootImplTest.java +++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java @@ -660,10 +660,22 @@ public class ViewRootImplTest { public void votePreferredFrameRate_voteFrameRateCategory_aggregate() { View view = new View(sContext); attachViewToWindow(view); + ViewRootImpl viewRootImpl = view.getViewRootImpl(); sInstrumentation.runOnMainSync(() -> { - ViewRootImpl viewRootImpl = view.getViewRootImpl(); assertEquals(viewRootImpl.getPreferredFrameRateCategory(), FRAME_RATE_CATEGORY_NO_PREFERENCE); + }); + + // reset the frame rate category counts + for (int i = 0; i < 5; i++) { + sInstrumentation.runOnMainSync(() -> { + view.setRequestedFrameRate(view.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE); + view.invalidate(); + }); + sInstrumentation.waitForIdleSync(); + } + + sInstrumentation.runOnMainSync(() -> { viewRootImpl.votePreferredFrameRateCategory(FRAME_RATE_CATEGORY_LOW); assertEquals(viewRootImpl.getPreferredFrameRateCategory(), FRAME_RATE_CATEGORY_LOW); viewRootImpl.votePreferredFrameRateCategory(FRAME_RATE_CATEGORY_NORMAL); @@ -699,6 +711,8 @@ public class ViewRootImplTest { viewRootImpl.votePreferredFrameRate(24); assertEquals(viewRootImpl.getPreferredFrameRate(), 24, 0.1); viewRootImpl.votePreferredFrameRate(30); + assertEquals(viewRootImpl.getPreferredFrameRate(), 30, 0.1); + viewRootImpl.votePreferredFrameRate(60); assertEquals(viewRootImpl.getPreferredFrameRate(), 60, 0.1); viewRootImpl.votePreferredFrameRate(120); assertEquals(viewRootImpl.getPreferredFrameRate(), 120, 0.1); @@ -721,6 +735,18 @@ public class ViewRootImplTest { sInstrumentation.runOnMainSync(() -> { assertEquals(viewRootImpl.getPreferredFrameRateCategory(), FRAME_RATE_CATEGORY_NO_PREFERENCE); + }); + + // reset the frame rate category counts + for (int i = 0; i < 5; i++) { + sInstrumentation.runOnMainSync(() -> { + view.setRequestedFrameRate(view.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE); + view.invalidate(); + }); + sInstrumentation.waitForIdleSync(); + } + + sInstrumentation.runOnMainSync(() -> { view.setRequestedFrameRate(view.REQUESTED_FRAME_RATE_CATEGORY_LOW); view.invalidate(); assertEquals(viewRootImpl.getPreferredFrameRateCategory(), FRAME_RATE_CATEGORY_LOW); @@ -847,7 +873,18 @@ public class ViewRootImplTest { assertEquals(viewRootImpl.getPreferredFrameRateCategory(), FRAME_RATE_CATEGORY_NO_PREFERENCE); assertEquals(viewRootImpl.getPreferredFrameRate(), frameRate, 0.1); + }); + + // reset the frame rate category counts + for (int i = 0; i < 5; i++) { + sInstrumentation.runOnMainSync(() -> { + view.setRequestedFrameRate(view.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE); + view.invalidate(); + }); + sInstrumentation.waitForIdleSync(); + } + sInstrumentation.runOnMainSync(() -> { view.setRequestedFrameRate(view.REQUESTED_FRAME_RATE_CATEGORY_LOW); view.invalidate(); assertEquals(viewRootImpl.getPreferredFrameRateCategory(), FRAME_RATE_CATEGORY_LOW); @@ -882,33 +919,56 @@ public class ViewRootImplTest { ViewRootImpl viewRootImpl = view.getViewRootImpl(); - // Frequent update + // In transistion from frequent update to infrequent update + Thread.sleep(delay); sInstrumentation.runOnMainSync(() -> { - assertEquals(viewRootImpl.getPreferredFrameRateCategory(), - FRAME_RATE_CATEGORY_NO_PREFERENCE); - view.invalidate(); - assertEquals(viewRootImpl.getPreferredFrameRateCategory(), FRAME_RATE_CATEGORY_HIGH); - view.invalidate(); - assertEquals(viewRootImpl.getPreferredFrameRateCategory(), FRAME_RATE_CATEGORY_HIGH); view.invalidate(); assertEquals(viewRootImpl.getPreferredFrameRateCategory(), FRAME_RATE_CATEGORY_HIGH); }); + // reset the frame rate category counts + for (int i = 0; i < 5; i++) { + sInstrumentation.runOnMainSync(() -> { + view.setRequestedFrameRate(view.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE); + view.invalidate(); + }); + sInstrumentation.waitForIdleSync(); + } + // In transistion from frequent update to infrequent update Thread.sleep(delay); sInstrumentation.runOnMainSync(() -> { + view.setRequestedFrameRate(view.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE); view.invalidate(); - assertEquals(viewRootImpl.getPreferredFrameRateCategory(), FRAME_RATE_CATEGORY_HIGH); + assertEquals(viewRootImpl.getPreferredFrameRateCategory(), + FRAME_RATE_CATEGORY_NO_PREFERENCE); }); // Infrequent update Thread.sleep(delay); sInstrumentation.runOnMainSync(() -> { + view.setRequestedFrameRate(view.REQUESTED_FRAME_RATE_CATEGORY_DEFAULT); view.invalidate(); assertEquals(viewRootImpl.getPreferredFrameRateCategory(), FRAME_RATE_CATEGORY_NORMAL); }); } + /** + * Test the IsFrameRatePowerSavingsBalanced values are properly set + */ + @UiThreadTest + @Test + @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public void votePreferredFrameRate_isFrameRatePowerSavingsBalanced() { + ViewRootImpl viewRootImpl = new ViewRootImpl(sContext, + sContext.getDisplayNoVerify()); + assertEquals(viewRootImpl.isFrameRatePowerSavingsBalanced(), true); + viewRootImpl.setFrameRatePowerSavingsBalanced(false); + assertEquals(viewRootImpl.isFrameRatePowerSavingsBalanced(), false); + viewRootImpl.setFrameRatePowerSavingsBalanced(true); + assertEquals(viewRootImpl.isFrameRatePowerSavingsBalanced(), true); + } + @Test public void forceInvertOffDarkThemeOff_forceDarkModeDisabled() { mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR); diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java index 3d5494de05ad..15c90474c017 100644 --- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java +++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java @@ -16,8 +16,6 @@ package android.widget; -import static android.appwidget.flags.Flags.drawDataParcel; - import static com.android.internal.R.id.pending_intent_tag; import static org.junit.Assert.assertArrayEquals; @@ -65,7 +63,6 @@ import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; @@ -417,25 +414,6 @@ public class RemoteViewsTest { assertNotNull(view.findViewById(R.id.light_background_text)); } - @Test - public void remoteCanvasCanAccessDrawInstructions() { - if (!drawDataParcel()) { - return; - } - final byte[] bytes = new byte[] {'h', 'e', 'l', 'l', 'o'}; - final RemoteViews.DrawInstructions drawInstructions = - new RemoteViews.DrawInstructions.Builder(Collections.singletonList(bytes)).build(); - final RemoteViews rv = new RemoteViews(drawInstructions); - final PendingIntent pi = PendingIntent.getActivity(mContext, 0, - new Intent(Intent.ACTION_VIEW), PendingIntent.FLAG_IMMUTABLE); - final Intent i = new Intent().putExtra("TEST", "Success"); - final int viewId = 1; - rv.setPendingIntentTemplate(viewId, pi); - rv.setOnClickFillInIntent(viewId, i); - final View view = rv.apply(mContext, mContainer); - assertEquals(drawInstructions, view.getTag()); - } - private RemoteViews createViewChained(int depth, String... texts) { RemoteViews result = new RemoteViews(mPackage, R.layout.remote_view_host); diff --git a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java index 3df3b9d2c555..b9841ff997e7 100644 --- a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java +++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java @@ -21,17 +21,28 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; +import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY; import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import android.app.Instrumentation; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.os.Binder; import android.platform.test.annotations.Presubmit; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.view.ActionMode; import android.view.ContextThemeWrapper; +import android.view.ViewRootImpl; +import android.view.WindowManager; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -40,6 +51,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.frameworks.coretests.R; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -54,6 +66,12 @@ public final class PhoneWindowTest { private PhoneWindow mPhoneWindow; private Context mContext; + private static Instrumentation sInstrumentation = + InstrumentationRegistry.getInstrumentation(); + + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + @Before public void setUp() throws Exception { mContext = InstrumentationRegistry.getContext(); @@ -154,6 +172,48 @@ public final class PhoneWindowTest { assertThat(colorDrawable.getColor(), is(Color.BLUE)); } + @Test + @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public void testWindowFrameRateHint_disabled() { + createPhoneWindowWithTheme(R.style.IsFrameRatePowerSavingsBalancedDisabled); + installDecor(); + + DecorView decorView = (DecorView) mPhoneWindow.getDecorView(); + + WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY); + wmlp.token = new Binder(); // Set a fake token to bypass 'is your activity running' check + + sInstrumentation.runOnMainSync(() -> { + WindowManager wm = mContext.getSystemService(WindowManager.class); + wm.addView(decorView, wmlp); + }); + sInstrumentation.waitForIdleSync(); + + ViewRootImpl viewRootImpl = decorView.getViewRootImpl(); + assertFalse(viewRootImpl.isFrameRatePowerSavingsBalanced()); + } + + @Test + @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) + public void testWindowFrameRateHint_enabled() { + createPhoneWindowWithTheme(R.style.IsFrameRatePowerSavingsBalancedEnabled); + installDecor(); + + DecorView decorView = (DecorView) mPhoneWindow.getDecorView(); + + WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY); + wmlp.token = new Binder(); // Set a fake token to bypass 'is your activity running' check + + sInstrumentation.runOnMainSync(() -> { + WindowManager wm = mContext.getSystemService(WindowManager.class); + wm.addView(decorView, wmlp); + }); + sInstrumentation.waitForIdleSync(); + + ViewRootImpl viewRootImpl = decorView.getViewRootImpl(); + assertTrue(viewRootImpl.isFrameRatePowerSavingsBalanced()); + } + private void createPhoneWindowWithTheme(int theme) { mPhoneWindow = new PhoneWindow(new ContextThemeWrapper(mContext, theme)); } diff --git a/data/etc/com.android.intentresolver.xml b/data/etc/com.android.intentresolver.xml index af6492609157..afd4f7cdba53 100644 --- a/data/etc/com.android.intentresolver.xml +++ b/data/etc/com.android.intentresolver.xml @@ -17,8 +17,10 @@ <permissions> <privapp-permissions package="com.android.intentresolver"> <permission name="android.permission.INTERACT_ACROSS_USERS"/> + <permission name="android.permission.LOG_COMPAT_CHANGE"/> <permission name="android.permission.MANAGE_USERS"/> <permission name="android.permission.PACKAGE_USAGE_STATS"/> <permission name="android.permission.QUERY_CLONED_APPS"/> + <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG"/> </privapp-permissions> </permissions> diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index c8cbb9800626..42e3387e3eb5 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -2077,6 +2077,12 @@ "group": "WM_DEBUG_LOCKTASK", "at": "com\/android\/server\/wm\/LockTaskController.java" }, + "-315778658": { + "message": "transferTouchGesture failed because args transferFromToken or transferToToken is null", + "level": "ERROR", + "group": "WM_DEBUG_EMBEDDED_WINDOWS", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, "-312353598": { "message": "Executing finish of activity: %s", "level": "VERBOSE", @@ -2293,12 +2299,6 @@ "group": "WM_DEBUG_ANIM", "at": "com\/android\/server\/wm\/WindowState.java" }, - "-90559682": { - "message": "Config is skipping already pausing %s", - "level": "VERBOSE", - "group": "WM_DEBUG_CONFIGURATION", - "at": "com\/android\/server\/wm\/ActivityRecord.java" - }, "-87705714": { "message": "findFocusedWindow: focusedApp=null using new focus @ %s", "level": "VERBOSE", @@ -3547,12 +3547,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, - "1011462000": { - "message": "Re-launching after pause: %s", - "level": "VERBOSE", - "group": "WM_DEBUG_STATES", - "at": "com\/android\/server\/wm\/TaskFragment.java" - }, "1015746067": { "message": "Display id=%d is ignoring orientation request for %d, return %d following a per-app override for %s", "level": "VERBOSE", diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index b33a5d2dcef8..f3bb21719890 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -1128,6 +1128,30 @@ public class Canvas extends BaseCanvas { return false; } + /** + * Intersect the current clip with the specified shader. + * The shader will be treated as an alpha mask, taking the intersection of the two. + * + * @param shader The shader to intersect with the current clip + */ + @FlaggedApi(Flags.FLAG_CLIP_SHADER) + public void clipShader(@NonNull Shader shader) { + nClipShader(mNativeCanvasWrapper, shader.getNativeInstance(), + Region.Op.INTERSECT.nativeInt); + } + + /** + * Set the clip to the difference of the current clip and the shader. + * The shader will be treated as an alpha mask, taking the difference of the two. + * + * @param shader The shader to intersect with the current clip + */ + @FlaggedApi(Flags.FLAG_CLIP_SHADER) + public void clipOutShader(@NonNull Shader shader) { + nClipShader(mNativeCanvasWrapper, shader.getNativeInstance(), + Region.Op.DIFFERENCE.nativeInt); + } + public @Nullable DrawFilter getDrawFilter() { return mDrawFilter; } @@ -1472,6 +1496,8 @@ public class Canvas extends BaseCanvas { @CriticalNative private static native boolean nClipPath(long nativeCanvas, long nativePath, int regionOp); @CriticalNative + private static native void nClipShader(long nativeCanvas, long nativeShader, int regionOp); + @CriticalNative private static native void nSetDrawFilter(long nativeCanvas, long nativeFilter); @CriticalNative private static native void nGetMatrix(long nativeCanvas, long nativeMatrix); diff --git a/graphics/java/android/graphics/pdf/PdfEditor.java b/graphics/java/android/graphics/pdf/PdfEditor.java index 3cd709ea10e5..69e19824da26 100644 --- a/graphics/java/android/graphics/pdf/PdfEditor.java +++ b/graphics/java/android/graphics/pdf/PdfEditor.java @@ -25,7 +25,9 @@ import android.os.ParcelFileDescriptor; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; + import dalvik.system.CloseGuard; + import libcore.io.IoUtils; import java.io.IOException; @@ -37,6 +39,12 @@ import java.io.IOException; */ public final class PdfEditor { + /** + * Any call the native pdfium code has to be single threaded as the library does not support + * parallel use. + */ + private static final Object sPdfiumLock = new Object(); + private final CloseGuard mCloseGuard = CloseGuard.get(); private long mNativeDocument; @@ -79,7 +87,7 @@ public final class PdfEditor { } mInput = input; - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { mNativeDocument = nativeOpen(mInput.getFd(), size); try { mPageCount = nativeGetPageCount(mNativeDocument); @@ -112,7 +120,7 @@ public final class PdfEditor { throwIfClosed(); throwIfPageNotInDocument(pageIndex); - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { mPageCount = nativeRemovePage(mNativeDocument, pageIndex); } } @@ -138,12 +146,12 @@ public final class PdfEditor { Point size = new Point(); getPageSize(pageIndex, size); - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.ni(), 0, 0, size.x, size.y); } } else { - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.ni(), clip.left, clip.top, clip.right, clip.bottom); } @@ -161,7 +169,7 @@ public final class PdfEditor { throwIfOutSizeNull(outSize); throwIfPageNotInDocument(pageIndex); - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { nativeGetPageSize(mNativeDocument, pageIndex, outSize); } } @@ -177,7 +185,7 @@ public final class PdfEditor { throwIfOutMediaBoxNull(outMediaBox); throwIfPageNotInDocument(pageIndex); - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { return nativeGetPageMediaBox(mNativeDocument, pageIndex, outMediaBox); } } @@ -193,7 +201,7 @@ public final class PdfEditor { throwIfMediaBoxNull(mediaBox); throwIfPageNotInDocument(pageIndex); - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { nativeSetPageMediaBox(mNativeDocument, pageIndex, mediaBox); } } @@ -209,7 +217,7 @@ public final class PdfEditor { throwIfOutCropBoxNull(outCropBox); throwIfPageNotInDocument(pageIndex); - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { return nativeGetPageCropBox(mNativeDocument, pageIndex, outCropBox); } } @@ -225,7 +233,7 @@ public final class PdfEditor { throwIfCropBoxNull(cropBox); throwIfPageNotInDocument(pageIndex); - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { nativeSetPageCropBox(mNativeDocument, pageIndex, cropBox); } } @@ -238,7 +246,7 @@ public final class PdfEditor { public boolean shouldScaleForPrinting() { throwIfClosed(); - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { return nativeScaleForPrinting(mNativeDocument); } } @@ -255,7 +263,7 @@ public final class PdfEditor { try { throwIfClosed(); - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { nativeWrite(mNativeDocument, output.getFd()); } } finally { @@ -287,7 +295,7 @@ public final class PdfEditor { private void doClose() { if (mNativeDocument != 0) { - synchronized (PdfRenderer.sPdfiumLock) { + synchronized (sPdfiumLock) { nativeClose(mNativeDocument); } mNativeDocument = 0; diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java deleted file mode 100644 index 4666963b5dd4..000000000000 --- a/graphics/java/android/graphics/pdf/PdfRenderer.java +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (C) 2014 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.graphics.pdf; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.compat.annotation.UnsupportedAppUsage; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.Matrix; -import android.graphics.Point; -import android.graphics.Rect; -import android.os.Build; -import android.os.ParcelFileDescriptor; -import android.system.ErrnoException; -import android.system.Os; -import android.system.OsConstants; - -import com.android.internal.util.Preconditions; - -import dalvik.system.CloseGuard; - -import libcore.io.IoUtils; - -import java.io.IOException; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * <p> - * This class enables rendering a PDF document. This class is not thread safe. - * </p> - * <p> - * If you want to render a PDF, you create a renderer and for every page you want - * to render, you open the page, render it, and close the page. After you are done - * with rendering, you close the renderer. After the renderer is closed it should not - * be used anymore. Note that the pages are rendered one by one, i.e. you can have - * only a single page opened at any given time. - * </p> - * <p> - * A typical use of the APIs to render a PDF looks like this: - * </p> - * <pre> - * // create a new renderer - * PdfRenderer renderer = new PdfRenderer(getSeekableFileDescriptor()); - * - * // let us just render all pages - * final int pageCount = renderer.getPageCount(); - * for (int i = 0; i < pageCount; i++) { - * Page page = renderer.openPage(i); - * - * // say we render for showing on the screen - * page.render(mBitmap, null, null, Page.RENDER_MODE_FOR_DISPLAY); - * - * // do stuff with the bitmap - * - * // close the page - * page.close(); - * } - * - * // close the renderer - * renderer.close(); - * </pre> - * - * <h3>Print preview and print output</h3> - * <p> - * If you are using this class to rasterize a PDF for printing or show a print - * preview, it is recommended that you respect the following contract in order - * to provide a consistent user experience when seeing a preview and printing, - * i.e. the user sees a preview that is the same as the printout. - * </p> - * <ul> - * <li> - * Respect the property whether the document would like to be scaled for printing - * as per {@link #shouldScaleForPrinting()}. - * </li> - * <li> - * When scaling a document for printing the aspect ratio should be preserved. - * </li> - * <li> - * Do not inset the content with any margins from the {@link android.print.PrintAttributes} - * as the application is responsible to render it such that the margins are respected. - * </li> - * <li> - * If document page size is greater than the printed media size the content should - * be anchored to the upper left corner of the page for left-to-right locales and - * top right corner for right-to-left locales. - * </li> - * </ul> - * - * @see #close() - */ -public final class PdfRenderer implements AutoCloseable { - /** - * Any call the native pdfium code has to be single threaded as the library does not support - * parallel use. - */ - final static Object sPdfiumLock = new Object(); - - private final CloseGuard mCloseGuard = CloseGuard.get(); - - private final Point mTempPoint = new Point(); - - private long mNativeDocument; - - private final int mPageCount; - - private ParcelFileDescriptor mInput; - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - private Page mCurrentPage; - - /** @hide */ - @IntDef({ - Page.RENDER_MODE_FOR_DISPLAY, - Page.RENDER_MODE_FOR_PRINT - }) - @Retention(RetentionPolicy.SOURCE) - public @interface RenderMode {} - - /** - * Creates a new instance. - * <p> - * <strong>Note:</strong> The provided file descriptor must be <strong>seekable</strong>, - * i.e. its data being randomly accessed, e.g. pointing to a file. - * </p> - * <p> - * <strong>Note:</strong> This class takes ownership of the passed in file descriptor - * and is responsible for closing it when the renderer is closed. - * </p> - * <p> - * If the file is from an untrusted source it is recommended to run the renderer in a separate, - * isolated process with minimal permissions to limit the impact of security exploits. - * </p> - * - * @param input Seekable file descriptor to read from. - * - * @throws java.io.IOException If an error occurs while reading the file. - * @throws java.lang.SecurityException If the file requires a password or - * the security scheme is not supported. - */ - public PdfRenderer(@NonNull ParcelFileDescriptor input) throws IOException { - if (input == null) { - throw new NullPointerException("input cannot be null"); - } - - final long size; - try { - Os.lseek(input.getFileDescriptor(), 0, OsConstants.SEEK_SET); - size = Os.fstat(input.getFileDescriptor()).st_size; - } catch (ErrnoException ee) { - throw new IllegalArgumentException("file descriptor not seekable"); - } - mInput = input; - - synchronized (sPdfiumLock) { - mNativeDocument = nativeCreate(mInput.getFd(), size); - try { - mPageCount = nativeGetPageCount(mNativeDocument); - } catch (Throwable t) { - nativeClose(mNativeDocument); - mNativeDocument = 0; - throw t; - } - } - - mCloseGuard.open("close"); - } - - /** - * Closes this renderer. You should not use this instance - * after this method is called. - */ - public void close() { - throwIfClosed(); - throwIfPageOpened(); - doClose(); - } - - /** - * Gets the number of pages in the document. - * - * @return The page count. - */ - public int getPageCount() { - throwIfClosed(); - return mPageCount; - } - - /** - * Gets whether the document prefers to be scaled for printing. - * You should take this info account if the document is rendered - * for printing and the target media size differs from the page - * size. - * - * @return If to scale the document. - */ - public boolean shouldScaleForPrinting() { - throwIfClosed(); - - synchronized (sPdfiumLock) { - return nativeScaleForPrinting(mNativeDocument); - } - } - - /** - * Opens a page for rendering. - * - * @param index The page index. - * @return A page that can be rendered. - * - * @see android.graphics.pdf.PdfRenderer.Page#close() PdfRenderer.Page.close() - */ - public Page openPage(int index) { - throwIfClosed(); - throwIfPageOpened(); - throwIfPageNotInDocument(index); - mCurrentPage = new Page(index); - return mCurrentPage; - } - - @Override - protected void finalize() throws Throwable { - try { - if (mCloseGuard != null) { - mCloseGuard.warnIfOpen(); - } - - doClose(); - } finally { - super.finalize(); - } - } - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - private void doClose() { - if (mCurrentPage != null) { - mCurrentPage.close(); - mCurrentPage = null; - } - - if (mNativeDocument != 0) { - synchronized (sPdfiumLock) { - nativeClose(mNativeDocument); - } - mNativeDocument = 0; - } - - if (mInput != null) { - IoUtils.closeQuietly(mInput); - mInput = null; - } - mCloseGuard.close(); - } - - private void throwIfClosed() { - if (mInput == null) { - throw new IllegalStateException("Already closed"); - } - } - - private void throwIfPageOpened() { - if (mCurrentPage != null) { - throw new IllegalStateException("Current page not closed"); - } - } - - private void throwIfPageNotInDocument(int pageIndex) { - if (pageIndex < 0 || pageIndex >= mPageCount) { - throw new IllegalArgumentException("Invalid page index"); - } - } - - /** - * This class represents a PDF document page for rendering. - */ - public final class Page implements AutoCloseable { - - private final CloseGuard mCloseGuard = CloseGuard.get(); - - /** - * Mode to render the content for display on a screen. - */ - public static final int RENDER_MODE_FOR_DISPLAY = 1; - - /** - * Mode to render the content for printing. - */ - public static final int RENDER_MODE_FOR_PRINT = 2; - - private final int mIndex; - private final int mWidth; - private final int mHeight; - - private long mNativePage; - - private Page(int index) { - Point size = mTempPoint; - synchronized (sPdfiumLock) { - mNativePage = nativeOpenPageAndGetSize(mNativeDocument, index, size); - } - mIndex = index; - mWidth = size.x; - mHeight = size.y; - mCloseGuard.open("close"); - } - - /** - * Gets the page index. - * - * @return The index. - */ - public int getIndex() { - return mIndex; - } - - /** - * Gets the page width in points (1/72"). - * - * @return The width in points. - */ - public int getWidth() { - return mWidth; - } - - /** - * Gets the page height in points (1/72"). - * - * @return The height in points. - */ - public int getHeight() { - return mHeight; - } - - /** - * Renders a page to a bitmap. - * <p> - * You may optionally specify a rectangular clip in the bitmap bounds. No rendering - * outside the clip will be performed, hence it is your responsibility to initialize - * the bitmap outside the clip. - * </p> - * <p> - * You may optionally specify a matrix to transform the content from page coordinates - * which are in points (1/72") to bitmap coordinates which are in pixels. If this - * matrix is not provided this method will apply a transformation that will fit the - * whole page to the destination clip if provided or the destination bitmap if no - * clip is provided. - * </p> - * <p> - * The clip and transformation are useful for implementing tile rendering where the - * destination bitmap contains a portion of the image, for example when zooming. - * Another useful application is for printing where the size of the bitmap holding - * the page is too large and a client can render the page in stripes. - * </p> - * <p> - * <strong>Note: </strong> The destination bitmap format must be - * {@link Config#ARGB_8888 ARGB}. - * </p> - * <p> - * <strong>Note: </strong> The optional transformation matrix must be affine as per - * {@link android.graphics.Matrix#isAffine() Matrix.isAffine()}. Hence, you can specify - * rotation, scaling, translation but not a perspective transformation. - * </p> - * - * @param destination Destination bitmap to which to render. - * @param destClip Optional clip in the bitmap bounds. - * @param transform Optional transformation to apply when rendering. - * @param renderMode The render mode. - * - * @see #RENDER_MODE_FOR_DISPLAY - * @see #RENDER_MODE_FOR_PRINT - */ - public void render(@NonNull Bitmap destination, @Nullable Rect destClip, - @Nullable Matrix transform, @RenderMode int renderMode) { - if (mNativePage == 0) { - throw new NullPointerException(); - } - - destination = Preconditions.checkNotNull(destination, "bitmap null"); - - if (destination.getConfig() != Config.ARGB_8888) { - throw new IllegalArgumentException("Unsupported pixel format"); - } - - if (destClip != null) { - if (destClip.left < 0 || destClip.top < 0 - || destClip.right > destination.getWidth() - || destClip.bottom > destination.getHeight()) { - throw new IllegalArgumentException("destBounds not in destination"); - } - } - - if (transform != null && !transform.isAffine()) { - throw new IllegalArgumentException("transform not affine"); - } - - if (renderMode != RENDER_MODE_FOR_PRINT && renderMode != RENDER_MODE_FOR_DISPLAY) { - throw new IllegalArgumentException("Unsupported render mode"); - } - - if (renderMode == RENDER_MODE_FOR_PRINT && renderMode == RENDER_MODE_FOR_DISPLAY) { - throw new IllegalArgumentException("Only single render mode supported"); - } - - final int contentLeft = (destClip != null) ? destClip.left : 0; - final int contentTop = (destClip != null) ? destClip.top : 0; - final int contentRight = (destClip != null) ? destClip.right - : destination.getWidth(); - final int contentBottom = (destClip != null) ? destClip.bottom - : destination.getHeight(); - - // If transform is not set, stretch page to whole clipped area - if (transform == null) { - int clipWidth = contentRight - contentLeft; - int clipHeight = contentBottom - contentTop; - - transform = new Matrix(); - transform.postScale((float)clipWidth / getWidth(), - (float)clipHeight / getHeight()); - transform.postTranslate(contentLeft, contentTop); - } - - // FIXME: This code is planned to be outside the UI rendering module, so it should not - // be able to access native instances from Bitmap, Matrix, etc. - final long transformPtr = transform.ni(); - - synchronized (sPdfiumLock) { - nativeRenderPage(mNativeDocument, mNativePage, destination.getNativeInstance(), - contentLeft, contentTop, contentRight, contentBottom, transformPtr, - renderMode); - } - } - - /** - * Closes this page. - * - * @see android.graphics.pdf.PdfRenderer#openPage(int) - */ - @Override - public void close() { - throwIfClosed(); - doClose(); - } - - @Override - protected void finalize() throws Throwable { - try { - if (mCloseGuard != null) { - mCloseGuard.warnIfOpen(); - } - - doClose(); - } finally { - super.finalize(); - } - } - - private void doClose() { - if (mNativePage != 0) { - synchronized (sPdfiumLock) { - nativeClosePage(mNativePage); - } - mNativePage = 0; - } - - mCloseGuard.close(); - mCurrentPage = null; - } - - private void throwIfClosed() { - if (mNativePage == 0) { - throw new IllegalStateException("Already closed"); - } - } - } - - private static native long nativeCreate(int fd, long size); - private static native void nativeClose(long documentPtr); - private static native int nativeGetPageCount(long documentPtr); - private static native boolean nativeScaleForPrinting(long documentPtr); - private static native void nativeRenderPage(long documentPtr, long pagePtr, long bitmapHandle, - int clipLeft, int clipTop, int clipRight, int clipBottom, long transformPtr, - int renderMode); - private static native long nativeOpenPageAndGetSize(long documentPtr, int pageIndex, - Point outSize); - private static native void nativeClosePage(long pagePtr); -} diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index 90b13cdc79b4..dd6f8455f82a 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Maak toe"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Vou uit"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Instellings"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Gaan by verdeelde skerm in"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Kieslys"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Prent-in-prent-kieslys"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in beeld-in-beeld"</string> diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index 478585aace68..18a4ccf5c16d 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"ዝጋ"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"ዘርጋ"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"ቅንብሮች"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"የተከፈለ ማያ ገጽን አስገባ"</string> <string name="pip_menu_title" msgid="5393619322111827096">"ምናሌ"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"የሥዕል-ላይ-ሥዕል ምናሌ"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> በሥዕል-ላይ-ሥዕል ውስጥ ነው"</string> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index b2a522c89f8c..7ca335e4a655 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"إغلاق"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"توسيع"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"الإعدادات"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"الدخول في وضع تقسيم الشاشة"</string> <string name="pip_menu_title" msgid="5393619322111827096">"القائمة"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"قائمة نافذة ضمن النافذة"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> يظهر في صورة داخل صورة"</string> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index 897c38f66e4b..944c4f25bf2a 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"বন্ধ কৰক"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"বিস্তাৰ কৰক"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"ছেটিং"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"বিভাজিত স্ক্ৰীন ম’ডলৈ যাওক"</string> <string name="pip_menu_title" msgid="5393619322111827096">"মেনু"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"চিত্ৰৰ ভিতৰৰ চিত্ৰ মেনু"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> চিত্ৰৰ ভিতৰৰ চিত্ৰত আছে"</string> diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index 4854e0db7ed5..c320e415d604 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Bağlayın"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Genişləndirin"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Ayarlar"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Bölünmüş ekrana daxil olun"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Şəkildə Şəkil Menyusu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> şəkil içində şəkildədir"</string> diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml index cac4e67b1cfc..19ca4d300b7e 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Zatvori"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Proširi"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Podešavanja"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Uđi na podeljeni ekran"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Meni slike u slici."</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je slika u slici"</string> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index cac76df15910..74ae1d7637d0 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Закрыць"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Разгарнуць"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Налады"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Падзяліць экран"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Меню рэжыму \"Відарыс у відарысе\""</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> з’яўляецца відарысам у відарысе"</string> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index ac9a20806b72..1b753f5359ba 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Затваряне"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Разгъване"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Настройки"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Преминаване към разделен екран"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Меню за режима „Картина в картината“"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> е в режима „Картина в картината“"</string> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index 3b83dcb461ee..2ea22cc1455a 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"বন্ধ করুন"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"বড় করুন"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"সেটিংস"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"\'স্প্লিট স্ক্রিন\' মোড চালু করুন"</string> <string name="pip_menu_title" msgid="5393619322111827096">"মেনু"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"ছবির-মধ্যে-ছবি মেনু"</string> <string name="pip_notification_title" msgid="1347104727641353453">"ছবির-মধ্যে-ছবি তে <xliff:g id="NAME">%s</xliff:g> আছেন"</string> diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index 813d163d07fe..13655b3c5c85 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Zatvori"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Proširi"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Postavke"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Otvori podijeljeni ekran"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Meni načina rada slike u slici"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je u načinu priakza Slika u slici"</string> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index d00c50bb0294..cb897c5b612d 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Tanca"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Desplega"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Configuració"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Entra al mode de pantalla dividida"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menú d\'imatge sobre imatge"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> està en mode d\'imatge sobre imatge"</string> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index 40132e4f67f8..ded2707afd1d 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Zavřít"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Rozbalit"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Nastavení"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Aktivovat rozdělenou obrazovku"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Nabídka"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Nabídka režimu obrazu v obraze"</string> <string name="pip_notification_title" msgid="1347104727641353453">"Aplikace <xliff:g id="NAME">%s</xliff:g> je v režimu obraz v obraze"</string> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index 6e9738dc7398..2bdb29d67447 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Luk"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Udvid"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Indstillinger"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Åbn opdelt skærm"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu for integreret billede"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> vises som integreret billede"</string> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index 5da224d35360..e99d9d0c269a 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Schließen"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Maximieren"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Einstellungen"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Splitscreen aktivieren"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menü „Bild im Bild“"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ist in Bild im Bild"</string> diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index 822b5526c6fd..d8bb740535fc 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Κλείσιμο"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Ανάπτυξη"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Ρυθμίσεις"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Μετάβαση σε διαχωρισμό οθόνης"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Μενού"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Μενού λειτουργίας Picture-in-Picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"Η λειτουργία picture-in-picture είναι ενεργή σε <xliff:g id="NAME">%s</xliff:g>."</string> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index 76464b398f89..5e1b274705dd 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Close"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Expand"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index c0c46cd608ee..2525b321d9d7 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Close"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Expand"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-Picture Menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml index 76464b398f89..5e1b274705dd 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Close"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Expand"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml index 76464b398f89..5e1b274705dd 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Close"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Expand"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-picture menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml index f089938fd9cb..0623bef925e2 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Close"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Expand"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Settings"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Enter split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Picture-in-Picture Menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string> diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index 6bbc1e37671f..9fe77ddf7e28 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Cerrar"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Expandir"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Configuración"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Introducir pantalla dividida"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menú de pantalla en pantalla"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está en modo de Pantalla en pantalla"</string> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index c662ff603dd7..b88f215eb54e 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Cerrar"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Mostrar"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Ajustes"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Introducir pantalla dividida"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menú de imagen en imagen"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está en imagen en imagen"</string> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index ade5e2d18645..529b6d10b3c6 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Sule"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Laiendamine"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Seaded"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Ava jagatud ekraanikuva"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menüü"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menüü Pilt pildis"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> on režiimis Pilt pildis"</string> diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index d6cb66885cf5..7438f4240eae 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Itxi"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Zabaldu"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Ezarpenak"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Sartu pantaila zatituan"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menua"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Pantaila txiki gainjarriaren menua"</string> <string name="pip_notification_title" msgid="1347104727641353453">"Pantaila txiki gainjarrian dago <xliff:g id="NAME">%s</xliff:g>"</string> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index ba0f51cb1490..f7fcb2162603 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"بستن"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"بزرگ کردن"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"تنظیمات"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"ورود به حالت «صفحهٔ دونیمه»"</string> <string name="pip_menu_title" msgid="5393619322111827096">"منو"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"منو تصویر در تصویر"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> درحالت تصویر در تصویر است"</string> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index a53f861e1d18..400107317637 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Sulje"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Laajenna"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Asetukset"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Avaa jaettu näyttö"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Valikko"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Kuva kuvassa ‑valikko"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> on kuva kuvassa ‑tilassa"</string> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index 4563556657af..a883e087cb3b 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Fermer"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Développer"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Paramètres"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Entrer dans l\'écran partagé"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu d\'incrustation d\'image"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> est en mode d\'incrustation d\'image"</string> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index 895757184b23..357ff91df06d 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Fermer"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Développer"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Paramètres"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Accéder à l\'écran partagé"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu \"Picture-in-picture\""</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> est en mode Picture-in-picture"</string> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index 54c864eced47..a62190754129 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Pechar"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Despregar"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Configuración"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Inserir pantalla dividida"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menú de pantalla superposta"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está na pantalla superposta"</string> diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index 2b092795b035..43c178f50d15 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"બંધ કરો"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"વિસ્તૃત કરો"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"સેટિંગ"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"વિભાજિત સ્ક્રીન મોડમાં દાખલ થાઓ"</string> <string name="pip_menu_title" msgid="5393619322111827096">"મેનૂ"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"ચિત્રમાં ચિત્ર મેનૂ"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ચિત્રમાં-ચિત્રની અંદર છે"</string> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index 35b099ac6d38..9f6a57fa0d73 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"बंद करें"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"विस्तार करें"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"सेटिंग"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रीन मोड में जाएं"</string> <string name="pip_menu_title" msgid="5393619322111827096">"मेन्यू"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"पिक्चर में पिक्चर मेन्यू"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> \"पिक्चर में पिक्चर\" के अंदर है"</string> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index f2c3c22414df..4378c5642f5c 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Zatvori"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Proširivanje"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Postavke"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Otvorite podijeljeni zaslon"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Izbornik"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Izbornik slike u slici"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> jest na slici u slici"</string> diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index d94bb29f1d73..e5f199fea647 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Bezárás"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Kibontás"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Beállítások"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Váltás osztott képernyőre"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Kép a képben menü"</string> <string name="pip_notification_title" msgid="1347104727641353453">"A(z) <xliff:g id="NAME">%s</xliff:g> kép a képben funkciót használ"</string> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index f2945c16e50b..e0a5afe13827 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Փակել"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Ընդարձակել"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Կարգավորումներ"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Մտնել տրոհված էկրանի ռեժիմ"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Ընտրացանկ"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"«Նկար նկարի մեջ» ռեժիմի ընտրացանկ"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>-ը «Նկար նկարի մեջ» ռեժիմում է"</string> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index c39b429e489c..802583771852 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Tutup"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Luaskan"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Setelan"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Masuk ke mode layar terpisah"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu Picture-in-Picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> adalah picture-in-picture"</string> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index 630eaa3855c1..cece56ec960f 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Loka"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Stækka"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Stillingar"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Opna skjáskiptingu"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Valmynd"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Valmynd fyrir mynd í mynd"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> er með mynd í mynd"</string> diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index 77893c9e38cf..731db8c12825 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Chiudi"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Espandi"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Impostazioni"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Accedi a schermo diviso"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu Picture in picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> è in Picture in picture"</string> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index 4f28c23ba5df..adf55f3696c3 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"סגירה"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"הרחבה"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"הגדרות"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"כניסה למסך המפוצל"</string> <string name="pip_menu_title" msgid="5393619322111827096">"תפריט"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"תפריט \'תמונה בתוך תמונה\'"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> במצב תמונה בתוך תמונה"</string> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index 60b4d7eb8b4d..35432229dc7b 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"閉じる"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"展開"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"分割画面に切り替え"</string> <string name="pip_menu_title" msgid="5393619322111827096">"メニュー"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"ピクチャー イン ピクチャーのメニュー"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>はピクチャー イン ピクチャーで表示中です"</string> diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index 28d2257786a7..1e6e657b5cf8 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"დახურვა"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"გაშლა"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"პარამეტრები"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"გაყოფილ ეკრანში შესვლა"</string> <string name="pip_menu_title" msgid="5393619322111827096">"მენიუ"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"„ეკრანი ეკრანში“ რეჟიმის მენიუ"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> იყენებს რეჟიმს „ეკრანი ეკრანში“"</string> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index 441df8d70e95..6d9ff26132ea 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Жабу"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Жаю"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Параметрлер"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Бөлінген экранға кіру"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Mәзір"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"\"Сурет ішіндегі сурет\" мәзірі"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> \"суреттегі сурет\" режимінде"</string> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index efa6418eaa47..586ef7327a70 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"បិទ"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"ពង្រីក"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"ការកំណត់"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"ចូលមុខងារបំបែកអេក្រង់"</string> <string name="pip_menu_title" msgid="5393619322111827096">"ម៉ឺនុយ"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"ម៉ឺនុយរូបក្នុងរូប"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ស្ថិតក្នុងមុខងាររូបក្នុងរូប"</string> diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index 0cda44509b54..78ca0c7979a9 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"ಮುಚ್ಚಿ"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"ವಿಸ್ತೃತಗೊಳಿಸು"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"ಸ್ಪ್ಲಿಟ್-ಸ್ಕ್ರೀನ್ಗೆ ಪ್ರವೇಶಿಸಿ"</string> <string name="pip_menu_title" msgid="5393619322111827096">"ಮೆನು"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ ಮೆನು"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರವಾಗಿದೆ"</string> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index 676506fc68dd..70aa3767d7dd 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"닫기"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"펼치기"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"설정"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"화면 분할 모드로 전환"</string> <string name="pip_menu_title" msgid="5393619322111827096">"메뉴"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"PIP 모드 메뉴"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>에서 PIP 사용 중"</string> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index 57253ef55085..b2a0a49b401a 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Жабуу"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Жайып көрсөтүү"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Параметрлер"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Экранды бөлүү режимине өтүү"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Сүрөт ичиндеги сүрөт менюсу"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> – сүрөт ичиндеги сүрөт"</string> diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index c5f6e2245b31..1cbdbd412631 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"ປິດ"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"ຂະຫຍາຍ"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"ການຕັ້ງຄ່າ"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"ເຂົ້າການແບ່ງໜ້າຈໍ"</string> <string name="pip_menu_title" msgid="5393619322111827096">"ເມນູ"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"ເມນູການສະແດງຜົນຊ້ອນກັນ"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ແມ່ນເປັນການສະແດງຜົນຫຼາຍຢ່າງພ້ອມກັນ"</string> diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index eeed5a416fdc..d154c57704a1 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Uždaryti"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Išskleisti"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Nustatymai"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Įjungti išskaidyto ekrano režimą"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meniu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Vaizdo vaizde meniu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> rodom. vaizdo vaizde"</string> diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index 4324d468042b..ce269503ceef 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Aizvērt"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Izvērst"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Iestatījumi"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Piekļūt ekrāna sadalīšanas režīmam"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Izvēlne"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Izvēlne attēlam attēlā"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ir attēlā attēlā"</string> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index 471f5bdfcf1a..9d69c50626be 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Затвори"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Проширете"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Поставки"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Влези во поделен екран"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Мени"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Мени за „Слика во слика“"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> е во слика во слика"</string> diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index 5bc694a10747..c0e83386d572 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"അവസാനിപ്പിക്കുക"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"വികസിപ്പിക്കുക"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"ക്രമീകരണം"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"സ്ക്രീൻ വിഭജന മോഡിൽ പ്രവേശിക്കുക"</string> <string name="pip_menu_title" msgid="5393619322111827096">"മെനു"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"ചിത്രത്തിനുള്ളിൽ ചിത്രം മെനു"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ചിത്രത്തിനുള്ളിൽ ചിത്രം രീതിയിലാണ്"</string> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index 0268c649380d..ba5d283fb8a7 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Хаах"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Дэлгэх"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Тохиргоо"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Хуваасан дэлгэцийг оруулна уу"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Цэс"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Дэлгэц доторх дэлгэцийн цэс"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> дэлгэцэн доторх дэлгэцэд байна"</string> diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index 2e6163e65668..17601c18366a 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"बंद करा"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"विस्तृत करा"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"सेटिंग्ज"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रीन एंटर करा"</string> <string name="pip_menu_title" msgid="5393619322111827096">"मेनू"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"चित्रात-चित्र मेनू"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> चित्रामध्ये चित्र मध्ये आहे"</string> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index a60e61b892cb..d5547fa8a056 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Tutup"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Kembangkan"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Tetapan"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Masuk skrin pisah"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu Gambar dalam Gambar"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> terdapat dalam gambar dalam gambar"</string> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index 6b91d4676621..07bfc990d62d 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"ပိတ်ရန်"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"ချဲ့ရန်"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"ဆက်တင်များ"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းသို့ ဝင်ရန်"</string> <string name="pip_menu_title" msgid="5393619322111827096">"မီနူး"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"နှစ်ခုထပ်၍ ကြည့်ခြင်းမီနူး"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> သည် နှစ်ခုထပ်၍ကြည့်ခြင်း ဖွင့်ထားသည်"</string> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index ec9ece3484b8..f609d019daae 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Lukk"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Vis"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Innstillinger"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Aktivér delt skjerm"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meny"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Bilde-i-bilde-meny"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> er i bilde-i-bilde"</string> diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index 8bb07be12c48..f7d49908a9f7 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"बन्द गर्नुहोस्"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"विस्तृत गर्नुहोस्"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"सेटिङहरू"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"स्प्लिट स्क्रिन मोड प्रयोग गर्नुहोस्"</string> <string name="pip_menu_title" msgid="5393619322111827096">"मेनु"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"\"picture-in-picture\" मेनु"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> Picture-in-picture मा छ"</string> diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index c6c60ae4b1f2..a38cb7547385 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Sluiten"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Uitvouwen"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Instellingen"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Gesplitst scherm openen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Scherm-in-scherm-menu"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> is in scherm-in-scherm"</string> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index 927dde40134d..e3097beb6166 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"ବନ୍ଦ କରନ୍ତୁ"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"ବଢ଼ାନ୍ତୁ"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"ସେଟିଂସ୍"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ମୋଡ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="pip_menu_title" msgid="5393619322111827096">"ମେନୁ"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"ପିକଚର-ଇନ-ପିକଚର ମେନୁ"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> \"ଛବି-ଭିତରେ-ଛବି\"ରେ ଅଛି"</string> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index 0e12fb872005..3aea6f69749f 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"ਬੰਦ ਕਰੋ"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"ਵਿਸਤਾਰ ਕਰੋ"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"ਸੈਟਿੰਗਾਂ"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string> <string name="pip_menu_title" msgid="5393619322111827096">"ਮੀਨੂ"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"ਤਸਵੀਰ-ਵਿੱਚ-ਤਸਵੀਰ ਮੀਨੂ"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ਤਸਵੀਰ-ਅੰਦਰ-ਤਸਵੀਰ ਵਿੱਚ ਹੈ"</string> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index 75a8ce6bc16d..aec3722cefa5 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Zamknij"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Rozwiń"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Ustawienia"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Włącz podzielony ekran"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu funkcji Obraz w obrazie."</string> <string name="pip_notification_title" msgid="1347104727641353453">"Aplikacja <xliff:g id="NAME">%s</xliff:g> działa w trybie obraz w obrazie"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index b84a0ded4939..49935ada4656 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Fechar"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Abrir"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Configurações"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Dividir tela"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu do picture-in-picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está em picture-in-picture"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index d84bfcdd73ff..f636da7997eb 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Fechar"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Expandir"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Definições"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Aceder ao ecrã dividido"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu de ecrã no ecrã"</string> <string name="pip_notification_title" msgid="1347104727641353453">"A app <xliff:g id="NAME">%s</xliff:g> está no modo de ecrã no ecrã"</string> diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index b84a0ded4939..49935ada4656 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Fechar"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Abrir"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Configurações"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Dividir tela"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu do picture-in-picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> está em picture-in-picture"</string> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index eeea428cc8fa..c20f350ae198 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Închide"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Extinde"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Setări"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Accesează ecranul împărțit"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meniu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Meniu picture-in-picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> este în modul picture-in-picture"</string> diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index 26b0f94eb585..49347d2d8086 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Закрыть"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Развернуть"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Настройки"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Включить разделение экрана"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Меню \"Картинка в картинке\""</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> находится в режиме \"Картинка в картинке\""</string> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index 9b9a430ce73f..e5a974683e49 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"වසන්න"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"දිග හරින්න"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"සැකසීම්"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"බෙදුම් තිරයට ඇතුළු වන්න"</string> <string name="pip_menu_title" msgid="5393619322111827096">"මෙනුව"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"පින්තූරය තුළ පින්තූරය මෙනුව"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> පින්තූරය-තුළ-පින්තූරය තුළ වේ"</string> diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index 4b2153180cbe..c2d20ddb0d3b 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Zavrieť"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Rozbaliť"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Nastavenia"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Prejsť na rozdelenú obrazovku"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Ponuka"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Ponuka obrazu v obraze"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je v režime obraz v obraze"</string> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index 581cf5b815c6..cfe4480c6e1a 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Zapri"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Razširi"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Nastavitve"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Vklopi razdeljen zaslon"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meni"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Meni za sliko v sliki"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> je v načinu slika v sliki"</string> diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index 9dc7b7ebef99..cba98c2fb61a 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Mbyll"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Zgjero"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Cilësimet"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Hyr në ekranin e ndarë"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menyja"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menyja e \"Figurës brenda figurës\""</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> është në figurë brenda figurës"</string> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index cd532f79dd78..5031f5bf5d64 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Затвори"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Прошири"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Подешавања"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Уђи на подељени екран"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Мени"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Мени слике у слици."</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> је слика у слици"</string> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index 386dda7e088d..742be37b67ef 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Stäng"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Utöka"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Inställningar"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Starta delad skärm"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Meny"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Bild-i-bild-meny"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> visas i bild-i-bild"</string> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index 69b2e34ada3c..68a7262d0eaf 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Funga"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Panua"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Mipangilio"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Weka skrini iliyogawanywa"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menyu ya kipengele cha Kupachika Picha ndani ya Picha nyingine."</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> iko katika hali ya picha ndani ya picha nyingine"</string> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index 037b5aba22f5..fe8fa057dc95 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"மூடு"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"விரி"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"அமைப்புகள்"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"திரைப் பிரிப்பு பயன்முறைக்குச் செல்"</string> <string name="pip_menu_title" msgid="5393619322111827096">"மெனு"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"பிக்ச்சர்-இன்-பிக்ச்சர் மெனு"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> தற்போது பிக்ச்சர்-இன்-பிக்ச்சரில் உள்ளது"</string> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 694ecb951210..593c8fc28a0d 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"మూసివేయి"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"విస్తరింపజేయి"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"సెట్టింగ్లు"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"స్ప్లిట్ స్క్రీన్ను ఎంటర్ చేయండి"</string> <string name="pip_menu_title" msgid="5393619322111827096">"మెనూ"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"పిక్చర్-ఇన్-పిక్చర్ మెనూ"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> చిత్రంలో చిత్రం రూపంలో ఉంది"</string> diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index d4b6aff2ee7d..cd3bf6a626c0 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"ปิด"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"ขยาย"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"การตั้งค่า"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"เข้าสู่โหมดแบ่งหน้าจอ"</string> <string name="pip_menu_title" msgid="5393619322111827096">"เมนู"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"เมนูการแสดงภาพซ้อนภาพ"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ใช้การแสดงภาพซ้อนภาพ"</string> diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index db9303c0fd9c..bf05e149ea57 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Isara"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Palawakin"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Mga Setting"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Pumasok sa split screen"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menu ng Picture-in-Picture"</string> <string name="pip_notification_title" msgid="1347104727641353453">"Nasa picture-in-picture ang <xliff:g id="NAME">%s</xliff:g>"</string> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index 818666c79973..2dfa38a76dfa 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Kapat"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Genişlet"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Ayarlar"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Bölünmüş ekrana geç"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Pencere içinde pencere menüsü"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>, pencere içinde pencere özelliğini kullanıyor"</string> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index 85fb8e114476..57ca64f5b159 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Закрити"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Розгорнути"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Налаштування"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Розділити екран"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Меню \"Картинка в картинці\""</string> <string name="pip_notification_title" msgid="1347104727641353453">"У додатку <xliff:g id="NAME">%s</xliff:g> є функція \"Картинка в картинці\""</string> diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index 813870b134b4..077037373aa2 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"بند کریں"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"پھیلائیں"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"ترتیبات"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"اسپلٹ اسکرین تک رسائی"</string> <string name="pip_menu_title" msgid="5393619322111827096">"مینیو"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"تصویر میں تصویر کا مینیو"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> تصویر میں تصویر میں ہے"</string> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index 7bcacbb93f1f..e2d1f47c210b 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Yopish"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Yoyish"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Sozlamalar"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Ajratilgan ekranga kirish"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menyu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Tasvir ustida tasvir menyusi"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> tasvir ustida tasvir rejimida"</string> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index 416dd91162c2..4608b2b10c3f 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Đóng"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Mở rộng"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Cài đặt"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Truy cập chế độ chia đôi màn hình"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Trình đơn hình trong hình."</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> đang ở chế độ ảnh trong ảnh"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index 9d4e6f0ce660..cbb857c58611 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"关闭"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"展开"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"设置"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"进入分屏模式"</string> <string name="pip_menu_title" msgid="5393619322111827096">"菜单"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"画中画菜单"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g>目前位于“画中画”中"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index b5b94ec40fd1..d89b2c29216e 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"關閉"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"展開"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"進入分割螢幕"</string> <string name="pip_menu_title" msgid="5393619322111827096">"選單"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"畫中畫選單"</string> <string name="pip_notification_title" msgid="1347104727641353453">"「<xliff:g id="NAME">%s</xliff:g>」目前在畫中畫模式"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index 0f2a052dbbe0..4ce50a44e12a 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"關閉"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"展開"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"設定"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"進入分割畫面"</string> <string name="pip_menu_title" msgid="5393619322111827096">"選單"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"子母畫面選單"</string> <string name="pip_notification_title" msgid="1347104727641353453">"「<xliff:g id="NAME">%s</xliff:g>」目前在子母畫面中"</string> diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index a696f9ec6251..fa680f6eee89 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -20,7 +20,6 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Vala"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Nweba"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Amasethingi"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"Faka ukuhlukanisa isikrini"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Imenyu"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Imenyu Yesithombe-Esithombeni"</string> <string name="pip_notification_title" msgid="1347104727641353453">"U-<xliff:g id="NAME">%s</xliff:g> ungaphakathi kwesithombe esiphakathi kwesithombe"</string> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt new file mode 100644 index 000000000000..4c34971c4fb1 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wm.shell.common + +import android.app.PendingIntent +import android.content.ComponentName +import android.content.Context +import android.content.pm.LauncherApps +import android.content.pm.PackageManager +import android.os.UserHandle +import android.view.WindowManager +import android.view.WindowManager.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI +import com.android.internal.annotations.VisibleForTesting +import com.android.wm.shell.R +import com.android.wm.shell.protolog.ShellProtoLogGroup +import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL +import com.android.wm.shell.util.KtProtoLog +import java.util.Arrays + +/** + * Helper for multi-instance related checks. + */ +class MultiInstanceHelper @JvmOverloads constructor( + private val context: Context, + private val packageManager: PackageManager, + private val staticAppsSupportingMultiInstance: Array<String> = context.resources + .getStringArray(R.array.config_appsSupportMultiInstancesSplit)) { + + /** + * Returns whether a specific component desires to be launched in multiple instances. + */ + @VisibleForTesting + fun supportsMultiInstanceSplit(componentName: ComponentName?): Boolean { + if (componentName == null || componentName.packageName == null) { + // TODO(b/262864589): Handle empty component case + return false + } + + // Check the pre-defined allow list + val packageName = componentName.packageName + for (pkg in staticAppsSupportingMultiInstance) { + if (pkg == packageName) { + KtProtoLog.v(WM_SHELL, "application=%s in allowlist supports multi-instance", + packageName) + return true + } + } + + // Check the activity property first + try { + val activityProp = packageManager.getProperty( + PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, componentName) + // If the above call doesn't throw a NameNotFoundException, then the activity property + // should override the application property value + if (activityProp.isBoolean) { + KtProtoLog.v(WM_SHELL, "activity=%s supports multi-instance", componentName) + return activityProp.boolean + } else { + KtProtoLog.w(WM_SHELL, "Warning: property=%s for activity=%s has non-bool type=%d", + PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName, activityProp.type) + } + } catch (nnfe: PackageManager.NameNotFoundException) { + // Not specified in the activity, fall through + } + + // Check the application property otherwise + try { + val appProp = packageManager.getProperty( + PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName) + if (appProp.isBoolean) { + KtProtoLog.v(WM_SHELL, "application=%s supports multi-instance", packageName) + return appProp.boolean + } else { + KtProtoLog.w(WM_SHELL, + "Warning: property=%s for application=%s has non-bool type=%d", + PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName, appProp.type) + } + } catch (nnfe: PackageManager.NameNotFoundException) { + // Not specified in either application or activity + } + return false + } + + companion object { + /** Returns the component from a PendingIntent */ + @JvmStatic + fun getComponent(pendingIntent: PendingIntent?): ComponentName? { + return pendingIntent?.intent?.component + } + + /** Returns the component from a shortcut */ + @JvmStatic + fun getShortcutComponent(packageName: String, shortcutId: String, + user: UserHandle, launcherApps: LauncherApps): ComponentName? { + val query = LauncherApps.ShortcutQuery() + query.setPackage(packageName) + query.setShortcutIds(Arrays.asList(shortcutId)) + query.setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED) + val shortcuts = launcherApps.getShortcuts(query, user) + val info = if (shortcuts != null && shortcuts.size > 0) shortcuts[0] else null + return info?.activity + } + + /** Returns true if package names and user ids match. */ + @JvmStatic + fun samePackage(packageName1: String?, packageName2: String?, + userId1: Int, userId2: Int): Boolean { + return (packageName1 != null && packageName1 == packageName2) && (userId1 == userId2) + } + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/IPip.aidl index 8b3de6298b2a..b5f25433f9aa 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/IPip.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.pip; +package com.android.wm.shell.common.pip; import android.app.PictureInPictureParams; import android.view.SurfaceControl; @@ -22,7 +22,7 @@ import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.graphics.Rect; -import com.android.wm.shell.pip.IPipAnimationListener; +import com.android.wm.shell.common.pip.IPipAnimationListener; /** * Interface that is exposed to remote callers to manipulate the Pip feature. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/IPipAnimationListener.aidl index 062e3ba26356..b8d1966100a4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/IPipAnimationListener.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.pip; +package com.android.wm.shell.common.pip; /** * Listener interface that Launcher attaches to SystemUI to get Pip animation callbacks. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipPerfHintController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipPerfHintController.java new file mode 100644 index 000000000000..317e48e19c13 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipPerfHintController.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.common.pip; + +import static android.window.SystemPerformanceHinter.HINT_SF; + +import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE; + +import android.window.SystemPerformanceHinter; +import android.window.SystemPerformanceHinter.HighPerfSession; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.internal.protolog.common.ProtoLog; +import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.common.annotations.ShellMainThread; + +import java.io.PrintWriter; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.function.Consumer; + +/** + * Manages system performance hints for PiP CUJs and interactions. + */ +public class PipPerfHintController { + private static final String TAG = PipPerfHintController.class.getSimpleName(); + + // Delay until signal about a session cleanup is sent. + private static final int SESSION_TIMEOUT_DELAY = 20_000; + + // Maximum number of possible high perf session. + private static final int SESSION_POOL_SIZE = 20; + + private final SystemPerformanceHinter mSystemPerformanceHinter; + @NonNull + private final PipDisplayLayoutState mPipDisplayLayoutState; + @NonNull + private final ShellExecutor mMainExecutor; + + + public PipPerfHintController(@NonNull PipDisplayLayoutState pipDisplayLayoutState, + @ShellMainThread ShellExecutor mainExecutor, + @NonNull SystemPerformanceHinter systemPerformanceHinter) { + mPipDisplayLayoutState = pipDisplayLayoutState; + mMainExecutor = mainExecutor; + mSystemPerformanceHinter = systemPerformanceHinter; + } + + /** + * Starts a high perf session. + * + * @param timeoutCallback an optional callback to be executed upon session timeout. + * @return a wrapper around the session to allow for early closing; null if no free sessions + * left available in the pool. + */ + @Nullable + public PipHighPerfSession startSession(@Nullable Consumer<PipHighPerfSession> timeoutCallback, + String reason) { + if (PipHighPerfSession.getActiveSessionsCount() == SESSION_POOL_SIZE) { + return null; + } + + HighPerfSession highPerfSession = mSystemPerformanceHinter.startSession(HINT_SF, + mPipDisplayLayoutState.getDisplayId(), "pip-high-perf-session"); + PipHighPerfSession pipHighPerfSession = new PipHighPerfSession(highPerfSession, reason); + + if (timeoutCallback != null) { + mMainExecutor.executeDelayed(() -> { + if (PipHighPerfSession.hasClosedOrFinalized(pipHighPerfSession)) { + // If the session is either directly closed or GC collected before timeout + // was reached, do not send the timeout callback. + return; + } + // The session hasn't been closed yet, so do that now, along with any cleanup. + pipHighPerfSession.close(); + ProtoLog.d(WM_SHELL_PICTURE_IN_PICTURE, "%s: high perf session %s timed out", TAG, + pipHighPerfSession.toString()); + timeoutCallback.accept(pipHighPerfSession); + }, SESSION_TIMEOUT_DELAY); + } + ProtoLog.d(WM_SHELL_PICTURE_IN_PICTURE, "%s: high perf session %s is started", + TAG, pipHighPerfSession.toString()); + return pipHighPerfSession; + } + + /** + * Dumps the inner state. + */ + public void dump(PrintWriter pw, String prefix) { + final String innerPrefix = prefix + " "; + pw.println(prefix + TAG); + pw.println(innerPrefix + "activeSessionCount=" + + PipHighPerfSession.getActiveSessionsCount()); + } + + /** + * A wrapper around {@link HighPerfSession} to keep track of some extra metadata about + * the session's status. + */ + public class PipHighPerfSession implements AutoCloseable{ + + // THe actual HighPerfSession we wrap around. + private final HighPerfSession mSession; + + private final String mReason; + + /** + * Keeps track of all active sessions using weakly referenced keys. + * This makes sure that that sessions do not get accidentally leaked if not closed. + */ + private static Map<PipHighPerfSession, Boolean> sActiveSessions = new WeakHashMap<>(); + + private PipHighPerfSession(HighPerfSession session, String reason) { + mSession = session; + mReason = reason; + sActiveSessions.put(this, true); + } + + /** + * Closes a high perf session. + */ + @Override + public void close() { + sActiveSessions.remove(this); + mSession.close(); + ProtoLog.d(WM_SHELL_PICTURE_IN_PICTURE, + "%s: high perf session %s is closed", + TAG, toString()); + } + + @Override + public void finalize() { + // The entry should be removed from the weak hash map as well by default. + mSession.close(); + } + + @Override + public String toString() { + return "[" + super.toString() + "] initially started due to: " + mReason; + } + + private static boolean hasClosedOrFinalized(PipHighPerfSession pipHighPerfSession) { + return !sActiveSessions.containsKey(pipHighPerfSession); + } + + private static int getActiveSessionsCount() { + return sActiveSessions.size(); + } + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java index 662f325be38c..f9259e79472e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java @@ -99,12 +99,6 @@ public class SplitScreenUtils { return taskInfo != null ? taskInfo.userId : -1; } - /** Returns true if package names and user ids match. */ - public static boolean samePackage(String packageName1, String packageName2, - int userId1, int userId2) { - return (packageName1 != null && packageName1.equals(packageName2)) && (userId1 == userId2); - } - /** Generates a common log message for split screen failures */ public static String splitFailureMessage(String caller, String reason) { return "(" + caller + ") Splitscreen aborted: " + reason; @@ -143,28 +137,4 @@ public class SplitScreenUtils { return isLandscape; } } - - /** Returns the component from a PendingIntent */ - @Nullable - public static ComponentName getComponent(@Nullable PendingIntent pendingIntent) { - if (pendingIntent == null || pendingIntent.getIntent() == null) { - return null; - } - return pendingIntent.getIntent().getComponent(); - } - - /** Returns the component from a shortcut */ - @Nullable - public static ComponentName getShortcutComponent(@NonNull String packageName, String shortcutId, - @NonNull UserHandle user, @NonNull LauncherApps launcherApps) { - LauncherApps.ShortcutQuery query = new LauncherApps.ShortcutQuery(); - query.setPackage(packageName); - query.setShortcutIds(Arrays.asList(shortcutId)); - query.setQueryFlags(FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED); - List<ShortcutInfo> shortcuts = launcherApps.getShortcuts(query, user); - ShortcutInfo info = shortcuts != null && shortcuts.size() > 0 - ? shortcuts.get(0) - : null; - return info != null ? info.getActivity() : null; - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java index d4ed0170dca8..216da070754b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java @@ -26,6 +26,7 @@ import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.LaunchAdjacentController; +import com.android.wm.shell.common.MultiInstanceHelper; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; @@ -88,13 +89,14 @@ public class TvWMShellModule { IconProvider iconProvider, Optional<RecentTasksController> recentTasks, LaunchAdjacentController launchAdjacentController, + MultiInstanceHelper multiInstanceHelper, @ShellMainThread ShellExecutor mainExecutor, Handler mainHandler, SystemWindows systemWindows) { return new TvSplitScreenController(context, shellInit, shellCommandHandler, shellController, shellTaskOrganizer, syncQueue, rootTDAOrganizer, displayController, displayImeController, displayInsetsController, transitions, transactionPool, - iconProvider, recentTasks, launchAdjacentController, mainExecutor, mainHandler, - systemWindows); + iconProvider, recentTasks, launchAdjacentController, multiInstanceHelper, + mainExecutor, mainHandler, systemWindows); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java index 0d6a85271fd1..8b2ec0a35685 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java @@ -50,6 +50,7 @@ import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DockStateReader; import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.LaunchAdjacentController; +import com.android.wm.shell.common.MultiInstanceHelper; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; @@ -66,6 +67,7 @@ import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipDisplayLayoutState; import com.android.wm.shell.common.pip.PipMediaController; +import com.android.wm.shell.common.pip.PipPerfHintController; import com.android.wm.shell.common.pip.PipSnapAlgorithm; import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.common.pip.SizeSpecSource; @@ -321,6 +323,12 @@ public abstract class WMShellBaseModule { return Optional.of(perfHintController.getHinter()); } + @WMSingleton + @Provides + static MultiInstanceHelper provideMultiInstanceHelper(Context context) { + return new MultiInstanceHelper(context, context.getPackageManager()); + } + // // Back animation // @@ -396,6 +404,20 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides + static Optional<PipPerfHintController> providePipPerfHintController( + PipDisplayLayoutState pipDisplayLayoutState, + @ShellMainThread ShellExecutor mainExecutor, + Optional<SystemPerformanceHinter> systemPerformanceHinterOptional) { + if (systemPerformanceHinterOptional.isPresent()) { + return Optional.of(new PipPerfHintController(pipDisplayLayoutState, mainExecutor, + systemPerformanceHinterOptional.get())); + } else { + return Optional.empty(); + } + } + + @WMSingleton + @Provides static PipBoundsState providePipBoundsState(Context context, SizeSpecSource sizeSpecSource, PipDisplayLayoutState pipDisplayLayoutState) { return new PipBoundsState(context, sizeSpecSource, pipDisplayLayoutState); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index bd9d89c9892e..4fe79c13e722 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -47,6 +47,7 @@ import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.LaunchAdjacentController; +import com.android.wm.shell.common.MultiInstanceHelper; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TaskStackListenerImpl; @@ -347,12 +348,14 @@ public abstract class WMShellModule { LaunchAdjacentController launchAdjacentController, Optional<WindowDecorViewModel> windowDecorViewModel, Optional<DesktopTasksController> desktopTasksController, + MultiInstanceHelper multiInstanceHelper, @ShellMainThread ShellExecutor mainExecutor) { return new SplitScreenController(context, shellInit, shellCommandHandler, shellController, shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer, displayController, displayImeController, displayInsetsController, dragAndDropController, transitions, transactionPool, iconProvider, recentTasks, launchAdjacentController, - windowDecorViewModel, desktopTasksController, mainExecutor); + windowDecorViewModel, desktopTasksController, null /* stageCoordinator */, + multiInstanceHelper, mainExecutor); } // diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java index 805336943d89..1e3d7fb06da2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java @@ -36,6 +36,7 @@ import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipDisplayLayoutState; import com.android.wm.shell.common.pip.PipMediaController; +import com.android.wm.shell.common.pip.PipPerfHintController; import com.android.wm.shell.common.pip.PipSnapAlgorithm; import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.common.pip.PipUtils; @@ -143,10 +144,12 @@ public abstract class Pip1Module { PipMotionHelper pipMotionHelper, FloatingContentCoordinator floatingContentCoordinator, PipUiEventLogger pipUiEventLogger, - @ShellMainThread ShellExecutor mainExecutor) { + @ShellMainThread ShellExecutor mainExecutor, + Optional<PipPerfHintController> pipPerfHintControllerOptional) { return new PipTouchHandler(context, shellInit, menuPhoneController, pipBoundsAlgorithm, pipBoundsState, sizeSpecSource, pipTaskOrganizer, pipMotionHelper, - floatingContentCoordinator, pipUiEventLogger, mainExecutor); + floatingContentCoordinator, pipUiEventLogger, mainExecutor, + pipPerfHintControllerOptional); } @WMSingleton @@ -169,6 +172,7 @@ public abstract class Pip1Module { PipTransitionController pipTransitionController, PipParamsChangedForwarder pipParamsChangedForwarder, Optional<SplitScreenController> splitScreenControllerOptional, + Optional<PipPerfHintController> pipPerfHintControllerOptional, DisplayController displayController, PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer, @ShellMainThread ShellExecutor mainExecutor) { @@ -176,8 +180,8 @@ public abstract class Pip1Module { syncTransactionQueue, pipTransitionState, pipBoundsState, pipDisplayLayoutState, pipBoundsAlgorithm, menuPhoneController, pipAnimationController, pipSurfaceTransactionHelper, pipTransitionController, pipParamsChangedForwarder, - splitScreenControllerOptional, displayController, pipUiEventLogger, - shellTaskOrganizer, mainExecutor); + splitScreenControllerOptional, pipPerfHintControllerOptional, displayController, + pipUiEventLogger, shellTaskOrganizer, mainExecutor); } @WMSingleton @@ -209,10 +213,11 @@ public abstract class Pip1Module { PipBoundsState pipBoundsState, PipTaskOrganizer pipTaskOrganizer, PhonePipMenuController menuController, PipSnapAlgorithm pipSnapAlgorithm, PipTransitionController pipTransitionController, - FloatingContentCoordinator floatingContentCoordinator) { + FloatingContentCoordinator floatingContentCoordinator, + Optional<PipPerfHintController> pipPerfHintControllerOptional) { return new PipMotionHelper(context, pipBoundsState, pipTaskOrganizer, menuController, pipSnapAlgorithm, pipTransitionController, - floatingContentCoordinator); + floatingContentCoordinator, pipPerfHintControllerOptional); } @WMSingleton diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java index 1947097c2f15..54c2aeab4976 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java @@ -34,6 +34,7 @@ import com.android.wm.shell.common.pip.LegacySizeSpecSource; import com.android.wm.shell.common.pip.PipAppOpsListener; import com.android.wm.shell.common.pip.PipDisplayLayoutState; import com.android.wm.shell.common.pip.PipMediaController; +import com.android.wm.shell.common.pip.PipPerfHintController; import com.android.wm.shell.common.pip.PipSnapAlgorithm; import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.dagger.WMShellBaseModule; @@ -212,6 +213,7 @@ public abstract class TvPipModule { PipParamsChangedForwarder pipParamsChangedForwarder, PipSurfaceTransactionHelper pipSurfaceTransactionHelper, Optional<SplitScreenController> splitScreenControllerOptional, + Optional<PipPerfHintController> pipPerfHintControllerOptional, DisplayController displayController, PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer, @ShellMainThread ShellExecutor mainExecutor) { @@ -219,8 +221,8 @@ public abstract class TvPipModule { syncTransactionQueue, pipTransitionState, tvPipBoundsState, pipDisplayLayoutState, tvPipBoundsAlgorithm, tvPipMenuController, pipAnimationController, pipSurfaceTransactionHelper, tvPipTransition, pipParamsChangedForwarder, - splitScreenControllerOptional, displayController, pipUiEventLogger, - shellTaskOrganizer, mainExecutor); + splitScreenControllerOptional, pipPerfHintControllerOptional, displayController, + pipUiEventLogger, shellTaskOrganizer, mainExecutor); } @WMSingleton diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt index 837cb99602c8..11304ec587e7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt @@ -62,7 +62,7 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE import com.android.wm.shell.recents.RecentsTransitionHandler import com.android.wm.shell.recents.RecentsTransitionStateListener import com.android.wm.shell.splitscreen.SplitScreenController -import com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_ENTER_DESKTOP +import com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DESKTOP_MODE import com.android.wm.shell.sysui.ShellCommandHandler import com.android.wm.shell.sysui.ShellController import com.android.wm.shell.sysui.ShellInit @@ -355,7 +355,7 @@ class DesktopTasksController( splitScreenController.prepareExitSplitScreen( wct, splitScreenController.getStageOfTask(taskInfo.taskId), - EXIT_REASON_ENTER_DESKTOP + EXIT_REASON_DESKTOP_MODE ) getOtherSplitTask(taskInfo.taskId)?.let { otherTaskInfo -> wct.removeTask(otherTaskInfo.token) @@ -919,19 +919,13 @@ class DesktopTasksController( } if (inputCoordinate.x <= transitionAreaWidth) { releaseVisualIndicator() - val wct = WindowContainerTransaction() - addMoveToSplitChanges(wct, taskInfo) - splitScreenController.requestEnterSplitSelect(taskInfo, wct, - SPLIT_POSITION_TOP_OR_LEFT, taskBounds) + snapToHalfScreen(taskInfo, SnapPosition.LEFT) return } if (inputCoordinate.x >= (displayController.getDisplayLayout(taskInfo.displayId)?.width() ?.minus(transitionAreaWidth) ?: return)) { releaseVisualIndicator() - val wct = WindowContainerTransaction() - addMoveToSplitChanges(wct, taskInfo) - splitScreenController.requestEnterSplitSelect(taskInfo, wct, - SPLIT_POSITION_BOTTOM_OR_RIGHT, taskBounds) + snapToHalfScreen(taskInfo, SnapPosition.RIGHT) return } // A freeform drag-move ended, remove the indicator immediately. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index 271a939c4882..ef32f6f5dbe1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -86,6 +86,7 @@ import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipDisplayLayoutState; import com.android.wm.shell.common.pip.PipMenuController; +import com.android.wm.shell.common.pip.PipPerfHintController; import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.pip.phone.PipMotionHelper; @@ -140,6 +141,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private final int mCrossFadeAnimationDuration; private final PipSurfaceTransactionHelper mSurfaceTransactionHelper; private final Optional<SplitScreenController> mSplitScreenOptional; + @Nullable private final PipPerfHintController mPipPerfHintController; protected final ShellTaskOrganizer mTaskOrganizer; protected final ShellExecutor mMainExecutor; @@ -157,10 +159,30 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private final PipAnimationController.PipAnimationCallback mPipAnimationCallback = new PipAnimationController.PipAnimationCallback() { private boolean mIsCancelled; + @Nullable private PipPerfHintController.PipHighPerfSession mPipHighPerfSession; + + private void onHighPerfSessionTimeout( + PipPerfHintController.PipHighPerfSession session) {} + + private void cleanUpHighPerfSessionMaybe() { + if (mPipHighPerfSession != null) { + // Close the high perf session once pointer interactions are over; + mPipHighPerfSession.close(); + mPipHighPerfSession = null; + } + } + @Override public void onPipAnimationStart(TaskInfo taskInfo, PipAnimationController.PipTransitionAnimator animator) { + if (mPipPerfHintController != null) { + // Start a high perf session with a timeout callback. + mPipHighPerfSession = mPipPerfHintController.startSession( + this::onHighPerfSessionTimeout, + "PipTaskOrganizer::mPipAnimationCallback"); + } + final int direction = animator.getTransitionDirection(); mIsCancelled = false; sendOnPipTransitionStarted(direction); @@ -169,6 +191,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, @Override public void onPipAnimationEnd(TaskInfo taskInfo, SurfaceControl.Transaction tx, PipAnimationController.PipTransitionAnimator animator) { + // Close the high perf session if needed. + cleanUpHighPerfSessionMaybe(); + final int direction = animator.getTransitionDirection(); if (mIsCancelled) { sendOnPipTransitionFinished(direction); @@ -356,6 +381,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, @NonNull PipTransitionController pipTransitionController, @NonNull PipParamsChangedForwarder pipParamsChangedForwarder, Optional<SplitScreenController> splitScreenOptional, + Optional<PipPerfHintController> pipPerfHintControllerOptional, @NonNull DisplayController displayController, @NonNull PipUiEventLogger pipUiEventLogger, @NonNull ShellTaskOrganizer shellTaskOrganizer, @@ -381,6 +407,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mSurfaceControlTransactionFactory = new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); mSplitScreenOptional = splitScreenOptional; + mPipPerfHintController = pipPerfHintControllerOptional.orElse(null); mTaskOrganizer = shellTaskOrganizer; mMainExecutor = mainExecutor; @@ -1972,6 +1999,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, pw.println(innerPrefix + "mState=" + mPipTransitionState.getTransitionState()); pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams); mPipTransitionController.dump(pw, innerPrefix); + if (mPipPerfHintController != null) { + mPipPerfHintController.dump(pw, innerPrefix); + } } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java index 6191fea1595a..d17317522694 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java @@ -305,6 +305,12 @@ public abstract class PipTransitionController implements Transitions.TransitionH public void end() { } + /** Starts the {@link android.window.SystemPerformanceHinter.HighPerfSession}. */ + public void startHighPerfSession() {} + + /** Closes the {@link android.window.SystemPerformanceHinter.HighPerfSession}. */ + public void closeHighPerfSession() {} + /** * Callback interface for PiP transitions (both from and to PiP mode) */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 05d4f53986b8..4b12134cb377 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -75,6 +75,8 @@ import com.android.wm.shell.common.SingleInstanceRemoteListener; import com.android.wm.shell.common.TabletopModeController; import com.android.wm.shell.common.TaskStackListenerCallback; import com.android.wm.shell.common.TaskStackListenerImpl; +import com.android.wm.shell.common.pip.IPip; +import com.android.wm.shell.common.pip.IPipAnimationListener; import com.android.wm.shell.common.pip.PipAppOpsListener; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; @@ -85,8 +87,6 @@ import com.android.wm.shell.common.pip.PipSnapAlgorithm; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.onehanded.OneHandedTransitionCallback; -import com.android.wm.shell.pip.IPip; -import com.android.wm.shell.pip.IPipAnimationListener; import com.android.wm.shell.pip.PinnedStackListenerForwarder; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipAnimationController; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java index c708b86e88c5..df67707e2014 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java @@ -42,6 +42,7 @@ import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.magnetictarget.MagnetizedObject; import com.android.wm.shell.common.pip.PipAppOpsListener; import com.android.wm.shell.common.pip.PipBoundsState; +import com.android.wm.shell.common.pip.PipPerfHintController; import com.android.wm.shell.common.pip.PipSnapAlgorithm; import com.android.wm.shell.pip.PipTaskOrganizer; import com.android.wm.shell.pip.PipTransitionController; @@ -50,6 +51,7 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup; import kotlin.Unit; import kotlin.jvm.functions.Function0; +import java.util.Optional; import java.util.function.Consumer; /** @@ -84,6 +86,9 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, /** Coordinator instance for resolving conflicts with other floating content. */ private FloatingContentCoordinator mFloatingContentCoordinator; + @Nullable private final PipPerfHintController mPipPerfHintController; + @Nullable private PipPerfHintController.PipHighPerfSession mPipHighPerfSession; + /** * PhysicsAnimator instance for animating {@link PipBoundsState#getMotionBoundsState()} * using physics animations. @@ -169,13 +174,15 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, public PipMotionHelper(Context context, @NonNull PipBoundsState pipBoundsState, PipTaskOrganizer pipTaskOrganizer, PhonePipMenuController menuController, PipSnapAlgorithm snapAlgorithm, PipTransitionController pipTransitionController, - FloatingContentCoordinator floatingContentCoordinator) { + FloatingContentCoordinator floatingContentCoordinator, + Optional<PipPerfHintController> pipPerfHintControllerOptional) { mContext = context; mPipTaskOrganizer = pipTaskOrganizer; mPipBoundsState = pipBoundsState; mMenuController = menuController; mSnapAlgorithm = snapAlgorithm; mFloatingContentCoordinator = floatingContentCoordinator; + mPipPerfHintController = pipPerfHintControllerOptional.orElse(null); pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback); mResizePipUpdateListener = (target, values) -> { if (mPipBoundsState.getMotionBoundsState().isInMotion()) { @@ -386,6 +393,16 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, movetoTarget(velX, velY, postBoundsUpdateCallback, true /* isStash */); } + private void onHighPerfSessionTimeout(PipPerfHintController.PipHighPerfSession session) {} + + private void cleanUpHighPerfSessionMaybe() { + if (mPipHighPerfSession != null) { + // Close the high perf session once pointer interactions are over; + mPipHighPerfSession.close(); + mPipHighPerfSession = null; + } + } + private void movetoTarget( float velocityX, float velocityY, @@ -591,6 +608,11 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, (int) toY + getBounds().height())); if (!mTemporaryBoundsPhysicsAnimator.isRunning()) { + if (mPipPerfHintController != null) { + // Start a high perf session with a timeout callback. + mPipHighPerfSession = mPipPerfHintController.startSession( + this::onHighPerfSessionTimeout, "startBoundsAnimator"); + } if (postBoundsUpdateCallback != null) { mTemporaryBoundsPhysicsAnimator .addUpdateListener(mResizePipUpdateListener) @@ -633,6 +655,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded(); mSpringingToTouch = false; mDismissalPending = false; + cleanUpHighPerfSessionMaybe(); } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java index 5f9195a37c1b..89d3dd63a08e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java @@ -17,6 +17,7 @@ package com.android.wm.shell.pip.phone; import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE; +import android.annotation.Nullable; import android.content.Context; import android.content.res.Resources; import android.graphics.Point; @@ -39,6 +40,7 @@ import com.android.wm.shell.R; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; +import com.android.wm.shell.common.pip.PipPerfHintController; import com.android.wm.shell.common.pip.PipPinchResizingAlgorithm; import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.pip.PipAnimationController; @@ -98,6 +100,12 @@ public class PipResizeGestureHandler { private InputMonitor mInputMonitor; private InputEventReceiver mInputEventReceiver; + @Nullable + private final PipPerfHintController mPipPerfHintController; + + @Nullable + private PipPerfHintController.PipHighPerfSession mPipHighPerfSession; + private int mCtrlType; private int mOhmOffset; @@ -107,10 +115,11 @@ public class PipResizeGestureHandler { PipDismissTargetHandler pipDismissTargetHandler, Runnable updateMovementBoundsRunnable, PipUiEventLogger pipUiEventLogger, PhonePipMenuController menuActivityController, - ShellExecutor mainExecutor) { + ShellExecutor mainExecutor, @Nullable PipPerfHintController pipPerfHintController) { mContext = context; mDisplayId = context.getDisplayId(); mMainExecutor = mainExecutor; + mPipPerfHintController = pipPerfHintController; mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipBoundsState = pipBoundsState; mMotionHelper = motionHelper; @@ -266,6 +275,16 @@ public class PipResizeGestureHandler { return mIsSysUiStateValid; } + private void onHighPerfSessionTimeout(PipPerfHintController.PipHighPerfSession session) {} + + private void cleanUpHighPerfSessionMaybe() { + if (mPipHighPerfSession != null) { + // Close the high perf session once pointer interactions are over; + mPipHighPerfSession.close(); + mPipHighPerfSession = null; + } + } + @VisibleForTesting void onPinchResize(MotionEvent ev) { int action = ev.getActionMasked(); @@ -275,6 +294,7 @@ public class PipResizeGestureHandler { mSecondIndex = -1; mAllowGesture = false; finishResize(); + cleanUpHighPerfSessionMaybe(); } if (ev.getPointerCount() != 2) { @@ -296,6 +316,12 @@ public class PipResizeGestureHandler { mLastPoint.set(mDownPoint); mLastSecondPoint.set(mLastSecondPoint); mLastResizeBounds.set(mDownBounds); + + // start the high perf session as the second pointer gets detected + if (mPipPerfHintController != null) { + mPipHighPerfSession = mPipPerfHintController.startSession( + this::onHighPerfSessionTimeout, "onPinchResize"); + } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchGesture.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchGesture.java index 1a3cc8b1c1d2..fcac2c6b90ac 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchGesture.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchGesture.java @@ -39,4 +39,9 @@ public abstract class PipTouchGesture { public boolean onUp(PipTouchState touchState) { return false; } + + /** + * Cleans up the high performance hint session if needed. + */ + public void cleanUpHighPerfSessionMaybe() {} } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java index d5925d11ccf0..e7dd31cc1fa9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java @@ -25,8 +25,10 @@ import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTI import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_FULL; import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_NONE; import static com.android.wm.shell.pip.phone.PipMenuView.ANIM_TYPE_NONE; +import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SuppressLint; import android.content.ComponentName; import android.content.Context; @@ -53,16 +55,17 @@ import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipDoubleTapHelper; +import com.android.wm.shell.common.pip.PipPerfHintController; import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.common.pip.SizeSpecSource; import com.android.wm.shell.pip.PipAnimationController; import com.android.wm.shell.pip.PipTaskOrganizer; import com.android.wm.shell.pip.PipTransitionController; -import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.sysui.ShellInit; import java.io.PrintWriter; +import java.util.Optional; /** * Manages all the touch handling for PIP on the Phone, including moving, dismissing and expanding @@ -83,6 +86,7 @@ public class PipTouchHandler { private final PipDismissTargetHandler mPipDismissTargetHandler; private final PipTaskOrganizer mPipTaskOrganizer; private final ShellExecutor mMainExecutor; + @Nullable private final PipPerfHintController mPipPerfHintController; private PipResizeGestureHandler mPipResizeGestureHandler; @@ -172,9 +176,11 @@ public class PipTouchHandler { PipMotionHelper pipMotionHelper, FloatingContentCoordinator floatingContentCoordinator, PipUiEventLogger pipUiEventLogger, - ShellExecutor mainExecutor) { + ShellExecutor mainExecutor, + Optional<PipPerfHintController> pipPerfHintControllerOptional) { mContext = context; mMainExecutor = mainExecutor; + mPipPerfHintController = pipPerfHintControllerOptional.orElse(null); mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipBoundsState = pipBoundsState; @@ -208,7 +214,7 @@ public class PipTouchHandler { new PipResizeGestureHandler(context, pipBoundsAlgorithm, pipBoundsState, mMotionHelper, mTouchState, pipTaskOrganizer, mPipDismissTargetHandler, this::updateMovementBounds, pipUiEventLogger, - menuController, mainExecutor); + menuController, mainExecutor, mPipPerfHintController); mConnection = new PipAccessibilityInteractionConnection(mContext, pipBoundsState, mMotionHelper, pipTaskOrganizer, mPipBoundsAlgorithm.getSnapAlgorithm(), this::onAccessibilityShowMenu, this::updateMovementBounds, @@ -520,6 +526,7 @@ public class PipTouchHandler { } if (mPipResizeGestureHandler.hasOngoingGesture()) { + mGesture.cleanUpHighPerfSessionMaybe(); mPipDismissTargetHandler.hideDismissTargetMaybe(); return true; } @@ -542,7 +549,7 @@ public class PipTouchHandler { // Ignore the motion event When the entry animation is waiting to be started if (!mTouchState.isUserInteracting() && mPipTaskOrganizer.isEntryScheduled()) { - ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + ProtoLog.wtf(WM_SHELL_PICTURE_IN_PICTURE, "%s: Waiting to start the entry animation, skip the motion event.", TAG); return true; } @@ -789,12 +796,31 @@ public class PipTouchHandler { private final PointF mDelta = new PointF(); private boolean mShouldHideMenuAfterFling; + @Nullable private PipPerfHintController.PipHighPerfSession mPipHighPerfSession; + + private void onHighPerfSessionTimeout(PipPerfHintController.PipHighPerfSession session) {} + + @Override + public void cleanUpHighPerfSessionMaybe() { + if (mPipHighPerfSession != null) { + // Close the high perf session once pointer interactions are over; + mPipHighPerfSession.close(); + mPipHighPerfSession = null; + } + } + @Override public void onDown(PipTouchState touchState) { if (!touchState.isUserInteracting()) { return; } + if (mPipPerfHintController != null) { + // Cache the PiP high perf session to close it upon touch up. + mPipHighPerfSession = mPipPerfHintController.startSession( + this::onHighPerfSessionTimeout, "DefaultPipTouchGesture#onDown"); + } + Rect bounds = getPossiblyMotionBounds(); mDelta.set(0f, 0f); mStartPosition.set(bounds.left, bounds.top); @@ -937,6 +963,7 @@ public class PipTouchHandler { mTouchState.scheduleDoubleTapTimeoutCallback(); } } + cleanUpHighPerfSessionMaybe(); return true; } @@ -1028,7 +1055,7 @@ public class PipTouchHandler { } final Size estimatedMinMenuSize = mMenuController.getEstimatedMinMenuSize(); if (estimatedMinMenuSize == null) { - ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + ProtoLog.wtf(WM_SHELL_PICTURE_IN_PICTURE, "%s: Failed to get estimated menu size", TAG); return false; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java index cac63eb2a2ad..614ef2ab9831 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java @@ -29,6 +29,7 @@ import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipDisplayLayoutState; import com.android.wm.shell.common.pip.PipMenuController; +import com.android.wm.shell.common.pip.PipPerfHintController; import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.pip.PipAnimationController; @@ -59,6 +60,7 @@ public class TvPipTaskOrganizer extends PipTaskOrganizer { @NonNull TvPipTransition tvPipTransition, @NonNull PipParamsChangedForwarder pipParamsChangedForwarder, Optional<SplitScreenController> splitScreenOptional, + Optional<PipPerfHintController> pipPerfHintControllerOptional, @NonNull DisplayController displayController, @NonNull PipUiEventLogger pipUiEventLogger, @NonNull ShellTaskOrganizer shellTaskOrganizer, @@ -66,8 +68,8 @@ public class TvPipTaskOrganizer extends PipTaskOrganizer { super(context, syncTransactionQueue, pipTransitionState, pipBoundsState, pipDisplayLayoutState, boundsHandler, pipMenuController, pipAnimationController, surfaceTransactionHelper, tvPipTransition, pipParamsChangedForwarder, - splitScreenOptional, displayController, pipUiEventLogger, shellTaskOrganizer, - mainExecutor); + splitScreenOptional, pipPerfHintControllerOptional, displayController, + pipUiEventLogger, shellTaskOrganizer, mainExecutor); mTvPipTransition = tvPipTransition; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java index 05e4af3302af..ad29d15019c5 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java @@ -26,6 +26,8 @@ import com.android.internal.protolog.common.IProtoLogGroup; public enum ShellProtoLogGroup implements IProtoLogGroup { // NOTE: Since we enable these from the same WM ShellCommand, these names should not conflict // with those in the framework ProtoLogGroup + WM_SHELL(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true, + Consts.TAG_WM_SHELL), WM_SHELL_INIT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true, Consts.TAG_WM_SHELL), WM_SHELL_TASK_ORG(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java index dffcc6df79d8..b5ea1b1b43ea 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java @@ -24,6 +24,7 @@ import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED; import static android.view.WindowManager.TRANSIT_SLEEP; import static android.view.WindowManager.TRANSIT_TO_FRONT; +import static android.window.TransitionInfo.FLAG_TRANSLUCENT; import static com.android.wm.shell.util.SplitBounds.KEY_EXTRA_SPLIT_BOUNDS; @@ -929,7 +930,14 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { Slog.e(TAG, "Duplicate call to finish"); return; } - if (!toHome) { + + boolean returningToApp = !toHome + && !mWillFinishToHome + && mPausingTasks != null + && mState == STATE_NORMAL; + if (returningToApp && allAppsAreTranslucent(mPausingTasks)) { + mHomeTransitionObserver.notifyHomeVisibilityChanged(true); + } else if (!toHome) { // For some transitions, we may have notified home activity that it became visible. // We need to notify the observer that we are no longer going home. mHomeTransitionObserver.notifyHomeVisibilityChanged(false); @@ -948,7 +956,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { if (toHome) wct.reorder(mRecentsTask, true /* toTop */); else wct.restoreTransientOrder(mRecentsTask); } - if (!toHome && !mWillFinishToHome && mPausingTasks != null && mState == STATE_NORMAL) { + if (returningToApp) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, " returning to app"); // The gesture is returning to the pausing-task(s) rather than continuing with // recents, so end the transition by moving the app back to the top (and also @@ -1048,6 +1056,18 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { } } + private boolean allAppsAreTranslucent(ArrayList<TaskState> tasks) { + if (tasks == null || tasks.isEmpty()) { + return false; + } + for (int i = tasks.size() - 1; i >= 0; --i) { + if (!tasks.get(i).mIsTranslucent) { + return false; + } + } + return true; + } + private void cleanUpPausingOrClosingTask(TaskState task, WindowContainerTransaction wct, SurfaceControl.Transaction finishTransaction, boolean sendUserLeaveHint) { if (!sendUserLeaveHint && task.isLeaf()) { @@ -1118,6 +1138,9 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { /** The surface/leash of the task provided by Core. */ SurfaceControl mTaskSurface; + /** True when the task is translucent. */ + final boolean mIsTranslucent; + /** The (local) animation-leash created for this task. Only non-null for leafs. */ @Nullable SurfaceControl mLeash; @@ -1126,6 +1149,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { mToken = change.getContainer(); mTaskInfo = change.getTaskInfo(); mTaskSurface = change.getLeash(); + mIsTranslucent = (change.getFlags() & FLAG_TRANSLUCENT) != 0; mLeash = leash; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index 1b124c2168df..53dd981755d2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -23,25 +23,22 @@ import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.RemoteAnimationTarget.MODE_OPENING; -import static android.view.WindowManager.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI; import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; +import static com.android.wm.shell.common.MultiInstanceHelper.getComponent; +import static com.android.wm.shell.common.MultiInstanceHelper.getShortcutComponent; +import static com.android.wm.shell.common.MultiInstanceHelper.samePackage; import static com.android.wm.shell.common.split.SplitScreenConstants.KEY_EXTRA_WIDGET_INTENT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; -import static com.android.wm.shell.common.split.SplitScreenUtils.getComponent; -import static com.android.wm.shell.common.split.SplitScreenUtils.getShortcutComponent; import static com.android.wm.shell.common.split.SplitScreenUtils.isValidToSplit; import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition; -import static com.android.wm.shell.common.split.SplitScreenUtils.samePackage; import static com.android.wm.shell.common.split.SplitScreenUtils.splitFailureMessage; import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED; import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SPLIT_SCREEN; import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS; -import android.annotation.NonNull; -import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.ActivityTaskManager; @@ -51,7 +48,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; -import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.graphics.Rect; import android.os.Bundle; @@ -73,6 +69,8 @@ import android.window.WindowContainerTransaction; import androidx.annotation.BinderThread; import androidx.annotation.IntDef; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.InstanceId; @@ -86,6 +84,7 @@ import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.ExternalInterfaceBinder; import com.android.wm.shell.common.LaunchAdjacentController; +import com.android.wm.shell.common.MultiInstanceHelper; import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SingleInstanceRemoteListener; @@ -138,7 +137,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, public static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9; public static final int EXIT_REASON_RECREATE_SPLIT = 10; public static final int EXIT_REASON_FULLSCREEN_SHORTCUT = 11; - public static final int EXIT_REASON_ENTER_DESKTOP = 12; + public static final int EXIT_REASON_DESKTOP_MODE = 12; @IntDef(value = { EXIT_REASON_UNKNOWN, EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW, @@ -152,7 +151,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, EXIT_REASON_CHILD_TASK_ENTER_PIP, EXIT_REASON_RECREATE_SPLIT, EXIT_REASON_FULLSCREEN_SHORTCUT, - EXIT_REASON_ENTER_DESKTOP + EXIT_REASON_DESKTOP_MODE }) @Retention(RetentionPolicy.SOURCE) @interface ExitReason{} @@ -176,7 +175,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, private final ShellTaskOrganizer mTaskOrganizer; private final SyncTransactionQueue mSyncQueue; private final Context mContext; - private final PackageManager mPackageManager; private final LauncherApps mLauncherApps; private final RootTaskDisplayAreaOrganizer mRootTDAOrganizer; private final ShellExecutor mMainExecutor; @@ -192,9 +190,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, private final LaunchAdjacentController mLaunchAdjacentController; private final Optional<WindowDecorViewModel> mWindowDecorViewModel; private final Optional<DesktopTasksController> mDesktopTasksController; + private final MultiInstanceHelper mMultiInstanceHelpher; private final SplitScreenShellCommandHandler mSplitScreenShellCommandHandler; - // A static allow list of apps which support multi-instance - private final String[] mAppsSupportingMultiInstance; @VisibleForTesting StageCoordinator mStageCoordinator; @@ -204,6 +201,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, private SurfaceControl mGoingToRecentsTasksLayer; private SurfaceControl mStartingSplitTasksLayer; + /** + * @param stageCoordinator if null, a stage coordinator will be created when this controller is + * initialized. Can be non-null for testing purposes. + */ public SplitScreenController(Context context, ShellInit shellInit, ShellCommandHandler shellCommandHandler, @@ -222,13 +223,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, LaunchAdjacentController launchAdjacentController, Optional<WindowDecorViewModel> windowDecorViewModel, Optional<DesktopTasksController> desktopTasksController, + @Nullable StageCoordinator stageCoordinator, + MultiInstanceHelper multiInstanceHelper, ShellExecutor mainExecutor) { mShellCommandHandler = shellCommandHandler; mShellController = shellController; mTaskOrganizer = shellTaskOrganizer; mSyncQueue = syncQueue; mContext = context; - mPackageManager = context.getPackageManager(); mLauncherApps = context.getSystemService(LauncherApps.class); mRootTDAOrganizer = rootTDAOrganizer; mMainExecutor = mainExecutor; @@ -243,65 +245,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, mLaunchAdjacentController = launchAdjacentController; mWindowDecorViewModel = windowDecorViewModel; mDesktopTasksController = desktopTasksController; + mStageCoordinator = stageCoordinator; + mMultiInstanceHelpher = multiInstanceHelper; mSplitScreenShellCommandHandler = new SplitScreenShellCommandHandler(this); // TODO(b/238217847): Temporarily add this check here until we can remove the dynamic // override for this controller from the base module if (ActivityTaskManager.supportsSplitScreenMultiWindow(context)) { shellInit.addInitCallback(this::onInit, this); } - - // TODO(255224696): Remove the config once having a way for client apps to opt-in - // multi-instances split. - mAppsSupportingMultiInstance = mContext.getResources() - .getStringArray(R.array.config_appsSupportMultiInstancesSplit); - } - - @VisibleForTesting - SplitScreenController(Context context, - ShellInit shellInit, - ShellCommandHandler shellCommandHandler, - ShellController shellController, - ShellTaskOrganizer shellTaskOrganizer, - SyncTransactionQueue syncQueue, - RootTaskDisplayAreaOrganizer rootTDAOrganizer, - DisplayController displayController, - DisplayImeController displayImeController, - DisplayInsetsController displayInsetsController, - DragAndDropController dragAndDropController, - Transitions transitions, - TransactionPool transactionPool, - IconProvider iconProvider, - RecentTasksController recentTasks, - LaunchAdjacentController launchAdjacentController, - WindowDecorViewModel windowDecorViewModel, - DesktopTasksController desktopTasksController, - ShellExecutor mainExecutor, - StageCoordinator stageCoordinator, - String[] appsSupportingMultiInstance) { - mShellCommandHandler = shellCommandHandler; - mShellController = shellController; - mTaskOrganizer = shellTaskOrganizer; - mSyncQueue = syncQueue; - mContext = context; - mPackageManager = context.getPackageManager(); - mLauncherApps = context.getSystemService(LauncherApps.class); - mRootTDAOrganizer = rootTDAOrganizer; - mMainExecutor = mainExecutor; - mDisplayController = displayController; - mDisplayImeController = displayImeController; - mDisplayInsetsController = displayInsetsController; - mDragAndDropController = dragAndDropController; - mTransitions = transitions; - mTransactionPool = transactionPool; - mIconProvider = iconProvider; - mRecentTasksOptional = Optional.of(recentTasks); - mLaunchAdjacentController = launchAdjacentController; - mWindowDecorViewModel = Optional.of(windowDecorViewModel); - mDesktopTasksController = Optional.of(desktopTasksController); - mStageCoordinator = stageCoordinator; - mSplitScreenShellCommandHandler = new SplitScreenShellCommandHandler(this); - shellInit.addInitCallback(this::onInit, this); - mAppsSupportingMultiInstance = appsSupportingMultiInstance; } public SplitScreen asSplitScreen() { @@ -529,8 +480,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, } /** Move the specified task to fullscreen, regardless of focus state. */ - public void moveTaskToFullscreen(int taskId) { - mStageCoordinator.moveTaskToFullscreen(taskId); + public void moveTaskToFullscreen(int taskId, int exitReason) { + mStageCoordinator.moveTaskToFullscreen(taskId, exitReason); } public boolean isLaunchToSplit(TaskInfo taskInfo) { @@ -613,8 +564,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, if (samePackage(packageName, getPackageName(reverseSplitPosition(position)), user.getIdentifier(), getUserId(reverseSplitPosition(position)))) { - if (supportsMultiInstanceSplit(getShortcutComponent(packageName, shortcutId, user, - mLauncherApps))) { + if (mMultiInstanceHelpher.supportsMultiInstanceSplit( + getShortcutComponent(packageName, shortcutId, user, mLauncherApps))) { activityOptions.setApplyMultipleTaskFlagForShortcut(true); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); } else if (isSplitScreenVisible()) { @@ -647,7 +598,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, final int userId1 = shortcutInfo.getUserId(); final int userId2 = SplitScreenUtils.getUserId(taskId, mTaskOrganizer); if (samePackage(packageName1, packageName2, userId1, userId2)) { - if (supportsMultiInstanceSplit(shortcutInfo.getActivity())) { + if (mMultiInstanceHelpher.supportsMultiInstanceSplit(shortcutInfo.getActivity())) { activityOptions.setApplyMultipleTaskFlagForShortcut(true); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); } else { @@ -679,7 +630,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, final int userId1 = shortcutInfo.getUserId(); final int userId2 = SplitScreenUtils.getUserId(taskId, mTaskOrganizer); if (samePackage(packageName1, packageName2, userId1, userId2)) { - if (supportsMultiInstanceSplit(shortcutInfo.getActivity())) { + if (mMultiInstanceHelpher.supportsMultiInstanceSplit(shortcutInfo.getActivity())) { activityOptions.setApplyMultipleTaskFlagForShortcut(true); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); } else { @@ -718,7 +669,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer); final int userId2 = SplitScreenUtils.getUserId(taskId, mTaskOrganizer); if (samePackage(packageName1, packageName2, userId1, userId2)) { - if (supportsMultiInstanceSplit(getComponent(pendingIntent))) { + if (mMultiInstanceHelpher.supportsMultiInstanceSplit(getComponent(pendingIntent))) { fillInIntent = new Intent(); fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); @@ -748,7 +699,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, final int userId2 = SplitScreenUtils.getUserId(taskId, mTaskOrganizer); boolean setSecondIntentMultipleTask = false; if (samePackage(packageName1, packageName2, userId1, userId2)) { - if (supportsMultiInstanceSplit(getComponent(pendingIntent))) { + if (mMultiInstanceHelpher.supportsMultiInstanceSplit(getComponent(pendingIntent))) { setSecondIntentMultipleTask = true; ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); } else { @@ -783,7 +734,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent1); final String packageName2 = SplitScreenUtils.getPackageName(pendingIntent2); if (samePackage(packageName1, packageName2, userId1, userId2)) { - if (supportsMultiInstanceSplit(getComponent(pendingIntent1))) { + if (mMultiInstanceHelpher.supportsMultiInstanceSplit(getComponent(pendingIntent1))) { fillInIntent1 = new Intent(); fillInIntent1.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); fillInIntent2 = new Intent(); @@ -820,7 +771,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, ? ActivityOptions.fromBundle(options2) : ActivityOptions.makeBasic(); boolean setSecondIntentMultipleTask = false; if (samePackage(packageName1, packageName2, userId1, userId2)) { - if (supportsMultiInstanceSplit(getComponent(pendingIntent1))) { + if (mMultiInstanceHelpher.supportsMultiInstanceSplit(getComponent(pendingIntent1))) { fillInIntent1 = new Intent(); fillInIntent1.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); setSecondIntentMultipleTask = true; @@ -882,7 +833,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return; } if (samePackage(packageName1, packageName2, userId1, userId2)) { - if (supportsMultiInstanceSplit(getComponent(intent))) { + if (mMultiInstanceHelpher.supportsMultiInstanceSplit(getComponent(intent))) { // Flag with MULTIPLE_TASK if this is launching the same activity into both sides of // the split and there is no reusable background task. fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); @@ -942,66 +893,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, } /** - * Returns whether a specific component desires to be launched in multiple instances for - * split screen. - */ - @VisibleForTesting - boolean supportsMultiInstanceSplit(@Nullable ComponentName componentName) { - if (componentName == null || componentName.getPackageName() == null) { - // TODO(b/262864589): Handle empty component case - return false; - } - - // Check the pre-defined allow list - final String packageName = componentName.getPackageName(); - for (int i = 0; i < mAppsSupportingMultiInstance.length; i++) { - if (mAppsSupportingMultiInstance[i].equals(packageName)) { - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, - "application=%s in allowlist supports multi-instance", packageName); - return true; - } - } - - // Check the activity property first - try { - final PackageManager.Property activityProp = mPackageManager.getProperty( - PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, componentName); - // If the above call doesn't throw a NameNotFoundException, then the activity property - // should override the application property value - if (activityProp.isBoolean()) { - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, - "activity=%s supports multi-instance", componentName); - return activityProp.getBoolean(); - } else { - ProtoLog.w(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, - "Warning: property=%s for activity=%s has non-bool type=%d", - PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName, - activityProp.getType()); - } - } catch (PackageManager.NameNotFoundException nnfe) { - // Not specified in the activity, fall through - } - - // Check the application property otherwise - try { - final PackageManager.Property appProp = mPackageManager.getProperty( - PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName); - if (appProp.isBoolean()) { - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, - "application=%s supports multi-instance", packageName); - return appProp.getBoolean(); - } else { - ProtoLog.w(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, - "Warning: property=%s for application=%s has non-bool type=%d", - PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName, appProp.getType()); - } - } catch (PackageManager.NameNotFoundException nnfe) { - // Not specified in either application or activity - } - return false; - } - - /** * Determines whether the widgetIntent needs to be modified if multiple tasks of its * corresponding package/app are supported. There are 4 possible paths: * <li> We select a widget for second app which is the same as the first app </li> @@ -1144,8 +1035,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return "CHILD_TASK_ENTER_PIP"; case EXIT_REASON_RECREATE_SPLIT: return "RECREATE_SPLIT"; - case EXIT_REASON_ENTER_DESKTOP: - return "ENTER_DESKTOP"; + case EXIT_REASON_DESKTOP_MODE: + return "DESKTOP_MODE"; default: return "unknown reason, reason int = " + exitReason; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java index f4ab2266179a..a0bf843444df 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java @@ -25,7 +25,7 @@ import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED_ import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DEVICE_FOLDED; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DRAG_DIVIDER; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__FULLSCREEN_SHORTCUT; -import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__ENTER_DESKTOP; +import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DESKTOP_MODE; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RECREATE_SPLIT; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__ROOT_TASK_VANISHED; @@ -43,7 +43,7 @@ import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER; -import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_ENTER_DESKTOP; +import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DESKTOP_MODE; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_SHORTCUT; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RECREATE_SPLIT; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME; @@ -194,8 +194,8 @@ public class SplitscreenEventLogger { return SPLITSCREEN_UICHANGED__EXIT_REASON__RECREATE_SPLIT; case EXIT_REASON_FULLSCREEN_SHORTCUT: return SPLITSCREEN_UICHANGED__EXIT_REASON__FULLSCREEN_SHORTCUT; - case EXIT_REASON_ENTER_DESKTOP: - return SPLITSCREEN_UICHANGED__EXIT_REASON__ENTER_DESKTOP; + case EXIT_REASON_DESKTOP_MODE: + return SPLITSCREEN_UICHANGED__EXIT_REASON__DESKTOP_MODE; case EXIT_REASON_UNKNOWN: // Fall through default: diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 70b2f211d943..fa14b4c64fe0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -2973,7 +2973,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } /** Move the specified task to fullscreen, regardless of focus state. */ - public void moveTaskToFullscreen(int taskId) { + public void moveTaskToFullscreen(int taskId, int exitReason) { boolean leftOrTop; if (mMainStage.containsTask(taskId)) { leftOrTop = (mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT); @@ -2982,7 +2982,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } else { return; } - mSplitLayout.flingDividerToDismiss(!leftOrTop, EXIT_REASON_FULLSCREEN_SHORTCUT); + mSplitLayout.flingDividerToDismiss(!leftOrTop, exitReason); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java index aec4d1176dc0..e330f3ab65ab 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java @@ -28,6 +28,7 @@ import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.LaunchAdjacentController; +import com.android.wm.shell.common.MultiInstanceHelper; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; @@ -79,6 +80,7 @@ public class TvSplitScreenController extends SplitScreenController { IconProvider iconProvider, Optional<RecentTasksController> recentTasks, LaunchAdjacentController launchAdjacentController, + MultiInstanceHelper multiInstanceHelper, ShellExecutor mainExecutor, Handler mainHandler, SystemWindows systemWindows) { @@ -86,7 +88,7 @@ public class TvSplitScreenController extends SplitScreenController { syncQueue, rootTDAOrganizer, displayController, displayImeController, displayInsetsController, null, transitions, transactionPool, iconProvider, recentTasks, launchAdjacentController, Optional.empty(), - Optional.empty(), mainExecutor); + Optional.empty(), null /* stageCoordinator */, multiInstanceHelper, mainExecutor); mTaskOrganizer = shellTaskOrganizer; mSyncQueue = syncQueue; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index 7db3d382ed8e..c713a2ed24b0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -339,7 +339,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { final int id = v.getId(); if (id == R.id.close_window) { if (isTaskInSplitScreen(mTaskId)) { - mSplitScreenController.moveTaskToFullscreen(getOtherSplitTask(mTaskId).taskId); + mSplitScreenController.moveTaskToFullscreen(getOtherSplitTask(mTaskId).taskId, + SplitScreenController.EXIT_REASON_DESKTOP_MODE); } else { mTaskOperations.closeTask(mTaskToken); } @@ -365,7 +366,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { } else if (id == R.id.fullscreen_button) { decoration.closeHandleMenu(); if (isTaskInSplitScreen(mTaskId)) { - mSplitScreenController.moveTaskToFullscreen(mTaskId); + mSplitScreenController.moveTaskToFullscreen(mTaskId, + SplitScreenController.EXIT_REASON_DESKTOP_MODE); } else { mDesktopTasksController.ifPresent(c -> c.moveToFullscreen(mTaskId)); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java index 7c6e69eb1ec9..5c69d5542227 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java @@ -61,7 +61,6 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback, private int mCtrlType; private boolean mIsResizingOrAnimatingResize; @Surface.Rotation private int mRotation; - private boolean mVeilIsVisible; public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, DesktopModeWindowDecoration windowDecoration, @@ -119,10 +118,9 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback, if (isResizing() && DragPositioningCallbackUtility.changeBounds(mCtrlType, mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, delta, mDisplayController, mDesktopWindowDecoration)) { - mIsResizingOrAnimatingResize = true; - if (!mVeilIsVisible) { + if (!mIsResizingOrAnimatingResize) { mDesktopWindowDecoration.showResizeVeil(mRepositionTaskBounds); - mVeilIsVisible = true; + mIsResizingOrAnimatingResize = true; } else { mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds); } @@ -148,11 +146,10 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback, final WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setBounds(mDesktopWindowDecoration.mTaskInfo.token, mRepositionTaskBounds); mTransitions.startTransition(TRANSIT_CHANGE, wct, this); - } else if (mVeilIsVisible) { + } else { // If bounds haven't changed, perform necessary veil reset here as startAnimation // won't be called. - mDesktopWindowDecoration.hideResizeVeil(); - mIsResizingOrAnimatingResize = false; + resetVeilIfVisible(); } } else if (DragPositioningCallbackUtility.isBelowDisallowedArea( mDisallowedAreaForEndBoundsHeight, mTaskBoundsAtDragStart, mRepositionStartPoint, @@ -168,7 +165,6 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback, mCtrlType = CTRL_TYPE_UNDEFINED; mTaskBoundsAtDragStart.setEmpty(); mRepositionStartPoint.set(0, 0); - mVeilIsVisible = false; return new Rect(mRepositionTaskBounds); } @@ -177,6 +173,13 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback, || (mCtrlType & CTRL_TYPE_LEFT) != 0 || (mCtrlType & CTRL_TYPE_RIGHT) != 0; } + private void resetVeilIfVisible() { + if (mIsResizingOrAnimatingResize) { + mDesktopWindowDecoration.hideResizeVeil(); + mIsResizingOrAnimatingResize = false; + } + } + @Override public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @@ -192,7 +195,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback, } startTransaction.apply(); - mDesktopWindowDecoration.hideResizeVeil(); + resetVeilIfVisible(); mCtrlType = CTRL_TYPE_UNDEFINED; finishCallback.onTransitionFinished(null); mIsResizingOrAnimatingResize = false; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/MultiInstanceHelperTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/MultiInstanceHelperTest.kt new file mode 100644 index 000000000000..2f5fe11634a4 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/MultiInstanceHelperTest.kt @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.common + +import android.app.ActivityTaskManager +import android.content.ComponentName +import android.content.pm.LauncherApps +import android.content.pm.PackageManager +import android.content.pm.ShortcutInfo +import android.os.UserHandle +import android.view.WindowManager.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.wm.shell.ShellTestCase +import org.junit.Assert.assertEquals +import org.junit.Assume.assumeTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers +import org.mockito.ArgumentMatchers.eq +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.doThrow +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +@RunWith(AndroidJUnit4::class) +class MultiInstanceHelperTest : ShellTestCase() { + + @Before + fun setup() { + assumeTrue(ActivityTaskManager.supportsSplitScreenMultiWindow(mContext)) + } + + @Test + fun getShortcutComponent_nullShortcuts() { + val launcherApps = mock<LauncherApps>() + whenever(launcherApps.getShortcuts(ArgumentMatchers.any(), ArgumentMatchers.any())) + .thenReturn(null) + assertEquals(null, MultiInstanceHelper.getShortcutComponent(TEST_PACKAGE, + TEST_SHORTCUT_ID, UserHandle.CURRENT, launcherApps)) + } + + @Test + fun getShortcutComponent_noShortcuts() { + val launcherApps = mock<LauncherApps>() + whenever(launcherApps.getShortcuts(ArgumentMatchers.any(), ArgumentMatchers.any())) + .thenReturn(ArrayList<ShortcutInfo>()) + assertEquals(null, MultiInstanceHelper.getShortcutComponent(TEST_PACKAGE, + TEST_SHORTCUT_ID, UserHandle.CURRENT, launcherApps)) + } + + @Test + fun getShortcutComponent_validShortcut() { + val component = ComponentName(TEST_PACKAGE, TEST_ACTIVITY) + val shortcutInfo = ShortcutInfo.Builder(context, "id").setActivity(component).build() + val launcherApps = mock<LauncherApps>() + whenever(launcherApps.getShortcuts(ArgumentMatchers.any(), ArgumentMatchers.any())) + .thenReturn(arrayListOf(shortcutInfo)) + assertEquals(component, MultiInstanceHelper.getShortcutComponent(TEST_PACKAGE, + TEST_SHORTCUT_ID, UserHandle.CURRENT, launcherApps)) + } + + @Test + fun supportsMultiInstanceSplit_inStaticAllowList() { + val allowList = arrayOf(TEST_PACKAGE) + val helper = MultiInstanceHelper(mContext, context.packageManager, allowList) + val component = ComponentName(TEST_PACKAGE, TEST_ACTIVITY) + assertEquals(true, helper.supportsMultiInstanceSplit(component)) + } + + @Test + fun supportsMultiInstanceSplit_notInStaticAllowList() { + val allowList = arrayOf(TEST_PACKAGE) + val helper = MultiInstanceHelper(mContext, context.packageManager, allowList) + val component = ComponentName(TEST_NOT_ALLOWED_PACKAGE, TEST_ACTIVITY) + assertEquals(false, helper.supportsMultiInstanceSplit(component)) + } + + @Test + @Throws(PackageManager.NameNotFoundException::class) + fun supportsMultiInstanceSplit_activityPropertyTrue() { + val component = ComponentName(TEST_PACKAGE, TEST_ACTIVITY) + val pm = mock<PackageManager>() + val activityProp = PackageManager.Property("", true, "", "") + whenever(pm.getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), + eq(component))) + .thenReturn(activityProp) + val appProp = PackageManager.Property("", false, "", "") + whenever(pm.getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), + eq(component.packageName))) + .thenReturn(appProp) + + val helper = MultiInstanceHelper(mContext, pm, emptyArray()) + // Expect activity property to override application property + assertEquals(true, helper.supportsMultiInstanceSplit(component)) + } + + @Test + @Throws(PackageManager.NameNotFoundException::class) + fun supportsMultiInstanceSplit_activityPropertyFalseApplicationPropertyTrue() { + val component = ComponentName(TEST_PACKAGE, TEST_ACTIVITY) + val pm = mock<PackageManager>() + val activityProp = PackageManager.Property("", false, "", "") + whenever(pm.getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), + eq(component))) + .thenReturn(activityProp) + val appProp = PackageManager.Property("", true, "", "") + whenever(pm.getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), + eq(component.packageName))) + .thenReturn(appProp) + + val helper = MultiInstanceHelper(mContext, pm, emptyArray()) + // Expect activity property to override application property + assertEquals(false, helper.supportsMultiInstanceSplit(component)) + } + + @Test + @Throws(PackageManager.NameNotFoundException::class) + fun supportsMultiInstanceSplit_noActivityPropertyApplicationPropertyTrue() { + val component = ComponentName(TEST_PACKAGE, TEST_ACTIVITY) + val pm = mock<PackageManager>() + whenever(pm.getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), + eq(component))) + .thenThrow(PackageManager.NameNotFoundException()) + val appProp = PackageManager.Property("", true, "", "") + whenever(pm.getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), + eq(component.packageName))) + .thenReturn(appProp) + + val helper = MultiInstanceHelper(mContext, pm, emptyArray()) + // Expect fall through to app property + assertEquals(true, helper.supportsMultiInstanceSplit(component)) + } + + @Test + @Throws(PackageManager.NameNotFoundException::class) + fun supportsMultiInstanceSplit_noActivityOrAppProperty() { + val component = ComponentName(TEST_PACKAGE, TEST_ACTIVITY) + val pm = mock<PackageManager>() + whenever(pm.getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), + eq(component))) + .thenThrow(PackageManager.NameNotFoundException()) + whenever(pm.getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), + eq(component.packageName))) + .thenThrow(PackageManager.NameNotFoundException()) + + val helper = MultiInstanceHelper(mContext, pm, emptyArray()) + assertEquals(false, helper.supportsMultiInstanceSplit(component)) + } + + companion object { + val TEST_PACKAGE = "com.android.wm.shell.common" + val TEST_NOT_ALLOWED_PACKAGE = "com.android.wm.shell.common.fake"; + val TEST_ACTIVITY = "TestActivity"; + val TEST_SHORTCUT_ID = "test_shortcut_1" + } +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitScreenUtilsTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitScreenUtilsTests.kt deleted file mode 100644 index 955660c396d0..000000000000 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitScreenUtilsTests.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.common.split - -import android.content.ComponentName -import android.content.pm.LauncherApps -import android.content.pm.ShortcutInfo -import android.os.UserHandle -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.android.wm.shell.ShellTestCase -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.any -import org.mockito.Mockito.mock -import org.mockito.Mockito.`when` - -@RunWith(AndroidJUnit4::class) -class SplitScreenUtilsTests : ShellTestCase() { - - @Test - fun getShortcutComponent_nullShortcuts() { - val launcherApps = mock(LauncherApps::class.java).also { - `when`(it.getShortcuts(any(), any())).thenReturn(null) - } - assertEquals(null, SplitScreenUtils.getShortcutComponent(TEST_PACKAGE, - TEST_SHORTCUT_ID, UserHandle.CURRENT, launcherApps)) - } - - @Test - fun getShortcutComponent_noShortcuts() { - val launcherApps = mock(LauncherApps::class.java).also { - `when`(it.getShortcuts(any(), any())).thenReturn(ArrayList<ShortcutInfo>()) - } - assertEquals(null, SplitScreenUtils.getShortcutComponent(TEST_PACKAGE, - TEST_SHORTCUT_ID, UserHandle.CURRENT, launcherApps)) - } - - @Test - fun getShortcutComponent_validShortcut() { - val component = ComponentName(TEST_PACKAGE, TEST_ACTIVITY) - val shortcutInfo = ShortcutInfo.Builder(context, "id").setActivity(component).build() - val launcherApps = mock(LauncherApps::class.java).also { - `when`(it.getShortcuts(any(), any())).thenReturn(arrayListOf(shortcutInfo)) - } - assertEquals(component, SplitScreenUtils.getShortcutComponent(TEST_PACKAGE, - TEST_SHORTCUT_ID, UserHandle.CURRENT, launcherApps)) - } - - companion object { - val TEST_PACKAGE = "com.android.wm.shell.common.split" - val TEST_ACTIVITY = "TestActivity"; - val TEST_SHORTCUT_ID = "test_shortcut_1" - } -}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt index 79634e6040c4..63618f4d0673 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt @@ -373,7 +373,7 @@ class DesktopTasksControllerTest : ShellTestCase() { assertThat(wct.changes[task.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FREEFORM) verify(splitScreenController).prepareExitSplitScreen(any(), anyInt(), - eq(SplitScreenController.EXIT_REASON_ENTER_DESKTOP) + eq(SplitScreenController.EXIT_REASON_DESKTOP_MODE) ) } @@ -385,7 +385,7 @@ class DesktopTasksControllerTest : ShellTestCase() { assertThat(wct.changes[task.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FREEFORM) verify(splitScreenController, never()).prepareExitSplitScreen(any(), anyInt(), - eq(SplitScreenController.EXIT_REASON_ENTER_DESKTOP) + eq(SplitScreenController.EXIT_REASON_DESKTOP_MODE) ) } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java index 800f9e4e5371..d4e9ac96d221 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java @@ -118,7 +118,8 @@ public class PipTaskOrganizerTest extends ShellTestCase { mPipTransitionState, mPipBoundsState, mPipDisplayLayoutState, mPipBoundsAlgorithm, mMockPhonePipMenuController, mMockPipAnimationController, mMockPipSurfaceTransactionHelper, mMockPipTransitionController, - mMockPipParamsChangedForwarder, mMockOptionalSplitScreen, mMockDisplayController, + mMockPipParamsChangedForwarder, mMockOptionalSplitScreen, + Optional.empty() /* pipPerfHintControllerOptional */, mMockDisplayController, mMockPipUiEventLogger, mMockShellTaskOrganizer, mMainExecutor); mMainExecutor.flushAll(); preparePipTaskOrg(); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java index cc726cb0adcf..ace09a82d71c 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java @@ -55,6 +55,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Optional; + /** * Unit tests against {@link PipResizeGestureHandler} */ @@ -114,7 +116,8 @@ public class PipResizeGestureHandlerTest extends ShellTestCase { mSizeSpecSource); final PipMotionHelper motionHelper = new PipMotionHelper(mContext, mPipBoundsState, mPipTaskOrganizer, mPhonePipMenuController, pipSnapAlgorithm, - mMockPipTransitionController, mFloatingContentCoordinator); + mMockPipTransitionController, mFloatingContentCoordinator, + Optional.empty() /* pipPerfHintControllerOptional */); mPipTouchState = new PipTouchState(ViewConfiguration.get(mContext), () -> {}, () -> {}, mMainExecutor); @@ -122,7 +125,7 @@ public class PipResizeGestureHandlerTest extends ShellTestCase { mPipBoundsState, motionHelper, mPipTouchState, mPipTaskOrganizer, mPipDismissTargetHandler, () -> {}, mPipUiEventLogger, mPhonePipMenuController, - mMainExecutor) { + mMainExecutor, null /* pipPerfHintController */) { @Override public void pilferPointers() { // Overridden just to avoid calling into InputMonitor. diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java index 9aaabd130527..92762fa68550 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java @@ -51,6 +51,8 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import java.util.Optional; + /** * Unit tests against {@link PipTouchHandler}, including but not limited to: * - Update movement bounds based on new bounds @@ -116,10 +118,12 @@ public class PipTouchHandlerTest extends ShellTestCase { new PipKeepClearAlgorithmInterface() {}, mPipDisplayLayoutState, mSizeSpecSource); PipMotionHelper pipMotionHelper = new PipMotionHelper(mContext, mPipBoundsState, mPipTaskOrganizer, mPhonePipMenuController, mPipSnapAlgorithm, - mMockPipTransitionController, mFloatingContentCoordinator); + mMockPipTransitionController, mFloatingContentCoordinator, + Optional.empty() /* pipPerfHintControllerOptional */); mPipTouchHandler = new PipTouchHandler(mContext, mShellInit, mPhonePipMenuController, mPipBoundsAlgorithm, mPipBoundsState, mSizeSpecSource, mPipTaskOrganizer, - pipMotionHelper, mFloatingContentCoordinator, mPipUiEventLogger, mMainExecutor); + pipMotionHelper, mFloatingContentCoordinator, mPipUiEventLogger, mMainExecutor, + Optional.empty() /* pipPerfHintControllerOptional */); // We aren't actually using ShellInit, so just call init directly mPipTouchHandler.onInit(); mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper()); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java index 7f3bfbb0e81d..315d97ed333b 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java @@ -22,7 +22,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION; -import static android.view.WindowManager.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; @@ -37,8 +36,6 @@ import static org.mockito.ArgumentMatchers.isA; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -49,10 +46,8 @@ import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.PendingIntent; import android.content.ComponentName; -import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; import android.os.Bundle; import androidx.test.annotation.UiThreadTest; @@ -60,7 +55,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.launcher3.icons.IconProvider; -import com.android.wm.shell.R; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; @@ -69,6 +63,7 @@ import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.LaunchAdjacentController; +import com.android.wm.shell.common.MultiInstanceHelper; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TransactionPool; @@ -90,6 +85,8 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Optional; + /** * Tests for {@link SplitScreenController} */ @@ -97,10 +94,6 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class SplitScreenControllerTests extends ShellTestCase { - private static final String TEST_PACKAGE = "com.android.wm.shell.splitscreen"; - private static final String TEST_NOT_ALLOWED_PACKAGE = "com.android.wm.shell.splitscreen.fake"; - private static final String TEST_ACTIVITY = "TestActivity"; - @Mock ShellInit mShellInit; @Mock ShellCommandHandler mShellCommandHandler; @Mock ShellTaskOrganizer mTaskOrganizer; @@ -119,6 +112,7 @@ public class SplitScreenControllerTests extends ShellTestCase { @Mock LaunchAdjacentController mLaunchAdjacentController; @Mock WindowDecorViewModel mWindowDecorViewModel; @Mock DesktopTasksController mDesktopTasksController; + @Mock MultiInstanceHelper mMultiInstanceHelper; @Captor ArgumentCaptor<Intent> mIntentCaptor; private ShellController mShellController; @@ -128,17 +122,15 @@ public class SplitScreenControllerTests extends ShellTestCase { public void setup() { assumeTrue(ActivityTaskManager.supportsSplitScreenMultiWindow(mContext)); MockitoAnnotations.initMocks(this); - String[] appsSupportingMultiInstance = mContext.getResources() - .getStringArray(R.array.config_appsSupportMultiInstancesSplit); mShellController = spy(new ShellController(mContext, mShellInit, mShellCommandHandler, mMainExecutor)); mSplitScreenController = spy(new SplitScreenController(mContext, mShellInit, mShellCommandHandler, mShellController, mTaskOrganizer, mSyncQueue, mRootTDAOrganizer, mDisplayController, mDisplayImeController, mDisplayInsetsController, mDragAndDropController, mTransitions, mTransactionPool, - mIconProvider, mRecentTasks, mLaunchAdjacentController, mWindowDecorViewModel, - mDesktopTasksController, mMainExecutor, mStageCoordinator, - appsSupportingMultiInstance)); + mIconProvider, Optional.of(mRecentTasks), mLaunchAdjacentController, + Optional.of(mWindowDecorViewModel), Optional.of(mDesktopTasksController), + mStageCoordinator, mMultiInstanceHelper, mMainExecutor)); } @Test @@ -213,7 +205,7 @@ public class SplitScreenControllerTests extends ShellTestCase { @Test public void startIntent_multiInstancesSupported_appendsMultipleTaskFag() { - doReturn(true).when(mSplitScreenController).supportsMultiInstanceSplit(any()); + doReturn(true).when(mMultiInstanceHelper).supportsMultiInstanceSplit(any()); Intent startIntent = createStartIntent("startActivity"); PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE); @@ -250,13 +242,13 @@ public class SplitScreenControllerTests extends ShellTestCase { verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT), isNull()); - verify(mSplitScreenController, never()).supportsMultiInstanceSplit(any()); + verify(mMultiInstanceHelper, never()).supportsMultiInstanceSplit(any()); verify(mStageCoordinator, never()).switchSplitPosition(any()); } @Test public void startIntent_multiInstancesSupported_startTaskInBackgroundAfterSplitActivated() { - doReturn(true).when(mSplitScreenController).supportsMultiInstanceSplit(any()); + doReturn(true).when(mMultiInstanceHelper).supportsMultiInstanceSplit(any()); doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any()); Intent startIntent = createStartIntent("startActivity"); PendingIntent pendingIntent = @@ -273,14 +265,14 @@ public class SplitScreenControllerTests extends ShellTestCase { mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null, SPLIT_POSITION_TOP_OR_LEFT, null); - verify(mSplitScreenController, never()).supportsMultiInstanceSplit(any()); + verify(mMultiInstanceHelper, never()).supportsMultiInstanceSplit(any()); verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT), isNull()); } @Test public void startIntent_multiInstancesNotSupported_switchesPositionAfterSplitActivated() { - doReturn(false).when(mSplitScreenController).supportsMultiInstanceSplit(any()); + doReturn(false).when(mMultiInstanceHelper).supportsMultiInstanceSplit(any()); Intent startIntent = createStartIntent("startActivity"); PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE); @@ -298,130 +290,6 @@ public class SplitScreenControllerTests extends ShellTestCase { } @Test - public void supportsMultiInstanceSplit_inStaticAllowList() { - String[] allowList = { TEST_PACKAGE }; - SplitScreenController controller = new SplitScreenController(mContext, mShellInit, - mShellCommandHandler, mShellController, mTaskOrganizer, mSyncQueue, - mRootTDAOrganizer, mDisplayController, mDisplayImeController, - mDisplayInsetsController, mDragAndDropController, mTransitions, mTransactionPool, - mIconProvider, mRecentTasks, mLaunchAdjacentController, mWindowDecorViewModel, - mDesktopTasksController, mMainExecutor, mStageCoordinator, - allowList); - ComponentName component = new ComponentName(TEST_PACKAGE, TEST_ACTIVITY); - assertEquals(true, controller.supportsMultiInstanceSplit(component)); - } - - @Test - public void supportsMultiInstanceSplit_notInStaticAllowList() { - String[] allowList = { TEST_PACKAGE }; - SplitScreenController controller = new SplitScreenController(mContext, mShellInit, - mShellCommandHandler, mShellController, mTaskOrganizer, mSyncQueue, - mRootTDAOrganizer, mDisplayController, mDisplayImeController, - mDisplayInsetsController, mDragAndDropController, mTransitions, mTransactionPool, - mIconProvider, mRecentTasks, mLaunchAdjacentController, mWindowDecorViewModel, - mDesktopTasksController, mMainExecutor, mStageCoordinator, - allowList); - ComponentName component = new ComponentName(TEST_NOT_ALLOWED_PACKAGE, TEST_ACTIVITY); - assertEquals(false, controller.supportsMultiInstanceSplit(component)); - } - - @Test - public void supportsMultiInstanceSplit_activityPropertyTrue() - throws PackageManager.NameNotFoundException { - Context context = spy(mContext); - ComponentName component = new ComponentName(TEST_PACKAGE, TEST_ACTIVITY); - PackageManager pm = mock(PackageManager.class); - doReturn(pm).when(context).getPackageManager(); - PackageManager.Property activityProp = new PackageManager.Property("", true, "", ""); - doReturn(activityProp).when(pm).getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), - eq(component)); - PackageManager.Property appProp = new PackageManager.Property("", false, "", ""); - doReturn(appProp).when(pm).getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), - eq(component.getPackageName())); - - SplitScreenController controller = new SplitScreenController(context, mShellInit, - mShellCommandHandler, mShellController, mTaskOrganizer, mSyncQueue, - mRootTDAOrganizer, mDisplayController, mDisplayImeController, - mDisplayInsetsController, mDragAndDropController, mTransitions, mTransactionPool, - mIconProvider, mRecentTasks, mLaunchAdjacentController, mWindowDecorViewModel, - mDesktopTasksController, mMainExecutor, mStageCoordinator, - new String[0]); - // Expect activity property to override application property - assertEquals(true, controller.supportsMultiInstanceSplit(component)); - } - - @Test - public void supportsMultiInstanceSplit_activityPropertyFalseApplicationPropertyTrue() - throws PackageManager.NameNotFoundException { - Context context = spy(mContext); - ComponentName component = new ComponentName(TEST_PACKAGE, TEST_ACTIVITY); - PackageManager pm = mock(PackageManager.class); - doReturn(pm).when(context).getPackageManager(); - PackageManager.Property activityProp = new PackageManager.Property("", false, "", ""); - doReturn(activityProp).when(pm).getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), - eq(component)); - PackageManager.Property appProp = new PackageManager.Property("", true, "", ""); - doReturn(appProp).when(pm).getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), - eq(component.getPackageName())); - - SplitScreenController controller = new SplitScreenController(context, mShellInit, - mShellCommandHandler, mShellController, mTaskOrganizer, mSyncQueue, - mRootTDAOrganizer, mDisplayController, mDisplayImeController, - mDisplayInsetsController, mDragAndDropController, mTransitions, mTransactionPool, - mIconProvider, mRecentTasks, mLaunchAdjacentController, mWindowDecorViewModel, - mDesktopTasksController, mMainExecutor, mStageCoordinator, - new String[0]); - // Expect activity property to override application property - assertEquals(false, controller.supportsMultiInstanceSplit(component)); - } - - @Test - public void supportsMultiInstanceSplit_noActivityPropertyApplicationPropertyTrue() - throws PackageManager.NameNotFoundException { - Context context = spy(mContext); - ComponentName component = new ComponentName(TEST_PACKAGE, TEST_ACTIVITY); - PackageManager pm = mock(PackageManager.class); - doReturn(pm).when(context).getPackageManager(); - doThrow(PackageManager.NameNotFoundException.class).when(pm).getProperty( - eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), eq(component)); - PackageManager.Property appProp = new PackageManager.Property("", true, "", ""); - doReturn(appProp).when(pm).getProperty(eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), - eq(component.getPackageName())); - - SplitScreenController controller = new SplitScreenController(context, mShellInit, - mShellCommandHandler, mShellController, mTaskOrganizer, mSyncQueue, - mRootTDAOrganizer, mDisplayController, mDisplayImeController, - mDisplayInsetsController, mDragAndDropController, mTransitions, mTransactionPool, - mIconProvider, mRecentTasks, mLaunchAdjacentController, mWindowDecorViewModel, - mDesktopTasksController, mMainExecutor, mStageCoordinator, - new String[0]); - // Expect fall through to app property - assertEquals(true, controller.supportsMultiInstanceSplit(component)); - } - - @Test - public void supportsMultiInstanceSplit_noActivityOrAppProperty() - throws PackageManager.NameNotFoundException { - Context context = spy(mContext); - ComponentName component = new ComponentName(TEST_PACKAGE, TEST_ACTIVITY); - PackageManager pm = mock(PackageManager.class); - doReturn(pm).when(context).getPackageManager(); - doThrow(PackageManager.NameNotFoundException.class).when(pm).getProperty( - eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), eq(component)); - doThrow(PackageManager.NameNotFoundException.class).when(pm).getProperty( - eq(PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI), eq(component.getPackageName())); - - SplitScreenController controller = new SplitScreenController(context, mShellInit, - mShellCommandHandler, mShellController, mTaskOrganizer, mSyncQueue, - mRootTDAOrganizer, mDisplayController, mDisplayImeController, - mDisplayInsetsController, mDragAndDropController, mTransitions, mTransactionPool, - mIconProvider, mRecentTasks, mLaunchAdjacentController, mWindowDecorViewModel, - mDesktopTasksController, mMainExecutor, mStageCoordinator, - new String[0]); - assertEquals(false, controller.supportsMultiInstanceSplit(component)); - } - - @Test public void testSwitchSplitPosition_checksIsSplitScreenVisible() { final String reason = "test"; when(mSplitScreenController.isSplitScreenVisible()).thenReturn(true, false); diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index 4e330da417be..e4f3e2defb25 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -427,7 +427,6 @@ cc_defaults { "jni/MovieImpl.cpp", "jni/pdf/PdfDocument.cpp", "jni/pdf/PdfEditor.cpp", - "jni/pdf/PdfRenderer.cpp", "jni/pdf/PdfUtils.cpp", ], shared_libs: [ diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 14b8d8d0aa12..0b739c361d64 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -70,6 +70,8 @@ public: : mType(Type::RRect), mOp(op), mMatrix(m), mRRect(rrect) {} Clip(const SkPath& path, SkClipOp op, const SkMatrix& m) : mType(Type::Path), mOp(op), mMatrix(m), mPath(std::in_place, path) {} + Clip(const sk_sp<SkShader> shader, SkClipOp op, const SkMatrix& m) + : mType(Type::Shader), mOp(op), mMatrix(m), mShader(shader) {} void apply(SkCanvas* canvas) const { canvas->setMatrix(mMatrix); @@ -86,6 +88,8 @@ public: // Ensure path clips are anti-aliased canvas->clipPath(mPath.value(), mOp, true); break; + case Type::Shader: + canvas->clipShader(mShader, mOp); } } @@ -94,6 +98,7 @@ private: Rect, RRect, Path, + Shader, }; Type mType; @@ -103,6 +108,7 @@ private: // These are logically a union (tracked separately due to non-POD path). std::optional<SkPath> mPath; SkRRect mRRect; + sk_sp<SkShader> mShader; }; Canvas* Canvas::create_canvas(const SkBitmap& bitmap) { @@ -413,6 +419,11 @@ bool SkiaCanvas::clipPath(const SkPath* path, SkClipOp op) { return !mCanvas->isClipEmpty(); } +void SkiaCanvas::clipShader(sk_sp<SkShader> shader, SkClipOp op) { + this->recordClip(shader, op); + mCanvas->clipShader(shader, op); +} + bool SkiaCanvas::replaceClipRect_deprecated(float left, float top, float right, float bottom) { SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h index 5e3553bbbbb4..4a012bc601c9 100644 --- a/libs/hwui/SkiaCanvas.h +++ b/libs/hwui/SkiaCanvas.h @@ -97,6 +97,7 @@ public: virtual bool quickRejectPath(const SkPath& path) const override; virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) override; virtual bool clipPath(const SkPath* path, SkClipOp op) override; + virtual void clipShader(sk_sp<SkShader> shader, SkClipOp op) override; virtual bool replaceClipRect_deprecated(float left, float top, float right, float bottom) override; virtual bool replaceClipPath_deprecated(const SkPath* path) override; diff --git a/libs/hwui/apex/jni_runtime.cpp b/libs/hwui/apex/jni_runtime.cpp index 883f273b5d3d..fb0cdb034575 100644 --- a/libs/hwui/apex/jni_runtime.cpp +++ b/libs/hwui/apex/jni_runtime.cpp @@ -70,7 +70,6 @@ extern int register_android_graphics_fonts_Font(JNIEnv* env); extern int register_android_graphics_fonts_FontFamily(JNIEnv* env); extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env); extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env); -extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env); extern int register_android_graphics_text_MeasuredText(JNIEnv* env); extern int register_android_graphics_text_LineBreaker(JNIEnv *env); extern int register_android_graphics_text_TextShaper(JNIEnv *env); @@ -142,7 +141,6 @@ extern int register_android_graphics_HardwareBufferRenderer(JNIEnv* env); REG_JNI(register_android_graphics_fonts_FontFamily), REG_JNI(register_android_graphics_pdf_PdfDocument), REG_JNI(register_android_graphics_pdf_PdfEditor), - REG_JNI(register_android_graphics_pdf_PdfRenderer), REG_JNI(register_android_graphics_text_MeasuredText), REG_JNI(register_android_graphics_text_LineBreaker), REG_JNI(register_android_graphics_text_TextShaper), diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h index 20e3ad2c8202..14b4f584f0f3 100644 --- a/libs/hwui/hwui/Canvas.h +++ b/libs/hwui/hwui/Canvas.h @@ -188,6 +188,7 @@ public: virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) = 0; virtual bool clipPath(const SkPath* path, SkClipOp op) = 0; + virtual void clipShader(sk_sp<SkShader> shader, SkClipOp op) = 0; // Resets clip to wide open, used to emulate the now-removed SkClipOp::kReplace on // apps with compatibility < P. Canvases for version P and later are restricted to // intersect and difference at the Java level, matching SkClipOp's definition. diff --git a/libs/hwui/jni/android_graphics_Canvas.cpp b/libs/hwui/jni/android_graphics_Canvas.cpp index e5bdeeea75be..1fc34d633370 100644 --- a/libs/hwui/jni/android_graphics_Canvas.cpp +++ b/libs/hwui/jni/android_graphics_Canvas.cpp @@ -261,6 +261,23 @@ static jboolean clipPath(CRITICAL_JNI_PARAMS_COMMA jlong canvasHandle, jlong pat return nonEmptyClip ? JNI_TRUE : JNI_FALSE; } +static void clipShader(CRITICAL_JNI_PARAMS_COMMA jlong canvasHandle, jlong shaderHandle, + jint opHandle) { + SkRegion::Op rgnOp = static_cast<SkRegion::Op>(opHandle); + sk_sp<SkShader> shader = sk_ref_sp(reinterpret_cast<SkShader*>(shaderHandle)); + switch (rgnOp) { + case SkRegion::Op::kIntersect_Op: + case SkRegion::Op::kDifference_Op: + get_canvas(canvasHandle)->clipShader(shader, static_cast<SkClipOp>(rgnOp)); + break; + default: + ALOGW("Ignoring unsupported clip operation %d", opHandle); + SkRect clipBounds; // ignored + get_canvas(canvasHandle)->getClipBounds(&clipBounds); + break; + } +} + static void drawColor(JNIEnv* env, jobject, jlong canvasHandle, jint color, jint modeHandle) { SkBlendMode mode = static_cast<SkBlendMode>(modeHandle); get_canvas(canvasHandle)->drawColor(color, mode); @@ -797,6 +814,7 @@ static const JNINativeMethod gMethods[] = { {"nQuickReject", "(JFFFF)Z", (void*)CanvasJNI::quickRejectRect}, {"nClipRect", "(JFFFFI)Z", (void*)CanvasJNI::clipRect}, {"nClipPath", "(JJI)Z", (void*)CanvasJNI::clipPath}, + {"nClipShader", "(JJI)V", (void*)CanvasJNI::clipShader}, {"nSetDrawFilter", "(JJ)V", (void*)CanvasJNI::setPaintFilter}, }; diff --git a/libs/hwui/jni/pdf/PdfRenderer.cpp b/libs/hwui/jni/pdf/PdfRenderer.cpp deleted file mode 100644 index cc1f96197c74..000000000000 --- a/libs/hwui/jni/pdf/PdfRenderer.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2014 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. - */ - -#include "PdfUtils.h" - -#include "GraphicsJNI.h" -#include "SkBitmap.h" -#include "SkMatrix.h" -#include "fpdfview.h" - -#include <vector> -#include <utils/Log.h> -#include <unistd.h> -#include <sys/types.h> -#include <unistd.h> - -namespace android { - -static const int RENDER_MODE_FOR_DISPLAY = 1; -static const int RENDER_MODE_FOR_PRINT = 2; - -static struct { - jfieldID x; - jfieldID y; -} gPointClassInfo; - -static jlong nativeOpenPageAndGetSize(JNIEnv* env, jclass thiz, jlong documentPtr, - jint pageIndex, jobject outSize) { - FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); - - FPDF_PAGE page = FPDF_LoadPage(document, pageIndex); - if (!page) { - jniThrowException(env, "java/lang/IllegalStateException", - "cannot load page"); - return -1; - } - - double width = 0; - double height = 0; - - int result = FPDF_GetPageSizeByIndex(document, pageIndex, &width, &height); - if (!result) { - jniThrowException(env, "java/lang/IllegalStateException", - "cannot get page size"); - return -1; - } - - env->SetIntField(outSize, gPointClassInfo.x, width); - env->SetIntField(outSize, gPointClassInfo.y, height); - - return reinterpret_cast<jlong>(page); -} - -static void nativeClosePage(JNIEnv* env, jclass thiz, jlong pagePtr) { - FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr); - FPDF_ClosePage(page); -} - -static void nativeRenderPage(JNIEnv* env, jclass thiz, jlong documentPtr, jlong pagePtr, - jlong bitmapPtr, jint clipLeft, jint clipTop, jint clipRight, jint clipBottom, - jlong transformPtr, jint renderMode) { - FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr); - - SkBitmap skBitmap; - bitmap::toBitmap(bitmapPtr).getSkBitmap(&skBitmap); - - const int stride = skBitmap.width() * 4; - - FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(skBitmap.width(), skBitmap.height(), - FPDFBitmap_BGRA, skBitmap.getPixels(), stride); - - int renderFlags = FPDF_REVERSE_BYTE_ORDER; - if (renderMode == RENDER_MODE_FOR_DISPLAY) { - renderFlags |= FPDF_LCD_TEXT; - } else if (renderMode == RENDER_MODE_FOR_PRINT) { - renderFlags |= FPDF_PRINTING; - } - - SkMatrix matrix = *reinterpret_cast<SkMatrix*>(transformPtr); - SkScalar transformValues[6]; - if (!matrix.asAffine(transformValues)) { - jniThrowException(env, "java/lang/IllegalArgumentException", - "transform matrix has perspective. Only affine matrices are allowed."); - return; - } - - FS_MATRIX transform = {transformValues[SkMatrix::kAScaleX], transformValues[SkMatrix::kASkewY], - transformValues[SkMatrix::kASkewX], transformValues[SkMatrix::kAScaleY], - transformValues[SkMatrix::kATransX], - transformValues[SkMatrix::kATransY]}; - - FS_RECTF clip = {(float) clipLeft, (float) clipTop, (float) clipRight, (float) clipBottom}; - - FPDF_RenderPageBitmapWithMatrix(bitmap, page, &transform, &clip, renderFlags); - - skBitmap.notifyPixelsChanged(); -} - -static const JNINativeMethod gPdfRenderer_Methods[] = { - {"nativeCreate", "(IJ)J", (void*) nativeOpen}, - {"nativeClose", "(J)V", (void*) nativeClose}, - {"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount}, - {"nativeScaleForPrinting", "(J)Z", (void*) nativeScaleForPrinting}, - {"nativeRenderPage", "(JJJIIIIJI)V", (void*) nativeRenderPage}, - {"nativeOpenPageAndGetSize", "(JILandroid/graphics/Point;)J", (void*) nativeOpenPageAndGetSize}, - {"nativeClosePage", "(J)V", (void*) nativeClosePage} -}; - -int register_android_graphics_pdf_PdfRenderer(JNIEnv* env) { - int result = RegisterMethodsOrDie( - env, "android/graphics/pdf/PdfRenderer", gPdfRenderer_Methods, - NELEM(gPdfRenderer_Methods)); - - jclass clazz = FindClassOrDie(env, "android/graphics/Point"); - gPointClassInfo.x = GetFieldIDOrDie(env, clazz, "x", "I"); - gPointClassInfo.y = GetFieldIDOrDie(env, clazz, "y", "I"); - - return result; -}; - -}; diff --git a/location/api/current.txt b/location/api/current.txt index 5ed8c3c8eb4b..85e9f65a0718 100644 --- a/location/api/current.txt +++ b/location/api/current.txt @@ -88,12 +88,12 @@ package android.location { public final class Geocoder { ctor public Geocoder(@NonNull android.content.Context); ctor public Geocoder(@NonNull android.content.Context, @NonNull java.util.Locale); - method @Deprecated @Nullable public java.util.List<android.location.Address> getFromLocation(@FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @IntRange int) throws java.io.IOException; - method public void getFromLocation(@FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @IntRange int, @NonNull android.location.Geocoder.GeocodeListener); - method @Deprecated @Nullable public java.util.List<android.location.Address> getFromLocationName(@NonNull String, @IntRange int) throws java.io.IOException; - method public void getFromLocationName(@NonNull String, @IntRange int, @NonNull android.location.Geocoder.GeocodeListener); - method @Deprecated @Nullable public java.util.List<android.location.Address> getFromLocationName(@NonNull String, @IntRange int, @FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double) throws java.io.IOException; - method public void getFromLocationName(@NonNull String, @IntRange int, @FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @NonNull android.location.Geocoder.GeocodeListener); + method @Deprecated @Nullable public java.util.List<android.location.Address> getFromLocation(@FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @IntRange(from=1) int) throws java.io.IOException; + method public void getFromLocation(@FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @IntRange(from=1) int, @NonNull android.location.Geocoder.GeocodeListener); + method @Deprecated @Nullable public java.util.List<android.location.Address> getFromLocationName(@NonNull String, @IntRange(from=1) int) throws java.io.IOException; + method public void getFromLocationName(@NonNull String, @IntRange(from=1) int, @NonNull android.location.Geocoder.GeocodeListener); + method @Deprecated @Nullable public java.util.List<android.location.Address> getFromLocationName(@NonNull String, @IntRange(from=1) int, @FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double) throws java.io.IOException; + method public void getFromLocationName(@NonNull String, @IntRange(from=1) int, @FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @NonNull android.location.Geocoder.GeocodeListener); method public static boolean isPresent(); } diff --git a/location/api/system-current.txt b/location/api/system-current.txt index b1cf96d41497..2e7a541ecb60 100644 --- a/location/api/system-current.txt +++ b/location/api/system-current.txt @@ -591,6 +591,36 @@ package android.location { package android.location.provider { + @FlaggedApi(Flags.FLAG_NEW_GEOCODER) public final class ForwardGeocodeRequest implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public String getCallingAttributionTag(); + method @NonNull public String getCallingPackage(); + method public int getCallingUid(); + method @NonNull public java.util.Locale getLocale(); + method @NonNull public String getLocationName(); + method @FloatRange(from=-90.0, to=90.0) public double getLowerLeftLatitude(); + method @FloatRange(from=-180.0, to=180.0) public double getLowerLeftLongitude(); + method @IntRange(from=1) public int getMaxResults(); + method @FloatRange(from=-90.0, to=90.0) public double getUpperRightLatitude(); + method @FloatRange(from=-180.0, to=180.0) public double getUpperRightLongitude(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.location.provider.ForwardGeocodeRequest> CREATOR; + } + + public static final class ForwardGeocodeRequest.Builder { + ctor public ForwardGeocodeRequest.Builder(@NonNull String, @FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @IntRange(from=1) int, @NonNull java.util.Locale, int, @NonNull String); + method @NonNull public android.location.provider.ForwardGeocodeRequest build(); + method @NonNull public android.location.provider.ForwardGeocodeRequest.Builder setCallingAttributionTag(@NonNull String); + } + + @FlaggedApi(Flags.FLAG_NEW_GEOCODER) public abstract class GeocodeProviderBase { + ctor public GeocodeProviderBase(@NonNull android.content.Context, @NonNull String); + method @NonNull public final android.os.IBinder getBinder(); + method public abstract void onForwardGeocode(@NonNull android.location.provider.ForwardGeocodeRequest, @NonNull android.os.OutcomeReceiver<java.util.List<android.location.Address>,java.lang.Exception>); + method public abstract void onReverseGeocode(@NonNull android.location.provider.ReverseGeocodeRequest, @NonNull android.os.OutcomeReceiver<java.util.List<android.location.Address>,java.lang.Exception>); + field public static final String ACTION_GEOCODE_PROVIDER = "com.android.location.service.GeocodeProvider"; + } + public abstract class LocationProviderBase { ctor public LocationProviderBase(@NonNull android.content.Context, @NonNull String, @NonNull android.location.provider.ProviderProperties); method @Nullable public final android.os.IBinder getBinder(); @@ -642,5 +672,24 @@ package android.location.provider { method public void onProviderRequestChanged(@NonNull String, @NonNull android.location.provider.ProviderRequest); } + @FlaggedApi(Flags.FLAG_NEW_GEOCODER) public final class ReverseGeocodeRequest implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public String getCallingAttributionTag(); + method @NonNull public String getCallingPackage(); + method public int getCallingUid(); + method @FloatRange(from=-90.0, to=90.0) public double getLatitude(); + method @NonNull public java.util.Locale getLocale(); + method @FloatRange(from=-180.0, to=180.0) public double getLongitude(); + method @IntRange(from=1) public int getMaxResults(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.location.provider.ReverseGeocodeRequest> CREATOR; + } + + public static final class ReverseGeocodeRequest.Builder { + ctor public ReverseGeocodeRequest.Builder(@FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @IntRange(from=0) int, @NonNull java.util.Locale, int, @NonNull String); + method @NonNull public android.location.provider.ReverseGeocodeRequest build(); + method @NonNull public android.location.provider.ReverseGeocodeRequest.Builder setCallingAttributionTag(@NonNull String); + } + } diff --git a/location/java/android/location/Geocoder.java b/location/java/android/location/Geocoder.java index a15834407315..cdde7c66e268 100644 --- a/location/java/android/location/Geocoder.java +++ b/location/java/android/location/Geocoder.java @@ -21,11 +21,13 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.location.provider.ForwardGeocodeRequest; +import android.location.provider.IGeocodeCallback; +import android.location.provider.ReverseGeocodeRequest; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; -import com.android.internal.util.Preconditions; - import java.io.IOException; import java.util.Collections; import java.util.List; @@ -33,6 +35,7 @@ import java.util.Locale; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; /** * A class for handling geocoding and reverse geocoding. Geocoding is the process of transforming a @@ -42,9 +45,12 @@ import java.util.concurrent.TimeUnit; * example one might contain the full street address of the closest building, while another might * contain only a city name and postal code. * - * The Geocoder class requires a backend service that is not included in the core android framework. - * The Geocoder query methods will return an empty list if there no backend service in the platform. - * Use the isPresent() method to determine whether a Geocoder implementation exists. + * <p>Use the isPresent() method to determine whether a Geocoder implementation exists on the + * current device. If no implementation is present, any attempt to geocode will result in an error. + * + * <p>Geocoder implementations are only required to make a best effort to return results in the + * chosen locale. Note that geocoder implementations may return results in other locales if they + * have no information available for the chosen locale. * * <p class="note"><strong>Warning:</strong> Geocoding services may provide no guarantees on * availability or accuracy. Results are a best guess, and are not guaranteed to be meaningful or @@ -52,45 +58,53 @@ import java.util.concurrent.TimeUnit; */ public final class Geocoder { - /** A listener for asynchronous geocoding results. */ + /** + * A listener for asynchronous geocoding results. Only one of the methods will ever be invoked + * per geocoding attempt. There are no guarantees on how long it will take for a method to be + * invoked, nor any guarantees on the format or availability of error information. + */ public interface GeocodeListener { /** Invoked when geocoding completes successfully. May return an empty list. */ void onGeocode(@NonNull List<Address> addresses); - /** Invoked when geocoding fails, with a brief error message. */ + + /** Invoked when geocoding fails, with an optional error message. */ default void onError(@Nullable String errorMessage) {} } - private static final long TIMEOUT_MS = 60000; + private static final long TIMEOUT_MS = 15000; - private final GeocoderParams mParams; + private final Context mContext; + private final Locale mLocale; private final ILocationManager mService; /** - * Returns true if there is a geocoder implementation present that may return results. If true, - * there is still no guarantee that any individual geocoding attempt will succeed. + * Returns true if there is a geocoder implementation present on the device that may return + * results. If true, there is still no guarantee that any individual geocoding attempt will + * succeed. */ public static boolean isPresent() { ILocationManager lm = Objects.requireNonNull(ILocationManager.Stub.asInterface( ServiceManager.getService(Context.LOCATION_SERVICE))); try { - return lm.geocoderIsPresent(); + return lm.isGeocodeAvailable(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } - /** - * Constructs a Geocoder localized for the default locale. - */ + /** Constructs a Geocoder localized for {@link Locale#getDefault()}. */ public Geocoder(@NonNull Context context) { this(context, Locale.getDefault()); } /** - * Constructs a Geocoder localized for the given locale. + * Constructs a Geocoder localized for the given locale. Note that geocoder implementations will + * only make a best effort to return results in the given locale, and there is no guarantee that + * returned results will be in the specific locale. */ public Geocoder(@NonNull Context context, @NonNull Locale locale) { - mParams = new GeocoderParams(context, locale); + mContext = Objects.requireNonNull(context); + mLocale = Objects.requireNonNull(locale); mService = ILocationManager.Stub.asInterface( ServiceManager.getService(Context.LOCATION_SERVICE)); } @@ -103,31 +117,28 @@ public final class Geocoder { * <p class="warning"><strong>Warning:</strong> Geocoding services may provide no guarantees on * availability or accuracy. Results are a best guess, and are not guaranteed to be meaningful * or correct. Do <b>NOT</b> use this API for any safety-critical or regulatory compliance - * purposes.</p> + * purposes. * * <p class="warning"><strong>Warning:</strong> This API may hit the network, and may block for - * excessive amounts of time, up to 60 seconds or more. It's strongly encouraged to use the - * asynchronous version of this API. If that is not possible, this should be run on a background - * thread to avoid blocking other operations.</p> + * excessive amounts of time. It's strongly encouraged to use the asynchronous version of this + * API. If that is not possible, this should be run on a background thread to avoid blocking + * other operations. * * @param latitude the latitude a point for the search * @param longitude the longitude a point for the search * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended - * - * @return a list of Address objects. Returns null or empty list if no matches were - * found or there is no backend service available. - * + * @return a list of Address objects. Returns null or empty list if no matches were found or + * there is no backend service available. * @throws IllegalArgumentException if latitude or longitude is invalid * @throws IOException if there is a failure - * * @deprecated Use {@link #getFromLocation(double, double, int, GeocodeListener)} instead to - * avoid blocking a thread waiting for results. + * avoid blocking a thread waiting for results. */ @Deprecated public @Nullable List<Address> getFromLocation( @FloatRange(from = -90D, to = 90D) double latitude, - @FloatRange(from = -180D, to = 180D)double longitude, - @IntRange int maxResults) + @FloatRange(from = -180D, to = 180D) double longitude, + @IntRange(from = 1) int maxResults) throws IOException { SynchronousGeocoder listener = new SynchronousGeocoder(); getFromLocation(latitude, longitude, maxResults, listener); @@ -142,26 +153,32 @@ public final class Geocoder { * <p class="warning"><strong>Warning:</strong> Geocoding services may provide no guarantees on * availability or accuracy. Results are a best guess, and are not guaranteed to be meaningful * or correct. Do <b>NOT</b> use this API for any safety-critical or regulatory compliance - * purposes.</p> + * purposes. * * @param latitude the latitude a point for the search * @param longitude the longitude a point for the search * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended * @param listener a listener for receiving results - * * @throws IllegalArgumentException if latitude or longitude is invalid */ public void getFromLocation( @FloatRange(from = -90D, to = 90D) double latitude, @FloatRange(from = -180D, to = 180D) double longitude, - @IntRange int maxResults, + @IntRange(from = 1) int maxResults, @NonNull GeocodeListener listener) { - Preconditions.checkArgumentInRange(latitude, -90.0, 90.0, "latitude"); - Preconditions.checkArgumentInRange(longitude, -180.0, 180.0, "longitude"); - + ReverseGeocodeRequest.Builder b = + new ReverseGeocodeRequest.Builder( + latitude, + longitude, + maxResults, + mLocale, + Process.myUid(), + mContext.getPackageName()); + if (mContext.getAttributionTag() != null) { + b.setCallingAttributionTag(mContext.getAttributionTag()); + } try { - mService.getFromLocation(latitude, longitude, maxResults, mParams, - new GeocoderImpl(listener)); + mService.reverseGeocode(b.build(), new GeocodeCallbackImpl(listener)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -176,29 +193,25 @@ public final class Geocoder { * <p class="note"><strong>Warning:</strong> Geocoding services may provide no guarantees on * availability or accuracy. Results are a best guess, and are not guaranteed to be meaningful * or correct. Do <b>NOT</b> use this API for any safety-critical or regulatory compliance - * purposes.</p> + * purposes. * * <p class="warning"><strong>Warning:</strong> This API may hit the network, and may block for - * excessive amounts of time, up to 60 seconds or more. It's strongly encouraged to use the - * asynchronous version of this API. If that is not possible, this should be run on a background - * thread to avoid blocking other operations.</p> + * excessive amounts of time. It's strongly encouraged to use the asynchronous version of this + * API. If that is not possible, this should be run on a background thread to avoid blocking + * other operations. * * @param locationName a user-supplied description of a location * @param maxResults max number of results to return. Smaller numbers (1 to 5) are recommended - * - * @return a list of Address objects. Returns null or empty list if no matches were - * found or there is no backend service available. - * + * @return a list of Address objects. Returns null or empty list if no matches were found or + * there is no backend service available. * @throws IllegalArgumentException if locationName is null * @throws IOException if there is a failure - * * @deprecated Use {@link #getFromLocationName(String, int, GeocodeListener)} instead to avoid - * blocking a thread waiting for results. + * blocking a thread waiting for results. */ @Deprecated public @Nullable List<Address> getFromLocationName( - @NonNull String locationName, - @IntRange int maxResults) throws IOException { + @NonNull String locationName, @IntRange(from = 1) int maxResults) throws IOException { return getFromLocationName(locationName, maxResults, 0, 0, 0, 0); } @@ -211,17 +224,16 @@ public final class Geocoder { * <p class="note"><strong>Warning:</strong> Geocoding services may provide no guarantees on * availability or accuracy. Results are a best guess, and are not guaranteed to be meaningful * or correct. Do <b>NOT</b> use this API for any safety-critical or regulatory compliance - * purposes.</p> + * purposes. * * @param locationName a user-supplied description of a location * @param maxResults max number of results to return. Smaller numbers (1 to 5) are recommended * @param listener a listener for receiving results - * * @throws IllegalArgumentException if locationName is null */ public void getFromLocationName( @NonNull String locationName, - @IntRange int maxResults, + @IntRange(from = 1) int maxResults, @NonNull GeocodeListener listener) { getFromLocationName(locationName, maxResults, 0, 0, 0, 0, listener); } @@ -232,45 +244,42 @@ public final class Geocoder { * View, CA", an airport code such as "SFO", and so forth. The returned addresses should be * localized for the locale provided to this class's constructor. * - * <p> You may specify a bounding box for the search results by including the latitude and + * <p>You may specify a bounding box for the search results by including the latitude and * longitude of the lower left point and upper right point of the box. * * <p class="note"><strong>Warning:</strong> Geocoding services may provide no guarantees on * availability or accuracy. Results are a best guess, and are not guaranteed to be meaningful * or correct. Do <b>NOT</b> use this API for any safety-critical or regulatory compliance - * purposes.</p> + * purposes. * * <p class="warning"><strong>Warning:</strong> This API may hit the network, and may block for - * excessive amounts of time, up to 60 seconds or more. It's strongly encouraged to use the - * asynchronous version of this API. If that is not possible, this should be run on a background - * thread to avoid blocking other operations.</p> + * excessive amounts of time. It's strongly encouraged to use the asynchronous version of this + * API. If that is not possible, this should be run on a background thread to avoid blocking + * other operations. * - * @param locationName a user-supplied description of a location - * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are - * recommended - * @param lowerLeftLatitude the latitude of the lower left corner of the bounding box - * @param lowerLeftLongitude the longitude of the lower left corner of the bounding box - * @param upperRightLatitude the latitude of the upper right corner of the bounding box + * @param locationName a user-supplied description of a location + * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended + * @param lowerLeftLatitude the latitude of the lower left corner of the bounding box + * @param lowerLeftLongitude the longitude of the lower left corner of the bounding box + * @param upperRightLatitude the latitude of the upper right corner of the bounding box * @param upperRightLongitude the longitude of the upper right corner of the bounding box - * - * @return a list of Address objects. Returns null or empty list if no matches were - * found or there is no backend service available. - * + * @return a list of Address objects. Returns null or empty list if no matches were found or + * there is no backend service available. * @throws IllegalArgumentException if locationName is null * @throws IllegalArgumentException if any latitude or longitude is invalid - * @throws IOException if there is a failure - * + * @throws IOException if there is a failure * @deprecated Use {@link #getFromLocationName(String, int, double, double, double, double, - * GeocodeListener)} instead to avoid blocking a thread waiting for results. + * GeocodeListener)} instead to avoid blocking a thread waiting for results. */ @Deprecated public @Nullable List<Address> getFromLocationName( @NonNull String locationName, - @IntRange int maxResults, + @IntRange(from = 1) int maxResults, @FloatRange(from = -90D, to = 90D) double lowerLeftLatitude, @FloatRange(from = -180D, to = 180D) double lowerLeftLongitude, @FloatRange(from = -90D, to = 90D) double upperRightLatitude, - @FloatRange(from = -180D, to = 180D) double upperRightLongitude) throws IOException { + @FloatRange(from = -180D, to = 180D) double upperRightLongitude) + throws IOException { SynchronousGeocoder listener = new SynchronousGeocoder(); getFromLocationName(locationName, maxResults, lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude, listener); @@ -283,75 +292,79 @@ public final class Geocoder { * View, CA", an airport code such as "SFO", and so forth. The returned addresses should be * localized for the locale provided to this class's constructor. * - * <p> You may specify a bounding box for the search results by including the latitude and + * <p>You may specify a bounding box for the search results by including the latitude and * longitude of the lower left point and upper right point of the box. * * <p class="note"><strong>Warning:</strong> Geocoding services may provide no guarantees on * availability or accuracy. Results are a best guess, and are not guaranteed to be meaningful * or correct. Do <b>NOT</b> use this API for any safety-critical or regulatory compliance - * purposes.</p> + * purposes. * - * @param locationName a user-supplied description of a location - * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are - * recommended - * @param lowerLeftLatitude the latitude of the lower left corner of the bounding box - * @param lowerLeftLongitude the longitude of the lower left corner of the bounding box - * @param upperRightLatitude the latitude of the upper right corner of the bounding box + * @param locationName a user-supplied description of a location + * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended + * @param lowerLeftLatitude the latitude of the lower left corner of the bounding box + * @param lowerLeftLongitude the longitude of the lower left corner of the bounding box + * @param upperRightLatitude the latitude of the upper right corner of the bounding box * @param upperRightLongitude the longitude of the upper right corner of the bounding box - * @param listener a listener for receiving results - * + * @param listener a listener for receiving results * @throws IllegalArgumentException if locationName is null * @throws IllegalArgumentException if any latitude or longitude is invalid */ public void getFromLocationName( @NonNull String locationName, - @IntRange int maxResults, + @IntRange(from = 1) int maxResults, @FloatRange(from = -90D, to = 90D) double lowerLeftLatitude, @FloatRange(from = -180D, to = 180D) double lowerLeftLongitude, @FloatRange(from = -90D, to = 90D) double upperRightLatitude, @FloatRange(from = -180D, to = 180D) double upperRightLongitude, @NonNull GeocodeListener listener) { - Preconditions.checkArgument(locationName != null); - Preconditions.checkArgumentInRange(lowerLeftLatitude, -90.0, 90.0, "lowerLeftLatitude"); - Preconditions.checkArgumentInRange(lowerLeftLongitude, -180.0, 180.0, "lowerLeftLongitude"); - Preconditions.checkArgumentInRange(upperRightLatitude, -90.0, 90.0, "upperRightLatitude"); - Preconditions.checkArgumentInRange(upperRightLongitude, -180.0, 180.0, - "upperRightLongitude"); - + ForwardGeocodeRequest.Builder b = + new ForwardGeocodeRequest.Builder( + locationName, + lowerLeftLatitude, + lowerLeftLongitude, + upperRightLatitude, + upperRightLongitude, + maxResults, + mLocale, + Process.myUid(), + mContext.getPackageName()); + if (mContext.getAttributionTag() != null) { + b.setCallingAttributionTag(mContext.getAttributionTag()); + } try { - mService.getFromLocationName(locationName, lowerLeftLatitude, lowerLeftLongitude, - upperRightLatitude, upperRightLongitude, maxResults, mParams, - new GeocoderImpl(listener)); + mService.forwardGeocode(b.build(), new GeocodeCallbackImpl(listener)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } - private static class GeocoderImpl extends IGeocodeListener.Stub { + private static class GeocodeCallbackImpl extends IGeocodeCallback.Stub { - private GeocodeListener mListener; + @Nullable private GeocodeListener mListener; - GeocoderImpl(GeocodeListener listener) { + GeocodeCallbackImpl(GeocodeListener listener) { mListener = Objects.requireNonNull(listener); } @Override - public void onResults(String error, List<Address> addresses) throws RemoteException { + public void onError(@Nullable String error) { if (mListener == null) { return; } - GeocodeListener listener = mListener; + mListener.onError(error); mListener = null; + } - if (error != null) { - listener.onError(error); - } else { - if (addresses == null) { - addresses = Collections.emptyList(); - } - listener.onGeocode(addresses); + @Override + public void onResults(List<Address> addresses) { + if (mListener == null) { + return; } + + mListener.onGeocode(addresses); + mListener = null; } } @@ -364,21 +377,21 @@ public final class Geocoder { SynchronousGeocoder() {} @Override - public void onGeocode(List<Address> addresses) { + public void onGeocode(@NonNull List<Address> addresses) { mResults = addresses; mLatch.countDown(); } @Override - public void onError(String errorMessage) { - mError = errorMessage; + public void onError(@Nullable String error) { + mError = error; mLatch.countDown(); } public List<Address> getResults() throws IOException { try { if (!mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) { - mError = "Service not Available"; + throw new IOException(new TimeoutException()); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); diff --git a/location/java/android/location/IGeocodeProvider.aidl b/location/java/android/location/IGeocodeProvider.aidl deleted file mode 100644 index e661ca6cca2e..000000000000 --- a/location/java/android/location/IGeocodeProvider.aidl +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2009 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.location; - -import android.location.Address; -import android.location.IGeocodeListener; -import android.location.GeocoderParams; - -/** - * An interface for location providers implementing the Geocoder services. - * - * {@hide} - */ -interface IGeocodeProvider { - - oneway void getFromLocation(double latitude, double longitude, int maxResults, in GeocoderParams params, in IGeocodeListener listener); - oneway void getFromLocationName(String locationName, double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, - double upperRightLongitude, int maxResults, in GeocoderParams params, in IGeocodeListener listener); -} diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index 72761ef47569..c96c11898671 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -19,13 +19,11 @@ package android.location; import android.app.PendingIntent; import android.location.Address; import android.location.Criteria; -import android.location.GeocoderParams; import android.location.Geofence; import android.location.GnssAntennaInfo; import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.GnssMeasurementRequest; -import android.location.IGeocodeListener; import android.location.IGnssAntennaInfoListener; import android.location.IGnssMeasurementsListener; import android.location.IGnssStatusListener; @@ -37,8 +35,11 @@ import android.location.LastLocationRequest; import android.location.Location; import android.location.LocationRequest; import android.location.LocationTime; +import android.location.provider.ForwardGeocodeRequest; +import android.location.provider.IGeocodeCallback; import android.location.provider.IProviderRequestListener; import android.location.provider.ProviderProperties; +import android.location.provider.ReverseGeocodeRequest; import android.os.Bundle; import android.os.ICancellationSignal; import android.os.PackageTagsList; @@ -68,13 +69,9 @@ interface ILocationManager void requestGeofence(in Geofence geofence, in PendingIntent intent, String packageName, String attributionTag); void removeGeofence(in PendingIntent intent); - boolean geocoderIsPresent(); - void getFromLocation(double latitude, double longitude, int maxResults, - in GeocoderParams params, in IGeocodeListener listener); - void getFromLocationName(String locationName, - double lowerLeftLatitude, double lowerLeftLongitude, - double upperRightLatitude, double upperRightLongitude, int maxResults, - in GeocoderParams params, in IGeocodeListener listener); + boolean isGeocodeAvailable(); + void reverseGeocode(in ReverseGeocodeRequest request, in IGeocodeCallback callback); + void forwardGeocode(in ForwardGeocodeRequest request, in IGeocodeCallback callback); GnssCapabilities getGnssCapabilities(); int getGnssYearOfHardware(); diff --git a/location/java/android/location/flags/location.aconfig b/location/java/android/location/flags/location.aconfig index 0fa641b926a9..156be389fe84 100644 --- a/location/java/android/location/flags/location.aconfig +++ b/location/java/android/location/flags/location.aconfig @@ -1,6 +1,13 @@ package: "android.location.flags" flag { + name: "new_geocoder" + namespace: "location" + description: "Flag for new Geocoder APIs" + bug: "229872126" +} + +flag { name: "location_bypass" namespace: "location" description: "Enable location bypass appops behavior" diff --git a/core/java/android/service/voice/HotwordTrainingAudio.aidl b/location/java/android/location/provider/ForwardGeocodeRequest.aidl index 4dd22897f831..acd6190aeec8 100644 --- a/core/java/android/service/voice/HotwordTrainingAudio.aidl +++ b/location/java/android/location/provider/ForwardGeocodeRequest.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.service.voice; +package android.location.provider; -parcelable HotwordTrainingAudio;
\ No newline at end of file +parcelable ForwardGeocodeRequest; diff --git a/location/java/android/location/provider/ForwardGeocodeRequest.java b/location/java/android/location/provider/ForwardGeocodeRequest.java new file mode 100644 index 000000000000..8f227b1604b7 --- /dev/null +++ b/location/java/android/location/provider/ForwardGeocodeRequest.java @@ -0,0 +1,286 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.location.provider; + +import static java.lang.Math.max; + +import android.annotation.FlaggedApi; +import android.annotation.FloatRange; +import android.annotation.IntRange; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.location.flags.Flags; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; + +import java.util.Locale; +import java.util.Objects; + +/** + * Forward geocode (ie from address to lat/lng) provider request. + * + * @hide + */ +@FlaggedApi(Flags.FLAG_NEW_GEOCODER) +@SystemApi +public final class ForwardGeocodeRequest implements Parcelable { + + private final String mLocationName; + private final double mLowerLeftLatitude; + private final double mLowerLeftLongitude; + private final double mUpperRightLatitude; + private final double mUpperRightLongitude; + private final int mMaxResults; + private final Locale mLocale; + private final int mCallingUid; + private final String mCallingPackage; + @Nullable private final String mCallingAttributionTag; + + private ForwardGeocodeRequest( + @NonNull String locationName, + double lowerLeftLatitude, + double lowerLeftLongitude, + double upperRightLatitude, + double upperRightLongitude, + int maxResults, + @NonNull Locale locale, + int callingUid, + @NonNull String callingPackage, + @Nullable String callingAttributionTag) { + Preconditions.checkArgument(locationName != null, "locationName must not be null"); + Preconditions.checkArgumentInRange(lowerLeftLatitude, -90.0, 90.0, "lowerLeftLatitude"); + Preconditions.checkArgumentInRange(lowerLeftLongitude, -180.0, 180.0, "lowerLeftLongitude"); + Preconditions.checkArgumentInRange(upperRightLatitude, -90.0, 90.0, "upperRightLatitude"); + Preconditions.checkArgumentInRange( + upperRightLongitude, -180.0, 180.0, "upperRightLongitude"); + + mLocationName = locationName; + mLowerLeftLatitude = lowerLeftLatitude; + mLowerLeftLongitude = lowerLeftLongitude; + mUpperRightLatitude = upperRightLatitude; + mUpperRightLongitude = upperRightLongitude; + mMaxResults = max(maxResults, 1); + mLocale = Objects.requireNonNull(locale); + + mCallingUid = callingUid; + mCallingPackage = Objects.requireNonNull(callingPackage); + mCallingAttributionTag = callingAttributionTag; + } + + /** + * The location name to be forward geocoded. An arbitrary user string that could have any value. + */ + @NonNull + public String getLocationName() { + return mLocationName; + } + + /** The lower left latitude of the bounding box that should constrain forward geocoding. */ + @FloatRange(from = -90.0, to = 90.0) + public double getLowerLeftLatitude() { + return mLowerLeftLatitude; + } + + /** The lower left longitude of the bounding box that should constrain forward geocoding. */ + @FloatRange(from = -180.0, to = 180.0) + public double getLowerLeftLongitude() { + return mLowerLeftLongitude; + } + + /** The upper right latitude of the bounding box that should constrain forward geocoding. */ + @FloatRange(from = -90.0, to = 90.0) + public double getUpperRightLatitude() { + return mUpperRightLatitude; + } + + /** The upper right longitude of the bounding box that should constrain forward geocoding. */ + @FloatRange(from = -180.0, to = 180.0) + public double getUpperRightLongitude() { + return mUpperRightLongitude; + } + + /** The maximum number of forward geocoding results that should be returned. */ + @IntRange(from = 1) + public int getMaxResults() { + return mMaxResults; + } + + /** The locale that results should be localized to (best effort). */ + @NonNull + public Locale getLocale() { + return mLocale; + } + + /** The UID of the caller this geocoding request is happening on behalf of. */ + public int getCallingUid() { + return mCallingUid; + } + + /** The package of the caller this geocoding request is happening on behalf of. */ + @NonNull + public String getCallingPackage() { + return mCallingPackage; + } + + /** The attribution tag of the caller this geocoding request is happening on behalf of. */ + @Nullable + public String getCallingAttributionTag() { + return mCallingAttributionTag; + } + + public static final @NonNull Creator<ForwardGeocodeRequest> CREATOR = + new Creator<>() { + @Override + public ForwardGeocodeRequest createFromParcel(Parcel in) { + return new ForwardGeocodeRequest( + Objects.requireNonNull(in.readString8()), + in.readDouble(), + in.readDouble(), + in.readDouble(), + in.readDouble(), + in.readInt(), + new Locale(in.readString8(), in.readString8(), in.readString8()), + in.readInt(), + Objects.requireNonNull(in.readString8()), + in.readString8()); + } + + @Override + public ForwardGeocodeRequest[] newArray(int size) { + return new ForwardGeocodeRequest[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel parcel, int flags) { + parcel.writeString8(mLocationName); + parcel.writeDouble(mLowerLeftLatitude); + parcel.writeDouble(mLowerLeftLongitude); + parcel.writeDouble(mUpperRightLatitude); + parcel.writeDouble(mUpperRightLongitude); + parcel.writeInt(mMaxResults); + parcel.writeString8(mLocale.getLanguage()); + parcel.writeString8(mLocale.getCountry()); + parcel.writeString8(mLocale.getVariant()); + parcel.writeInt(mCallingUid); + parcel.writeString8(mCallingPackage); + parcel.writeString8(mCallingAttributionTag); + } + + @Override + public boolean equals(@Nullable Object object) { + if (object instanceof ForwardGeocodeRequest that) { + return mLowerLeftLatitude == that.mLowerLeftLatitude + && mLowerLeftLongitude == that.mLowerLeftLongitude + && mUpperRightLatitude == that.mUpperRightLatitude + && mUpperRightLongitude == that.mUpperRightLongitude + && mMaxResults == that.mMaxResults + && mCallingUid == that.mCallingUid + && mLocale.equals(that.mLocale) + && mCallingPackage.equals(that.mCallingPackage) + && mLocationName.equals(that.mLocationName) + && Objects.equals(mCallingAttributionTag, that.mCallingAttributionTag); + } + + return false; + } + + @Override + public int hashCode() { + return Objects.hash( + mLocationName, + mLowerLeftLatitude, + mLowerLeftLongitude, + mUpperRightLatitude, + mUpperRightLongitude, + mMaxResults, + mLocale, + mCallingUid, + mCallingPackage, + mCallingAttributionTag); + } + + /** A Builder for {@link ReverseGeocodeRequest}s. */ + public static final class Builder { + + private final String mLocationName; + private final double mLowerLeftLatitude; + private final double mLowerLeftLongitude; + private final double mUpperRightLatitude; + private final double mUpperRightLongitude; + private final int mMaxResults; + private final Locale mLocale; + + private final int mCallingUid; + private final String mCallingPackage; + @Nullable private String mCallingAttributionTag; + + /** Creates a new Builder instance with the given parameters. */ + public Builder( + @NonNull String locationName, + @FloatRange(from = -90.0, to = 90.0) double lowerLeftLatitude, + @FloatRange(from = -180.0, to = 180.0) double lowerLeftLongitude, + @FloatRange(from = -90.0, to = 90.0) double upperRightLatitude, + @FloatRange(from = -180.0, to = 180.0) double upperRightLongitude, + @IntRange(from = 1) int maxResults, + @NonNull Locale locale, + int callingUid, + @NonNull String callingPackage) { + mLocationName = locationName; + mLowerLeftLatitude = lowerLeftLatitude; + mLowerLeftLongitude = lowerLeftLongitude; + mUpperRightLatitude = upperRightLatitude; + mUpperRightLongitude = upperRightLongitude; + mMaxResults = maxResults; + mLocale = locale; + mCallingUid = callingUid; + mCallingPackage = callingPackage; + mCallingAttributionTag = null; + } + + /** Sets the attribution tag. */ + @NonNull + public Builder setCallingAttributionTag(@NonNull String attributionTag) { + mCallingAttributionTag = attributionTag; + return this; + } + + /** Builds a {@link ForwardGeocodeRequest}. */ + @NonNull + public ForwardGeocodeRequest build() { + return new ForwardGeocodeRequest( + mLocationName, + mLowerLeftLatitude, + mLowerLeftLongitude, + mUpperRightLatitude, + mUpperRightLongitude, + mMaxResults, + mLocale, + mCallingUid, + mCallingPackage, + mCallingAttributionTag); + } + } +} diff --git a/location/java/android/location/provider/GeocodeProviderBase.java b/location/java/android/location/provider/GeocodeProviderBase.java new file mode 100644 index 000000000000..e2c48b9c3515 --- /dev/null +++ b/location/java/android/location/provider/GeocodeProviderBase.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2010 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.location.provider; + +import android.annotation.FlaggedApi; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.content.Context; +import android.content.Intent; +import android.location.Address; +import android.location.flags.Flags; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.OutcomeReceiver; +import android.os.RemoteException; +import android.util.Log; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + +/** + * Base class for geocode providers outside the system server. + * + * <p>Geocode providers should be wrapped in a non-exported service which returns the result of + * {@link #getBinder()} from the service's {@link android.app.Service#onBind(Intent)} method. The + * service should not be exported so that components other than the system server cannot bind to it. + * Alternatively, the service may be guarded by a permission that only system server can obtain. The + * service may specify metadata on its capabilities: + * + * <ul> + * <li>"serviceVersion": An integer version code to help tie break if multiple services are + * capable of implementing the geocode provider. All else equal, the service with the highest + * version code will be chosen. Assumed to be 0 if not specified. + * <li>"serviceIsMultiuser": A boolean property, indicating if the service wishes to take + * responsibility for handling changes to the current user on the device. If true, the service + * will always be bound from the system user. If false, the service will always be bound from + * the current user. If the current user changes, the old binding will be released, and a new + * binding established under the new user. Assumed to be false if not specified. + * </ul> + * + * <p>The service should have an intent filter in place for the geocode provider as specified by the + * constant in this class. + * + * <p>Geocode providers are identified by their UID / package name / attribution tag. Based on this + * identity, geocode providers may be given some special privileges. + * + * @hide + */ +@FlaggedApi(Flags.FLAG_NEW_GEOCODER) +@SystemApi +public abstract class GeocodeProviderBase { + + /** + * The action the wrapping service should have in its intent filter to implement the geocode + * provider. + */ + @SuppressLint("ActionValue") + public static final String ACTION_GEOCODE_PROVIDER = + "com.android.location.service.GeocodeProvider"; + + final String mTag; + @Nullable final String mAttributionTag; + final IBinder mBinder; + + /** + * Subclasses should pass in a context and an arbitrary tag that may be used for logcat logging + * of errors, and thus should uniquely identify the class. + */ + public GeocodeProviderBase(@NonNull Context context, @NonNull String tag) { + mTag = tag; + mAttributionTag = context.getAttributionTag(); + mBinder = new Service(); + } + + /** + * Returns the IBinder instance that should be returned from the {@link + * android.app.Service#onBind(Intent)} method of the wrapping service. + */ + @NonNull + public final IBinder getBinder() { + return mBinder; + } + + /** + * Requests forward geocoding of the given arguments. The given callback must be invoked once. + */ + public abstract void onForwardGeocode( + @NonNull ForwardGeocodeRequest request, + @NonNull OutcomeReceiver<List<Address>, Exception> callback); + + /** + * Requests reverse geocoding of the given arguments. The given callback must be invoked once. + */ + public abstract void onReverseGeocode( + @NonNull ReverseGeocodeRequest request, + @NonNull OutcomeReceiver<List<Address>, Exception> callback); + + private class Service extends IGeocodeProvider.Stub { + @Override + public void forwardGeocode(ForwardGeocodeRequest request, IGeocodeCallback callback) { + try { + onForwardGeocode(request, new SingleUseCallback(callback)); + } catch (RuntimeException e) { + // exceptions on one-way binder threads are dropped - move to a different thread + Log.w(mTag, e); + new Handler(Looper.getMainLooper()) + .post( + () -> { + throw new AssertionError(e); + }); + } + } + + @Override + public void reverseGeocode(ReverseGeocodeRequest request, IGeocodeCallback callback) { + try { + onReverseGeocode(request, new SingleUseCallback(callback)); + } catch (RuntimeException e) { + // exceptions on one-way binder threads are dropped - move to a different thread + Log.w(mTag, e); + new Handler(Looper.getMainLooper()) + .post( + () -> { + throw new AssertionError(e); + }); + } + } + } + + private static class SingleUseCallback implements OutcomeReceiver<List<Address>, Exception> { + + private final AtomicReference<IGeocodeCallback> mCallback; + + SingleUseCallback(IGeocodeCallback callback) { + mCallback = new AtomicReference<>(callback); + } + + @Override + public void onError(Exception e) { + try { + Objects.requireNonNull(mCallback.getAndSet(null)).onError(e.toString()); + } catch (RemoteException r) { + throw r.rethrowFromSystemServer(); + } + } + + @Override + public void onResult(List<Address> results) { + try { + Objects.requireNonNull(mCallback.getAndSet(null)).onResults(results); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } +} diff --git a/location/java/android/location/IGeocodeListener.aidl b/location/java/android/location/provider/IGeocodeCallback.aidl index 8e104119a6f3..cf527130bcc3 100644 --- a/location/java/android/location/IGeocodeListener.aidl +++ b/location/java/android/location/provider/IGeocodeCallback.aidl @@ -14,16 +14,15 @@ * limitations under the License. */ -package android.location; +package android.location.provider; import android.location.Address; /** - * An interface for returning geocode results. - * - * {@hide} + * Binder interface for geocoding callbacks. + * @hide */ -interface IGeocodeListener { - - oneway void onResults(String error, in List<Address> results); +oneway interface IGeocodeCallback { + void onError(String error); + void onResults(in List<Address> results); } diff --git a/location/java/android/location/provider/IGeocodeProvider.aidl b/location/java/android/location/provider/IGeocodeProvider.aidl new file mode 100644 index 000000000000..92174387c578 --- /dev/null +++ b/location/java/android/location/provider/IGeocodeProvider.aidl @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2009 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.location.provider; + +import android.location.provider.IGeocodeCallback; +import android.location.provider.ForwardGeocodeRequest; +import android.location.provider.ReverseGeocodeRequest; + +/** + * Binder interface for services that implement geocode providers. Do not implement this directly, + * extend {@link GeocodeProviderBase} instead. + * @hide + */ +oneway interface IGeocodeProvider { + void forwardGeocode(in ForwardGeocodeRequest request, in IGeocodeCallback callback); + void reverseGeocode(in ReverseGeocodeRequest request, in IGeocodeCallback callback); +} diff --git a/core/java/android/service/voice/HotwordTrainingData.aidl b/location/java/android/location/provider/ReverseGeocodeRequest.aidl index 03cc8413d780..015757ad5d2d 100644 --- a/core/java/android/service/voice/HotwordTrainingData.aidl +++ b/location/java/android/location/provider/ReverseGeocodeRequest.aidl @@ -1,6 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project - * + * Copyright (C) 2024 * 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 @@ -14,6 +13,6 @@ * limitations under the License. */ -package android.service.voice; +package android.location.provider; -parcelable HotwordTrainingData; +parcelable ReverseGeocodeRequest; diff --git a/location/java/android/location/provider/ReverseGeocodeRequest.java b/location/java/android/location/provider/ReverseGeocodeRequest.java new file mode 100644 index 000000000000..57c9047f07ca --- /dev/null +++ b/location/java/android/location/provider/ReverseGeocodeRequest.java @@ -0,0 +1,230 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.location.provider; + +import static java.lang.Math.max; + +import android.annotation.FlaggedApi; +import android.annotation.FloatRange; +import android.annotation.IntRange; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.location.flags.Flags; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; + +import java.util.Locale; +import java.util.Objects; + +/** + * Reverse geocode (ie from lat/lng to address) provider request. + * + * @hide + */ +@FlaggedApi(Flags.FLAG_NEW_GEOCODER) +@SystemApi +public final class ReverseGeocodeRequest implements Parcelable { + + private final double mLatitude; + private final double mLongitude; + private final int mMaxResults; + private final Locale mLocale; + + private final int mCallingUid; + private final String mCallingPackage; + @Nullable private final String mCallingAttributionTag; + + private ReverseGeocodeRequest( + double latitude, + double longitude, + int maxResults, + Locale locale, + int callingUid, + String callingPackage, + @Nullable String callingAttributionTag) { + Preconditions.checkArgumentInRange(latitude, -90.0, 90.0, "latitude"); + Preconditions.checkArgumentInRange(longitude, -180.0, 180.0, "longitude"); + + mLatitude = latitude; + mLongitude = longitude; + mMaxResults = max(maxResults, 1); + mLocale = Objects.requireNonNull(locale); + + mCallingUid = callingUid; + mCallingPackage = Objects.requireNonNull(callingPackage); + mCallingAttributionTag = callingAttributionTag; + } + + /** The latitude of the point to be reverse geocoded. */ + @FloatRange(from = -90.0, to = 90.0) + public double getLatitude() { + return mLatitude; + } + + /** The longitude of the point to be reverse geocoded. */ + @FloatRange(from = -180.0, to = 180.0) + public double getLongitude() { + return mLongitude; + } + + /** The maximum number of reverse geocoding results that should be returned. */ + @IntRange(from = 1) + public int getMaxResults() { + return mMaxResults; + } + + /** The locale that results should be localized to (best effort). */ + @NonNull + public Locale getLocale() { + return mLocale; + } + + /** The UID of the caller this geocoding request is happening on behalf of. */ + public int getCallingUid() { + return mCallingUid; + } + + /** The package of the caller this geocoding request is happening on behalf of. */ + @NonNull + public String getCallingPackage() { + return mCallingPackage; + } + + /** The attribution tag of the caller this geocoding request is happening on behalf of. */ + @Nullable + public String getCallingAttributionTag() { + return mCallingAttributionTag; + } + + public static final @NonNull Creator<ReverseGeocodeRequest> CREATOR = + new Creator<>() { + @Override + public ReverseGeocodeRequest createFromParcel(Parcel in) { + return new ReverseGeocodeRequest( + in.readDouble(), + in.readDouble(), + in.readInt(), + new Locale(in.readString8(), in.readString8(), in.readString8()), + in.readInt(), + Objects.requireNonNull(in.readString8()), + in.readString8()); + } + + @Override + public ReverseGeocodeRequest[] newArray(int size) { + return new ReverseGeocodeRequest[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel parcel, int flags) { + parcel.writeDouble(mLatitude); + parcel.writeDouble(mLongitude); + parcel.writeInt(mMaxResults); + parcel.writeString8(mLocale.getLanguage()); + parcel.writeString8(mLocale.getCountry()); + parcel.writeString8(mLocale.getVariant()); + parcel.writeInt(mCallingUid); + parcel.writeString8(mCallingPackage); + parcel.writeString8(mCallingAttributionTag); + } + + @Override + public boolean equals(@Nullable Object object) { + if (object instanceof ReverseGeocodeRequest that) { + return mLatitude == that.mLatitude + && mLongitude == that.mLongitude + && mMaxResults == that.mMaxResults + && mCallingUid == that.mCallingUid + && mLocale.equals(that.mLocale) + && mCallingPackage.equals(that.mCallingPackage) + && Objects.equals(mCallingAttributionTag, that.mCallingAttributionTag); + } + + return false; + } + + @Override + public int hashCode() { + return Objects.hash( + mLatitude, + mLongitude, + mMaxResults, + mLocale, + mCallingUid, + mCallingPackage, + mCallingAttributionTag); + } + + /** A Builder for {@link ReverseGeocodeRequest}s. */ + public static final class Builder { + + private final double mLatitude; + private final double mLongitude; + private final int mMaxResults; + private final Locale mLocale; + + private final int mCallingUid; + private final String mCallingPackage; + @Nullable private String mCallingAttributionTag; + + /** Creates a new Builder instance with the given parameters. */ + public Builder( + @FloatRange(from = -90.0, to = 90.0) double latitude, + @FloatRange(from = -180.0, to = 180.0) double longitude, + @IntRange(from = 0) int maxResults, + @NonNull Locale locale, + int callingUid, + @NonNull String callingPackage) { + mLatitude = latitude; + mLongitude = longitude; + mMaxResults = maxResults; + mLocale = locale; + mCallingUid = callingUid; + mCallingPackage = callingPackage; + mCallingAttributionTag = null; + } + + /** Sets the attribution tag. */ + @NonNull + public Builder setCallingAttributionTag(@NonNull String attributionTag) { + mCallingAttributionTag = attributionTag; + return this; + } + + /** Builds a {@link ReverseGeocodeRequest}. */ + @NonNull + public ReverseGeocodeRequest build() { + return new ReverseGeocodeRequest( + mLatitude, + mLongitude, + mMaxResults, + mLocale, + mCallingUid, + mCallingPackage, + mCallingAttributionTag); + } + } +} diff --git a/location/lib/Android.bp b/location/lib/Android.bp index c9be5797fdbc..b10019a94209 100644 --- a/location/lib/Android.bp +++ b/location/lib/Android.bp @@ -30,6 +30,7 @@ java_sdk_library { "androidx.annotation_annotation", ], api_packages: [ + "android.location", "com.android.location.provider", "com.android.location.timezone.provider", ], diff --git a/location/lib/README.txt b/location/lib/README.txt index 400a7dd3f6ba..ae5187245163 100644 --- a/location/lib/README.txt +++ b/location/lib/README.txt @@ -1,30 +1,12 @@ This library (com.android.location.provider.jar) is a shared java library -containing classes required by unbundled location providers. - ---- Rules of this library --- -o This library is effectively a PUBLIC API for unbundled location providers - that may be distributed outside the system image. So it MUST BE API STABLE. - You can add but not remove. The rules are the same as for the - public platform SDK API. -o This library can see and instantiate internal platform classes (such as - ProviderRequest.java), but it must not expose them in any public method - (or by extending them via inheritance). This would break clients of the - library because they cannot see the internal platform classes. - -This library is distributed in the system image, and loaded as -a shared library. So you can change the implementation, but not -the interface. In this way it is like framework.jar. - ---- Why does this library exists? --- - -Unbundled location providers (such as the NetworkLocationProvider) -can not use internal platform classes. - -So ideally all of these classes would be part of the public platform SDK API, -but that doesn't seem like a great idea when only applications with a special -signature can implement this API. - -The compromise is this library. - -It wraps internal platform classes (like ProviderRequest) with a stable -API that does not leak the internal classes. +containing classes required by unbundled providers. The library was created +as a way of exposing API classes outside of the public API before SystemApi +was possible. Now that SystemApi exists, no new classes should ever be added +to this library, and all classes in this library should eventually be +deprecated and new SystemApi replacements offered. + +Whether or not classes in this library can ever be removed must be answered on +a case by case basis. Most of the classes are usually referenced by Google Play +services (in which case references can be removed from that code base), but +these classes may also be referenced by OEM code, which must be considered +before any removal. diff --git a/location/lib/api/system-current.txt b/location/lib/api/system-current.txt index 7046abd8fd3b..75e6bb437ca4 100644 --- a/location/lib/api/system-current.txt +++ b/location/lib/api/system-current.txt @@ -1,4 +1,21 @@ // Signature format: 2.0 +package android.location { + + @Deprecated public class GeocoderParams implements android.os.Parcelable { + ctor @Deprecated public GeocoderParams(android.content.Context); + ctor @Deprecated public GeocoderParams(android.content.Context, java.util.Locale); + ctor @Deprecated public GeocoderParams(int, String, @Nullable String, java.util.Locale); + method @Deprecated public int describeContents(); + method @Deprecated @Nullable public String getClientAttributionTag(); + method @Deprecated @NonNull public String getClientPackage(); + method @Deprecated public int getClientUid(); + method @Deprecated @NonNull public java.util.Locale getLocale(); + method @Deprecated public void writeToParcel(android.os.Parcel, int); + field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.location.GeocoderParams> CREATOR; + } + +} + package com.android.location.provider { @Deprecated public final class FusedLocationHardware { @@ -25,6 +42,13 @@ package com.android.location.provider { method @Deprecated public void onStatusChanged(int); } + @Deprecated public abstract class GeocodeProvider { + ctor @Deprecated public GeocodeProvider(); + method @Deprecated public android.os.IBinder getBinder(); + method @Deprecated public abstract String onGetFromLocation(double, double, int, android.location.GeocoderParams, java.util.List<android.location.Address>); + method @Deprecated public abstract String onGetFromLocationName(String, double, double, double, double, int, android.location.GeocoderParams, java.util.List<android.location.Address>); + } + @Deprecated public class GmsFusedBatchOptions { ctor @Deprecated public GmsFusedBatchOptions(); method @Deprecated public int getFlags(); diff --git a/core/java/android/location/GeocoderParams.java b/location/lib/java/android/location/GeocoderParams.java index 3ea6364e07c5..780ccf4ca53c 100644 --- a/core/java/android/location/GeocoderParams.java +++ b/location/lib/java/android/location/GeocoderParams.java @@ -18,7 +18,7 @@ package android.location; import android.annotation.NonNull; import android.annotation.Nullable; -import android.compat.annotation.UnsupportedAppUsage; +import android.annotation.SystemApi; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; @@ -28,15 +28,15 @@ import java.util.Locale; import java.util.Objects; /** - * This class contains extra parameters to pass to an IGeocodeProvider - * implementation from the Geocoder class. Currently this contains the - * language, country and variant information from the Geocoder's locale - * as well as the Geocoder client's package name for geocoder server - * logging. This information is kept in a separate class to allow for - * future expansion of the IGeocodeProvider interface. + * This class was originally shipped out-of-band from the normal API processes as a separate drop + * before SystemApi existed. Now that SystemApi does exist, this class has been retroactively + * published through SystemApi. * + * @deprecated Do not use. * @hide */ +@Deprecated +@SystemApi public class GeocoderParams implements Parcelable { private final int mUid; @@ -52,7 +52,8 @@ public class GeocoderParams implements Parcelable { this(Process.myUid(), context.getPackageName(), context.getAttributionTag(), locale); } - private GeocoderParams(int uid, String packageName, String attributionTag, Locale locale) { + public GeocoderParams( + int uid, String packageName, @Nullable String attributionTag, Locale locale) { mUid = uid; mPackageName = Objects.requireNonNull(packageName); mAttributionTag = attributionTag; @@ -62,7 +63,6 @@ public class GeocoderParams implements Parcelable { /** * Returns the client UID. */ - @UnsupportedAppUsage public int getClientUid() { return mUid; } @@ -70,7 +70,6 @@ public class GeocoderParams implements Parcelable { /** * Returns the client package name. */ - @UnsupportedAppUsage public @NonNull String getClientPackage() { return mPackageName; } @@ -78,7 +77,6 @@ public class GeocoderParams implements Parcelable { /** * Returns the client attribution tag. */ - @UnsupportedAppUsage public @Nullable String getClientAttributionTag() { return mAttributionTag; } @@ -86,34 +84,38 @@ public class GeocoderParams implements Parcelable { /** * Returns the locale. */ - @UnsupportedAppUsage public @NonNull Locale getLocale() { return mLocale; } public static final @NonNull Parcelable.Creator<GeocoderParams> CREATOR = - new Parcelable.Creator<GeocoderParams>() { - public GeocoderParams createFromParcel(Parcel in) { - int uid = in.readInt(); - String packageName = in.readString8(); - String attributionTag = in.readString8(); - String language = in.readString8(); - String country = in.readString8(); - String variant = in.readString8(); - - return new GeocoderParams(uid, packageName, attributionTag, - new Locale(language, country, variant)); - } - - public GeocoderParams[] newArray(int size) { - return new GeocoderParams[size]; - } - }; - + new Parcelable.Creator<>() { + public GeocoderParams createFromParcel(Parcel in) { + int uid = in.readInt(); + String packageName = in.readString8(); + String attributionTag = in.readString8(); + String language = in.readString8(); + String country = in.readString8(); + String variant = in.readString8(); + + return new GeocoderParams( + uid, + packageName, + attributionTag, + new Locale(language, country, variant)); + } + + public GeocoderParams[] newArray(int size) { + return new GeocoderParams[size]; + } + }; + + @Override public int describeContents() { return 0; } + @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(mUid); parcel.writeString8(mPackageName); diff --git a/location/lib/java/com/android/location/provider/GeocodeProvider.java b/location/lib/java/com/android/location/provider/GeocodeProvider.java index 05d793542202..45077ba8adc5 100644 --- a/location/lib/java/com/android/location/provider/GeocodeProvider.java +++ b/location/lib/java/com/android/location/provider/GeocodeProvider.java @@ -16,10 +16,13 @@ package com.android.location.provider; +import android.annotation.SystemApi; import android.location.Address; import android.location.GeocoderParams; -import android.location.IGeocodeListener; -import android.location.IGeocodeProvider; +import android.location.provider.ForwardGeocodeRequest; +import android.location.provider.IGeocodeCallback; +import android.location.provider.IGeocodeProvider; +import android.location.provider.ReverseGeocodeRequest; import android.os.IBinder; import android.os.RemoteException; @@ -27,47 +30,74 @@ import java.util.ArrayList; import java.util.List; /** - * Base class for geocode providers implemented as unbundled services. + * This class was originally shipped out-of-band from the normal API processes as a separate drop + * before SystemApi existed. Now that SystemApi does exist, this class has been retroactively + * published through SystemApi. * - * <p>Geocode providers can be implemented as services and return the result of - * {@link GeocodeProvider#getBinder()} in its getBinder() method. - * - * <p>IMPORTANT: This class is effectively a public API for unbundled - * applications, and must remain API stable. See README.txt in the root - * of this package for more information. + * @deprecated Use {@link android.location.provider.GeocodeProviderBase} instead. * @hide */ +@Deprecated +@SystemApi public abstract class GeocodeProvider { - private IGeocodeProvider.Stub mProvider = new IGeocodeProvider.Stub() { - @Override - public void getFromLocation(double latitude, double longitude, int maxResults, - GeocoderParams params, IGeocodeListener listener) { - List<Address> results = new ArrayList<>(); - String error = onGetFromLocation(latitude, longitude, maxResults, params, results); - try { - listener.onResults(error, results); - } catch (RemoteException e) { - // ignore - } - } + private final IGeocodeProvider.Stub mProvider = + new IGeocodeProvider.Stub() { + @Override + public void reverseGeocode( + ReverseGeocodeRequest request, IGeocodeCallback callback) { + List<Address> results = new ArrayList<>(); + String error = + onGetFromLocation( + request.getLatitude(), + request.getLongitude(), + request.getMaxResults(), + new GeocoderParams( + request.getCallingUid(), + request.getCallingPackage(), + request.getCallingAttributionTag(), + request.getLocale()), + results); + try { + if (error != null) { + callback.onError(error); + } else { + callback.onResults(results); + } + } catch (RemoteException e) { + // ignore + } + } - @Override - public void getFromLocationName(String locationName, - double lowerLeftLatitude, double lowerLeftLongitude, - double upperRightLatitude, double upperRightLongitude, int maxResults, - GeocoderParams params, IGeocodeListener listener) { - List<Address> results = new ArrayList<>(); - String error = onGetFromLocationName(locationName, lowerLeftLatitude, - lowerLeftLongitude, upperRightLatitude, upperRightLongitude, - maxResults, params, results); - try { - listener.onResults(error, results); - } catch (RemoteException e) { - // ignore - } - } - }; + @Override + public void forwardGeocode( + ForwardGeocodeRequest request, IGeocodeCallback callback) { + List<Address> results = new ArrayList<>(); + String error = + onGetFromLocationName( + request.getLocationName(), + request.getLowerLeftLatitude(), + request.getLowerLeftLongitude(), + request.getUpperRightLatitude(), + request.getUpperRightLongitude(), + request.getMaxResults(), + new GeocoderParams( + request.getCallingUid(), + request.getCallingPackage(), + request.getCallingAttributionTag(), + request.getLocale()), + results); + try { + if (error != null) { + callback.onError(error); + } else { + callback.onResults(results); + } + } catch (RemoteException e) { + // ignore + } + } + }; /** * This method is overridden to implement the diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index ac94a6f6ad3c..9548525d68d1 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -3557,6 +3557,36 @@ final public class MediaCodec { } /** + * Set a linear block that contain multiple non-encrypted access unit to this + * queue request. Exactly one buffer must be set for a queue request before + * calling {@link #queue}. Multiple access units if present must be laid out contiguously + * and without gaps and in order. An IllegalArgumentException will be thrown + * during {@link #queue} if access units are not laid out contiguously. + * + * @param block The linear block object + * @param infos Represents {@link MediaCodec.BufferInfo} objects to mark + * individual access-unit boundaries and the timestamps associated with it. + * @return this object + * @throws IllegalStateException if a buffer is already set + */ + @FlaggedApi(FLAG_LARGE_AUDIO_FRAME) + public @NonNull QueueRequest setMultiFrameLinearBlock( + @NonNull LinearBlock block, + @NonNull ArrayDeque<BufferInfo> infos) { + if (!isAccessible()) { + throw new IllegalStateException("The request is stale"); + } + if (mLinearBlock != null || mHardwareBuffer != null) { + throw new IllegalStateException("Cannot set block twice"); + } + mLinearBlock = block; + mBufferInfos.clear(); + mBufferInfos.addAll(infos); + mCryptoInfos.clear(); + return this; + } + + /** * Set an encrypted linear block to this queue request. Exactly one buffer must be * set for a queue request before calling {@link #queue}. It is possible * to use the same {@link LinearBlock} object for multiple queue @@ -3691,26 +3721,6 @@ final public class MediaCodec { } /** - * Sets MediaCodec.BufferInfo objects describing the access units - * contained in this queue request. Access units must be laid out - * contiguously without gaps and in order. - * - * @param infos Represents {@link MediaCodec.BufferInfo} objects to mark - * individual access-unit boundaries and the timestamps associated with it. - * The buffer is expected to contain the data in a continuous manner. - * @return this object - */ - @FlaggedApi(FLAG_LARGE_AUDIO_FRAME) - public @NonNull QueueRequest setBufferInfos(@NonNull ArrayDeque<BufferInfo> infos) { - if (!isAccessible()) { - throw new IllegalStateException("The request is stale"); - } - mBufferInfos.clear(); - mBufferInfos.addAll(infos); - return this; - } - - /** * Add an integer parameter. * See {@link MediaFormat} for an exhaustive list of supported keys with * values of type int, that can also be set with {@link MediaFormat#setInteger}. diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index 3174c377b91c..1e7bc4764dd7 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -20,10 +20,12 @@ import static android.media.Utils.intersectSortedDistinctRanges; import static android.media.Utils.sortDistinctRanges; import static android.media.codec.Flags.FLAG_DYNAMIC_COLOR_ASPECTS; import static android.media.codec.Flags.FLAG_HLG_EDITING; +import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC; import static android.media.codec.Flags.FLAG_NULL_OUTPUT_SURFACE; import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST; import android.annotation.FlaggedApi; +import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; @@ -40,6 +42,8 @@ import android.util.Range; import android.util.Rational; import android.util.Size; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -1808,6 +1812,55 @@ public final class MediaCodecInfo { } } + /** @hide */ + @IntDef(prefix = {"SECURITY_MODEL_"}, value = { + SECURITY_MODEL_SANDBOXED, + SECURITY_MODEL_MEMORY_SAFE, + SECURITY_MODEL_TRUSTED_CONTENT_ONLY, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SecurityModel {} + + /** + * In this model the codec is running in a sandboxed process. Even if a + * malicious content was fed to the codecs in this model, the impact will + * be contained in the sandboxed process. + */ + @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC) + public static final int SECURITY_MODEL_SANDBOXED = 0; + /** + * In this model the codec is not running in a sandboxed process, but + * written in a memory-safe way. It typically means that the software + * implementation of the codec is written in a memory-safe language such + * as Rust. + */ + @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC) + public static final int SECURITY_MODEL_MEMORY_SAFE = 1; + /** + * In this model the codec is suitable only for trusted content where + * the input can be verified to be well-formed and no malicious actor + * can alter it. For example, codecs in this model are not suitable + * for arbitrary media downloaded from the internet or present in a user + * directory. On the other hand, they could be suitable for media encoded + * in the backend that the app developer wholly controls. + * <p> + * Codecs with this security model is not included in + * {@link MediaCodecList#REGULAR_CODECS}, but included in + * {@link MediaCodecList#ALL_CODECS}. + */ + @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC) + public static final int SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 2; + + /** + * Query the security model of the codec. + */ + @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC) + @SecurityModel + public int getSecurityModel() { + // TODO b/297922713 --- detect security model of out-of-sandbox codecs + return SECURITY_MODEL_SANDBOXED; + } + /** * A class that supports querying the video capabilities of a codec. */ diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index 5e40eee26886..7b83842a9fb2 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -16,6 +16,8 @@ package android.media; +import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC; + import static com.android.media.codec.flags.Flags.FLAG_CODEC_IMPORTANCE; import static com.android.media.codec.flags.Flags.FLAG_LARGE_AUDIO_FRAME; @@ -1715,6 +1717,58 @@ public final class MediaFormat { @FlaggedApi(FLAG_CODEC_IMPORTANCE) public static final String KEY_IMPORTANCE = "importance"; + /** @hide */ + @IntDef(flag = true, prefix = {"FLAG_SECURITY_MODEL_"}, value = { + FLAG_SECURITY_MODEL_SANDBOXED, + FLAG_SECURITY_MODEL_MEMORY_SAFE, + FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SecurityModelFlag {} + + /** + * Flag for {@link MediaCodecInfo#SECURITY_MODEL_SANDBOXED}. + */ + @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC) + public static final int FLAG_SECURITY_MODEL_SANDBOXED = + (1 << MediaCodecInfo.SECURITY_MODEL_SANDBOXED); + /** + * Flag for {@link MediaCodecInfo#SECURITY_MODEL_MEMORY_SAFE}. + */ + @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC) + public static final int FLAG_SECURITY_MODEL_MEMORY_SAFE = + (1 << MediaCodecInfo.SECURITY_MODEL_MEMORY_SAFE); + /** + * Flag for {@link MediaCodecInfo#SECURITY_MODEL_TRUSTED_CONTENT_ONLY}. + */ + @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC) + public static final int FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY = + (1 << MediaCodecInfo.SECURITY_MODEL_TRUSTED_CONTENT_ONLY); + + /** + * A key describing the requested security model as flags. + * <p> + * The associated value is a flag of the following values: + * {@link FLAG_SECURITY_MODEL_SANDBOXED}, + * {@link FLAG_SECURITY_MODEL_MEMORY_SAFE}, + * {@link FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY}. The default value is + * {@link FLAG_SECURITY_MODEL_SANDBOXED}. + * <p> + * When passed to {@link MediaCodecList#findDecoderForFormat} or + * {@link MediaCodecList#findEncoderForFormat}, MediaCodecList filters + * the security model of the codecs according to this flag value. + * <p> + * When passed to {@link MediaCodec#configure}, MediaCodec verifies + * the security model matches the flag value passed, and throws + * {@link java.lang.IllegalArgumentException} if the model does not match. + * <p> + * @see MediaCodecInfo#getSecurityModel + * @see MediaCodecList#findDecoderForFormat + * @see MediaCodecList#findEncoderForFormat + */ + @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC) + public static final String KEY_SECURITY_MODEL = "security-model"; + /* package private */ MediaFormat(@NonNull Map<String, Object> map) { mMap = map; } diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java index 144b01a438a2..4d5a33d99b64 100644 --- a/media/java/android/media/MediaRouter2.java +++ b/media/java/android/media/MediaRouter2.java @@ -20,6 +20,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa import static com.android.media.flags.Flags.FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES; import static com.android.media.flags.Flags.FLAG_ENABLE_CROSS_USER_ROUTING_IN_MEDIA_ROUTER2; import static com.android.media.flags.Flags.FLAG_ENABLE_GET_TRANSFERABLE_ROUTES; +import static com.android.media.flags.Flags.FLAG_ENABLE_PRIVILEGED_ROUTING_FOR_MEDIA_ROUTING_CONTROL; import static com.android.media.flags.Flags.FLAG_ENABLE_RLP_CALLBACKS_IN_MEDIA_ROUTER2; import static com.android.media.flags.Flags.FLAG_ENABLE_SCREEN_OFF_SCANNING; @@ -989,17 +990,24 @@ public final class MediaRouter2 { } /** - * Requests a volume change for the route asynchronously. - * It may have no effect if the route is currently not selected. + * Sets the volume for a specific route. * - * <p>This will be no-op for non-system media routers. + * <p>The call may have no effect if the route is currently not selected. + * + * <p>This method is only supported by {@link #getInstance(Context, String) proxy MediaRouter2 + * instances}. Use {@link RoutingController#setVolume(int) RoutingController#setVolume(int)} + * instead for {@link #getInstance(Context) local MediaRouter2 instances}.</p> * * @param volume The new volume value between 0 and {@link MediaRoute2Info#getVolumeMax}. - * @see #getInstance(Context, String) - * @hide + * @throws UnsupportedOperationException If called on a {@link #getInstance(Context) local + * router instance}. */ - @SystemApi - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) + @FlaggedApi(FLAG_ENABLE_PRIVILEGED_ROUTING_FOR_MEDIA_ROUTING_CONTROL) + @RequiresPermission( + anyOf = { + Manifest.permission.MEDIA_CONTENT_CONTROL, + Manifest.permission.MEDIA_ROUTING_CONTROL + }) public void setRouteVolume(@NonNull MediaRoute2Info route, int volume) { Objects.requireNonNull(route, "route must not be null"); @@ -3464,10 +3472,11 @@ public final class MediaRouter2 { return result; } - /** No-op. Local routers cannot modify the volume of specific routes. */ + /** Local routers cannot modify the volume of specific routes. */ @Override public void setRouteVolume(MediaRoute2Info route, int volume) { - // Do nothing. + throw new UnsupportedOperationException( + "setRouteVolume is only supported by proxy routers. See javadoc."); // If this API needs to be public, use IMediaRouterService#setRouteVolumeWithRouter2() } diff --git a/media/java/android/media/metrics/EditingEndedEvent.java b/media/java/android/media/metrics/EditingEndedEvent.java index 9b3477f4bd69..54496bff077f 100644 --- a/media/java/android/media/metrics/EditingEndedEvent.java +++ b/media/java/android/media/metrics/EditingEndedEvent.java @@ -199,7 +199,7 @@ public final class EditingEndedEvent extends Event implements Parcelable { /** Input audio was edited. */ public static final long OPERATION_TYPE_AUDIO_EDIT = 1L << 3; - /** Input video samples were writted (muxed) directly to the output file without transcoding. */ + /** Input video samples were written (muxed) directly to the output file without transcoding. */ public static final long OPERATION_TYPE_VIDEO_TRANSMUX = 1L << 4; /** Input audio samples were written (muxed) directly to the output file without transcoding. */ @@ -272,7 +272,8 @@ public final class EditingEndedEvent extends Event implements Parcelable { } /** - * Returns the name of the library implementing the exporting operation, or {@code null} if + * Returns the name of the library implementing the exporting operation, for example, a Maven + * artifact ID like "androidx.media3.media3-transformer:1.3.0-beta01", or {@code null} if * unknown. */ @Nullable @@ -281,8 +282,8 @@ public final class EditingEndedEvent extends Event implements Parcelable { } /** - * Returns the name of the library implementing the media muxing operation, or {@code null} if - * unknown. + * Returns the name of the library implementing the media muxing operation, for example, a Maven + * artifact ID like "androidx.media3.media3-muxer:1.3.0-beta01", or {@code null} if unknown. */ @Nullable public String getMuxerName() { diff --git a/media/java/android/media/metrics/MediaItemInfo.java b/media/java/android/media/metrics/MediaItemInfo.java index 63dd3ccd3b33..338697fef76b 100644 --- a/media/java/android/media/metrics/MediaItemInfo.java +++ b/media/java/android/media/metrics/MediaItemInfo.java @@ -92,7 +92,7 @@ public final class MediaItemInfo implements Parcelable { DATA_TYPE_DEPTH, DATA_TYPE_GAIN_MAP, DATA_TYPE_HIGH_FRAME_RATE, - DATA_TYPE_CUE_POINTS, + DATA_TYPE_SPEED_SETTING_CUE_POINTS, DATA_TYPE_GAPLESS, DATA_TYPE_SPATIAL_AUDIO, DATA_TYPE_HIGH_DYNAMIC_RANGE_VIDEO, @@ -109,7 +109,10 @@ public final class MediaItemInfo implements Parcelable { /** The media item includes audio data. */ public static final long DATA_TYPE_AUDIO = 1L << 2; - /** The media item includes metadata. */ + /** + * The media item includes static media container metadata (for example, capture frame rate or + * location information). + */ public static final long DATA_TYPE_METADATA = 1L << 3; /** The media item includes depth (z-distance) information. */ @@ -121,8 +124,11 @@ public final class MediaItemInfo implements Parcelable { /** The media item includes high frame rate video data. */ public static final long DATA_TYPE_HIGH_FRAME_RATE = 1L << 6; - /** The media item includes time-dependent speed setting metadata. */ - public static final long DATA_TYPE_CUE_POINTS = 1L << 7; + /** + * The media item includes time-dependent speed information (for example, slow motion cue + * points). + */ + public static final long DATA_TYPE_SPEED_SETTING_CUE_POINTS = 1L << 7; /** The media item includes gapless audio metadata. */ public static final long DATA_TYPE_GAPLESS = 1L << 8; diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java index a8e94234e063..e92c7b3ba8b5 100644 --- a/media/java/android/service/media/MediaBrowserService.java +++ b/media/java/android/service/media/MediaBrowserService.java @@ -211,51 +211,40 @@ public abstract class MediaBrowserService extends Service { } private static class ServiceBinder extends IMediaBrowserService.Stub { - private WeakReference<MediaBrowserService> mService; + private WeakReference<ServiceState> mServiceState; - private ServiceBinder(MediaBrowserService service) { - mService = new WeakReference(service); + private ServiceBinder(ServiceState serviceState) { + mServiceState = new WeakReference(serviceState); } @Override public void connect(final String pkg, final Bundle rootHints, final IMediaBrowserServiceCallbacks callbacks) { - MediaBrowserService service = mService.get(); - if (service == null) { + ServiceState serviceState = mServiceState.get(); + if (serviceState == null) { return; } final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); - if (!service.isValidPackage(pkg, uid)) { + if (!serviceState.isValidPackage(pkg, uid)) { throw new IllegalArgumentException("Package/uid mismatch: uid=" + uid + " package=" + pkg); } - service.mHandler.post( - () -> service.connectOnHandler(pkg, pid, uid, rootHints, callbacks)); + serviceState.postOnHandler( + () -> serviceState.connectOnHandler(pkg, pid, uid, rootHints, callbacks)); } @Override public void disconnect(final IMediaBrowserServiceCallbacks callbacks) { - MediaBrowserService service = mService.get(); - if (service == null) { + ServiceState serviceState = mServiceState.get(); + if (serviceState == null) { return; } - service.mHandler.post(new Runnable() { - @Override - public void run() { - final IBinder b = callbacks.asBinder(); - - // Clear out the old subscriptions. We are getting new ones. - final ConnectionRecord old = service.mServiceState.mConnections.remove(b); - if (old != null) { - // TODO - old.callbacks.asBinder().unlinkToDeath(old, 0); - } - } - }); + serviceState.postOnHandler( + () -> serviceState.removeConnectionRecordOnHandler(callbacks)); } @Override @@ -266,13 +255,13 @@ public abstract class MediaBrowserService extends Service { @Override public void addSubscription(final String id, final IBinder token, final Bundle options, final IMediaBrowserServiceCallbacks callbacks) { - MediaBrowserService service = mService.get(); - if (service == null) { + ServiceState serviceState = mServiceState.get(); + if (serviceState == null) { return; } - service.mHandler.post( - () -> service.addSubscriptionOnHandler(id, callbacks, token, options)); + serviceState.postOnHandler( + () -> serviceState.addSubscriptionOnHandler(id, callbacks, token, options)); } @Override @@ -284,14 +273,14 @@ public abstract class MediaBrowserService extends Service { @Override public void removeSubscription(final String id, final IBinder token, final IMediaBrowserServiceCallbacks callbacks) { - MediaBrowserService service = mService.get(); - if (service == null) { + ServiceState serviceState = mServiceState.get(); + if (serviceState == null) { return; } - service.mHandler.post( + serviceState.postOnHandler( () -> { - if (!service.removeSubscriptionOnHandler(id, callbacks, token)) { + if (!serviceState.removeSubscriptionOnHandler(id, callbacks, token)) { Log.w(TAG, "removeSubscription for id with no subscription: " + id); } }); @@ -300,20 +289,20 @@ public abstract class MediaBrowserService extends Service { @Override public void getMediaItem(final String mediaId, final ResultReceiver receiver, final IMediaBrowserServiceCallbacks callbacks) { - MediaBrowserService service = mService.get(); - if (service == null) { + ServiceState serviceState = mServiceState.get(); + if (serviceState == null) { return; } - service.mHandler.post( - () -> service.performLoadItemOnHandler(mediaId, callbacks, receiver)); + serviceState.postOnHandler( + () -> serviceState.performLoadItemOnHandler(mediaId, callbacks, receiver)); } } @Override public void onCreate() { super.onCreate(); - mServiceState.mBinder = new ServiceBinder(this); + mServiceState.mBinder = new ServiceBinder(mServiceState); } @Override @@ -448,7 +437,7 @@ public abstract class MediaBrowserService extends Service { throw new IllegalStateException("The session token has already been set."); } mServiceState.mSession = token; - mHandler.post(() -> notifySessionTokenInitializedOnHandler(token)); + mHandler.post(() -> mServiceState.notifySessionTokenInitializedOnHandler(token)); } /** @@ -526,268 +515,7 @@ public abstract class MediaBrowserService extends Service { if (parentId == null) { throw new IllegalArgumentException("parentId cannot be null in notifyChildrenChanged"); } - mHandler.post(() -> notifyChildrenChangeOnHandler(parentId, options)); - } - - /** - * Return whether the given package is one of the ones that is owned by the uid. - */ - private boolean isValidPackage(String pkg, int uid) { - if (pkg == null) { - return false; - } - final PackageManager pm = getPackageManager(); - final String[] packages = pm.getPackagesForUid(uid); - final int N = packages.length; - for (int i = 0; i < N; i++) { - if (packages[i].equals(pkg)) { - return true; - } - } - return false; - } - - private void notifySessionTokenInitializedOnHandler(MediaSession.Token token) { - Iterator<ConnectionRecord> iter = mServiceState.mConnections.values().iterator(); - while (iter.hasNext()) { - ConnectionRecord connection = iter.next(); - try { - connection.callbacks.onConnect( - connection.root.getRootId(), token, connection.root.getExtras()); - } catch (RemoteException e) { - Log.w(TAG, "Connection for " + connection.pkg + " is no longer valid."); - iter.remove(); - } - } - } - - private void notifyChildrenChangeOnHandler(final String parentId, final Bundle options) { - for (IBinder binder : mServiceState.mConnections.keySet()) { - ConnectionRecord connection = mServiceState.mConnections.get(binder); - List<Pair<IBinder, Bundle>> callbackList = connection.subscriptions.get(parentId); - if (callbackList != null) { - for (Pair<IBinder, Bundle> callback : callbackList) { - if (MediaBrowserUtils.hasDuplicatedItems(options, callback.second)) { - performLoadChildrenOnHandler(parentId, connection, callback.second); - } - } - } - } - } - - /** Save the subscription and if it is a new subscription send the results. */ - private void addSubscriptionOnHandler( - String id, IMediaBrowserServiceCallbacks callbacks, IBinder token, Bundle options) { - IBinder b = callbacks.asBinder(); - // Get the record for the connection - ConnectionRecord connection = mServiceState.mConnections.get(b); - if (connection == null) { - Log.w(TAG, "addSubscription for callback that isn't registered id=" + id); - return; - } - - // Save the subscription - List<Pair<IBinder, Bundle>> callbackList = connection.subscriptions.get(id); - if (callbackList == null) { - callbackList = new ArrayList<>(); - } - for (Pair<IBinder, Bundle> callback : callbackList) { - if (token == callback.first - && MediaBrowserUtils.areSameOptions(options, callback.second)) { - return; - } - } - callbackList.add(new Pair<>(token, options)); - connection.subscriptions.put(id, callbackList); - // send the results - performLoadChildrenOnHandler(id, connection, options); - } - - private void connectOnHandler( - String pkg, - int pid, - int uid, - Bundle rootHints, - IMediaBrowserServiceCallbacks callbacks) { - IBinder b = callbacks.asBinder(); - // Clear out the old subscriptions. We are getting new ones. - mServiceState.mConnections.remove(b); - - // Temporarily sets a placeholder ConnectionRecord to make getCurrentBrowserInfo() work in - // onGetRoot(). - mServiceState.mCurConnection = - new ConnectionRecord( - /* service= */ this, pkg, pid, uid, rootHints, callbacks, /* root= */ null); - BrowserRoot root = onGetRoot(pkg, uid, rootHints); - mServiceState.mCurConnection = null; - - // If they didn't return something, don't allow this client. - if (root == null) { - Log.i(TAG, "No root for client " + pkg + " from service " + getClass().getName()); - try { - callbacks.onConnectFailed(); - } catch (RemoteException ex) { - Log.w(TAG, "Calling onConnectFailed() failed. Ignoring. pkg=" + pkg); - } - } else { - try { - ConnectionRecord connection = - new ConnectionRecord( - /* service= */ this, pkg, pid, uid, rootHints, callbacks, root); - mServiceState.mConnections.put(b, connection); - b.linkToDeath(connection, /* flags= */ 0); - if (mServiceState.mSession != null) { - callbacks.onConnect( - connection.root.getRootId(), - mServiceState.mSession, - connection.root.getExtras()); - } - } catch (RemoteException ex) { - Log.w(TAG, "Calling onConnect() failed. Dropping client. pkg=" + pkg); - mServiceState.mConnections.remove(b); - } - } - } - - /** Remove the subscription. */ - private boolean removeSubscriptionOnHandler( - String id, IMediaBrowserServiceCallbacks callbacks, IBinder token) { - final IBinder b = callbacks.asBinder(); - - ConnectionRecord connection = mServiceState.mConnections.get(b); - if (connection == null) { - Log.w(TAG, "removeSubscription for callback that isn't registered id=" + id); - return true; - } - - if (token == null) { - return connection.subscriptions.remove(id) != null; - } - boolean removed = false; - List<Pair<IBinder, Bundle>> callbackList = connection.subscriptions.get(id); - if (callbackList != null) { - Iterator<Pair<IBinder, Bundle>> iter = callbackList.iterator(); - while (iter.hasNext()) { - if (token == iter.next().first) { - removed = true; - iter.remove(); - } - } - if (callbackList.isEmpty()) { - connection.subscriptions.remove(id); - } - } - return removed; - } - - /** - * Call onLoadChildren and then send the results back to the connection. - * - * <p>Callers must make sure that this connection is still connected. - */ - private void performLoadChildrenOnHandler( - final String parentId, final ConnectionRecord connection, final Bundle options) { - final Result<List<MediaBrowser.MediaItem>> result = - new Result<>(parentId) { - @Override - void onResultSent(List<MediaBrowser.MediaItem> list, @ResultFlags int flag) { - if (mServiceState.mConnections.get(connection.callbacks.asBinder()) - != connection) { - if (DBG) { - Log.d( - TAG, - "Not sending onLoadChildren result for connection that has" - + " been disconnected. pkg=" - + connection.pkg - + " id=" - + parentId); - } - return; - } - - List<MediaBrowser.MediaItem> filteredList = - (flag & RESULT_FLAG_OPTION_NOT_HANDLED) != 0 - ? MediaBrowserUtils.applyPagingOptions(list, options) - : list; - ParceledListSlice<MediaBrowser.MediaItem> pls = null; - if (filteredList != null) { - pls = new ParceledListSlice<>(filteredList); - // Limit the size of initial Parcel to prevent binder buffer overflow - // as onLoadChildren is an async binder call. - pls.setInlineCountLimit(1); - } - try { - connection.callbacks.onLoadChildren(parentId, pls, options); - } catch (RemoteException ex) { - // The other side is in the process of crashing. - Log.w( - TAG, - "Calling onLoadChildren() failed for id=" - + parentId - + " package=" - + connection.pkg); - } - } - }; - - mServiceState.mCurConnection = connection; - if (options == null) { - onLoadChildren(parentId, result); - } else { - onLoadChildren(parentId, result, options); - } - mServiceState.mCurConnection = null; - - if (!result.isDone()) { - throw new IllegalStateException("onLoadChildren must call detach() or sendResult()" - + " before returning for package=" + connection.pkg + " id=" + parentId); - } - } - - private void performLoadItemOnHandler( - String itemId, IMediaBrowserServiceCallbacks callbacks, final ResultReceiver receiver) { - final IBinder b = callbacks.asBinder(); - ConnectionRecord connection = mServiceState.mConnections.get(b); - if (connection == null) { - Log.w(TAG, "getMediaItem for callback that isn't registered id=" + itemId); - return; - } - - final Result<MediaBrowser.MediaItem> result = - new Result<>(itemId) { - @Override - void onResultSent(MediaBrowser.MediaItem item, @ResultFlags int flag) { - if (mServiceState.mConnections.get(connection.callbacks.asBinder()) - != connection) { - if (DBG) { - Log.d( - TAG, - "Not sending onLoadItem result for connection that has" - + " been disconnected. pkg=" - + connection.pkg - + " id=" - + itemId); - } - return; - } - if ((flag & RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED) != 0) { - receiver.send(RESULT_ERROR, null); - return; - } - Bundle bundle = new Bundle(); - bundle.putParcelable(KEY_MEDIA_ITEM, item); - receiver.send(RESULT_OK, bundle); - } - }; - - mServiceState.mCurConnection = connection; - onLoadItem(itemId, result); - mServiceState.mCurConnection = null; - - if (!result.isDone()) { - throw new IllegalStateException("onLoadItem must call detach() or sendResult()" - + " before returning for id=" + itemId); - } + mHandler.post(() -> mServiceState.notifyChildrenChangeOnHandler(parentId, options)); } /** @@ -885,7 +613,7 @@ public abstract class MediaBrowserService extends Service { * service. This allows us to put the service in a valid state once the session is released * (which is an irrecoverable invalid state). More details about this in b/185136506. */ - private static class ServiceState { + private class ServiceState { // Fields accessed from any caller thread. @Nullable private MediaSession.Token mSession; @@ -894,5 +622,292 @@ public abstract class MediaBrowserService extends Service { // Fields accessed from mHandler only. @NonNull private final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap<>(); @Nullable private ConnectionRecord mCurConnection; + + public void postOnHandler(Runnable runnable) { + mHandler.post(runnable); + } + + public void removeConnectionRecordOnHandler(IMediaBrowserServiceCallbacks callbacks) { + IBinder b = callbacks.asBinder(); + // Clear out the old subscriptions. We are getting new ones. + ConnectionRecord old = mConnections.remove(b); + if (old != null) { + old.callbacks.asBinder().unlinkToDeath(old, 0); + } + } + + public void notifySessionTokenInitializedOnHandler(MediaSession.Token token) { + Iterator<ConnectionRecord> iter = mConnections.values().iterator(); + while (iter.hasNext()) { + ConnectionRecord connection = iter.next(); + try { + connection.callbacks.onConnect( + connection.root.getRootId(), token, connection.root.getExtras()); + } catch (RemoteException e) { + Log.w(TAG, "Connection for " + connection.pkg + " is no longer valid."); + iter.remove(); + } + } + } + + public void notifyChildrenChangeOnHandler(String parentId, Bundle options) { + for (IBinder binder : mConnections.keySet()) { + ConnectionRecord connection = mConnections.get(binder); + List<Pair<IBinder, Bundle>> callbackList = connection.subscriptions.get(parentId); + if (callbackList != null) { + for (Pair<IBinder, Bundle> callback : callbackList) { + if (MediaBrowserUtils.hasDuplicatedItems(options, callback.second)) { + performLoadChildrenOnHandler(parentId, connection, callback.second); + } + } + } + } + } + + /** Save the subscription and if it is a new subscription send the results. */ + public void addSubscriptionOnHandler( + String id, IMediaBrowserServiceCallbacks callbacks, IBinder token, Bundle options) { + IBinder b = callbacks.asBinder(); + // Get the record for the connection + ConnectionRecord connection = mConnections.get(b); + if (connection == null) { + Log.w(TAG, "addSubscription for callback that isn't registered id=" + id); + return; + } + + // Save the subscription + List<Pair<IBinder, Bundle>> callbackList = connection.subscriptions.get(id); + if (callbackList == null) { + callbackList = new ArrayList<>(); + } + for (Pair<IBinder, Bundle> callback : callbackList) { + if (token == callback.first + && MediaBrowserUtils.areSameOptions(options, callback.second)) { + return; + } + } + callbackList.add(new Pair<>(token, options)); + connection.subscriptions.put(id, callbackList); + // send the results + performLoadChildrenOnHandler(id, connection, options); + } + + public void connectOnHandler( + String pkg, + int pid, + int uid, + Bundle rootHints, + IMediaBrowserServiceCallbacks callbacks) { + IBinder b = callbacks.asBinder(); + // Clear out the old subscriptions. We are getting new ones. + mConnections.remove(b); + + // Temporarily sets a placeholder ConnectionRecord to make getCurrentBrowserInfo() work + // in onGetRoot(). + mCurConnection = + new ConnectionRecord( + /* service= */ MediaBrowserService.this, + pkg, + pid, + uid, + rootHints, + callbacks, + /* root= */ null); + BrowserRoot root = onGetRoot(pkg, uid, rootHints); + mCurConnection = null; + + // If they didn't return something, don't allow this client. + if (root == null) { + Log.i(TAG, "No root for client " + pkg + " from service " + getClass().getName()); + try { + callbacks.onConnectFailed(); + } catch (RemoteException ex) { + Log.w(TAG, "Calling onConnectFailed() failed. Ignoring. pkg=" + pkg); + } + } else { + try { + ConnectionRecord connection = + new ConnectionRecord( + /* service= */ MediaBrowserService.this, + pkg, + pid, + uid, + rootHints, + callbacks, + root); + mConnections.put(b, connection); + b.linkToDeath(connection, /* flags= */ 0); + if (mSession != null) { + callbacks.onConnect( + connection.root.getRootId(), mSession, connection.root.getExtras()); + } + } catch (RemoteException ex) { + Log.w(TAG, "Calling onConnect() failed. Dropping client. pkg=" + pkg); + mConnections.remove(b); + } + } + } + + /** Remove the subscription. */ + public boolean removeSubscriptionOnHandler( + String id, IMediaBrowserServiceCallbacks callbacks, IBinder token) { + IBinder b = callbacks.asBinder(); + + ConnectionRecord connection = mConnections.get(b); + if (connection == null) { + Log.w(TAG, "removeSubscription for callback that isn't registered id=" + id); + return true; + } + + if (token == null) { + return connection.subscriptions.remove(id) != null; + } + boolean removed = false; + List<Pair<IBinder, Bundle>> callbackList = connection.subscriptions.get(id); + if (callbackList != null) { + Iterator<Pair<IBinder, Bundle>> iter = callbackList.iterator(); + while (iter.hasNext()) { + if (token == iter.next().first) { + removed = true; + iter.remove(); + } + } + if (callbackList.isEmpty()) { + connection.subscriptions.remove(id); + } + } + return removed; + } + + /** + * Call onLoadChildren and then send the results back to the connection. + * + * <p>Callers must make sure that this connection is still connected. + */ + public void performLoadChildrenOnHandler( + String parentId, ConnectionRecord connection, Bundle options) { + Result<List<MediaBrowser.MediaItem>> result = + new Result<>(parentId) { + @Override + void onResultSent( + List<MediaBrowser.MediaItem> list, @ResultFlags int flag) { + if (mServiceState.mConnections.get(connection.callbacks.asBinder()) + != connection) { + if (DBG) { + Log.d( + TAG, + "Not sending onLoadChildren result for connection that" + + " has been disconnected. pkg=" + + connection.pkg + + " id=" + + parentId); + } + return; + } + + List<MediaBrowser.MediaItem> filteredList = + (flag & RESULT_FLAG_OPTION_NOT_HANDLED) != 0 + ? MediaBrowserUtils.applyPagingOptions(list, options) + : list; + ParceledListSlice<MediaBrowser.MediaItem> pls = null; + if (filteredList != null) { + pls = new ParceledListSlice<>(filteredList); + // Limit the size of initial Parcel to prevent binder buffer + // overflow as onLoadChildren is an async binder call. + pls.setInlineCountLimit(1); + } + try { + connection.callbacks.onLoadChildren(parentId, pls, options); + } catch (RemoteException ex) { + // The other side is in the process of crashing. + Log.w( + TAG, + "Calling onLoadChildren() failed for id=" + + parentId + + " package=" + + connection.pkg); + } + } + }; + + mCurConnection = connection; + if (options == null) { + onLoadChildren(parentId, result); + } else { + onLoadChildren(parentId, result, options); + } + mCurConnection = null; + + if (!result.isDone()) { + throw new IllegalStateException( + "onLoadChildren must call detach() or sendResult()" + + " before returning for package=" + + connection.pkg + + " id=" + + parentId); + } + } + + public void performLoadItemOnHandler( + String itemId, + IMediaBrowserServiceCallbacks callbacks, + ResultReceiver receiver) { + IBinder b = callbacks.asBinder(); + ConnectionRecord connection = mConnections.get(b); + if (connection == null) { + Log.w(TAG, "getMediaItem for callback that isn't registered id=" + itemId); + return; + } + + Result<MediaBrowser.MediaItem> result = + new Result<>(itemId) { + @Override + void onResultSent(MediaBrowser.MediaItem item, @ResultFlags int flag) { + if (mConnections.get(connection.callbacks.asBinder()) != connection) { + if (DBG) { + Log.d( + TAG, + "Not sending onLoadItem result for connection that has" + + " been disconnected. pkg=" + + connection.pkg + + " id=" + + itemId); + } + return; + } + if ((flag & RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED) != 0) { + receiver.send(RESULT_ERROR, null); + return; + } + Bundle bundle = new Bundle(); + bundle.putParcelable(KEY_MEDIA_ITEM, item); + receiver.send(RESULT_OK, bundle); + } + }; + + mCurConnection = connection; + onLoadItem(itemId, result); + mCurConnection = null; + + if (!result.isDone()) { + throw new IllegalStateException( + "onLoadItem must call detach() or sendResult() before returning for id=" + + itemId); + } + } + + /** Return whether the given package corresponds to the given uid. */ + public boolean isValidPackage(String providedPackage, int uid) { + if (providedPackage == null) { + return false; + } + PackageManager pm = getPackageManager(); + for (String packageForUid : pm.getPackagesForUid(uid)) { + if (packageForUid.equals(providedPackage)) { + return true; + } + } + return false; + } } } diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java index 388a65d2a904..00068bda60dd 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java @@ -1709,7 +1709,7 @@ public class CameraTestUtils extends Assert { * <p> * Two images are strongly equal if and only if the data, formats, sizes, * and timestamps are same. For {@link ImageFormat#PRIVATE PRIVATE} format - * images, the image data is not not accessible thus the data comparison is + * images, the image data is not accessible thus the data comparison is * effectively skipped as the number of planes is zero. * </p> * <p> @@ -2049,7 +2049,7 @@ public class CameraTestUtils extends Assert { } } else { // Case 2. - collector.expectEquals("Exif orientaiton should match requested orientation", + collector.expectEquals("Exif orientation should match requested orientation", requestedOrientation, getExifOrientationInDegree(exifOrientation, collector)); } diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java index ed70ab996ccd..5dcd1cba337d 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java @@ -1127,8 +1127,8 @@ public class StaticMetadata { * Get aeAvailableModes and do the validation check. * * <p>Depending on the check level this class has, for WAR or COLLECT levels, - * If the aeMode list is invalid, return an empty mode array. The the caller doesn't - * have to abort the execution even the aeMode list is invalid.</p> + * If the aeMode list is invalid, return an empty mode array. The caller doesn't + * have to abort the execution even if the aeMode list is invalid.</p> * @return AE available modes */ public int[] getAeAvailableModesChecked() { diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt index dd2e17409368..a72e53907796 100644 --- a/nfc/api/system-current.txt +++ b/nfc/api/system-current.txt @@ -26,6 +26,8 @@ package android.nfc { method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void unregisterNfcVendorNciCallback(@NonNull android.nfc.NfcAdapter.NfcVendorNciCallback); method @FlaggedApi("android.nfc.enable_nfc_charging") public void unregisterWlcStateListener(@NonNull android.nfc.NfcAdapter.WlcStateListener); field @FlaggedApi("android.nfc.enable_nfc_mainline") public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC = "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC"; + field @FlaggedApi("android.nfc.enable_nfc_mainline") @RequiresPermission(android.Manifest.permission.SHOW_CUSTOMIZED_RESOLVER) public static final String ACTION_SHOW_NFC_RESOLVER = "android.nfc.action.SHOW_NFC_RESOLVER"; + field @FlaggedApi("android.nfc.enable_nfc_mainline") public static final String EXTRA_RESOLVE_INFOS = "android.nfc.extra.RESOLVE_INFOS"; field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int MESSAGE_TYPE_COMMAND = 1; // 0x1 field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_FAILED = 3; // 0x3 field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_MESSAGE_CORRUPTED = 2; // 0x2 diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java index 252f46fc40a4..c5b758207603 100644 --- a/nfc/java/android/nfc/NfcAdapter.java +++ b/nfc/java/android/nfc/NfcAdapter.java @@ -16,6 +16,7 @@ package android.nfc; +import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.FlaggedApi; import android.annotation.IntDef; @@ -35,6 +36,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.net.Uri; import android.nfc.tech.MifareClassic; import android.nfc.tech.Ndef; @@ -485,6 +487,25 @@ public final class NfcAdapter { "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC"; /** + * Intent action to start a NFC resolver activity in a customized share session with list of + * {@link ResolveInfo}. + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @RequiresPermission(Manifest.permission.SHOW_CUSTOMIZED_RESOLVER) + public static final String ACTION_SHOW_NFC_RESOLVER = "android.nfc.action.SHOW_NFC_RESOLVER"; + + /** + * "Extras" key for an ArrayList of {@link ResolveInfo} records which are to be shown as the + * targets in the customized share session. + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public static final String EXTRA_RESOLVE_INFOS = "android.nfc.extra.RESOLVE_INFOS"; + + /** * The requested app is correctly added to the Tag intent app preference. * * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow) diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java index 3254a394c25a..f264b16347f9 100644 --- a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java +++ b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java @@ -44,6 +44,8 @@ import android.util.Log; import android.util.Xml; import android.util.proto.ProtoOutputStream; +import com.android.internal.R; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -138,6 +140,11 @@ public final class ApduServiceInfo implements Parcelable { private boolean mCategoryOtherServiceEnabled; /** + * Whether the NFC stack should default to Observe Mode when this preferred service. + */ + private boolean mDefaultToObserveMode; + + /** * @hide */ @UnsupportedAppUsage @@ -257,6 +264,9 @@ public final class ApduServiceInfo implements Parcelable { com.android.internal.R.styleable.HostApduService_settingsActivity); mOffHostName = null; mStaticOffHostName = mOffHostName; + mDefaultToObserveMode = sa.getBoolean( + R.styleable.HostApduService_defaultToObserveMode, + false); sa.recycle(); } else { TypedArray sa = res.obtainAttributes(attrs, @@ -276,6 +286,9 @@ public final class ApduServiceInfo implements Parcelable { com.android.internal.R.styleable.HostApduService_settingsActivity); mOffHostName = sa.getString( com.android.internal.R.styleable.OffHostApduService_secureElementName); + mDefaultToObserveMode = sa.getBoolean( + R.styleable.HostApduService_defaultToObserveMode, + false); if (mOffHostName != null) { if (mOffHostName.equals("eSE")) { mOffHostName = "eSE1"; @@ -611,6 +624,25 @@ public final class ApduServiceInfo implements Parcelable { } /** + * Returns whether the NFC stack should default to observe mode when this servise is preferred. + * @return whether the NFC stack should default to observe mode when this servise is preferred + */ + @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE) + public boolean defaultToObserveMode() { + return mDefaultToObserveMode; + } + + /** + * Sets whether the NFC stack should default to observe mode when this servise is preferred. + * @param defaultToObserveMode whether the NFC stack should default to observe mode when this + * servise is preferred + */ + @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE) + public void setDefaultToObserveMode(boolean defaultToObserveMode) { + mDefaultToObserveMode = defaultToObserveMode; + } + + /** * Returns description of service. * @return user readable description of service */ diff --git a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java index 6766afc5e45a..b5951e8e7927 100644 --- a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java +++ b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java @@ -40,7 +40,6 @@ import android.provider.Settings; import android.sysprop.CrashRecoveryProperties; import android.text.TextUtils; import android.util.ArraySet; -import android.util.ExceptionUtils; import android.util.Log; import android.util.Slog; @@ -136,7 +135,7 @@ public class RescueParty { } // We're disabled on all engineering devices - if (Build.IS_ENG) { + if (Build.TYPE.equals("eng")) { Slog.v(TAG, "Disabled because of eng build"); return true; } @@ -144,7 +143,7 @@ public class RescueParty { // We're disabled on userdebug devices connected over USB, since that's // a decent signal that someone is actively trying to debug the device, // or that it's in a lab environment. - if (Build.IS_USERDEBUG && isUsbActive()) { + if (Build.TYPE.equals("userdebug") && isUsbActive()) { Slog.v(TAG, "Disabled because of active USB connection"); return true; } @@ -478,9 +477,18 @@ public class RescueParty { } } + private static String getCompleteMessage(Throwable t) { + final StringBuilder builder = new StringBuilder(); + builder.append(t.getMessage()); + while ((t = t.getCause()) != null) { + builder.append(": ").append(t.getMessage()); + } + return builder.toString(); + } + private static void logRescueException(int level, @Nullable String failedPackageName, Throwable t) { - final String msg = ExceptionUtils.getCompleteMessage(t); + final String msg = getCompleteMessage(t); EventLogTags.writeRescueFailure(level, msg); String failureMsg = "Failed rescue level " + levelToString(level); if (!TextUtils.isEmpty(failedPackageName)) { diff --git a/packages/CredentialManager/res/values-kk/strings.xml b/packages/CredentialManager/res/values-kk/strings.xml index 4f5196d017e6..79fe5ce096a6 100644 --- a/packages/CredentialManager/res/values-kk/strings.xml +++ b/packages/CredentialManager/res/values-kk/strings.xml @@ -92,8 +92,6 @@ <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Басқа құрылғыдан жасау"</string> <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Басқа құрылғыны пайдалану"</string> <string name="request_cancelled_by" msgid="3735222326886267820">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы сұрауды тоқтатты."</string> - <!-- no translation found for dropdown_presentation_more_sign_in_options_text (1693727354272417902) --> - <skip /> - <!-- no translation found for more_options_content_description (1323427365788198808) --> - <skip /> + <string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"Кіру опциялары"</string> + <string name="more_options_content_description" msgid="1323427365788198808">"Жаю"</string> </resources> diff --git a/packages/PackageInstaller/res/values-af/strings.xml b/packages/PackageInstaller/res/values-af/strings.xml index 7ceaa8123249..140fa36b341c 100644 --- a/packages/PackageInstaller/res/values-af/strings.xml +++ b/packages/PackageInstaller/res/values-af/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Hierdie app sal in die agtergrond begin aflaai"</string> <string name="restore" msgid="8460854736328970444">"Stel terug"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Jy is vanlyn"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Om hierdie app terug te stel, gaan jou internetverbinding na en probeer weer"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Iets het skeefgeloop"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Kon nie hierdie app terugstel nie"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Te min berging"</string> diff --git a/packages/PackageInstaller/res/values-am/strings.xml b/packages/PackageInstaller/res/values-am/strings.xml index 4208346dadb0..e127152c8377 100644 --- a/packages/PackageInstaller/res/values-am/strings.xml +++ b/packages/PackageInstaller/res/values-am/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"ይህ መተግበሪያ በዳራ ማውረድ ይጀምራል።"</string> <string name="restore" msgid="8460854736328970444">"ወደነበረበት መልስ"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"ከመስመር ውጭ ነዎት"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"ይህን መተግበሪያ ወደነበረበት ለመመለስ፣ የበይነመረብ ግንኙነትዎን ይፈትሹ እና እንደገና ይሞክሩ"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"የሆነ ስህተት ተከስቷል"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"ይህን መተግበሪያ ወደነበረበት ለመመለስ እየተሞከረ ሳለ አንድ ችግር ነበር"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"በቂ ማከማቻ የለም"</string> diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml index 6bc508537065..de91c09c007f 100644 --- a/packages/PackageInstaller/res/values-ar/strings.xml +++ b/packages/PackageInstaller/res/values-ar/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"سيبدأ تنزيل هذا التطبيق في الخلفية."</string> <string name="restore" msgid="8460854736328970444">"استعادة"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"لا يتوفر اتصال بالإنترنت"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"لاستعادة هذا التطبيق، يُرجى التحقُّق من الاتصال بالإنترنت ثم إعادة المحاولة."</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"حدث خطأ"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"حدثت مشكلة أثناء محاولة استعادة هذا التطبيق."</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"مساحة التخزين غير كافية"</string> diff --git a/packages/PackageInstaller/res/values-as/strings.xml b/packages/PackageInstaller/res/values-as/strings.xml index e07cf7b3c6c4..323f7259d7e4 100644 --- a/packages/PackageInstaller/res/values-as/strings.xml +++ b/packages/PackageInstaller/res/values-as/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"এই এপ্টোৱে নেপথ্যত ডাউনল’ড কৰিবলৈ আৰম্ভ কৰিব"</string> <string name="restore" msgid="8460854736328970444">"পুনঃস্থাপন কৰক"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"আপুনি অফলাইন হৈ আছে"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"এই এপ্টো পুনঃস্থাপন কৰিবলৈ, আপোনাৰ ইণ্টাৰনেট সংযোগ পৰীক্ষা কৰক আৰু পুনৰ চেষ্টা কৰক"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"কিবা ভুল হ’ল"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"এই এপ্টো পুনঃস্থাপন কৰাত কিবা অসুবিধা হৈছিল"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"ষ্ট’ৰেজত পৰ্যাপ্ত ঠাই নাই"</string> diff --git a/packages/PackageInstaller/res/values-az/strings.xml b/packages/PackageInstaller/res/values-az/strings.xml index 6e7a84b701ea..8b4b68d7d963 100644 --- a/packages/PackageInstaller/res/values-az/strings.xml +++ b/packages/PackageInstaller/res/values-az/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Bu tətbiq arxa fonda endirilməyə başlayacaq"</string> <string name="restore" msgid="8460854736328970444">"Bərpa edin"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Oflaynsınız"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Bu tətbiqi bərpa etmək üçün internet bağlantısını yoxlayın və yenidən cəhd edin"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Xəta oldu"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Bu tətbiqi bərpa edərkən problem oldu"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Kifayət qədər yaddaş yoxdur"</string> diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml index d7133ec2273e..ccb0aeb3cecd 100644 --- a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml +++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Aplikacija će započeti preuzimanje u pozadini."</string> <string name="restore" msgid="8460854736328970444">"Vrati"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Oflajn ste"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Da biste vratili ovu aplikaciju, proverite internet vezu i probajte ponovo."</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Došlo je do greške"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Došlo je do problema pri vraćanju ove aplikacije"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Nema dovoljno memorijskog prostora"</string> diff --git a/packages/PackageInstaller/res/values-be/strings.xml b/packages/PackageInstaller/res/values-be/strings.xml index 70ee292771ed..d1cb7d05e682 100644 --- a/packages/PackageInstaller/res/values-be/strings.xml +++ b/packages/PackageInstaller/res/values-be/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Праграма пачне спампоўвацца ў фонавым рэжыме"</string> <string name="restore" msgid="8460854736328970444">"Аднавіць"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Вы па-за сеткай"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Каб аднавіць гэту праграму, праверце падключэнне да інтэрнэту і паўтарыце спробу"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Адбылася памылка"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Пры аднаўленні праграмы ўзнікла праблема"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Не хапае месца ў сховішчы"</string> diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml index c90009b01c13..f6efdf677343 100644 --- a/packages/PackageInstaller/res/values-bg/strings.xml +++ b/packages/PackageInstaller/res/values-bg/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Това приложение ще започне да се изтегля на заден план"</string> <string name="restore" msgid="8460854736328970444">"Възстановяване"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Офлайн сте"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"За да възстановите това приложение, проверете връзката си с интернет и опитайте отново"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Нещо се обърка"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"При опита за възстановяване на това приложение възникна проблем"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Няма достатъчно място в хранилището"</string> diff --git a/packages/PackageInstaller/res/values-bn/strings.xml b/packages/PackageInstaller/res/values-bn/strings.xml index 806c8863cbd2..231f451478de 100644 --- a/packages/PackageInstaller/res/values-bn/strings.xml +++ b/packages/PackageInstaller/res/values-bn/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"এই অ্যাপটি ব্যাকগ্রাউন্ডে ডাউনলোড হওয়া শুরু হবে"</string> <string name="restore" msgid="8460854736328970444">"ফিরিয়ে আনুন"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"আপনি অফলাইন আছেন"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"এই অ্যাপ ফিরিয়ে আনতে, আপনার ইন্টারনেট কানেকশন চেক করে আবার চেষ্টা করুন"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"কোনও সমস্যা হয়েছে"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"এই অ্যাপ ফিরিয়ে আনতে চেষ্টা করার সময় সমস্যা হয়েছে"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"পর্যাপ্ত স্টোরেজ নেই"</string> diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml index 8f9c007421ab..c1f8698e49b0 100644 --- a/packages/PackageInstaller/res/values-bs/strings.xml +++ b/packages/PackageInstaller/res/values-bs/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Preuzimanje aplikacije će započeti u pozadini"</string> <string name="restore" msgid="8460854736328970444">"Vrati"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Offline ste"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Da vratite ovu aplikaciju, provjerite internetsku vezu i pokušajte ponovo"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Nešto nije uredu"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Došlo je do problema prilikom pokušaja vraćanja aplikacije"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Nema dovoljno prostora za pohranu"</string> diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml index ad35c7abca59..2fb6fd86b956 100644 --- a/packages/PackageInstaller/res/values-ca/strings.xml +++ b/packages/PackageInstaller/res/values-ca/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Aquesta aplicació començarà a baixar-se en segon pla"</string> <string name="restore" msgid="8460854736328970444">"Restaura"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"No tens connexió"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Per restaurar aquesta aplicació, comprova la connexió a Internet i torna-ho a provar"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"S\'ha produït un error"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Hi ha hagut un problema en intentar restaurar aquesta aplicació"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"No hi ha prou emmagatzematge"</string> diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml index c4bb8f1c8164..5147c52d4acc 100644 --- a/packages/PackageInstaller/res/values-cs/strings.xml +++ b/packages/PackageInstaller/res/values-cs/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Aplikace se začne stahovat na pozadí"</string> <string name="restore" msgid="8460854736328970444">"Obnovit"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Nejste připojeni k internetu"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Pokud chcete aplikaci obnovit, zkontrolujte připojení k internetu a zkuste to znovu"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Něco se pokazilo"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Při pokusu o obnovení této aplikace došlo k problému"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Nedostatek úložného prostoru"</string> diff --git a/packages/PackageInstaller/res/values-da/strings.xml b/packages/PackageInstaller/res/values-da/strings.xml index 835d1d2494dc..1638ef4c5b16 100644 --- a/packages/PackageInstaller/res/values-da/strings.xml +++ b/packages/PackageInstaller/res/values-da/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Download af denne app startes i baggrunden"</string> <string name="restore" msgid="8460854736328970444">"Gendan"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Du er offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Hvis du vil gendanne denne app, skal du tjekke din internetforbindelse og prøve igen"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Noget gik galt"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Der opstod et problem under gendannelsen af denne app"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Ikke nok lagerplads"</string> diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml index eab0e9aec24e..ef9d207473c0 100644 --- a/packages/PackageInstaller/res/values-de/strings.xml +++ b/packages/PackageInstaller/res/values-de/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Diese App beginnt im Hintergrund mit dem Herunterladen"</string> <string name="restore" msgid="8460854736328970444">"Wiederherstellen"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Du bist offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Prüfe deine Internetverbindung und versuch es noch einmal, um die App wiederherzustellen"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Ein Fehler ist aufgetreten"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Beim Wiederherstellen der App ist ein Fehler aufgetreten"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Nicht genügend Speicherplatz"</string> diff --git a/packages/PackageInstaller/res/values-el/strings.xml b/packages/PackageInstaller/res/values-el/strings.xml index 6ab61daf8d9e..61aa4e65128a 100644 --- a/packages/PackageInstaller/res/values-el/strings.xml +++ b/packages/PackageInstaller/res/values-el/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Η λήψη της εφαρμογής θα ξεκινήσει στο παρασκήνιο"</string> <string name="restore" msgid="8460854736328970444">"Επαναφορά"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Είστε εκτός σύνδεσης"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Για να επαναφέρετε αυτή την εφαρμογή, ελέγξτε τη σύνδεσή σας στο διαδίκτυο και δοκιμάστε ξανά"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Κάτι πήγε στραβά"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Παρουσιάστηκε κάποιο πρόβλημα κατά την επαναφορά αυτής της εφαρμογής"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Δεν επαρκεί ο αποθηκευτικός χώρος"</string> diff --git a/packages/PackageInstaller/res/values-en-rAU/strings.xml b/packages/PackageInstaller/res/values-en-rAU/strings.xml index df336d1ebe84..88c33182b1d3 100644 --- a/packages/PackageInstaller/res/values-en-rAU/strings.xml +++ b/packages/PackageInstaller/res/values-en-rAU/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"This app will start downloading in the background"</string> <string name="restore" msgid="8460854736328970444">"Restore"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"You\'re offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"To restore this app, please check your Internet connection and try again"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Something went wrong"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"There was a problem trying to restore this app"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Not enough storage"</string> diff --git a/packages/PackageInstaller/res/values-en-rGB/strings.xml b/packages/PackageInstaller/res/values-en-rGB/strings.xml index df336d1ebe84..88c33182b1d3 100644 --- a/packages/PackageInstaller/res/values-en-rGB/strings.xml +++ b/packages/PackageInstaller/res/values-en-rGB/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"This app will start downloading in the background"</string> <string name="restore" msgid="8460854736328970444">"Restore"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"You\'re offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"To restore this app, please check your Internet connection and try again"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Something went wrong"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"There was a problem trying to restore this app"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Not enough storage"</string> diff --git a/packages/PackageInstaller/res/values-en-rIN/strings.xml b/packages/PackageInstaller/res/values-en-rIN/strings.xml index df336d1ebe84..88c33182b1d3 100644 --- a/packages/PackageInstaller/res/values-en-rIN/strings.xml +++ b/packages/PackageInstaller/res/values-en-rIN/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"This app will start downloading in the background"</string> <string name="restore" msgid="8460854736328970444">"Restore"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"You\'re offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"To restore this app, please check your Internet connection and try again"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Something went wrong"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"There was a problem trying to restore this app"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Not enough storage"</string> diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml index 99e0df189550..0e0bda550fe7 100644 --- a/packages/PackageInstaller/res/values-es-rUS/strings.xml +++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Esta app comenzará la descarga en segundo plano"</string> <string name="restore" msgid="8460854736328970444">"Restablecer"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"No tienes conexión"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Para restablecer esta app, revisa tu conexión a Internet y vuelve a intentarlo"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Se produjo un error"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Hubo un problema al intentar restablecer esta app"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"No hay suficiente espacio de almacenamiento"</string> diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml index 53fbada7d80f..5c5bcac4d19a 100644 --- a/packages/PackageInstaller/res/values-es/strings.xml +++ b/packages/PackageInstaller/res/values-es/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Esta aplicación comenzará a descargarse en segundo plano"</string> <string name="restore" msgid="8460854736328970444">"Restaurar"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"No tienes conexión a Internet"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Para restaurar esta aplicación, comprueba tu conexión a Internet y vuelve a intentarlo"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Se ha producido un error"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"No se ha podido restaurar esta aplicación"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"No hay suficiente espacio"</string> diff --git a/packages/PackageInstaller/res/values-et/strings.xml b/packages/PackageInstaller/res/values-et/strings.xml index 3be261138c53..29eb94fa10c3 100644 --- a/packages/PackageInstaller/res/values-et/strings.xml +++ b/packages/PackageInstaller/res/values-et/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Selle rakenduse allalaadimine algab taustal"</string> <string name="restore" msgid="8460854736328970444">"Taasta"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Võrguühendus puudub"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Selle rakenduse taastamiseks kontrollige oma internetiühendust ja proovige uuesti"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Midagi läks valesti"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Selle rakenduse taastamisel ilmnes probleem"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Pole piisavalt salvestusruumi"</string> diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml index e54502568a9b..7075ed0febf0 100644 --- a/packages/PackageInstaller/res/values-eu/strings.xml +++ b/packages/PackageInstaller/res/values-eu/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Atzeko planoan deskargatuko da aplikazioa"</string> <string name="restore" msgid="8460854736328970444">"Leheneratu"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Ez zaude konektatuta Internetera"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Aplikazioa leheneratzeko, egiaztatu Internetera konektatuta zaudela eta saiatu berriro"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Arazoren bat izan da"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Arazo bat izan da aplikazioa leheneratzean"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Ez dago behar adina toki"</string> diff --git a/packages/PackageInstaller/res/values-fa/strings.xml b/packages/PackageInstaller/res/values-fa/strings.xml index 9a70ca04a7ab..288653ad5b36 100644 --- a/packages/PackageInstaller/res/values-fa/strings.xml +++ b/packages/PackageInstaller/res/values-fa/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"این برنامه در پسزمینه شروع به بارگیری میکند"</string> <string name="restore" msgid="8460854736328970444">"بازیابی"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"آفلاین هستید"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"برای بازیابی این برنامه، اتصال اینترنت را بررسی کنید و دوباره امتحان کنید"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"مشکلی پیش آمد"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"هنگام بازیابی این برنامه مشکلی پیش آمد"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"فضای ذخیرهسازی کافی نیست"</string> diff --git a/packages/PackageInstaller/res/values-fi/strings.xml b/packages/PackageInstaller/res/values-fi/strings.xml index ce02ad3bf9bc..cbe94c387c11 100644 --- a/packages/PackageInstaller/res/values-fi/strings.xml +++ b/packages/PackageInstaller/res/values-fi/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Sovelluksen lataus aloitetaan taustalla"</string> <string name="restore" msgid="8460854736328970444">"Palauta"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Olet offline-tilassa"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Palauta tämä sovellus tarkistamalla internetyhteys ja yrittämällä uudelleen"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Jotain meni pieleen"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Sovelluksen palauttamisessa oli ongelma"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Tallennustila ei riitä"</string> diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml index 8abcf43cdb0a..de38df3ad708 100644 --- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml +++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Le téléchargement de cette application commencera en arrière-plan"</string> <string name="restore" msgid="8460854736328970444">"Restaurer"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Vous êtes hors ligne"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Pour restaurer cette application, vérifiez votre connexion Internet et réessayez."</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Un problème est survenu"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Un problème est survenu lors de la restauration de cette application"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Espace de stockage insuffisant"</string> diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml index 03d000d6d927..628b406e281b 100644 --- a/packages/PackageInstaller/res/values-fr/strings.xml +++ b/packages/PackageInstaller/res/values-fr/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Cette application commencera à se télécharger en arrière-plan"</string> <string name="restore" msgid="8460854736328970444">"Restaurer"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Vous n\'êtes pas connecté"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Pour restaurer cette appli, vérifiez votre connexion Internet, puis réessayez"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Un problème est survenu"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Un problème est survenu lors de la restauration de cette application"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Espace de stockage insuffisant"</string> diff --git a/packages/PackageInstaller/res/values-gl/strings.xml b/packages/PackageInstaller/res/values-gl/strings.xml index 6b3c930e6311..af8a14c2ff63 100644 --- a/packages/PackageInstaller/res/values-gl/strings.xml +++ b/packages/PackageInstaller/res/values-gl/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Esta aplicación comezará a descargarse en segundo plano"</string> <string name="restore" msgid="8460854736328970444">"Restaurar"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Estás sen conexión"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Para restaurar a aplicación, comproba a túa conexión a Internet e téntao de novo"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Produciuse un erro"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Produciuse un problema ao restaurar esta aplicación"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Non hai almacenamento suficiente"</string> diff --git a/packages/PackageInstaller/res/values-gu/strings.xml b/packages/PackageInstaller/res/values-gu/strings.xml index 202888cd0203..f642e145c78f 100644 --- a/packages/PackageInstaller/res/values-gu/strings.xml +++ b/packages/PackageInstaller/res/values-gu/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"બૅકગ્રાઉન્ડમાં આ ઍપ ડાઉનલોડ થવાનું શરૂ થશે"</string> <string name="restore" msgid="8460854736328970444">"રિસ્ટોર કરો"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"તમે ઑફલાઇન છો"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"આ ઍપ રિસ્ટોર કરવા માટે, તમારું ઇન્ટરનેટ કનેક્શન ચેક કરો અને ફરી પ્રયત્ન કરો"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"કંઈક ખોટું થયું"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"આ ઍપને રિસ્ટોર કરવામાં કોઈ સમસ્યા આવી હતી"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"પર્યાપ્ત સ્ટોરેજ નથી"</string> diff --git a/packages/PackageInstaller/res/values-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml index 1e2d20dcbbea..ce71f17d0df1 100644 --- a/packages/PackageInstaller/res/values-hi/strings.xml +++ b/packages/PackageInstaller/res/values-hi/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"यह ऐप्लिकेशन, बैकग्राउंड में डाउनलोड होना शुरू हो जाएगा"</string> <string name="restore" msgid="8460854736328970444">"वापस लाएं"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"आप ऑफ़लाइन हैं"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"इस ऐप्लिकेशन को वापस लाने के लिए, अपने इंटरनेट कनेक्शन की जांच करें और फिर से कोशिश करें"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"कोई गड़बड़ी हुई"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"इस ऐप्लिकेशन को वापस लाने में समस्या हुई"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"डिवाइस का स्टोरेज ज़रूरत से कम है"</string> diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml index 1010db8b64f5..92ad7f049606 100644 --- a/packages/PackageInstaller/res/values-hr/strings.xml +++ b/packages/PackageInstaller/res/values-hr/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Ova aplikacija počet će se preuzimati u pozadini"</string> <string name="restore" msgid="8460854736328970444">"Vrati"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Niste povezani s internetom"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Da biste vratili ovu aplikaciju, provjerite internetsku vezu i pokušajte ponovo"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Nešto nije u redu"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Došlo je do problema s vraćanjem aplikacije"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Nema dovoljno prostora za pohranu"</string> diff --git a/packages/PackageInstaller/res/values-hu/strings.xml b/packages/PackageInstaller/res/values-hu/strings.xml index 74de4a7280a8..436d6ce3a192 100644 --- a/packages/PackageInstaller/res/values-hu/strings.xml +++ b/packages/PackageInstaller/res/values-hu/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"A háttérben megkezdődik az app letöltése"</string> <string name="restore" msgid="8460854736328970444">"Visszaállítás"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Az eszköz offline állapotban van"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Az alkalmazás visszaállításához ellenőrizze az internetkapcsolatot, majd próbálkozzon újra."</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Hiba történt"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Hiba történt az alkalmazás visszaállítása során."</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Nincs elegendő tárhely"</string> diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml index 2121f8bd9e60..f2bc41e21e88 100644 --- a/packages/PackageInstaller/res/values-hy/strings.xml +++ b/packages/PackageInstaller/res/values-hy/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Այս հավելվածը կներբեռնվի ֆոնային ռեժիմում"</string> <string name="restore" msgid="8460854736328970444">"Վերականգնել"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Կապ չկա"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Այս հավելվածը վերականգնելու համար ստուգեք ձեր ինտերնետ կապը և նորից փորձեք"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Սխալ առաջացավ"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Չհաջողվեց վերականգնել այս հավելվածը"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Բավարար տարածք չկա"</string> diff --git a/packages/PackageInstaller/res/values-in/strings.xml b/packages/PackageInstaller/res/values-in/strings.xml index d2d912dccdb2..8115b50d2dad 100644 --- a/packages/PackageInstaller/res/values-in/strings.xml +++ b/packages/PackageInstaller/res/values-in/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Aplikasi ini akan mulai didownload di latar belakang"</string> <string name="restore" msgid="8460854736328970444">"Pulihkan"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Anda offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Untuk memulihkan aplikasi ini, periksa koneksi internet Anda, lalu coba lagi"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Terjadi error"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Terjadi error saat mencoba memulihkan aplikasi ini"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Penyimpanan tidak cukup"</string> diff --git a/packages/PackageInstaller/res/values-is/strings.xml b/packages/PackageInstaller/res/values-is/strings.xml index e49f5559a5c6..9d24d1859fb9 100644 --- a/packages/PackageInstaller/res/values-is/strings.xml +++ b/packages/PackageInstaller/res/values-is/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Forritið verður sótt í bakgrunni"</string> <string name="restore" msgid="8460854736328970444">"Endurheimta"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Þú ert ekki á netinu"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Til að endurheimta forritið skaltu athuga nettenginguna þína og reyna aftur"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Eitthvað fór úrskeiðis"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Vandamál kom upp við að endurheimta þetta forrit"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Ekki nógu mikið geymslurými"</string> diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml index 9d1be0a4b041..20fc299edd01 100644 --- a/packages/PackageInstaller/res/values-it/strings.xml +++ b/packages/PackageInstaller/res/values-it/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Il download di quest\'app inizierà in background"</string> <string name="restore" msgid="8460854736328970444">"Ripristina"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Sei offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Per ripristinare questa app, controlla la tua connessione a internet e riprova"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Si è verificato un problema"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Si è verificato un problema durante il ripristino di questa app"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Spazio di archiviazione insufficiente"</string> diff --git a/packages/PackageInstaller/res/values-iw/strings.xml b/packages/PackageInstaller/res/values-iw/strings.xml index 79d95b417478..1c7bd117c355 100644 --- a/packages/PackageInstaller/res/values-iw/strings.xml +++ b/packages/PackageInstaller/res/values-iw/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"תהליך ההורדה של האפליקציה יתחיל ברקע"</string> <string name="restore" msgid="8460854736328970444">"שחזור"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"אין חיבור לאינטרנט"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"כדי לשחזר את האפליקציה הזו, מומלץ לבדוק את החיבור לאינטרנט ולנסות שוב."</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"משהו השתבש"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"הייתה בעיה בניסיון לשחזר את האפליקציה הזו"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"אין מספיק נפח אחסון פנוי"</string> diff --git a/packages/PackageInstaller/res/values-ja/strings.xml b/packages/PackageInstaller/res/values-ja/strings.xml index 2660797bab11..5d961f6e6ed7 100644 --- a/packages/PackageInstaller/res/values-ja/strings.xml +++ b/packages/PackageInstaller/res/values-ja/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"このアプリのダウンロードをバックグラウンドで開始します"</string> <string name="restore" msgid="8460854736328970444">"復元する"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"オフラインです"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"このアプリを復元するには、インターネット接続を確認してからもう一度お試しください"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"エラーが発生しました"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"このアプリを復元しようとしたときに問題が発生しました"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"空き容量が不足しています"</string> diff --git a/packages/PackageInstaller/res/values-ka/strings.xml b/packages/PackageInstaller/res/values-ka/strings.xml index d5f56852315e..29cc33f5101e 100644 --- a/packages/PackageInstaller/res/values-ka/strings.xml +++ b/packages/PackageInstaller/res/values-ka/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"ამ აპის ჩამოტვირთვა ფონურ რეჟიმში დაიწყება"</string> <string name="restore" msgid="8460854736328970444">"აღდგენა"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"თქვენ ხაზგარეშე რეჟიმში ხართ"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"აპის აღსადგენად შეამოწმეთ ინტერნეტთან კავშირი და სცადეთ ხელახლა"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"წარმოიქმნა შეფერხება"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"ამ აპის აღდგენისას წარმოიქმნა პრობლემა"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"მეხსიერება საკმარისი არ არის"</string> diff --git a/packages/PackageInstaller/res/values-kk/strings.xml b/packages/PackageInstaller/res/values-kk/strings.xml index 5da373afdabe..a13cc4bf6917 100644 --- a/packages/PackageInstaller/res/values-kk/strings.xml +++ b/packages/PackageInstaller/res/values-kk/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Бұл қолданба фондық режимде жүктеп алына бастайды."</string> <string name="restore" msgid="8460854736328970444">"Қалпына келтіру"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Құрылғыңыз офлайн режимде"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Бұл қолданбаны қалпына келтіру үшін интернет байланысын тексеріп, қайталап көріңіз."</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Бірдеңе дұрыс болмады"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Бұл құрылғыны қалпына келтіру үшін әрекет жасалғанда мәселе туындады."</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Жадта орын жеткіліксіз"</string> diff --git a/packages/PackageInstaller/res/values-km/strings.xml b/packages/PackageInstaller/res/values-km/strings.xml index 4b57163e7e60..2ec2f4d615f8 100644 --- a/packages/PackageInstaller/res/values-km/strings.xml +++ b/packages/PackageInstaller/res/values-km/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"កម្មវិធីនេះនឹងចាប់ផ្ដើមទាញយកនៅផ្ទៃខាងក្រោយ"</string> <string name="restore" msgid="8460854736328970444">"ស្ដារ"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"អ្នកគ្មានអ៊ីនធឺណិតទេ"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"ដើម្បីស្ដារកម្មវិធីនេះ សូមពិនិត្យមើលការតភ្ជាប់អ៊ីនធឺណិតរបស់អ្នក រួចព្យាយាមម្ដងទៀត"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"មានអ្វីមួយខុសប្រក្រតី"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"មានបញ្ហាក្នុងការព្យាយាមស្ដារកម្មវិធីនេះ"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"ទំហំផ្ទុកមិនគ្រប់គ្រាន់"</string> diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml index a1ebc2a6b216..f26ac2d0229a 100644 --- a/packages/PackageInstaller/res/values-kn/strings.xml +++ b/packages/PackageInstaller/res/values-kn/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಡೌನ್ಲೋಡ್ ಆಗಲು ಈ ಆ್ಯಪ್ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ"</string> <string name="restore" msgid="8460854736328970444">"ಮರುಸ್ಥಾಪಿಸಿ"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"ನೀವು ಆಫ್ಲೈನ್ನಲ್ಲಿರುವಿರಿ"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಸ್ಥಾಪಿಸಲು, ನಿಮ್ಮ ಇಂಟರ್ನೆಟ್ ಕನೆಕ್ಷನ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"ಏನೋ ತಪ್ಪಾಗಿದೆ"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಸ್ಥಾಪಿಸಲು ಪ್ರಯತ್ನಿಸುವಾಗ ಸಮಸ್ಯೆ ಕಂಡುಬಂದಿದೆ"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"ಸಾಕಷ್ಟು ಸಂಗ್ರಹಣೆ ಇಲ್ಲ"</string> diff --git a/packages/PackageInstaller/res/values-ko/strings.xml b/packages/PackageInstaller/res/values-ko/strings.xml index d679bf11e78b..21da3e913df3 100644 --- a/packages/PackageInstaller/res/values-ko/strings.xml +++ b/packages/PackageInstaller/res/values-ko/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"백그라운드에서 앱이 다운로드되기 시작합니다"</string> <string name="restore" msgid="8460854736328970444">"복원"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"오프라인 상태"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"이 앱을 복원하려면 인터넷 연결을 확인하고 다시 시도해 보세요"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"문제가 발생했습니다"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"이 앱을 복원하려고 시도하던 중 문제가 발생했습니다"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"저장용량 부족"</string> diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml index 04119616e3ff..e788bf7e2f8f 100644 --- a/packages/PackageInstaller/res/values-ky/strings.xml +++ b/packages/PackageInstaller/res/values-ky/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Бул колдонмо фондо жүктөлүп алына баштайт"</string> <string name="restore" msgid="8460854736328970444">"Калыбына келтирүү"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Интернет байланышыңыз жок"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Бул колдонмону калыбына келтирүү үчүн Интернет байланышыңызды текшерип, кайталап көрүңүз"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Бир жерден ката кетти"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Бул колдонмону калыбына келтирүүдө маселе келип чыкты"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Сактагычта орун жетишсиз"</string> diff --git a/packages/PackageInstaller/res/values-lo/strings.xml b/packages/PackageInstaller/res/values-lo/strings.xml index 2ac57be4c140..57c358d1f1e0 100644 --- a/packages/PackageInstaller/res/values-lo/strings.xml +++ b/packages/PackageInstaller/res/values-lo/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"ແອັບນີ້ຈະເລີ່ມດາວໂຫຼດໃນພື້ນຫຼັງ"</string> <string name="restore" msgid="8460854736328970444">"ກູ້ຄືນ"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"ທ່ານອອບລາຍຢູ່"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"ເພື່ອກູ້ຄືນແອັບນີ້, ກະລຸນາກວດສອບການເຊື່ອມຕໍ່ອິນເຕີເນັດຂອງທ່ານແລ້ວລອງໃໝ່"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"ມີບາງຢ່າງຜິດພາດເກີດຂຶ້ນ"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"ເກີດບັນຫາໃນລະຫວ່າງທີ່ພະຍາຍາມກູ້ຄືນແອັບນີ້"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"ບ່ອນຈັດເກັບຂໍ້ມູນບໍ່ພຽງພໍ"</string> diff --git a/packages/PackageInstaller/res/values-lt/strings.xml b/packages/PackageInstaller/res/values-lt/strings.xml index c2608cbf3579..86140b6dc0a3 100644 --- a/packages/PackageInstaller/res/values-lt/strings.xml +++ b/packages/PackageInstaller/res/values-lt/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Šios programos atsisiuntimas bus pradėtas fone"</string> <string name="restore" msgid="8460854736328970444">"Atkurti"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Esate neprisijungę"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Jei norite atkurti šią programą, patikrinkite interneto ryšį ir bandykite dar kartą"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Kažkas nepavyko"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Bandant atkurti šią programą iškilo problema"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Trūksta saugyklos vietos"</string> diff --git a/packages/PackageInstaller/res/values-lv/strings.xml b/packages/PackageInstaller/res/values-lv/strings.xml index 67ec0f3c2601..96709ef2a3e2 100644 --- a/packages/PackageInstaller/res/values-lv/strings.xml +++ b/packages/PackageInstaller/res/values-lv/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Fonā tiks sākta šīs lietotnes lejupielāde."</string> <string name="restore" msgid="8460854736328970444">"Atjaunot"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Jūs esat bezsaistē"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Lai atjaunotu šo lietotni, pārbaudiet interneta savienojumu un mēģiniet vēlreiz."</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Radās problēma"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Mēģinot atjaunot šo lietotni, radās problēma."</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Krātuvē nepietiek vietas"</string> diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml index 0479537860f6..032ee0c1a052 100644 --- a/packages/PackageInstaller/res/values-mk/strings.xml +++ b/packages/PackageInstaller/res/values-mk/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Апликацијава ќе почне да се презема во заднина"</string> <string name="restore" msgid="8460854736328970444">"Враќање"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Офлајн сте"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"За да ја вратите апликацијава, проверете ја интернет-врската и обидете се повторно"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Нешто тргна наопаку"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Се јави проблем при обидот за враќање на апликацијава"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Нема доволно простор"</string> diff --git a/packages/PackageInstaller/res/values-ml/strings.xml b/packages/PackageInstaller/res/values-ml/strings.xml index c38ab575168c..f79662b76b95 100644 --- a/packages/PackageInstaller/res/values-ml/strings.xml +++ b/packages/PackageInstaller/res/values-ml/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"പശ്ചാത്തലത്തിൽ ഈ ആപ്പ് ഡൗൺലോഡ് ചെയ്ത് തുടങ്ങും"</string> <string name="restore" msgid="8460854736328970444">"പുനഃസ്ഥാപിക്കുക"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"നിങ്ങൾ ഓഫ്ലൈനാണ്"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"ഈ ആപ്പ് പുനഃസ്ഥാപിക്കാൻ, നിങ്ങളുടെ ഇന്റർനെറ്റ് കണക്ഷൻ പരിശോധിച്ച ശേഷം വീണ്ടും ശ്രമിക്കുക"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"എന്തോ കുഴപ്പമുണ്ടായി"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"ഈ ആപ്പ് പുനഃസ്ഥാപിക്കുന്നതിൽ ഒരു പ്രശ്നമുണ്ടായി"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"മതിയായ സ്റ്റോറേജ് ഇല്ല"</string> diff --git a/packages/PackageInstaller/res/values-mn/strings.xml b/packages/PackageInstaller/res/values-mn/strings.xml index 64eecc585c3c..ab2bb9f0472b 100644 --- a/packages/PackageInstaller/res/values-mn/strings.xml +++ b/packages/PackageInstaller/res/values-mn/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Энэ аппыг дэвсгэрт татаж эхэлнэ"</string> <string name="restore" msgid="8460854736328970444">"Сэргээх"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Та офлайн байна"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Энэ аппыг сэргээхийн тулд интернэт холболтоо шалгаад, дахин оролдоно уу"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Ямар нэг алдаа гарлаа"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Энэ аппыг сэргээхээр оролдоход асуудал гарлаа"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Хангалттай хадгалах сан байхгүй"</string> diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml index b071b73fdb8d..c64d62fdcf5c 100644 --- a/packages/PackageInstaller/res/values-mr/strings.xml +++ b/packages/PackageInstaller/res/values-mr/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"हे ॲप बॅकग्राउंडमध्ये डाउनलोड होण्यास सुरुवात होईल"</string> <string name="restore" msgid="8460854736328970444">"रिस्टोअर करा"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"तुम्ही ऑफलाइन आहात"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"हे ॲप रिस्टोअर करण्यासाठी, तुमचे इंटरनेट कनेक्शन तपासा आणि पुन्हा प्रयत्न करा"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"काहीतरी चुकले"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"हे अॅप रिस्टोअर करताना समस्या आली होती"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"पुरेसे स्टोरेज नाही"</string> diff --git a/packages/PackageInstaller/res/values-ms/strings.xml b/packages/PackageInstaller/res/values-ms/strings.xml index f15f5432b8bc..e4d321ca5142 100644 --- a/packages/PackageInstaller/res/values-ms/strings.xml +++ b/packages/PackageInstaller/res/values-ms/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Apl ini akan mula dimuat turun dalam latar"</string> <string name="restore" msgid="8460854736328970444">"Pulihkan"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Anda berstatus luar talian"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Untuk memulihkan apl ini, semak sambungan Internet anda dan cuba lagi"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Ada yang tidak kena"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Terdapat masalah semasa memuatkan apl ini"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Storan tidak mencukupi"</string> diff --git a/packages/PackageInstaller/res/values-my/strings.xml b/packages/PackageInstaller/res/values-my/strings.xml index 063068face2d..98eae5abe9a1 100644 --- a/packages/PackageInstaller/res/values-my/strings.xml +++ b/packages/PackageInstaller/res/values-my/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"ဤအက်ပ်ကို နောက်ခံတွင် စတင်ဒေါင်းလုဒ်လုပ်ပါမည်"</string> <string name="restore" msgid="8460854736328970444">"ပြန်ယူရန်"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"သင်အော့ဖ်လိုင်း ဖြစ်နေသည်"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"ဤအက်ပ် ပြန်ယူရန် သင့်အင်တာနက်ချိတ်ဆက်မှုကို စစ်ဆေးပြီး ထပ်စမ်းကြည့်ပါ"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"တစ်ခုခုမှားသွားသည်"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"ဤအက်ပ်ကို ပြန်ယူရန် ကြိုးပမ်းရာတွင် ပြဿနာရှိသည်"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"သိုလှောင်ခန်း မလုံလောက်ပါ"</string> diff --git a/packages/PackageInstaller/res/values-nb/strings.xml b/packages/PackageInstaller/res/values-nb/strings.xml index 7c7aecfb6ba7..5ba7682b5f49 100644 --- a/packages/PackageInstaller/res/values-nb/strings.xml +++ b/packages/PackageInstaller/res/values-nb/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Denne appen begynner å laste ned i bakgrunnen"</string> <string name="restore" msgid="8460854736328970444">"Gjenopprett"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Du er uten nett"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"For å gjenopprette denne appen, sjekk internettilkoblingen din og prøv igjen"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Noe gikk galt"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Det oppsto et problem med å gjenopprette denne appen"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Ikke nok lagringsplass"</string> diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml index f7417736226c..0bc4be3e53d6 100644 --- a/packages/PackageInstaller/res/values-ne/strings.xml +++ b/packages/PackageInstaller/res/values-ne/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"यो एप ब्याकग्राउन्डमा डाउनलोड हुन थाल्ने छ"</string> <string name="restore" msgid="8460854736328970444">"रिस्टोर गर्नुहोस्"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"तपाईंको डिभाइस अफलाइन छ"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"यो एप रिस्टोर गर्न आफ्नो इन्टरनेट कनेक्सन जाँच्नुहोस् र फेरि प्रयास गर्नुहोस्।"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"कुनै समस्या आयो"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"यो एप रिस्टोर गर्ने क्रममा कुनै समस्या आयो"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"पर्याप्त खाली ठाउँ छैन"</string> diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml index d7c3480b9767..eaae47d00fa3 100644 --- a/packages/PackageInstaller/res/values-nl/strings.xml +++ b/packages/PackageInstaller/res/values-nl/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Deze app wordt gedownload op de achtergrond"</string> <string name="restore" msgid="8460854736328970444">"Herstellen"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Je bent offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Check de internetverbinding en probeer het opnieuw als je deze app wilt herstellen"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Er is iets misgegaan"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Er is iets misgegaan bij het herstellen van deze app"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Onvoldoende opslagruimte"</string> diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml index 4712dba0709c..8bf3225e530b 100644 --- a/packages/PackageInstaller/res/values-or/strings.xml +++ b/packages/PackageInstaller/res/values-or/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"ଏହି ଆପ ପୃଷ୍ଠପଟରେ ଡାଉନଲୋଡ ହେବା ଆରମ୍ଭ କରିବ"</string> <string name="restore" msgid="8460854736328970444">"ରିଷ୍ଟୋର କରନ୍ତୁ"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"ଆପଣ ଅଫଲାଇନ ଅଛନ୍ତି"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"ଏହି ଆପକୁ ରିଷ୍ଟୋର କରିବା ପାଇଁ ଆପଣଙ୍କ ଇଣ୍ଟରନେଟ କନେକ୍ସନ ଯାଞ୍ଚ କରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"କିଛି ତ୍ରୁଟି ହୋଇଛି"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"ଏହି ଆପ ରିଷ୍ଟୋର କରିବାକୁ ଚେଷ୍ଟା କରିବା ସମୟରେ ଏକ ସମସ୍ୟା ହୋଇଛି"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"ଯଥେଷ୍ଟ ଷ୍ଟୋରେଜ ନାହିଁ"</string> diff --git a/packages/PackageInstaller/res/values-pa/strings.xml b/packages/PackageInstaller/res/values-pa/strings.xml index d0640f28070d..34a0945e4aa7 100644 --- a/packages/PackageInstaller/res/values-pa/strings.xml +++ b/packages/PackageInstaller/res/values-pa/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"ਇਹ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡਾਊਨਲੋਡ ਹੋਣੀ ਸ਼ੁਰੂ ਹੋ ਜਾਵੇਗੀ"</string> <string name="restore" msgid="8460854736328970444">"ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"ਤੁਸੀਂ ਆਫ਼ਲਾਈਨ ਹੋ"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਬਹਾਲ ਕਰਨ ਲਈ, ਆਪਣੇ ਇੰਟਰਨੈੱਟ ਕਨੈਕਸ਼ਨ ਦੀ ਜਾਂਚ ਕਰ ਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਬਹਾਲ ਕਰਨ ਵੇਲੇ ਕੋਈ ਸਮੱਸਿਆ ਆਈ"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"ਲੋੜੀਂਦੀ ਸਟੋਰੇਜ ਨਹੀਂ ਹੈ"</string> diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml index 551d4553ba05..22a78e3b46c6 100644 --- a/packages/PackageInstaller/res/values-pl/strings.xml +++ b/packages/PackageInstaller/res/values-pl/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Ta aplikacja zacznie pobieranie w tle"</string> <string name="restore" msgid="8460854736328970444">"Przywróć"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Jesteś offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Aby przywrócić tę aplikację, sprawdź połączenie internetowe i spróbuj ponownie"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Coś poszło nie tak"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Podczas przywracania tej aplikacji wystąpił błąd"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Za mało miejsca na dane"</string> diff --git a/packages/PackageInstaller/res/values-pt-rBR/strings.xml b/packages/PackageInstaller/res/values-pt-rBR/strings.xml index 31e23dbd9d49..b96593e261d6 100644 --- a/packages/PackageInstaller/res/values-pt-rBR/strings.xml +++ b/packages/PackageInstaller/res/values-pt-rBR/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"O download desse app será feito em segundo plano"</string> <string name="restore" msgid="8460854736328970444">"Restaurar"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Você está off-line"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Para restaurar o app, confira sua conexão de Internet e tente de novo"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Algo deu errado"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Ocorreu um problema ao tentar restaurar este app"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Armazenamento insuficiente"</string> diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml index 692312716f70..c39956d63286 100644 --- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml +++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Esta app vai começar a ser transferida em segundo plano"</string> <string name="restore" msgid="8460854736328970444">"Restaurar"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Está offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Para restaurar esta app, verifique a sua ligação à Internet e tente novamente"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Algo correu mal"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Ocorreu um problema ao tentar repor esta app"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Sem armazenamento suficiente"</string> diff --git a/packages/PackageInstaller/res/values-pt/strings.xml b/packages/PackageInstaller/res/values-pt/strings.xml index 31e23dbd9d49..b96593e261d6 100644 --- a/packages/PackageInstaller/res/values-pt/strings.xml +++ b/packages/PackageInstaller/res/values-pt/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"O download desse app será feito em segundo plano"</string> <string name="restore" msgid="8460854736328970444">"Restaurar"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Você está off-line"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Para restaurar o app, confira sua conexão de Internet e tente de novo"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Algo deu errado"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Ocorreu um problema ao tentar restaurar este app"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Armazenamento insuficiente"</string> diff --git a/packages/PackageInstaller/res/values-ro/strings.xml b/packages/PackageInstaller/res/values-ro/strings.xml index 598fbe90633b..a74d94d07992 100644 --- a/packages/PackageInstaller/res/values-ro/strings.xml +++ b/packages/PackageInstaller/res/values-ro/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Descărcarea aplicației va începe în fundal"</string> <string name="restore" msgid="8460854736328970444">"Restabilește"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Ești offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Ca să restabilești aplicația, verifică-ți conexiunea la internet și încearcă din nou"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"A apărut o eroare"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"A apărut o problemă la restabilirea aplicației"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Nu există suficient spațiu de stocare"</string> diff --git a/packages/PackageInstaller/res/values-ru/strings.xml b/packages/PackageInstaller/res/values-ru/strings.xml index f8ca10f28832..c8686a3828ad 100644 --- a/packages/PackageInstaller/res/values-ru/strings.xml +++ b/packages/PackageInstaller/res/values-ru/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Приложение начнет скачиваться в фоновом режиме."</string> <string name="restore" msgid="8460854736328970444">"Восстановить"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Нет доступа к Сети"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Чтобы восстановить это приложение, проверьте подключение к интернету и повторите попытку."</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Что-то пошло не так"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Не удалось восстановить приложение."</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Недостаточно места"</string> diff --git a/packages/PackageInstaller/res/values-si/strings.xml b/packages/PackageInstaller/res/values-si/strings.xml index 0ea077eb5d59..1abd881ffbe2 100644 --- a/packages/PackageInstaller/res/values-si/strings.xml +++ b/packages/PackageInstaller/res/values-si/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"මෙම යෙදුම පසුබිමේ බාගැනීම ආරම්භ කරනු ඇත"</string> <string name="restore" msgid="8460854736328970444">"ප්රතිසාධනය කරන්න"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"ඔබ නොබැඳි වේ"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"මෙම යෙදුම ප්රතිසාධනය කිරීම සඳහා, ඔබේ අන්තර්ජාල සම්බන්ධතාවය පරීක්ෂා කර නැවත උත්සාහ කරන්න"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"යමක් වැරදී ඇත"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"මෙම යෙදුම ප්රතිසාධනය කිරීමට උත්සාහ කිරීමේ ගැටලුවක් ඇති විය"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"ප්රමාණවත් ආචයනයක් නොමැත"</string> diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml index ade533cb79a8..ce186f247b20 100644 --- a/packages/PackageInstaller/res/values-sk/strings.xml +++ b/packages/PackageInstaller/res/values-sk/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Táto aplikácia sa začne sťahovať na pozadí"</string> <string name="restore" msgid="8460854736328970444">"Obnoviť"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Ste offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Ak chcete túto aplikáciu obnoviť, skontrolujte internetové pripojenie a skúste to znova"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Niečo sa pokazilo"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Pri pokuse o obnovenie tejto aplikácie sa vyskytol problém"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Úložisko je nedostatočné"</string> diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml index e949b69cfe0c..05b826fc2506 100644 --- a/packages/PackageInstaller/res/values-sl/strings.xml +++ b/packages/PackageInstaller/res/values-sl/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Aplikacija bo začela prenos v ozadju"</string> <string name="restore" msgid="8460854736328970444">"Obnovi"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Nimate vzpostavljene povezave"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Če želite obnoviti to aplikacijo, preverite internetno povezavo in poskusite znova"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Prišlo je do težave"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Pri obnavljanju te aplikacije je prišlo do težave."</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Ni dovolj prostora za shranjevanje"</string> diff --git a/packages/PackageInstaller/res/values-sq/strings.xml b/packages/PackageInstaller/res/values-sq/strings.xml index bbcccd8bf978..b27207d4b36b 100644 --- a/packages/PackageInstaller/res/values-sq/strings.xml +++ b/packages/PackageInstaller/res/values-sq/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Ky aplikacion do të fillojë të shkarkohet në sfond"</string> <string name="restore" msgid="8460854736328970444">"Restauro"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Je offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Për ta restauruar këtë aplikacion, kontrollo lidhjen e internetit dhe provo përsëri"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Ndodhi një gabim"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Pati një problem gjatë përpjekjes për të restauruar këtë aplikacion"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Hapësira ruajtëse e pamjaftueshme"</string> diff --git a/packages/PackageInstaller/res/values-sr/strings.xml b/packages/PackageInstaller/res/values-sr/strings.xml index 0081516b05af..fcf575f9b236 100644 --- a/packages/PackageInstaller/res/values-sr/strings.xml +++ b/packages/PackageInstaller/res/values-sr/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Апликација ће започети преузимање у позадини."</string> <string name="restore" msgid="8460854736328970444">"Врати"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Офлајн сте"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Да бисте вратили ову апликацију, проверите интернет везу и пробајте поново."</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Дошло је до грешке"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Дошло је до проблема при враћању ове апликације"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Нема довољно меморијског простора"</string> diff --git a/packages/PackageInstaller/res/values-sv/strings.xml b/packages/PackageInstaller/res/values-sv/strings.xml index 76e936122879..8037dfba3521 100644 --- a/packages/PackageInstaller/res/values-sv/strings.xml +++ b/packages/PackageInstaller/res/values-sv/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Appen börjar ladda ned i bakgrunden"</string> <string name="restore" msgid="8460854736328970444">"Återställ"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Du är offline"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"För att återställa den här appen kontrollerar du internetanslutningen och försöker igen"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Något gick fel"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Det gick inte att återställa appen"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Inte tillräckligt med lagringsutrymme"</string> diff --git a/packages/PackageInstaller/res/values-sw/strings.xml b/packages/PackageInstaller/res/values-sw/strings.xml index 4bcdaaab78d5..7e1e3584f664 100644 --- a/packages/PackageInstaller/res/values-sw/strings.xml +++ b/packages/PackageInstaller/res/values-sw/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Itaanza kupakua programu hii chinichini"</string> <string name="restore" msgid="8460854736328970444">"Rejesha"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Uko nje ya mtandao"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Ili urejeshe programu hii, angalia muunganisho wako wa intaneti kisha ujaribu tena"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Hitilafu fulani imetokea"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Hitilafu fulani imetokea wakati wa kujaribu kurejesha programu hii"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Nafasi ya hifadhi haitoshi"</string> diff --git a/packages/PackageInstaller/res/values-ta/strings.xml b/packages/PackageInstaller/res/values-ta/strings.xml index 325455ee3cb6..c7a0d88fe059 100644 --- a/packages/PackageInstaller/res/values-ta/strings.xml +++ b/packages/PackageInstaller/res/values-ta/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"இந்த ஆப்ஸ் பின்னணியில் பதிவிறக்கத் தொடங்கும்"</string> <string name="restore" msgid="8460854736328970444">"மீட்டெடு"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"ஆஃப்லைனில் உள்ளீர்கள்"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"இந்த ஆப்ஸை மீட்டெடுக்க, உங்கள் இணைய இணைப்பைச் சரிபார்த்துவிட்டு மீண்டும் முயலவும்"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"ஏதோ தவறாகிவிட்டது"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"இந்த ஆப்ஸை மீட்டெடுக்க முயலும்போது சிக்கல் ஏற்பட்டது"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"போதுமான சேமிப்பகம் இல்லை"</string> diff --git a/packages/PackageInstaller/res/values-te/strings.xml b/packages/PackageInstaller/res/values-te/strings.xml index ae517919f14f..d91a9c7c2789 100644 --- a/packages/PackageInstaller/res/values-te/strings.xml +++ b/packages/PackageInstaller/res/values-te/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"ఈ యాప్ బ్యాక్గ్రౌండ్లో డౌన్లోడ్ అవ్వడం ప్రారంభమవుతుంది"</string> <string name="restore" msgid="8460854736328970444">"రీస్టోర్ చేయండి"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"మీరు ఆఫ్లైన్లో ఉన్నారు"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"ఈ యాప్ను రీస్టోర్ చేయడానికి, మీ ఇంటర్నెట్ కనెక్షన్ను చెక్ చేసి, మళ్లీ ట్రై చేయండి"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"ఏదో పొరపాటు జరిగింది"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"ఈ యాప్ను రీస్టోర్ చేయడానికి ట్రై చేస్తున్నపుడు సమస్య ఏర్పడింది"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"తగినంత స్టోరేజ్ స్పేస్ లేదు"</string> diff --git a/packages/PackageInstaller/res/values-th/strings.xml b/packages/PackageInstaller/res/values-th/strings.xml index 95fb2a3f19dc..7f3708432a19 100644 --- a/packages/PackageInstaller/res/values-th/strings.xml +++ b/packages/PackageInstaller/res/values-th/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"แอปนี้จะเริ่มดาวน์โหลดในเบื้องหลัง"</string> <string name="restore" msgid="8460854736328970444">"กู้คืน"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"คุณออฟไลน์อยู่"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"หากต้องการกู้คืนแอปนี้ ให้ตรวจสอบการเชื่อมต่ออินเทอร์เน็ตแล้วลองอีกครั้ง"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"เกิดข้อผิดพลาด"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"เกิดปัญหาขณะพยายามคืนค่าแอปนี้"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"พื้นที่เก็บข้อมูลไม่เพียงพอ"</string> diff --git a/packages/PackageInstaller/res/values-tl/strings.xml b/packages/PackageInstaller/res/values-tl/strings.xml index 0377b1bec454..9c2f15ca751e 100644 --- a/packages/PackageInstaller/res/values-tl/strings.xml +++ b/packages/PackageInstaller/res/values-tl/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Magsisimulang mag-download ang app na ito sa background"</string> <string name="restore" msgid="8460854736328970444">"I-restore"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Offline ka"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Para i-restore ang app na ito, suriin ang iyong koneksyon sa internet at subukan ulit"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Nagkaproblema"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Nagkaproblema sa pagsubok na i-restore ang app na ito"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Hindi sapat ang storage"</string> diff --git a/packages/PackageInstaller/res/values-tr/strings.xml b/packages/PackageInstaller/res/values-tr/strings.xml index d809748d0f9d..0af23520f870 100644 --- a/packages/PackageInstaller/res/values-tr/strings.xml +++ b/packages/PackageInstaller/res/values-tr/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Bu uygulama arka planda indirilmeye başlanacak"</string> <string name="restore" msgid="8460854736328970444">"Geri yükle"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"İnternete bağlı değilsiniz"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Bu uygulamayı geri yüklemek için internet bağlantınızı kontrol edip tekrar deneyin"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Bir hata oluştu"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Bu uygulamayı geri yüklemeye çalışırken bir sorun oluştu"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Yeterli depolama alanı yok"</string> diff --git a/packages/PackageInstaller/res/values-uk/strings.xml b/packages/PackageInstaller/res/values-uk/strings.xml index 1dbcb20d942b..15890f5de247 100644 --- a/packages/PackageInstaller/res/values-uk/strings.xml +++ b/packages/PackageInstaller/res/values-uk/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Цей додаток почне завантажуватись у фоновому режимі"</string> <string name="restore" msgid="8460854736328970444">"Відновити"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Пристрій не в мережі"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Щоб відновити цей додаток, перевірте інтернет-з\'єднання й повторіть спробу"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Помилка"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Під час спроби відновити цей додаток сталася помилка"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Недостатньо пам’яті"</string> diff --git a/packages/PackageInstaller/res/values-ur/strings.xml b/packages/PackageInstaller/res/values-ur/strings.xml index 4b0aa1f750f3..444fdd701e17 100644 --- a/packages/PackageInstaller/res/values-ur/strings.xml +++ b/packages/PackageInstaller/res/values-ur/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"یہ ایپ پس منظر میں ڈاؤن لوڈ ہونا شروع ہو جائے گی"</string> <string name="restore" msgid="8460854736328970444">"بحال کریں"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"آپ آف لائن ہیں"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"اس ایپ کو بحال کرنے کے لیے، اپنا انٹرنیٹ کنکشن چیک کریں اور دوبارہ کوشش کریں"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"کچھ غلط ہو گیا"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"اس ایپ کو بحال کرنے کی کوشش میں ایک مسئلہ تھا"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"کافی اسٹوریج نہیں ہے"</string> diff --git a/packages/PackageInstaller/res/values-uz/strings.xml b/packages/PackageInstaller/res/values-uz/strings.xml index 18f1d74d644f..24f8f55e53df 100644 --- a/packages/PackageInstaller/res/values-uz/strings.xml +++ b/packages/PackageInstaller/res/values-uz/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Bu ilova orqa fonda yuklab olinishi boshlanadi"</string> <string name="restore" msgid="8460854736328970444">"Tiklash"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Siz internetga ulanmagansiz"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Bu ilovani tiklash uchun internetga aloqasini tekshiring va qayta urining"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Nimadir xato ketdi"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Bu ilovani tiklashda muammo chiqdi"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Xotirada yetarli boʻsh joy yoʻq"</string> diff --git a/packages/PackageInstaller/res/values-vi/strings.xml b/packages/PackageInstaller/res/values-vi/strings.xml index ef71ea21c594..09d6c71a71dc 100644 --- a/packages/PackageInstaller/res/values-vi/strings.xml +++ b/packages/PackageInstaller/res/values-vi/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Ứng dụng này sẽ bắt đầu tải xuống ở chế độ nền"</string> <string name="restore" msgid="8460854736328970444">"Khôi phục"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Không có kết nối mạng"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Để khôi phục ứng dụng này, hãy kiểm tra kết nối Internet rồi thử lại"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Đã xảy ra lỗi"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Đã xảy ra vấn đề khi tìm cách khôi phục ứng dụng này"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Không đủ dung lượng lưu trữ"</string> diff --git a/packages/PackageInstaller/res/values-zh-rCN/strings.xml b/packages/PackageInstaller/res/values-zh-rCN/strings.xml index 98c717253405..f4bad7e7ab0e 100644 --- a/packages/PackageInstaller/res/values-zh-rCN/strings.xml +++ b/packages/PackageInstaller/res/values-zh-rCN/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"系统将开始在后台下载此应用"</string> <string name="restore" msgid="8460854736328970444">"恢复"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"您没有联网"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"若要恢复此应用,请检查互联网连接,然后重试"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"出了点问题"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"尝试恢复此应用时出现问题"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"存储空间不足"</string> diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml index 22359df8c9b9..3c07151f318f 100644 --- a/packages/PackageInstaller/res/values-zh-rHK/strings.xml +++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"此應用程式將開始在背景下載"</string> <string name="restore" msgid="8460854736328970444">"還原"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"你已離線"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"如要還原此應用程式,請檢查你的互聯網連線,然後再試一次"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"發生問題"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"嘗試還原此應用程式時發生問題"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"儲存空間不足"</string> diff --git a/packages/PackageInstaller/res/values-zh-rTW/strings.xml b/packages/PackageInstaller/res/values-zh-rTW/strings.xml index ed4fd39032ee..11046757c1e5 100644 --- a/packages/PackageInstaller/res/values-zh-rTW/strings.xml +++ b/packages/PackageInstaller/res/values-zh-rTW/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"系統將開始在背景下載這個應用程式"</string> <string name="restore" msgid="8460854736328970444">"還原"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"裝置目前離線"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"如要還原這個應用程式,請檢查網際網路連線,然後再試一次"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"發生錯誤"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"嘗試還原這個應用程式時發生問題"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"儲存空間不足"</string> diff --git a/packages/PackageInstaller/res/values-zu/strings.xml b/packages/PackageInstaller/res/values-zu/strings.xml index eff6e600a336..679a5af0c7e0 100644 --- a/packages/PackageInstaller/res/values-zu/strings.xml +++ b/packages/PackageInstaller/res/values-zu/strings.xml @@ -113,8 +113,7 @@ <string name="unarchive_body_text" msgid="8244155079861708964">"Le app izoqala ukudawuniloda ingemuva"</string> <string name="restore" msgid="8460854736328970444">"Buyisela"</string> <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Awuxhunyiwe ku-inthanethi"</string> - <!-- no translation found for unarchive_error_offline_body (2256042209364094099) --> - <skip /> + <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Ukuze ubuyisele le app, hlola ukuxhumeka kwakho kwe-inthanethi uphinde uzame futhi"</string> <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Kukhona okungahambanga kahle"</string> <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Kube nenkinga ekuzameni ukubuyisa le app"</string> <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Indawo yokubeka ayanele"</string> diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index ca93fa54faa5..3729b00b8baf 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Kon nie \'n nuwe gebruiker skep nie"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Kon nie ’n nuwe gas skep nie"</string> <string name="user_nickname" msgid="262624187455825083">"Bynaam"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Jou naam en prent sal sigbaar wees vir enigiemand wat hierdie toestel gebruik."</string> <string name="user_add_user" msgid="7876449291500212468">"Voeg gebruiker by"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Voeg gas by"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Verwyder gas"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index ccaea8f933e2..87916340f739 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"አዲስ ተጠቃሚን መፍጠር አልተሳካም"</string> <string name="add_guest_failed" msgid="8074548434469843443">"አዲስ እንግዳ መፍጠር አልተሳካም"</string> <string name="user_nickname" msgid="262624187455825083">"ቅጽል ስም"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"ይህን መሳሪያ ለሚጠቀም ማንኛውም ሰው ስምዎ እና ምስልዎ ይታያል።"</string> <string name="user_add_user" msgid="7876449291500212468">"ተጠቃሚን አክል"</string> <string name="guest_new_guest" msgid="3482026122932643557">"እንግዳን አክል"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"እንግዳን አስወግድ"</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 00bc6137cd44..e0b56074dba2 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"تعذّر إنشاء مستخدم جديد."</string> <string name="add_guest_failed" msgid="8074548434469843443">"تعذّر إنشاء جلسة ضيف جديدة."</string> <string name="user_nickname" msgid="262624187455825083">"اللقب"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"سيكون اسمك وصورتك مرئيَين لأي شخص يستخدم هذا الجهاز."</string> <string name="user_add_user" msgid="7876449291500212468">"إضافة مستخدم"</string> <string name="guest_new_guest" msgid="3482026122932643557">"إضافة ضيف"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"إزالة جلسة الضيف"</string> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index 59c87d2ff062..9a4268a84e38 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"নতুন ব্যৱহাৰকাৰী সৃষ্টি কৰিব পৰা নগ’ল"</string> <string name="add_guest_failed" msgid="8074548434469843443">"নতুন অতিথি সৃষ্টি কৰিব পৰা নগ’ল"</string> <string name="user_nickname" msgid="262624187455825083">"উপনাম"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"এই ডিভাইচটো ব্যৱহাৰ কৰা যিকোনো লোকে আপোনাৰ নাম আৰু চিত্ৰ দেখা পাব।"</string> <string name="user_add_user" msgid="7876449291500212468">"ব্যৱহাৰকাৰী যোগ দিয়ক"</string> <string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ দিয়ক"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি আঁতৰাওক"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index 7dfe3bef233c..a217406fb0f0 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Yeni istifadəçi yaratmaq alınmadı"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Yeni qonaq yaratmaq alınmadı"</string> <string name="user_nickname" msgid="262624187455825083">"Ləqəb"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Ad və şəklinizi bu cihazdan istifadə edən hər kəs görəcək."</string> <string name="user_add_user" msgid="7876449291500212468">"İstifadəçi əlavə edin"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Qonaq əlavə edin"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Qonağı silin"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index 8786acb36be1..76429ca3fe20 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Pravljenje novog korisnika nije uspelo"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Pravljenje novog gosta nije uspelo"</string> <string name="user_nickname" msgid="262624187455825083">"Nadimak"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Ime i slika će biti vidljivi svakom ko koristi ovaj uređaj."</string> <string name="user_add_user" msgid="7876449291500212468">"Dodaj korisnika"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 4a1f939617be..e6bb3061b269 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Не ўдалося стварыць новага карыстальніка"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Не ўдалося стварыць новага госця"</string> <string name="user_nickname" msgid="262624187455825083">"Псеўданім"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Ваша імя і відарыс профілю будуць бачныя ўсім, хто выкарыстоўвае гэту прыладу."</string> <string name="user_add_user" msgid="7876449291500212468">"Дадаць карыстальніка"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Дадаць госця"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Выдаліць госця"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 3bc531ff94a1..9f406ee2a8fd 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Неуспешно създаване на нов потребител"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Създаването на нов гост не бе успешно"</string> <string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Вашето име и снимка няма да бъдат видими за нито един потребител, който използва това устройство."</string> <string name="user_add_user" msgid="7876449291500212468">"Добавяне на потребител"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Добавяне на гост"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Премахване на госта"</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index 1342aa3e43ed..1262c1efa804 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"নতুন ব্যবহারকারী যোগ করা যায়নি"</string> <string name="add_guest_failed" msgid="8074548434469843443">"নতুন অতিথি তৈরি করা যায়নি"</string> <string name="user_nickname" msgid="262624187455825083">"বিশেষ নাম"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"এই ডিভাইস ব্যবহার করেন এমন যেকেউ আপনার নাম ও ছবি দেখতে পাবেন।"</string> <string name="user_add_user" msgid="7876449291500212468">"ব্যবহারকারীর অ্যাকাউন্ট যোগ করুন"</string> <string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ করুন"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি সরান"</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index 996856257213..d806e6213c05 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Kreiranje novog korisnika nije uspjelo"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Kreiranje novog gosta nije uspjelo"</string> <string name="user_nickname" msgid="262624187455825083">"Nadimak"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Vaše ime i slika će biti vidljivi svakom ko koristi ovaj uređaj."</string> <string name="user_add_user" msgid="7876449291500212468">"Dodavanje korisnika"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Dodavanje gosta"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 98226f62ddd3..3e7a5a1ebb1f 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"No s\'ha pogut crear l\'usuari"</string> <string name="add_guest_failed" msgid="8074548434469843443">"No s\'ha pogut crear un convidat"</string> <string name="user_nickname" msgid="262624187455825083">"Àlies"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"El teu nom i la teva foto seran visibles per a qualsevol persona que utilitzi aquest dispositiu."</string> <string name="user_add_user" msgid="7876449291500212468">"Afegeix un usuari"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Afegeix un convidat"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Suprimeix el convidat"</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 96272a8bd91f..23b0c823104c 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Nového uživatele se nepodařilo vytvořit"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Vytvoření nového hosta se nezdařilo"</string> <string name="user_nickname" msgid="262624187455825083">"Přezdívka"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Vaše jméno a fotku uvidí kdokoli, kdo toto zařízení použije."</string> <string name="user_add_user" msgid="7876449291500212468">"Přidat uživatele"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Přidat hosta"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Odstranit hosta"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index c1e200622426..972073fd6ada 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Der kunne ikke oprettes en ny bruger"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Der kunne ikke oprettes en ny gæst"</string> <string name="user_nickname" msgid="262624187455825083">"Kaldenavn"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Dit navn og profilbillede vil være synligt for alle, der bruger denne enhed."</string> <string name="user_add_user" msgid="7876449291500212468">"Tilføj bruger"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Tilføj gæst"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gæsten"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index f6be521667d6..52cdba17c924 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Nutzer konnte nicht erstellt werden"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Fehler beim Erstellen eines neuen Gasts"</string> <string name="user_nickname" msgid="262624187455825083">"Alias"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Dein Name und Bild sind für alle Nutzer dieses Geräts sichtbar."</string> <string name="user_add_user" msgid="7876449291500212468">"Nutzer hinzufügen"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Gast hinzufügen"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Gast entfernen"</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index 61e8ab43c850..3c93c6218121 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Η δημιουργία νέου χρήστη απέτυχε"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Αποτυχία δημιουργίας νέου επισκέπτη"</string> <string name="user_nickname" msgid="262624187455825083">"Ψευδώνυμο"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Το όνομα και η εικόνα σας θα είναι ορατά σε όλους τους χρήστες που χρησιμοποιούν αυτή τη συσκευή."</string> <string name="user_add_user" msgid="7876449291500212468">"Προσθήκη χρήστη"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Προσθήκη επισκέπτη"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Κατάργηση επισκέπτη"</string> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index b140131d5c94..199f30f1f8e4 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Failed to create a new guest"</string> <string name="user_nickname" msgid="262624187455825083">"Nickname"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Your name and picture will be visible to anyone that uses this device."</string> <string name="user_add_user" msgid="7876449291500212468">"Add user"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index b140131d5c94..199f30f1f8e4 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Failed to create a new guest"</string> <string name="user_nickname" msgid="262624187455825083">"Nickname"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Your name and picture will be visible to anyone that uses this device."</string> <string name="user_add_user" msgid="7876449291500212468">"Add user"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index b140131d5c94..199f30f1f8e4 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Failed to create a new guest"</string> <string name="user_nickname" msgid="262624187455825083">"Nickname"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Your name and picture will be visible to anyone that uses this device."</string> <string name="user_add_user" msgid="7876449291500212468">"Add user"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index fa83538a144d..6d2bd55d0612 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"No se pudo crear el usuario nuevo"</string> <string name="add_guest_failed" msgid="8074548434469843443">"No se pudo crear un nuevo invitado"</string> <string name="user_nickname" msgid="262624187455825083">"Sobrenombre"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Todas las personas que usen este dispositivo podrán ver tu nombre y foto."</string> <string name="user_add_user" msgid="7876449291500212468">"Agregar usuario"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Agregar invitado"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 2248d6509b8b..0e689f88d921 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"No se ha podido crear el usuario"</string> <string name="add_guest_failed" msgid="8074548434469843443">"No se ha podido crear un nuevo invitado"</string> <string name="user_nickname" msgid="262624187455825083">"Apodo"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Cualquiera que use este dispositivo podrá ver tu nombre y tu imagen"</string> <string name="user_add_user" msgid="7876449291500212468">"Añadir usuario"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Añadir invitado"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index d7f6c5ac5bbc..e4d192575b8b 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Uue kasutaja loomine ebaõnnestus"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Uue külalise loomine ei õnnestunud"</string> <string name="user_nickname" msgid="262624187455825083">"Hüüdnimi"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Teie nimi ja pilt on nähtav kõigile selle seadme kasutajatele."</string> <string name="user_add_user" msgid="7876449291500212468">"Lisa kasutaja"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Lisa külaline"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Eemalda külaline"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 12803c5f8db1..d4346f7ab3dc 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Ezin izan da sortu erabiltzailea"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Ezin izan da sortu beste gonbidatu bat"</string> <string name="user_nickname" msgid="262624187455825083">"Goitizena"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Gailu hau darabilen edonork ikusi ahal izango ditu zure izena eta argazkia."</string> <string name="user_add_user" msgid="7876449291500212468">"Gehitu erabiltzaile bat"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Gehitu gonbidatu bat"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Kendu gonbidatua"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 86193bdb7e55..68f3d3d74957 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"کاربر جدید ایجاد نشد"</string> <string name="add_guest_failed" msgid="8074548434469843443">"مهمان جدید ایجاد نشد"</string> <string name="user_nickname" msgid="262624187455825083">"نام مستعار"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"افرادی که از این دستگاه استفاده میکنند میتوانند نام و عکس شما را ببینند."</string> <string name="user_add_user" msgid="7876449291500212468">"افزودن کاربر"</string> <string name="guest_new_guest" msgid="3482026122932643557">"افزودن مهمان"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"حذف مهمان"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 320357c2781c..dc23e14b6190 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -192,7 +192,7 @@ <string name="tts_play_example_title" msgid="1599468547216481684">"Kuuntele esimerkki"</string> <string name="tts_play_example_summary" msgid="634044730710636383">"Toista lyhyt esittely puhesynteesistä"</string> <string name="tts_install_data_title" msgid="1829942496472751703">"Asenna äänidata"</string> - <string name="tts_install_data_summary" msgid="3608874324992243851">"Asenna puhesynteesiin tarvittavat äänitiedot"</string> + <string name="tts_install_data_summary" msgid="3608874324992243851">"Asenna puhesynteesiin tarvittava äänidata"</string> <string name="tts_engine_security_warning" msgid="3372432853837988146">"Tämä puhesynteesimoottori saattaa kerätä kaiken puhutun tekstin, mukaan lukien henkilökohtaiset tiedot kuten salasanat ja luottokorttinumerot. Se on lähtöisin moottorista <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Haluatko ottaa tämän puhesynteesimoottorin käyttöön?"</string> <string name="tts_engine_network_required" msgid="8722087649733906851">"Tämä kieli vaatii verkkoyhteyden, jotta tekstistä puheeksi muuntaminen toimii."</string> <string name="tts_default_sample_string" msgid="6388016028292967973">"Tämä on esimerkki puhesynteesistä."</string> @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Uuden käyttäjän luominen epäonnistui"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Uutta vierasta ei voitu luoda"</string> <string name="user_nickname" msgid="262624187455825083">"Lempinimi"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Nimesi ja kuvasi ovat näkyvillä kaikille tätä laitetta käyttäville henkilöille."</string> <string name="user_add_user" msgid="7876449291500212468">"Lisää käyttäjä"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Lisää vieras"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Poista vieras"</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index e0285b54fe09..78f0ded467af 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Impossible de créer un utilisateur"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Impossible de créer un nouvel invité"</string> <string name="user_nickname" msgid="262624187455825083">"Pseudo"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Votre nom et votre photo seront visibles à toute personne utilisant cet appareil."</string> <string name="user_add_user" msgid="7876449291500212468">"Ajouter un utilisateur"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index 63b47472dd42..d3bd3d1b3b42 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Échec de la création d\'un utilisateur"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Impossible de créer un profil invité"</string> <string name="user_nickname" msgid="262624187455825083">"Pseudo"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Votre nom et votre photo seront visibles par quiconque utilise cet appareil."</string> <string name="user_add_user" msgid="7876449291500212468">"Ajouter un utilisateur"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 7088dc6bc6e4..fef8f803b03b 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Non se puido crear un novo usuario"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Produciuse un erro ao crear o convidado"</string> <string name="user_nickname" msgid="262624187455825083">"Alcume"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Calquera que use este dispositivo poderá ver o teu nome e imaxe."</string> <string name="user_add_user" msgid="7876449291500212468">"Engadir usuario"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Engadir convidado"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar convidado"</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index 77fc573fc164..f664a9873c10 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"નવો વપરાશકર્તા બનાવવામાં નિષ્ફળ"</string> <string name="add_guest_failed" msgid="8074548434469843443">"નવી અતિથિ બનાવવામાં નિષ્ફળ રહ્યાં"</string> <string name="user_nickname" msgid="262624187455825083">"ઉપનામ"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"તમારું નામ અને ફોટો આ ડિવાઇસનો ઉપયોગ કરનાર કોઈપણ વ્યક્તિને દેખાશે."</string> <string name="user_add_user" msgid="7876449291500212468">"વપરાશકર્તા ઉમેરો"</string> <string name="guest_new_guest" msgid="3482026122932643557">"અતિથિ ઉમેરો"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"અતિથિને કાઢી નાખો"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 4b1da1d14ada..31b14ce31247 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"नया उपयोगकर्ता जोड़ा नहीं जा सका"</string> <string name="add_guest_failed" msgid="8074548434469843443">"नया मेहमान खाता नहीं बनाया जा सका"</string> <string name="user_nickname" msgid="262624187455825083">"प्रचलित नाम"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"इस डिवाइस का इस्तेमाल करने वाले लोगों को आपका नाम और तस्वीर दिखेगी."</string> <string name="user_add_user" msgid="7876449291500212468">"उपयोगकर्ता जोड़ें"</string> <string name="guest_new_guest" msgid="3482026122932643557">"मेहमान जोड़ें"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"मेहमान को हटाएं"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index 6c7e4144bf4b..98e2f0197263 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Izrada novog korisnika nije uspjela"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Izrada novog gosta nije uspjela"</string> <string name="user_nickname" msgid="262624187455825083">"Nadimak"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Vaše ime i slika bit će vidljivi svima koji upotrebljavaju taj uređaj."</string> <string name="user_add_user" msgid="7876449291500212468">"Dodajte korisnika"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Dodajte gosta"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index cf5bed2a6104..4f9452ad1716 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Az új felhasználó létrehozása sikertelen"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Az új vendég létrehozása nem sikerült"</string> <string name="user_nickname" msgid="262624187455825083">"Becenév"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Neve és képe mindenki számára látható lesz, aki ezt az eszközt használja."</string> <string name="user_add_user" msgid="7876449291500212468">"Felhasználó hozzáadása"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Vendég hozzáadása"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Vendég munkamenet eltávolítása"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index ad2ccaee3add..ad4ca1b3ec72 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Չհաջողվեց ստեղծել նոր օգտատեր"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Չհաջողվեց նոր հյուր ստեղծել"</string> <string name="user_nickname" msgid="262624187455825083">"Կեղծանուն"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Ձեր անունն ու նկարը տեսանելի կլինեն այս սարքն օգտագործող բոլոր մարդկանց։"</string> <string name="user_add_user" msgid="7876449291500212468">"Ավելացնել օգտատեր"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Ավելացնել հյուր"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Հեռացնել հյուրին"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index ce85a0d28df1..449540a1a059 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Gagal membuat pengguna baru"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Gagal membuat tamu baru"</string> <string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Nama dan foto Anda akan dapat dilihat oleh siapa saja yang menggunakan perangkat ini."</string> <string name="user_add_user" msgid="7876449291500212468">"Tambahkan pengguna"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Tambahkan tamu"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Hapus tamu"</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index 30dba227163f..f1ce78b6dc35 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Ekki tókst að stofna nýjan notanda"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Ekki tókst að búa til nýjan gest"</string> <string name="user_nickname" msgid="262624187455825083">"Gælunafn"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Allir sem nota þetta tæki geta séð nafnið þitt og myndina."</string> <string name="user_add_user" msgid="7876449291500212468">"Bæta notanda við"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Bæta gesti við"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Fjarlægja gest"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 5fe9e4cda45a..60455a169063 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Creazione nuovo utente non riuscita"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Impossibile creare un nuovo ospite"</string> <string name="user_nickname" msgid="262624187455825083">"Nickname"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Il tuo nome e la tua foto saranno visibili a chiunque usi questo dispositivo."</string> <string name="user_add_user" msgid="7876449291500212468">"Aggiungi utente"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Aggiungi ospite"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Rimuovi ospite"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 92e0516841ae..18fec960877c 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"לא ניתן היה ליצור משתמש חדש"</string> <string name="add_guest_failed" msgid="8074548434469843443">"יצירת אורח חדש נכשלה"</string> <string name="user_nickname" msgid="262624187455825083">"כינוי"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"השם והתמונה שלך יהיו גלויים לכל מי שמשתמש במכשיר הזה."</string> <string name="user_add_user" msgid="7876449291500212468">"הוספת משתמש"</string> <string name="guest_new_guest" msgid="3482026122932643557">"הוספת אורח"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"הסרת אורח"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 5c7a9dd48f4e..7a4eaf133b48 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"新しいユーザーを作成できませんでした"</string> <string name="add_guest_failed" msgid="8074548434469843443">"新しいゲストを作成できませんでした"</string> <string name="user_nickname" msgid="262624187455825083">"ニックネーム"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"このデバイスを使用するすべてのユーザーに、あなたの名前と写真が表示されます。"</string> <string name="user_add_user" msgid="7876449291500212468">"ユーザーを追加"</string> <string name="guest_new_guest" msgid="3482026122932643557">"ゲストを追加"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ゲストを削除"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index c70787f2d233..7c4d736be98f 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"ახალი მომხმარებლის შექმნა ვერ მოხერხდა"</string> <string name="add_guest_failed" msgid="8074548434469843443">"ახალი სტუმრის შექმნა ვერ მოხერხდა"</string> <string name="user_nickname" msgid="262624187455825083">"მეტსახელი"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"თქვენი სახელი და სურათი ხილვადი იქნება ყველასთვის, ვინც ამ მოწყობილობას იყენებს."</string> <string name="user_add_user" msgid="7876449291500212468">"მომხმარებლის დამატება"</string> <string name="guest_new_guest" msgid="3482026122932643557">"სტუმრის დამატება"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"სტუმრის ამოშლა"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 9eab6b0052ec..df0474fdedc0 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -552,8 +552,7 @@ <string name="zen_mode_forever" msgid="3339224497605461291">"Өшірілгенге дейін"</string> <string name="time_unit_just_now" msgid="3006134267292728099">"Дәл қазір"</string> <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Осы телефон"</string> - <!-- no translation found for media_transfer_this_device_name_tablet (2975593806278422086) --> - <skip /> + <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Осы планшет"</string> <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) --> <skip /> <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Қондыру динамигі"</string> @@ -620,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Жаңа пайдаланушы жасалмады."</string> <string name="add_guest_failed" msgid="8074548434469843443">"Жаңа қонақ профилі жасалмады."</string> <string name="user_nickname" msgid="262624187455825083">"Лақап ат"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Атыңыз бен суретіңіз осы құрылғыны пайдаланатын барлық адамға көрінеді."</string> <string name="user_add_user" msgid="7876449291500212468">"Пайдаланушы қосу"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Қонақ қосу"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Қонақты жою"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index de00d948e01b..ce1738ddfcce 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"មិនអាចបង្កើតអ្នកប្រើប្រាស់ថ្មីបានទេ"</string> <string name="add_guest_failed" msgid="8074548434469843443">"មិនអាចបង្កើតភ្ញៀវថ្មីបានទេ"</string> <string name="user_nickname" msgid="262624187455825083">"ឈ្មោះហៅក្រៅ"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"គ្រប់គ្នាដែលប្រើឧបករណ៍នេះនឹងអាចមើលឃើញឈ្មោះ និងរូបភាពរបស់អ្នក។"</string> <string name="user_add_user" msgid="7876449291500212468">"បញ្ចូលអ្នកប្រើប្រាស់"</string> <string name="guest_new_guest" msgid="3482026122932643557">"បញ្ចូលភ្ញៀវ"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ដកភ្ញៀវចេញ"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index 93432b1c2129..203cc6d04ea4 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು ವಿಫಲವಾಗಿದೆ"</string> <string name="add_guest_failed" msgid="8074548434469843443">"ಹೊಸ ಅತಿಥಿಯನ್ನು ರಚಿಸಲು ವಿಫಲವಾಗಿದೆ"</string> <string name="user_nickname" msgid="262624187455825083">"ಅಡ್ಡ ಹೆಸರು"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"ಈ ಸಾಧನವನ್ನು ಬಳಸುವ ಯಾರಿಗಾದರೂ ನಿಮ್ಮ ಹೆಸರು ಮತ್ತು ಚಿತ್ರವು ಗೋಚರಿಸುತ್ತದೆ."</string> <string name="user_add_user" msgid="7876449291500212468">"ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ"</string> <string name="guest_new_guest" msgid="3482026122932643557">"ಅತಿಥಿಯನ್ನು ಸೇರಿಸಿ"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index c30e11252d64..d52d71692f0b 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"새 사용자를 만들지 못함"</string> <string name="add_guest_failed" msgid="8074548434469843443">"새 게스트 생성 실패"</string> <string name="user_nickname" msgid="262624187455825083">"닉네임"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"이 기기를 사용하는 모든 사람에게 내 이름과 사진이 공개됩니다."</string> <string name="user_add_user" msgid="7876449291500212468">"사용자 추가"</string> <string name="guest_new_guest" msgid="3482026122932643557">"게스트 추가"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"게스트 삭제"</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index 45773b932c0d..20c476ad473a 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Жаңы колдонуучу түзүлбөй калды"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Жаңы конок түзүлгөн жок"</string> <string name="user_nickname" msgid="262624187455825083">"Ылакап аты"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Аты-жөнүңүз менен сүрөтүңүз ушул түзмөктү колдонгондордун баарына көрүнөт."</string> <string name="user_add_user" msgid="7876449291500212468">"Колдонуучу кошуу"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Конок кошуу"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Конокту өчүрүү"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 5dedbdec374d..e0b7e8442478 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"ສ້າງຜູ້ໃຊ້ໃໝ່ບໍ່ສຳເລັດ"</string> <string name="add_guest_failed" msgid="8074548434469843443">"ສ້າງແຂກໃໝ່ບໍ່ສຳເລັດ"</string> <string name="user_nickname" msgid="262624187455825083">"ຊື່ຫຼິ້ນ"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"ຊື່ ແລະ ຮູບຂອງທ່ານຈະເຫັນໄດ້ໂດຍທຸກຄົນທີ່ໃຊ້ອຸປະກອນນີ້."</string> <string name="user_add_user" msgid="7876449291500212468">"ເພີ່ມຜູ້ໃຊ້"</string> <string name="guest_new_guest" msgid="3482026122932643557">"ເພີ່ມແຂກ"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ລຶບແຂກອອກ"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index 9cc69b0d4473..de2f1c34801c 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Nepavyko sukurti naujo naudotojo"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Nepavyko sukurti naujo gesto"</string> <string name="user_nickname" msgid="262624187455825083">"Slapyvardis"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Jūsų vardas ir nuotrauka bus rodomi visiems šio įrenginio naudotojams."</string> <string name="user_add_user" msgid="7876449291500212468">"Pridėti naudotoją"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Pridėti svečią"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Pašalinti svečią"</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index 2bf1bee19392..8f09595c86eb 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Neizdevās izveidot jaunu lietotāju"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Neizdevās izveidot jaunu viesa profilu"</string> <string name="user_nickname" msgid="262624187455825083">"Segvārds"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Jūsu vārds un attēls būs redzams jebkuram šīs ierīces lietotājam."</string> <string name="user_add_user" msgid="7876449291500212468">"Pievienot lietotāju"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Pievienot viesi"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Noņemt viesi"</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 3f1fa533d648..0e03472d6703 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Не успеа да создаде нов корисник"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Не успеа создавањето нов гостин"</string> <string name="user_nickname" msgid="262624187455825083">"Прекар"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Вашите име и слика ќе бидат видливи за секој што го користи уредов."</string> <string name="user_add_user" msgid="7876449291500212468">"Додајте корисник"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Додајте гостин"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Отстрани гостин"</string> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 396547b18a2e..5a1bcff7a8c0 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"പുതിയ ഉപയോക്താവിനെ സൃഷ്ടിക്കാനായില്ല"</string> <string name="add_guest_failed" msgid="8074548434469843443">"പുതിയ അതിഥിയെ സൃഷ്ടിക്കാനായില്ല"</string> <string name="user_nickname" msgid="262624187455825083">"വിളിപ്പേര്"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"നിങ്ങളുടെ പേരും ചിത്രവും ഈ ഉപകരണം ഉപയോഗിക്കുന്ന എല്ലാവർക്കും ദൃശ്യമാകും."</string> <string name="user_add_user" msgid="7876449291500212468">"ഉപയോക്താവിനെ ചേർക്കുക"</string> <string name="guest_new_guest" msgid="3482026122932643557">"അതിഥിയെ ചേർക്കുക"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"അതിഥിയെ നീക്കം ചെയ്യുക"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index f1f3a90666b2..81636be50a8e 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Шинэ хэрэглэгч үүсгэж чадсангүй"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Шинэ зочин үүсгэж чадсангүй"</string> <string name="user_nickname" msgid="262624187455825083">"Хоч"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Таны нэр болон зураг энэ төхөөрөмжийг ашигладаг дурын хүнд харагдана."</string> <string name="user_add_user" msgid="7876449291500212468">"Хэрэглэгч нэмэх"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Зочин нэмэх"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Зочин хасах"</string> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index 562004fd396b..a85042dd2042 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"नवीन वापरकर्ता तयार करता आला नाही"</string> <string name="add_guest_failed" msgid="8074548434469843443">"नवीन अतिथी तयार करता आला नाही"</string> <string name="user_nickname" msgid="262624187455825083">"टोपणनाव"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"हे डिव्हाइस वापरणाऱ्या कोणत्याही व्यक्तीला तुमचे नाव आणि फोटो दिसेल."</string> <string name="user_add_user" msgid="7876449291500212468">"वापरकर्ता जोडा"</string> <string name="guest_new_guest" msgid="3482026122932643557">"अतिथी जोडा"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"अतिथी काढून टाका"</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index 264ab3552b0e..8292b6947b64 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Gagal membuat pengguna baharu"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Gagal membuat tetamu baharu"</string> <string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Nama dan gambar anda akan kelihatan kepada sesiapa yang menggunakan peranti ini."</string> <string name="user_add_user" msgid="7876449291500212468">"Tambah pengguna"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Tambah tetamu"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Alih keluar tetamu"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index d839a4544440..656cf599a37b 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"အသုံးပြုသူအသစ် ပြုလုပ်၍မရပါ"</string> <string name="add_guest_failed" msgid="8074548434469843443">"ဧည့်သည်သစ် ပြုလုပ်၍မရပါ"</string> <string name="user_nickname" msgid="262624187455825083">"နာမည်ပြောင်"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"သင့်အမည်နှင့် ဓာတ်ပုံကို ဤစက်သုံးသူတိုင်း မြင်ရပါမည်။"</string> <string name="user_add_user" msgid="7876449291500212468">"အသုံးပြုသူ ထည့်ရန်"</string> <string name="guest_new_guest" msgid="3482026122932643557">"ဧည့်သည် ထည့်ရန်"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ဧည့်သည်ကို ဖယ်ရှားရန်"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index dc326f0e4414..6023c848ada8 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Kunne ikke opprette noen ny bruker"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Kunne ikke opprette en ny gjest"</string> <string name="user_nickname" msgid="262624187455825083">"Kallenavn"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Navnet og bildet ditt blir synlige for alle som bruker denne enheten."</string> <string name="user_add_user" msgid="7876449291500212468">"Legg til bruker"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Legg til gjest"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gjesten"</string> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index d962cece54ce..e488df723478 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"नयाँ प्रयोगकर्ता सिर्जना गर्न सकिएन"</string> <string name="add_guest_failed" msgid="8074548434469843443">"नयाँ अतिथि बनाउन सकिएन"</string> <string name="user_nickname" msgid="262624187455825083">"उपनाम"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"यो डिभाइस प्रयोग गर्ने सबै जना मान्छे तपाईंको नाम र फोटो देख्ने छन्।"</string> <string name="user_add_user" msgid="7876449291500212468">"प्रयोगकर्ता कनेक्ट गर्नुहोस्"</string> <string name="guest_new_guest" msgid="3482026122932643557">"अतिथि कनेक्ट गर्नुहोस्"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"गेस्ट मोडबाट बाहिर निस्कियोस्"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 40c343c8a21b..92fb1052bb30 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Kan geen nieuwe gebruiker maken"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Kan geen nieuwe gast maken"</string> <string name="user_nickname" msgid="262624187455825083">"Bijnaam"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Je naam en foto zijn zichtbaar voor iedereen die dit apparaat gebruikt."</string> <string name="user_add_user" msgid="7876449291500212468">"Gebruiker toevoegen"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Gast toevoegen"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Gast verwijderen"</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index 133e5c752657..621d8e10f828 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବାକୁ ବିଫଳ ହେଲା"</string> <string name="add_guest_failed" msgid="8074548434469843443">"ଜଣେ ନୂଆ ଅତିଥି ତିଆରି କରିବାରେ ବିଫଳ ହୋଇଛି"</string> <string name="user_nickname" msgid="262624187455825083">"ଡାକନାମ"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"ଏହି ଡିଭାଇସ ବ୍ୟବହାର କରୁଥିବା ଯେ କୌଣସି ବ୍ୟକ୍ତିଙ୍କୁ ଆପଣଙ୍କ ନାମ ଏବଂ ଛବି ଦେଖାଯିବ।"</string> <string name="user_add_user" msgid="7876449291500212468">"ୟୁଜର ଯୋଗ କରନ୍ତୁ"</string> <string name="guest_new_guest" msgid="3482026122932643557">"ଅତିଥି ଯୋଗ କରନ୍ତୁ"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ଅତିଥିଙ୍କୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 160a43e10c4d..b32c07737ab8 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣਾ ਅਸਫਲ ਰਿਹਾ"</string> <string name="add_guest_failed" msgid="8074548434469843443">"ਨਵਾਂ ਮਹਿਮਾਨ ਪ੍ਰੋਫਾਈਲ ਬਣਾਉਣਾ ਅਸਫਲ ਰਿਹਾ"</string> <string name="user_nickname" msgid="262624187455825083">"ਉਪਨਾਮ"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"ਤੁਹਾਡਾ ਨਾਮ ਅਤੇ ਤਸਵੀਰ ਇਸ ਡੀਵਾਈਸ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵਾਲੇ ਕਿਸੇ ਵੀ ਵਿਅਕਤੀ ਦਿਖਾਈ ਦੇਵੇਗੀ।"</string> <string name="user_add_user" msgid="7876449291500212468">"ਵਰਤੋਂਕਾਰ ਨੂੰ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="guest_new_guest" msgid="3482026122932643557">"ਮਹਿਮਾਨ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ਮਹਿਮਾਨ ਹਟਾਓ"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 6669c22b6533..aa84b69f0b6e 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Nie udało się utworzyć nowego użytkownika"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Nie udało się utworzyć nowego gościa"</string> <string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Twoja nazwa użytkownika oraz zdjęcie będą widoczne dla każdego, kto korzysta z tego urządzenia."</string> <string name="user_add_user" msgid="7876449291500212468">"Dodaj użytkownika"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gościa"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Usuń gościa"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 0b44fc9fabdc..49607a44c55a 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Falha ao criar um novo usuário"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Falha ao criar um novo convidado"</string> <string name="user_nickname" msgid="262624187455825083">"Apelido"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Seu nome e foto vão ficar visíveis para qualquer pessoa que use este dispositivo."</string> <string name="user_add_user" msgid="7876449291500212468">"Adicionar usuário"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Adicionar visitante"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Remover visitante"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index de0eb7d9f4e8..485c29601782 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Falha ao criar um novo utilizador"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Falha ao criar um novo convidado"</string> <string name="user_nickname" msgid="262624187455825083">"Alcunha"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"O seu nome e imagem vão ser visíveis para qualquer pessoa que use este dispositivo."</string> <string name="user_add_user" msgid="7876449291500212468">"Adicionar utilizador"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 0b44fc9fabdc..49607a44c55a 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Falha ao criar um novo usuário"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Falha ao criar um novo convidado"</string> <string name="user_nickname" msgid="262624187455825083">"Apelido"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Seu nome e foto vão ficar visíveis para qualquer pessoa que use este dispositivo."</string> <string name="user_add_user" msgid="7876449291500212468">"Adicionar usuário"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Adicionar visitante"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Remover visitante"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index 848a5f6760a8..5fa52bbe08d6 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Nu s-a creat noul utilizator"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Nu s-a putut crea un invitat nou"</string> <string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Numele și fotografia ta vor fi vizibile pentru orice persoană care folosește acest dispozitiv."</string> <string name="user_add_user" msgid="7876449291500212468">"Adaugă un utilizator"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Adaugă un invitat"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Șterge invitatul"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 166e7cbf3f74..3a404882a57d 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Не удалось создать пользователя"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Не удалось создать гостя."</string> <string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Ваше имя и фото профиля будут видны всем пользователям этого устройства."</string> <string name="user_add_user" msgid="7876449291500212468">"Добавить пользователя"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Добавить гостя"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Удалить аккаунт гостя"</string> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index d87792db2fb3..bf55a30c67f5 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"නව පරිශීලකයෙකු තැනීමට අසමත් විය"</string> <string name="add_guest_failed" msgid="8074548434469843443">"නව අමුත්තකු තැනීම අසාර්ථක විය"</string> <string name="user_nickname" msgid="262624187455825083">"අපනාමය"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"මෙම උපාංගය භාවිත කරන ඕනෑම කෙනෙකුට ඔබේ නම සහ පින්තූරය දැකිය හැකි වෙයි."</string> <string name="user_add_user" msgid="7876449291500212468">"පරිශීලකයා එක් කරන්න"</string> <string name="guest_new_guest" msgid="3482026122932643557">"අමුත්තා එක් කරන්න"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"අමුත්තා ඉවත් කරන්න"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index 33293f83cbf4..045a7243bf26 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Nového použív. sa nepodarilo vytvoriť"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Nového hosťa sa nepodarilo vytvoriť"</string> <string name="user_nickname" msgid="262624187455825083">"Prezývka"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Vaše meno a fotku uvidia všetci používatelia tohto zariadenia."</string> <string name="user_add_user" msgid="7876449291500212468">"Pridať používateľa"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Pridať hosťa"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Odobrať hosťa"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 1ec258c59aaf..1b13195fc7f6 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Ustvarjanje novega uporabnika ni uspelo."</string> <string name="add_guest_failed" msgid="8074548434469843443">"Ustvarjanje novega gosta ni uspelo."</string> <string name="user_nickname" msgid="262624187455825083">"Vzdevek"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Vaša ime in fotografija bosta vidna vsem uporabnikom te naprave."</string> <string name="user_add_user" msgid="7876449291500212468">"Dodaj uporabnika"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Odstrani gosta"</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index 9ebfd6079ce1..d14772b259cb 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Krijimi i një përdoruesi të ri dështoi"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Profili i vizitorit të ri nuk u krijua"</string> <string name="user_nickname" msgid="262624187455825083">"Pseudonimi"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Emri dhe fotografia jote do të jenë të dukshme për çdo person që e përdor këtë pajisje."</string> <string name="user_add_user" msgid="7876449291500212468">"Shto përdorues"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Shto vizitor"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Hiq vizitorin"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 50e534132e51..fe8c11f58024 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Прављење новог корисника није успело"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Прављење новог госта није успело"</string> <string name="user_nickname" msgid="262624187455825083">"Надимак"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Име и слика ће бити видљиви сваком ко користи овај уређај."</string> <string name="user_add_user" msgid="7876449291500212468">"Додај корисника"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Додај госта"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Уклони госта"</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index 2d71c29922f6..7606b41e1d2f 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Det gick inte att skapa en ny användare"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Det gick inte att skapa en ny gäst"</string> <string name="user_nickname" msgid="262624187455825083">"Smeknamn"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Ditt namn och din bild visas för alla som använder den här enheten."</string> <string name="user_add_user" msgid="7876449291500212468">"Lägg till användare"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Lägg till gäst"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Ta bort gäst"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 8c064950dbf9..4c1816dd2c52 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Imeshindwa kuweka mtumiaji mpya"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Imeshindwa kuunda wasifu mpya wa mgeni"</string> <string name="user_nickname" msgid="262624187455825083">"Jina wakilishi"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Mtu yeyote anayetumia kifaa hiki ataona jina na picha yako."</string> <string name="user_add_user" msgid="7876449291500212468">"Ongeza mtumiaji"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Ongeza mgeni"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Ondoa mgeni"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index ceeb6035f2df..1248205442d5 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"புதிய பயனரை உருவாக்க முடியவில்லை"</string> <string name="add_guest_failed" msgid="8074548434469843443">"புதிய விருந்தினரை உருவாக்க முடியவில்லை"</string> <string name="user_nickname" msgid="262624187455825083">"புனைப்பெயர்"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"இந்தச் சாதனத்தைப் பயன்படுத்தும் அனைவருக்கும் உங்கள் பெயரும் படமும் காட்டப்படும்."</string> <string name="user_add_user" msgid="7876449291500212468">"பயனரைச் சேர்"</string> <string name="guest_new_guest" msgid="3482026122932643557">"கெஸ்ட்டைச் சேர்"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"கெஸ்ட்டை அகற்று"</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index cb3f8d30bd3d..440ed0fdb618 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"కొత్త యూజర్ను క్రియేట్ చేయడం విఫలమైంది"</string> <string name="add_guest_failed" msgid="8074548434469843443">"కొత్త అతిథిని క్రియేట్ చేయడం విఫలమైంది"</string> <string name="user_nickname" msgid="262624187455825083">"మారుపేరు"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"ఈ పరికరాన్ని ఉపయోగించే ప్రతి ఒక్కరికి మీ పేరు, ఫోటో కనిపిస్తుంది."</string> <string name="user_add_user" msgid="7876449291500212468">"యూజర్ను జోడించండి"</string> <string name="guest_new_guest" msgid="3482026122932643557">"గెస్ట్ను జోడించండి"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"గెస్ట్ను తీసివేయండి"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 9617c2a9bca8..68a7db63622e 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"สร้างผู้ใช้ใหม่ไม่ได้"</string> <string name="add_guest_failed" msgid="8074548434469843443">"สร้างผู้เข้าร่วมใหม่ไม่สำเร็จ"</string> <string name="user_nickname" msgid="262624187455825083">"ชื่อเล่น"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"ชื่อและภาพของคุณจะปรากฏแก่ทุกคนที่ใช้อุปกรณ์นี้"</string> <string name="user_add_user" msgid="7876449291500212468">"เพิ่มผู้ใช้"</string> <string name="guest_new_guest" msgid="3482026122932643557">"เพิ่มผู้ใช้ชั่วคราว"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"นำผู้ใช้ชั่วคราวออก"</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index a551e2a4289c..f5430ee852cf 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Hindi nakagawa ng bagong user"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Hindi nakagawa ng bagong guest"</string> <string name="user_nickname" msgid="262624187455825083">"Nickname"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Makikita ng sinumang gumagamit ng device na ito ang iyong pangalan at larawan."</string> <string name="user_add_user" msgid="7876449291500212468">"Magdagdag ng user"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Magdagdag ng bisita"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Alisin ang bisita"</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 54675f14a88e..3cd35963ebea 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Yeni kullanıcı oluşturulamadı"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Yeni misafir oluşturulamadı"</string> <string name="user_nickname" msgid="262624187455825083">"Takma ad"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Adınızı ve resminizi, bu cihazı kullanan herkes görebilir."</string> <string name="user_add_user" msgid="7876449291500212468">"Kullanıcı ekle"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Misafir ekle"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Misafir oturumunu kaldır"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 355f566d0c9d..080765c9edcb 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Не вдалося створити користувача"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Не вдалося створити гостя"</string> <string name="user_nickname" msgid="262624187455825083">"Псевдонім"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Ваше ім’я і зображення бачитимуть усі користувачі цього пристрою."</string> <string name="user_add_user" msgid="7876449291500212468">"Додати користувача"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Додати гостя"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Видалити гостя"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 5c3a0676ac1b..fd22bb69df49 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"نیا صارف بنانے میں ناکام"</string> <string name="add_guest_failed" msgid="8074548434469843443">"نیا مہمان بنانے میں ناکام"</string> <string name="user_nickname" msgid="262624187455825083">"عرفی نام"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"آپ کا نام اور تصویر ہر اس شخص کو نظر آئے گی جو اس آلہ کو استعمال کرتا ہے۔"</string> <string name="user_add_user" msgid="7876449291500212468">"صارف کو شامل کریں"</string> <string name="guest_new_guest" msgid="3482026122932643557">"مہمان کو شامل کریں"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"مہمان کو ہٹائیں"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index 950a24e0c43c..cdf5c282ad2b 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Yangi foydalanuvchi yaratilmadi"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Yangi mehmon yaratilmadi"</string> <string name="user_nickname" msgid="262624187455825083">"Nik"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Ismingiz va rasmingiz ushbu qurilmadan foydalanadigan har bir kishiga koʻrinadi."</string> <string name="user_add_user" msgid="7876449291500212468">"Foydalanuvchi kiritish"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Mehmon kiritish"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Mehmonni olib tashlash"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 0328e27a7832..16dbbabce8d3 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Không tạo được người dùng mới"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Không tạo được khách mới"</string> <string name="user_nickname" msgid="262624187455825083">"Biệt hiệu"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Bất kỳ ai dùng thiết bị này đều có thể thấy tên và hình ảnh của bạn."</string> <string name="user_add_user" msgid="7876449291500212468">"Thêm người dùng"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Thêm khách"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Xóa khách"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 6a35264e42b9..feb738dbca35 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"无法创建新用户"</string> <string name="add_guest_failed" msgid="8074548434469843443">"未能创建新的访客"</string> <string name="user_nickname" msgid="262624187455825083">"昵称"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"所有使用此设备的用户都将可以看到您的姓名和照片。"</string> <string name="user_add_user" msgid="7876449291500212468">"添加用户"</string> <string name="guest_new_guest" msgid="3482026122932643557">"添加访客"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"移除访客"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 6f49688f2b63..2b59ac8519be 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -552,7 +552,7 @@ <string name="zen_mode_forever" msgid="3339224497605461291">"直至你關閉為止"</string> <string name="time_unit_just_now" msgid="3006134267292728099">"剛剛"</string> <string name="media_transfer_this_device_name" msgid="2357329267148436433">"此手機"</string> - <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"這台平板電腦"</string> + <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"此平板電腦"</string> <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) --> <skip /> <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"插座喇叭"</string> @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"無法建立新使用者"</string> <string name="add_guest_failed" msgid="8074548434469843443">"無法建立新訪客"</string> <string name="user_nickname" msgid="262624187455825083">"暱稱"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"此裝置的使用者都會看到你的名稱和相片。"</string> <string name="user_add_user" msgid="7876449291500212468">"新增使用者"</string> <string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 0985041701cd..02a254fd55a9 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"無法建立新的使用者"</string> <string name="add_guest_failed" msgid="8074548434469843443">"無法建立新訪客"</string> <string name="user_nickname" msgid="262624187455825083">"暱稱"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"這部裝置的使用者都會看到你的名稱和相片。"</string> <string name="user_add_user" msgid="7876449291500212468">"新增使用者"</string> <string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index cce45ea35073..6a7033ef7063 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -619,8 +619,7 @@ <string name="add_user_failed" msgid="4809887794313944872">"Yehlulekile ukudala umsebenzisi omusha"</string> <string name="add_guest_failed" msgid="8074548434469843443">"Yehlulekile ukusungula isimenywa esisha"</string> <string name="user_nickname" msgid="262624187455825083">"Isiteketiso"</string> - <!-- no translation found for edit_user_info_message (5199468585059260053) --> - <skip /> + <string name="edit_user_info_message" msgid="5199468585059260053">"Igama nesithombe sakho kuzobonakala kunoma ubani osebenzisa le divayisi."</string> <string name="user_add_user" msgid="7876449291500212468">"Engeza umsebenzisi"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Engeza isivakashi"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Susa isihambeli"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/media/session/MediaSessionManagerExt.kt b/packages/SettingsLib/src/com/android/settingslib/media/session/MediaSessionManagerExt.kt new file mode 100644 index 000000000000..cda6b8bb36be --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/media/session/MediaSessionManagerExt.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.media.session + +import android.media.session.MediaController +import android.media.session.MediaSessionManager +import android.os.UserHandle +import androidx.concurrent.futures.DirectExecutor +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.buffer +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.launch + +/** [Flow] for [MediaSessionManager.OnActiveSessionsChangedListener]. */ +val MediaSessionManager.activeMediaChanges: Flow<Collection<MediaController>?> + get() = + callbackFlow { + val listener = + MediaSessionManager.OnActiveSessionsChangedListener { launch { send(it) } } + addOnActiveSessionsChangedListener( + null, + UserHandle.of(UserHandle.myUserId()), + DirectExecutor.INSTANCE, + listener, + ) + awaitClose { removeOnActiveSessionsChangedListener(listener) } + } + .buffer(capacity = Channel.CONFLATED) diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/MediaControllerExt.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/MediaControllerExt.kt new file mode 100644 index 000000000000..1f037c0280e3 --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/MediaControllerExt.kt @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.volume.data.repository + +import android.media.MediaMetadata +import android.media.session.MediaController +import android.media.session.MediaSession +import android.media.session.PlaybackState +import android.os.Bundle +import android.os.Handler +import kotlinx.coroutines.channels.ProducerScope +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.launch + +/** [MediaController.Callback] flow representation. */ +fun MediaController.stateChanges(handler: Handler): Flow<MediaControllerChange> { + return callbackFlow { + val callback = MediaControllerCallbackProducer(this) + registerCallback(callback, handler) + awaitClose { unregisterCallback(callback) } + } +} + +/** Models particular change event received by [MediaController.Callback]. */ +sealed interface MediaControllerChange { + + data object SessionDestroyed : MediaControllerChange + + data class SessionEvent(val event: String, val extras: Bundle?) : MediaControllerChange + + data class PlaybackStateChanged(val state: PlaybackState?) : MediaControllerChange + + data class MetadataChanged(val metadata: MediaMetadata?) : MediaControllerChange + + data class QueueChanged(val queue: MutableList<MediaSession.QueueItem>?) : + MediaControllerChange + + data class QueueTitleChanged(val title: CharSequence?) : MediaControllerChange + + data class ExtrasChanged(val extras: Bundle?) : MediaControllerChange + + data class AudioInfoChanged(val info: MediaController.PlaybackInfo?) : MediaControllerChange +} + +private class MediaControllerCallbackProducer( + private val producingScope: ProducerScope<MediaControllerChange> +) : MediaController.Callback() { + + override fun onSessionDestroyed() { + send(MediaControllerChange.SessionDestroyed) + } + + override fun onSessionEvent(event: String, extras: Bundle?) { + send(MediaControllerChange.SessionEvent(event, extras)) + } + + override fun onPlaybackStateChanged(state: PlaybackState?) { + send(MediaControllerChange.PlaybackStateChanged(state)) + } + + override fun onMetadataChanged(metadata: MediaMetadata?) { + send(MediaControllerChange.MetadataChanged(metadata)) + } + + override fun onQueueChanged(queue: MutableList<MediaSession.QueueItem>?) { + send(MediaControllerChange.QueueChanged(queue)) + } + + override fun onQueueTitleChanged(title: CharSequence?) { + send(MediaControllerChange.QueueTitleChanged(title)) + } + + override fun onExtrasChanged(extras: Bundle?) { + send(MediaControllerChange.ExtrasChanged(extras)) + } + + override fun onAudioInfoChanged(info: MediaController.PlaybackInfo?) { + send(MediaControllerChange.AudioInfoChanged(info)) + } + + private fun send(change: MediaControllerChange) { + producingScope.launch { producingScope.send(change) } + } +} diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/MediaControllerRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/MediaControllerRepository.kt index ab8c6b820177..6925c71fc68f 100644 --- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/MediaControllerRepository.kt +++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/MediaControllerRepository.kt @@ -16,21 +16,23 @@ package com.android.settingslib.volume.data.repository +import android.content.Intent import android.media.AudioManager import android.media.session.MediaController import android.media.session.MediaSessionManager import android.media.session.PlaybackState import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.settingslib.bluetooth.headsetAudioModeChanges +import com.android.settingslib.media.session.activeMediaChanges import com.android.settingslib.volume.shared.AudioManagerIntentsReceiver import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn @@ -38,7 +40,7 @@ import kotlinx.coroutines.flow.stateIn interface MediaControllerRepository { /** Current [MediaController]. Null is emitted when there is no active [MediaController]. */ - val activeMediaController: StateFlow<MediaController?> + val activeLocalMediaController: StateFlow<MediaController?> } class MediaControllerRepositoryImpl( @@ -53,26 +55,28 @@ class MediaControllerRepositoryImpl( audioManagerIntentsReceiver.intents.filter { AudioManager.STREAM_DEVICES_CHANGED_ACTION == it.action } - override val activeMediaController: StateFlow<MediaController?> = - buildList { - localBluetoothManager?.headsetAudioModeChanges?.let { add(it) } - add(devicesChanges) + + override val activeLocalMediaController: StateFlow<MediaController?> = + combine( + mediaSessionManager.activeMediaChanges.onStart { + emit(mediaSessionManager.getActiveSessions(null)) + }, + localBluetoothManager?.headsetAudioModeChanges?.onStart { emit(Unit) } + ?: flowOf(null), + devicesChanges.onStart { emit(Intent()) }, + ) { controllers, _, _ -> + controllers?.let(::findLocalMediaController) } - .merge() - .onStart { emit(Unit) } - .map { getActiveLocalMediaController() } .flowOn(backgroundContext) .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), null) - private fun getActiveLocalMediaController(): MediaController? { + private fun findLocalMediaController( + controllers: Collection<MediaController>, + ): MediaController? { var localController: MediaController? = null val remoteMediaSessionLists: MutableList<String> = ArrayList() - for (controller in mediaSessionManager.getActiveSessions(null)) { + for (controller in controllers) { val playbackInfo: MediaController.PlaybackInfo = controller.playbackInfo ?: continue - val playbackState = controller.playbackState ?: continue - if (inactivePlaybackStates.contains(playbackState.state)) { - continue - } when (playbackInfo.playbackType) { MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE -> { if (localController?.packageName.equals(controller.packageName)) { diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/MediaControllerRepositoryImplTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/MediaControllerRepositoryImplTest.kt index 430d733e4a88..7bd43d2cf8ab 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/MediaControllerRepositoryImplTest.kt +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/MediaControllerRepositoryImplTest.kt @@ -116,7 +116,7 @@ class MediaControllerRepositoryImplTest { ) ) var mediaController: MediaController? = null - underTest.activeMediaController + underTest.activeLocalMediaController .onEach { mediaController = it } .launchIn(backgroundScope) runCurrent() @@ -141,7 +141,7 @@ class MediaControllerRepositoryImplTest { ) ) var mediaController: MediaController? = null - underTest.activeMediaController + underTest.activeLocalMediaController .onEach { mediaController = it } .launchIn(backgroundScope) runCurrent() diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java index 5669276a0424..8edda1a1f3a2 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java @@ -90,7 +90,7 @@ public class DeviceIconUtilTest { public void getIconResIdFromMediaRouteType_hdmi() { assertThat(new DeviceIconUtil(/* isTv */ false) .getIconResIdFromMediaRouteType(MediaRoute2Info.TYPE_HDMI)) - .isEqualTo(R.drawable.ic_headphone); + .isEqualTo(R.drawable.ic_external_display); } @Test @@ -101,10 +101,10 @@ public class DeviceIconUtilTest { } @Test - public void getIconResIdFromMediaRouteType_hdmiArc_isHeadphone() { + public void getIconResIdFromMediaRouteType_hdmiArc_isExternalDisplay() { assertThat(new DeviceIconUtil(/* isTv */ false) .getIconResIdFromMediaRouteType(MediaRoute2Info.TYPE_HDMI_ARC)) - .isEqualTo(R.drawable.ic_headphone); + .isEqualTo(R.drawable.ic_external_display); } @Test @@ -115,10 +115,10 @@ public class DeviceIconUtilTest { } @Test - public void getIconResIdFromMediaRouteType_hdmiEarc_isHeadphone() { + public void getIconResIdFromMediaRouteType_hdmiEarc_isExternalDisplay() { assertThat(new DeviceIconUtil(/* isTv */ false) .getIconResIdFromMediaRouteType(MediaRoute2Info.TYPE_HDMI_EARC)) - .isEqualTo(R.drawable.ic_headphone); + .isEqualTo(R.drawable.ic_external_display); } @Test @@ -229,10 +229,10 @@ public class DeviceIconUtilTest { } @Test - public void getIconResIdFromAudioDeviceType_hdmi_isHeadphone() { + public void getIconResIdFromAudioDeviceType_hdmi_isExternalDisplay() { assertThat(new DeviceIconUtil(/* isTv */ false) .getIconResIdFromAudioDeviceType(AudioDeviceInfo.TYPE_HDMI)) - .isEqualTo(R.drawable.ic_headphone); + .isEqualTo(R.drawable.ic_external_display); } @Test @@ -243,10 +243,10 @@ public class DeviceIconUtilTest { } @Test - public void getIconResIdFromAudioDeviceType_hdmiArc_isHeadphone() { + public void getIconResIdFromAudioDeviceType_hdmiArc_isExternalDisplay() { assertThat(new DeviceIconUtil(/* isTv */ false) .getIconResIdFromAudioDeviceType(AudioDeviceInfo.TYPE_HDMI_ARC)) - .isEqualTo(R.drawable.ic_headphone); + .isEqualTo(R.drawable.ic_external_display); } @Test @@ -257,10 +257,10 @@ public class DeviceIconUtilTest { } @Test - public void getIconResIdFromAudioDeviceType_hdmiEarc_isHeadphone() { + public void getIconResIdFromAudioDeviceType_hdmiEarc_isExternalDisplay() { assertThat(new DeviceIconUtil(/* isTv */ false) .getIconResIdFromAudioDeviceType(AudioDeviceInfo.TYPE_HDMI_EARC)) - .isEqualTo(R.drawable.ic_headphone); + .isEqualTo(R.drawable.ic_external_display); } @Test diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 4305d912e806..53f2caf0b793 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -771,6 +771,9 @@ <!-- Permission required for CTS test - CtsDevicePolicyManagerTestCases --> <uses-permission android:name="android.permission.READ_NEARBY_STREAMING_POLICY" /> + <!-- Permission required for CTS test - CtsDevicePolicyTestCases --> + <uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING" /> + <!-- Permission required for CTS test - CtsKeystoreTestCases --> <uses-permission android:name="android.permission.REQUEST_UNIQUE_ID_ATTESTATION" /> diff --git a/packages/SystemUI/aconfig/Android.bp b/packages/SystemUI/aconfig/Android.bp index 03f9d74a4a34..5d0847cf479c 100644 --- a/packages/SystemUI/aconfig/Android.bp +++ b/packages/SystemUI/aconfig/Android.bp @@ -25,6 +25,7 @@ package { "//frameworks/base/packages/SystemUI:__subpackages__", "//frameworks/libs/systemui/tracinglib:__subpackages__", "//platform_testing:__subpackages__", + "//vendor:__subpackages__", "//cts:__subpackages__", ], } diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectView.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectView.kt new file mode 100644 index 000000000000..aad593eb6a05 --- /dev/null +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectView.kt @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.surfaceeffects.loadingeffect + +import android.content.Context +import android.graphics.BlendMode +import android.graphics.Canvas +import android.graphics.Paint +import android.util.AttributeSet +import android.view.View + +/** Custom View for drawing the [LoadingEffect] with [Canvas.drawPaint]. */ +open class LoadingEffectView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { + + private var paint: Paint? = null + private var blendMode: BlendMode = BlendMode.SRC_OVER + + override fun onDraw(canvas: Canvas) { + if (!canvas.isHardwareAccelerated) { + return + } + paint?.let { canvas.drawPaint(it) } + } + + /** Designed to be called on [LoadingEffect.PaintDrawCallback.onDraw]. */ + fun draw(paint: Paint) { + this.paint = paint + this.paint!!.blendMode = blendMode + + invalidate() + } + + /** Sets the blend mode of the [Paint]. */ + fun setBlendMode(blendMode: BlendMode) { + this.blendMode = blendMode + } +} diff --git a/packages/SystemUI/compose/core/src/com/android/compose/theme/AndroidColorScheme.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/AndroidColorScheme.kt index 1d6f813cfbdf..b28655b28b65 100644 --- a/packages/SystemUI/compose/core/src/com/android/compose/theme/AndroidColorScheme.kt +++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/AndroidColorScheme.kt @@ -69,6 +69,7 @@ class AndroidColorScheme(context: Context) { val onTertiary = getColor(context, R.attr.materialColorOnTertiary) val surfaceDim = getColor(context, R.attr.materialColorSurfaceDim) val surfaceBright = getColor(context, R.attr.materialColorSurfaceBright) + val error = getColor(context, R.attr.materialColorError) val onError = getColor(context, R.attr.materialColorOnError) val surface = getColor(context, R.attr.materialColorSurface) val surfaceContainerHigh = getColor(context, R.attr.materialColorSurfaceContainerHigh) diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt index 374a97d769c8..4398b2541f65 100644 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt +++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt @@ -69,7 +69,7 @@ object ComposeFacade : BaseComposeFacade { override fun setVolumePanelActivityContent( activity: ComponentActivity, viewModel: VolumePanelViewModel, - onDismissAnimationFinished: () -> Unit, + onDismiss: () -> Unit, ) { throwComposeUnavailableError() } diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt new file mode 100644 index 000000000000..8ad0a080a9dd --- /dev/null +++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.component.mediaoutput + +import dagger.Module + +@Module interface MediaOutputModule diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt index a1bbc7d7bfb8..aa567364d130 100644 --- a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt +++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt @@ -102,12 +102,12 @@ object ComposeFacade : BaseComposeFacade { override fun setVolumePanelActivityContent( activity: ComponentActivity, viewModel: VolumePanelViewModel, - onDismissAnimationFinished: () -> Unit, + onDismiss: () -> Unit, ) { activity.setContent { VolumePanelRoot( viewModel = viewModel, - onDismissAnimationFinished = onDismissAnimationFinished, + onDismiss = onDismiss, ) } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt index d9493961e3ed..621ddf796f58 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt @@ -557,13 +557,18 @@ private fun StatusMessage( targetState = message, label = "Bouncer message", animationSpec = if (message.isUpdateAnimated) tween() else snap(), - modifier = modifier, + modifier = modifier.fillMaxWidth(), ) { - Text( - text = it.text, - color = MaterialTheme.colorScheme.onSurface, - style = MaterialTheme.typography.bodyLarge, - ) + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.fillMaxWidth(), + ) { + Text( + text = it.text, + color = MaterialTheme.colorScheme.onSurface, + style = MaterialTheme.typography.bodyLarge, + ) + } } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt index 67b79a06b4a0..9b8c9d0ab616 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt @@ -17,6 +17,7 @@ package com.android.systemui.communal.ui.compose import android.content.ComponentName +import android.os.UserHandle import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.runtime.toMutableStateList @@ -33,9 +34,10 @@ fun rememberContentListState( return remember(communalContent) { ContentListState( communalContent, - { componentName, priority -> + { componentName, user, priority -> viewModel.onAddWidget( componentName, + user, priority, widgetConfigurator, ) @@ -54,7 +56,8 @@ fun rememberContentListState( class ContentListState internal constructor( communalContent: List<CommunalContentModel>, - private val onAddWidget: (componentName: ComponentName, priority: Int) -> Unit, + private val onAddWidget: + (componentName: ComponentName, user: UserHandle, priority: Int) -> Unit, private val onDeleteWidget: (id: Int) -> Unit, private val onReorderWidgets: (widgetIdToPriorityMap: Map<Int, Int>) -> Unit, ) { @@ -81,10 +84,16 @@ internal constructor( * * @param newItemComponentName name of the new widget that was dropped into the list; null if no * new widget was added. + * @param newItemUser user profile associated with the new widget that was dropped into the + * list; null if no new widget was added. * @param newItemIndex index at which the a new widget was dropped into the list; null if no new * widget was dropped. */ - fun onSaveList(newItemComponentName: ComponentName? = null, newItemIndex: Int? = null) { + fun onSaveList( + newItemComponentName: ComponentName? = null, + newItemUser: UserHandle? = null, + newItemIndex: Int? = null + ) { // filters placeholder, but, maintains the indices of the widgets as if the placeholder was // in the list. When persisted in DB, this leaves space for the new item (to be added) at // the correct priority. @@ -100,8 +109,8 @@ internal constructor( .toMap() // reorder and then add the new widget onReorderWidgets(widgetIdToPriorityMap) - if (newItemComponentName != null && newItemIndex != null) { - onAddWidget(newItemComponentName, /*priority=*/ list.size - newItemIndex) + if (newItemComponentName != null && newItemUser != null && newItemIndex != null) { + onAddWidget(newItemComponentName, newItemUser, /*priority=*/ list.size - newItemIndex) } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt index 881947ed6534..dee255917359 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt @@ -17,8 +17,6 @@ package com.android.systemui.communal.ui.compose import android.content.ClipDescription -import android.content.ComponentName -import android.content.Intent import android.view.DragEvent import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.draganddrop.dragAndDropTarget @@ -44,6 +42,8 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.dp import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.ui.compose.extensions.plus +import com.android.systemui.communal.util.WidgetPickerIntentUtils +import com.android.systemui.communal.util.WidgetPickerIntentUtils.getWidgetExtraFromIntent import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.isActive @@ -201,12 +201,14 @@ internal class DragAndDropTargetState( return false } return placeHolderIndex?.let { dropIndex -> - val componentName = event.maybeWidgetComponentName() - if (componentName != null) { + val widgetExtra = event.maybeWidgetExtra() ?: return false + val (componentName, user) = widgetExtra + if (componentName != null && user != null) { // Placeholder isn't removed yet to allow the setting the right priority for items // before adding in the new item. contentListState.onSaveList( newItemComponentName = componentName, + newItemUser = user, newItemIndex = dropIndex ) return@let true @@ -260,15 +262,12 @@ internal class DragAndDropTargetState( } /** - * Parses and returns the component name of the widget that was dropped into the communal grid. + * Parses and returns the intent extra associated with the widget that is dropped into the grid. * - * Returns null if the drop event didn't include the widget information. + * Returns null if the drop event didn't include intent information. */ - private fun DragAndDropEvent.maybeWidgetComponentName(): ComponentName? { + private fun DragAndDropEvent.maybeWidgetExtra(): WidgetPickerIntentUtils.WidgetExtra? { val clipData = this.toAndroidDragEvent().clipData.takeIf { it.itemCount != 0 } - return clipData - ?.getItemAt(0) - ?.intent - ?.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME, ComponentName::class.java) + return clipData?.getItemAt(0)?.intent?.let { intent -> getWidgetExtraFromIntent(intent) } } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt index f387021daeac..ed2cbb85ba1a 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt @@ -21,10 +21,10 @@ import android.view.ViewGroup import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.android.compose.animation.scene.SceneScope +import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.notifications.ui.composable.NotificationStack import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.statusbar.notification.stack.AmbientState @@ -59,37 +59,38 @@ constructor( ) { init { - if (!KeyguardShadeMigrationNssl.isUnexpectedlyInLegacyMode()) { - // This scene container section moves the NSSL to the SharedNotificationContainer. - // This also requires that SharedNotificationContainer gets moved to the - // SceneWindowRootView by the SceneWindowRootViewBinder. Prior to Scene Container, - // but when the KeyguardShadeMigrationNssl flag is enabled, NSSL is moved into this - // container by the NotificationStackScrollLayoutSection. - // Ensure stackScrollLayout is a child of sharedNotificationContainer. + if (!migrateClocksToBlueprint()) { + throw IllegalStateException("this requires migrateClocksToBlueprint()") + } + // This scene container section moves the NSSL to the SharedNotificationContainer. + // This also requires that SharedNotificationContainer gets moved to the + // SceneWindowRootView by the SceneWindowRootViewBinder. Prior to Scene Container, + // but when the KeyguardShadeMigrationNssl flag is enabled, NSSL is moved into this + // container by the NotificationStackScrollLayoutSection. + // Ensure stackScrollLayout is a child of sharedNotificationContainer. - if (stackScrollLayout.parent != sharedNotificationContainer) { - (stackScrollLayout.parent as? ViewGroup)?.removeView(stackScrollLayout) - sharedNotificationContainer.addNotificationStackScrollLayout(stackScrollLayout) - } + if (stackScrollLayout.parent != sharedNotificationContainer) { + (stackScrollLayout.parent as? ViewGroup)?.removeView(stackScrollLayout) + sharedNotificationContainer.addNotificationStackScrollLayout(stackScrollLayout) + } - SharedNotificationContainerBinder.bind( + SharedNotificationContainerBinder.bind( + sharedNotificationContainer, + sharedNotificationContainerViewModel, + sceneContainerFlags, + controller, + notificationStackSizeCalculator, + mainDispatcher, + ) + + if (sceneContainerFlags.flexiNotifsEnabled()) { + NotificationStackAppearanceViewBinder.bind( + context, sharedNotificationContainer, - sharedNotificationContainerViewModel, - sceneContainerFlags, + notificationStackAppearanceViewModel, + ambientState, controller, - notificationStackSizeCalculator, - mainDispatcher, ) - - if (sceneContainerFlags.flexiNotifsEnabled()) { - NotificationStackAppearanceViewBinder.bind( - context, - sharedNotificationContainer, - notificationStackAppearanceViewModel, - ambientState, - controller, - ) - } } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/bottombar/BottomBarModule.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/bottombar/BottomBarModule.kt index 43d545368536..236aee217f16 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/bottombar/BottomBarModule.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/bottombar/BottomBarModule.kt @@ -32,7 +32,7 @@ interface BottomBarModule { @Binds @IntoMap @StringKey(VolumePanelComponents.BOTTOM_BAR) - fun bindMediaVolumeSliderComponent(component: BottomBarComponent): VolumePanelUiComponent + fun bindVolumePanelUiComponent(component: BottomBarComponent): VolumePanelUiComponent @Binds @IntoMap diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/bottombar/ui/BottomBarComponent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/bottombar/ui/BottomBarComponent.kt index 03c07f714541..0cf43672c716 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/bottombar/ui/BottomBarComponent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/bottombar/ui/BottomBarComponent.kt @@ -20,6 +20,8 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -49,7 +51,13 @@ constructor( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, ) { - PlatformOutlinedButton(onClick = viewModel::onSettingsClicked) { + PlatformOutlinedButton( + onClick = viewModel::onSettingsClicked, + colors = + ButtonDefaults.outlinedButtonColors( + contentColor = MaterialTheme.colorScheme.onSurface, + ), + ) { Text(text = stringResource(R.string.volume_panel_dialog_settings_button)) } PlatformButton(onClick = viewModel::onDoneClicked) { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt new file mode 100644 index 000000000000..c73656eb1ec5 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.component.mediaoutput + +import com.android.systemui.volume.panel.component.mediaoutput.domain.MediaOutputAvailabilityCriteria +import com.android.systemui.volume.panel.component.mediaoutput.ui.composable.MediaOutputComponent +import com.android.systemui.volume.panel.component.shared.model.VolumePanelComponents +import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria +import com.android.systemui.volume.panel.shared.model.VolumePanelUiComponent +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import dagger.multibindings.StringKey + +/** Dagger module, that provides media output Volume Panel UI functionality. */ +@Module +interface MediaOutputModule { + + @Binds + @IntoMap + @StringKey(VolumePanelComponents.MEDIA_OUTPUT) + fun bindVolumePanelUiComponent(component: MediaOutputComponent): VolumePanelUiComponent + + @Binds + @IntoMap + @StringKey(VolumePanelComponents.MEDIA_OUTPUT) + fun bindComponentAvailabilityCriteria( + criteria: MediaOutputAvailabilityCriteria + ): ComponentAvailabilityCriteria +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/ui/composable/MediaOutputComponent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/ui/composable/MediaOutputComponent.kt new file mode 100644 index 000000000000..8ad6fdf829d7 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/ui/composable/MediaOutputComponent.kt @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.component.mediaoutput.ui.composable + +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.core.snap +import androidx.compose.animation.core.tween +import androidx.compose.animation.core.updateTransition +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.scaleIn +import androidx.compose.animation.scaleOut +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically +import androidx.compose.animation.togetherWith +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import com.android.compose.animation.Expandable +import com.android.systemui.common.ui.compose.Icon +import com.android.systemui.common.ui.compose.toColor +import com.android.systemui.volume.panel.component.mediaoutput.ui.viewmodel.ConnectedDeviceViewModel +import com.android.systemui.volume.panel.component.mediaoutput.ui.viewmodel.DeviceIconViewModel +import com.android.systemui.volume.panel.component.mediaoutput.ui.viewmodel.MediaOutputViewModel +import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope +import com.android.systemui.volume.panel.ui.composable.ComposeVolumePanelUiComponent +import com.android.systemui.volume.panel.ui.composable.VolumePanelComposeScope +import javax.inject.Inject + +@VolumePanelScope +class MediaOutputComponent +@Inject +constructor( + private val viewModel: MediaOutputViewModel, +) : ComposeVolumePanelUiComponent { + + @Composable + override fun VolumePanelComposeScope.Content(modifier: Modifier) { + val connectedDeviceViewModel: ConnectedDeviceViewModel? by + viewModel.connectedDeviceViewModel.collectAsState() + val deviceIconViewModel: DeviceIconViewModel? by + viewModel.deviceIconViewModel.collectAsState() + + Expandable( + modifier = Modifier.fillMaxWidth().height(80.dp), + color = MaterialTheme.colorScheme.surface, + shape = RoundedCornerShape(28.dp), + onClick = { viewModel.onBarClick(it) }, + ) { + Row { + connectedDeviceViewModel?.let { ConnectedDeviceText(it) } + + deviceIconViewModel?.let { ConnectedDeviceIcon(it) } + } + } + } + + @Composable + private fun RowScope.ConnectedDeviceText(connectedDeviceViewModel: ConnectedDeviceViewModel) { + Column( + modifier = + Modifier.weight(1f) + .padding(start = 24.dp, top = 20.dp, bottom = 20.dp) + .fillMaxHeight(), + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + Text( + connectedDeviceViewModel.label.toString(), + style = MaterialTheme.typography.labelMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + connectedDeviceViewModel.deviceName?.let { + Text( + it.toString(), + style = MaterialTheme.typography.titleMedium, + color = MaterialTheme.colorScheme.onSurface, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + } + } + + @Composable + private fun ConnectedDeviceIcon(deviceIconViewModel: DeviceIconViewModel) { + val transition = updateTransition(deviceIconViewModel, label = "MediaOutputIconTransition") + Box( + modifier = Modifier.padding(16.dp).fillMaxHeight().aspectRatio(1f), + contentAlignment = Alignment.Center + ) { + transition.AnimatedContent( + contentKey = { it.backgroundColor }, + transitionSpec = { + if (targetState is DeviceIconViewModel.IsPlaying) { + scaleIn( + initialScale = 0.9f, + animationSpec = isPlayingInIconBackgroundSpec(), + ) + fadeIn(animationSpec = isPlayingInIconBackgroundSpec()) togetherWith + fadeOut(animationSpec = snap()) + } else { + fadeIn(animationSpec = snap(delayMillis = 900)) togetherWith + scaleOut( + targetScale = 0.9f, + animationSpec = isPlayingOutSpec(), + ) + fadeOut(animationSpec = isPlayingOutSpec()) + } + } + ) { targetViewModel -> + Expandable( + modifier = Modifier.fillMaxSize(), + color = targetViewModel.backgroundColor.toColor(), + shape = RoundedCornerShape(12.dp), + onClick = { viewModel.onDeviceClick(it) }, + ) {} + } + transition.AnimatedContent( + contentKey = { it.icon }, + transitionSpec = { + if (targetState is DeviceIconViewModel.IsPlaying) { + fadeIn(animationSpec = snap(delayMillis = 700)) togetherWith + slideOutVertically( + targetOffsetY = { it }, + animationSpec = isPlayingInIconSpec(), + ) + fadeOut(animationSpec = isNotPlayingOutIconSpec()) + } else { + slideInVertically( + initialOffsetY = { it }, + animationSpec = isNotPlayingInIconSpec(), + ) + fadeIn(animationSpec = isNotPlayingInIconSpec()) togetherWith + fadeOut(animationSpec = isPlayingOutSpec()) + } + } + ) { + Icon( + icon = it.icon, + modifier = Modifier.padding(12.dp).fillMaxSize(), + ) + } + } + } +} + +private fun <T> isPlayingOutSpec() = tween<T>(durationMillis = 400, delayMillis = 500) + +private fun <T> isPlayingInIconSpec() = tween<T>(durationMillis = 400, delayMillis = 300) + +private fun <T> isPlayingInIconBackgroundSpec() = tween<T>(durationMillis = 400, delayMillis = 700) + +private fun <T> isNotPlayingOutIconSpec() = tween<T>(durationMillis = 400, delayMillis = 300) + +private fun <T> isNotPlayingInIconSpec() = tween<T>(durationMillis = 400, delayMillis = 900) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/HorizontalVolumePanelContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/HorizontalVolumePanelContent.kt new file mode 100644 index 000000000000..98ef0674e8a1 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/HorizontalVolumePanelContent.kt @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.ui.composable + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.android.systemui.volume.panel.ui.layout.ComponentsLayout + +@Composable +fun VolumePanelComposeScope.HorizontalVolumePanelContent( + layout: ComponentsLayout, + modifier: Modifier = Modifier, +) { + val spacing = 20.dp + Row(modifier = modifier, horizontalArrangement = Arrangement.spacedBy(space = spacing)) { + Column( + modifier = Modifier.weight(1f), + verticalArrangement = Arrangement.spacedBy(spacing) + ) { + for (component in layout.contentComponents) { + AnimatedVisibility(component.isVisible) { + with(component.component as ComposeVolumePanelUiComponent) { Content(Modifier) } + } + } + } + + Column( + modifier = Modifier.weight(1f), + verticalArrangement = Arrangement.spacedBy(space = spacing, alignment = Alignment.Top) + ) { + for (component in layout.headerComponents) { + AnimatedVisibility(component.isVisible) { + with(component.component as ComposeVolumePanelUiComponent) { + Content(Modifier.weight(1f)) + } + } + } + Row( + modifier = Modifier.fillMaxWidth().wrapContentHeight(), + horizontalArrangement = Arrangement.spacedBy(spacing), + ) { + for (component in layout.footerComponents) { + AnimatedVisibility(component.isVisible) { + with(component.component as ComposeVolumePanelUiComponent) { + Content(Modifier.weight(1f)) + } + } + } + } + } + } +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt index e8d59660cebf..86eb84929c02 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt @@ -17,6 +17,7 @@ package com.android.systemui.volume.panel.ui.composable import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.animateContentSize import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -33,9 +34,16 @@ fun VolumePanelComposeScope.VerticalVolumePanelContent( modifier: Modifier = Modifier, ) { Column( - modifier = modifier, + modifier = modifier.animateContentSize(), verticalArrangement = Arrangement.spacedBy(20.dp), ) { + for (component in layout.headerComponents) { + AnimatedVisibility(component.isVisible) { + with(component.component as ComposeVolumePanelUiComponent) { + Content(Modifier.weight(1f)) + } + } + } for (component in layout.contentComponents) { AnimatedVisibility(component.isVisible) { with(component.component as ComposeVolumePanelUiComponent) { Content(Modifier) } @@ -44,11 +52,13 @@ fun VolumePanelComposeScope.VerticalVolumePanelContent( if (layout.footerComponents.isNotEmpty()) { Row( modifier = Modifier.fillMaxWidth().wrapContentHeight(), - horizontalArrangement = Arrangement.spacedBy(20.dp) + horizontalArrangement = Arrangement.spacedBy(20.dp), ) { for (component in layout.footerComponents) { - with(component.component as ComposeVolumePanelUiComponent) { - Content(Modifier.weight(1f)) + AnimatedVisibility(component.isVisible) { + with(component.component as ComposeVolumePanelUiComponent) { + Content(Modifier.weight(1f)) + } } } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelComposeScope.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelComposeScope.kt index c70c6b1ad861..10731c7f2df7 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelComposeScope.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelComposeScope.kt @@ -16,17 +16,21 @@ package com.android.systemui.volume.panel.ui.composable +import android.content.res.Configuration import android.content.res.Configuration.Orientation import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelState class VolumePanelComposeScope(private val state: VolumePanelState) { - /** - * Layout orientation of the panel. It doesn't necessarily aligns with the device orientation, - * because in some cases we want to show bigger version of a portrait orientation when the - * device is in landscape. - */ + /** Layout orientation of the panel. This aligns with the device orientation. */ @Orientation val orientation: Int get() = state.orientation + + /** Is true when Volume Panel is using wide-screen layout and false the otherwise. */ + val isWideScreen: Boolean + get() = state.isWideScreen } + +val VolumePanelComposeScope.isPortrait: Boolean + get() = orientation == Configuration.ORIENTATION_PORTRAIT diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt index 60d03fc6a107..dd6342029885 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt @@ -17,17 +17,13 @@ package com.android.systemui.volume.panel.ui.composable import android.content.res.Configuration -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.MutableTransitionState -import androidx.compose.animation.slideInVertically -import androidx.compose.animation.slideOutVertically -import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape @@ -37,11 +33,10 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.unit.dp import com.android.compose.theme.PlatformTheme import com.android.systemui.res.R import com.android.systemui.volume.panel.ui.layout.ComponentsLayout @@ -51,48 +46,45 @@ import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel @Composable fun VolumePanelRoot( viewModel: VolumePanelViewModel, - onDismissAnimationFinished: () -> Unit, modifier: Modifier = Modifier, + onDismiss: () -> Unit ) { + LaunchedEffect(viewModel) { + viewModel.volumePanelState.collect { + if (!it.isVisible) { + onDismiss() + } + } + } + PlatformTheme(isSystemInDarkTheme()) { val state: VolumePanelState by viewModel.volumePanelState.collectAsState() val components by viewModel.componentsLayout.collectAsState(null) - val transitionState = - remember { MutableTransitionState(false) }.apply { targetState = state.isVisible } - - LaunchedEffect(transitionState.targetState, transitionState.isIdle) { - if (!transitionState.targetState && transitionState.isIdle) { - onDismissAnimationFinished() + with(VolumePanelComposeScope(state)) { + var boxModifier = modifier.fillMaxSize().clickable(onClick = onDismiss) + if (!isPortrait) { + boxModifier = boxModifier.padding(horizontal = 48.dp) } - } - - Box( - modifier = modifier.fillMaxSize(), - contentAlignment = Alignment.BottomCenter, - ) { - Spacer( - modifier = - Modifier.fillMaxSize() - .alpha(0.32f) - .background(MaterialTheme.colorScheme.scrim) - .clickable(onClick = { viewModel.dismissPanel() }) - ) - AnimatedVisibility( - visibleState = transitionState, - enter = slideInVertically { it }, - exit = slideOutVertically { it }, + Box( + modifier = boxModifier, + contentAlignment = Alignment.BottomCenter, ) { val radius = dimensionResource(R.dimen.volume_panel_corner_radius) Surface( + modifier = + Modifier.clickable( + interactionSource = null, + indication = null, + onClick = { + // prevent windowCloseOnTouchOutside from dismissing when tapped on + // the panel itself. + }, + ), shape = RoundedCornerShape(topStart = radius, topEnd = radius), color = MaterialTheme.colorScheme.surfaceContainer, ) { - Column { - components?.let { componentsState -> - with(VolumePanelComposeScope(state)) { Components(componentsState) } - } - } + Column { components?.let { componentsState -> Components(componentsState) } } } } } @@ -100,27 +92,38 @@ fun VolumePanelRoot( } @Composable -private fun VolumePanelComposeScope.Components(state: ComponentsLayout) { +private fun VolumePanelComposeScope.Components(components: ComponentsLayout) { if (orientation == Configuration.ORIENTATION_PORTRAIT) { VerticalVolumePanelContent( - state, - modifier = Modifier.padding(dimensionResource(R.dimen.volume_panel_content_padding)), + components, + modifier = Modifier.padding(24.dp), ) } else { - TODO("Add landscape layout") + HorizontalVolumePanelContent( + components, + modifier = + Modifier.padding(start = 24.dp, top = 24.dp, end = 24.dp, bottom = 20.dp) + .heightIn(max = 236.dp), + ) } - val horizontalPadding = dimensionResource(R.dimen.volume_panel_bottom_bar_horizontal_padding) - if (state.bottomBarComponent.isVisible) { - with(state.bottomBarComponent.component as ComposeVolumePanelUiComponent) { - Content( - Modifier.navigationBarsPadding() + if (components.bottomBarComponent.isVisible) { + val horizontalPadding = + dimensionResource(R.dimen.volume_panel_bottom_bar_horizontal_padding) + Box( + modifier = + Modifier.fillMaxWidth() + .navigationBarsPadding() .padding( start = horizontalPadding, end = horizontalPadding, bottom = dimensionResource(R.dimen.volume_panel_bottom_bar_bottom_padding), - ) - ) + ), + contentAlignment = Alignment.Center, + ) { + with(components.bottomBarComponent.component as ComposeVolumePanelUiComponent) { + Content(Modifier) + } } } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt index 0aca16d9aeaa..6b2831991416 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt @@ -20,6 +20,7 @@ import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL import android.app.admin.devicePolicyManager +import android.appwidget.AppWidgetProviderInfo import android.content.Intent import android.content.pm.UserInfo import android.platform.test.annotations.DisableFlags @@ -136,6 +137,29 @@ class CommunalSettingsRepositoryImplTest : SysuiTestCase() { ) } + @EnableFlags(FLAG_COMMUNAL_HUB) + @Test + fun hubShowsWidgetCategoriesSetByUser() = + testScope.runTest { + kosmos.fakeSettings.putIntForUser( + CommunalSettingsRepositoryImpl.GLANCEABLE_HUB_CONTENT_SETTING, + AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN, + PRIMARY_USER.id + ) + val setting by collectLastValue(underTest.getWidgetCategories(PRIMARY_USER)) + assertThat(setting?.categories) + .isEqualTo(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN) + } + + @EnableFlags(FLAG_COMMUNAL_HUB) + @Test + fun hubShowsKeyguardWidgetsByDefault() = + testScope.runTest { + val setting by collectLastValue(underTest.getWidgetCategories(PRIMARY_USER)) + assertThat(setting?.categories) + .isEqualTo(AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD) + } + private fun setKeyguardFeaturesDisabled(user: UserInfo, disabledFlags: Int) { whenever(kosmos.devicePolicyManager.getKeyguardDisabledFeatures(nullable(), eq(user.id))) .thenReturn(disabledFlags) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt index a54a00d539b8..a4c7abdbfc19 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt @@ -21,15 +21,16 @@ import android.appwidget.AppWidgetProviderInfo import android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_CONFIGURATION_OPTIONAL import android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_RECONFIGURABLE import android.content.ComponentName +import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.communal.data.db.CommunalItemRank import com.android.systemui.communal.data.db.CommunalWidgetDao import com.android.systemui.communal.data.db.CommunalWidgetItem -import com.android.systemui.communal.shared.CommunalWidgetHost import com.android.systemui.communal.shared.model.CommunalWidgetContentModel import com.android.systemui.communal.widgets.CommunalAppWidgetHost +import com.android.systemui.communal.widgets.CommunalWidgetHost import com.android.systemui.communal.widgets.widgetConfiguratorFail import com.android.systemui.communal.widgets.widgetConfiguratorSuccess import com.android.systemui.coroutines.collectLastValue @@ -136,14 +137,20 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { val provider = ComponentName("pkg_name", "cls_name") val id = 1 val priority = 1 + val user = UserHandle(0) whenever(communalWidgetHost.getAppWidgetInfo(id)) .thenReturn(PROVIDER_INFO_REQUIRES_CONFIGURATION) - whenever(communalWidgetHost.allocateIdAndBindWidget(any<ComponentName>())) + whenever( + communalWidgetHost.allocateIdAndBindWidget( + any<ComponentName>(), + any<UserHandle>() + ) + ) .thenReturn(id) - underTest.addWidget(provider, priority, kosmos.widgetConfiguratorSuccess) + underTest.addWidget(provider, user, priority, kosmos.widgetConfiguratorSuccess) runCurrent() - verify(communalWidgetHost).allocateIdAndBindWidget(provider) + verify(communalWidgetHost).allocateIdAndBindWidget(provider, user) verify(communalWidgetDao).addWidget(id, provider, priority) } @@ -153,13 +160,20 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { val provider = ComponentName("pkg_name", "cls_name") val id = 1 val priority = 1 + val user = UserHandle(0) whenever(communalWidgetHost.getAppWidgetInfo(id)) .thenReturn(PROVIDER_INFO_REQUIRES_CONFIGURATION) - whenever(communalWidgetHost.allocateIdAndBindWidget(provider)).thenReturn(id) - underTest.addWidget(provider, priority, kosmos.widgetConfiguratorFail) + whenever( + communalWidgetHost.allocateIdAndBindWidget( + any<ComponentName>(), + any<UserHandle>() + ) + ) + .thenReturn(id) + underTest.addWidget(provider, user, priority, kosmos.widgetConfiguratorFail) runCurrent() - verify(communalWidgetHost).allocateIdAndBindWidget(provider) + verify(communalWidgetHost).allocateIdAndBindWidget(provider, user) verify(communalWidgetDao, never()).addWidget(id, provider, priority) verify(appWidgetHost).deleteAppWidgetId(id) } @@ -170,13 +184,22 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { val provider = ComponentName("pkg_name", "cls_name") val id = 1 val priority = 1 + val user = UserHandle(0) whenever(communalWidgetHost.getAppWidgetInfo(id)) .thenReturn(PROVIDER_INFO_REQUIRES_CONFIGURATION) - whenever(communalWidgetHost.allocateIdAndBindWidget(provider)).thenReturn(id) - underTest.addWidget(provider, priority) { throw IllegalStateException("some error") } + whenever( + communalWidgetHost.allocateIdAndBindWidget( + any<ComponentName>(), + any<UserHandle>() + ) + ) + .thenReturn(id) + underTest.addWidget(provider, user, priority) { + throw IllegalStateException("some error") + } runCurrent() - verify(communalWidgetHost).allocateIdAndBindWidget(provider) + verify(communalWidgetHost).allocateIdAndBindWidget(provider, user) verify(communalWidgetDao, never()).addWidget(id, provider, priority) verify(appWidgetHost).deleteAppWidgetId(id) } @@ -187,14 +210,20 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { val provider = ComponentName("pkg_name", "cls_name") val id = 1 val priority = 1 + val user = UserHandle(0) whenever(communalWidgetHost.getAppWidgetInfo(id)) .thenReturn(PROVIDER_INFO_CONFIGURATION_OPTIONAL) - whenever(communalWidgetHost.allocateIdAndBindWidget(any<ComponentName>())) + whenever( + communalWidgetHost.allocateIdAndBindWidget( + any<ComponentName>(), + any<UserHandle>() + ) + ) .thenReturn(id) - underTest.addWidget(provider, priority, kosmos.widgetConfiguratorFail) + underTest.addWidget(provider, user, priority, kosmos.widgetConfiguratorFail) runCurrent() - verify(communalWidgetHost).allocateIdAndBindWidget(provider) + verify(communalWidgetHost).allocateIdAndBindWidget(provider, user) verify(communalWidgetDao).addWidget(id, provider, priority) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt index cf727cf5e180..ddb8582913e6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt @@ -30,6 +30,7 @@ import com.android.systemui.communal.data.repository.fakeCommunalMediaRepository import com.android.systemui.communal.data.repository.fakeCommunalTutorialRepository import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository import com.android.systemui.communal.domain.interactor.communalInteractor +import com.android.systemui.communal.domain.interactor.communalSettingsInteractor import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.shared.log.CommunalUiEvent import com.android.systemui.communal.shared.model.CommunalWidgetContentModel @@ -81,6 +82,7 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { underTest = CommunalEditModeViewModel( kosmos.communalInteractor, + kosmos.communalSettingsInteractor, mediaHost, uiEventLogger, logcatLogBuffer("CommunalEditModeViewModelTest"), diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalWidgetHostTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalWidgetHostTest.kt new file mode 100644 index 000000000000..12611cbd8c63 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalWidgetHostTest.kt @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.communal.widgets + +import android.appwidget.AppWidgetManager +import android.content.ComponentName +import android.content.pm.UserInfo +import android.os.UserHandle +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.kosmos.testScope +import com.android.systemui.log.logcatLogBuffer +import com.android.systemui.testKosmos +import com.android.systemui.user.data.model.SelectedUserModel +import com.android.systemui.user.data.model.SelectionStatus +import com.android.systemui.user.data.repository.fakeUserRepository +import com.android.systemui.user.domain.interactor.SelectedUserInteractor +import com.android.systemui.user.domain.interactor.selectedUserInteractor +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.nullable +import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Truth.assertThat +import java.util.Optional +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@SmallTest +@OptIn(ExperimentalCoroutinesApi::class) +@RunWith(AndroidJUnit4::class) +class CommunalWidgetHostTest : SysuiTestCase() { + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + + @Mock private lateinit var appWidgetManager: AppWidgetManager + @Mock private lateinit var appWidgetHost: CommunalAppWidgetHost + private val selectedUserInteractor: SelectedUserInteractor by lazy { + kosmos.selectedUserInteractor + } + + private lateinit var underTest: CommunalWidgetHost + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + underTest = + CommunalWidgetHost( + Optional.of(appWidgetManager), + appWidgetHost, + selectedUserInteractor, + logcatLogBuffer("CommunalWidgetHostTest"), + ) + } + + @Test + fun allocateIdAndBindWidget_withCurrentUser() = + testScope.runTest { + val provider = ComponentName("pkg_name", "cls_name") + val widgetId = 1 + val userId by collectLastValue(selectedUserInteractor.selectedUser) + selectUser() + runCurrent() + + val user = UserHandle(checkNotNull(userId)) + whenever(appWidgetHost.allocateAppWidgetId()).thenReturn(widgetId) + whenever( + appWidgetManager.bindAppWidgetIdIfAllowed( + any<Int>(), + any<UserHandle>(), + any<ComponentName>(), + nullable() + ) + ) + .thenReturn(true) + + // bind the widget with the current user when no user is explicitly set + val result = underTest.allocateIdAndBindWidget(provider) + + verify(appWidgetHost).allocateAppWidgetId() + verify(appWidgetManager).bindAppWidgetIdIfAllowed(widgetId, user, provider, null) + assertThat(result).isEqualTo(widgetId) + } + + @Test + fun allocateIdAndBindWidget_onSuccess() = + testScope.runTest { + val provider = ComponentName("pkg_name", "cls_name") + val widgetId = 1 + val user = UserHandle(0) + + whenever(appWidgetHost.allocateAppWidgetId()).thenReturn(widgetId) + whenever( + appWidgetManager.bindAppWidgetIdIfAllowed( + any<Int>(), + any<UserHandle>(), + any<ComponentName>(), + nullable() + ) + ) + .thenReturn(true) + + // provider and user handle are both set + val result = underTest.allocateIdAndBindWidget(provider, user) + + verify(appWidgetHost).allocateAppWidgetId() + verify(appWidgetManager).bindAppWidgetIdIfAllowed(widgetId, user, provider, null) + assertThat(result).isEqualTo(widgetId) + } + + @Test + fun allocateIdAndBindWidget_onFailure() = + testScope.runTest { + val provider = ComponentName("pkg_name", "cls_name") + val widgetId = 1 + val user = UserHandle(0) + + whenever(appWidgetHost.allocateAppWidgetId()).thenReturn(widgetId) + // failed to bind widget + whenever( + appWidgetManager.bindAppWidgetIdIfAllowed( + any<Int>(), + any<UserHandle>(), + any<ComponentName>(), + nullable() + ) + ) + .thenReturn(false) + val result = underTest.allocateIdAndBindWidget(provider, user) + + verify(appWidgetHost).allocateAppWidgetId() + verify(appWidgetManager).bindAppWidgetIdIfAllowed(widgetId, user, provider, null) + verify(appWidgetHost).deleteAppWidgetId(widgetId) + assertThat(result).isNull() + } + + private fun selectUser() { + kosmos.fakeUserRepository.selectedUser.value = + SelectedUserModel( + userInfo = UserInfo(0, "Current user", 0), + selectionStatus = SelectionStatus.SELECTION_COMPLETE + ) + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java index 7a78b366dd7f..91699381ae7a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java @@ -36,6 +36,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.LockIconViewController; import com.android.systemui.SysuiTestCase; import com.android.systemui.assist.AssistManager; import com.android.systemui.biometrics.AuthController; @@ -45,7 +46,7 @@ import com.android.systemui.flags.FakeFeatureFlagsClassic; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.domain.interactor.DozeInteractor; import com.android.systemui.shade.NotificationShadeWindowViewController; -import com.android.systemui.shade.ShadeViewController; +import com.android.systemui.shade.ShadeLockscreenInteractor; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.StatusBarState; @@ -91,7 +92,8 @@ public class DozeServiceHostTest extends SysuiTestCase { @Mock private NotificationIconAreaController mNotificationIconAreaController; @Mock private NotificationShadeWindowViewController mNotificationShadeWindowViewController; @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; - @Mock private ShadeViewController mShadeViewController; + @Mock private ShadeLockscreenInteractor mShadeLockscreenInteractor; + @Mock private LockIconViewController mLockIconViewController; @Mock private View mAmbientIndicationContainer; @Mock private BiometricUnlockController mBiometricUnlockController; @Mock private AuthController mAuthController; @@ -109,13 +111,12 @@ public class DozeServiceHostTest extends SysuiTestCase { () -> mBiometricUnlockController, () -> mAssistManager, mDozeScrimController, mKeyguardUpdateMonitor, mPulseExpansionHandler, mNotificationShadeWindowController, mNotificationWakeUpCoordinator, mAuthController, mNotificationIconAreaController, - mDozeInteractor); + mShadeLockscreenInteractor, mDozeInteractor); mDozeServiceHost.initialize( mCentralSurfaces, mStatusBarKeyguardViewManager, mNotificationShadeWindowViewController, - mShadeViewController, mAmbientIndicationContainer); } diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/domain/interactor/AudioModeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioModeInteractorTest.kt index 4dbf865475a4..fe34361540e1 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/domain/interactor/AudioModeInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioModeInteractorTest.kt @@ -14,13 +14,14 @@ * limitations under the License. */ -package com.android.settingslib.volume.domain.interactor +package com.android.systemui.volume.domain.interactor import android.media.AudioManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.settingslib.BaseTest -import com.android.settingslib.volume.data.repository.FakeAudioRepository +import com.android.settingslib.volume.domain.interactor.AudioModeInteractor +import com.android.systemui.SysuiTestCase +import com.android.systemui.volume.data.repository.FakeAudioRepository import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.launchIn @@ -34,7 +35,7 @@ import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidJUnit4::class) @SmallTest -class AudioModeInteractorTest : BaseTest() { +class AudioModeInteractorTest : SysuiTestCase() { private val testScope = TestScope() private val fakeAudioRepository = FakeAudioRepository() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteriaTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteriaTest.kt new file mode 100644 index 000000000000..ec37925af0f3 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteriaTest.kt @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.component.mediaoutput.domain + +import android.media.AudioManager +import android.media.session.MediaSession +import android.media.session.PlaybackState +import android.testing.TestableLooper.RunWithLooper +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos +import com.android.systemui.util.mockito.mock +import com.android.systemui.util.mockito.whenever +import com.android.systemui.volume.audioModeInteractor +import com.android.systemui.volume.audioRepository +import com.android.systemui.volume.localMediaRepository +import com.android.systemui.volume.mediaController +import com.android.systemui.volume.mediaControllerRepository +import com.android.systemui.volume.mediaOutputInteractor +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidJUnit4::class) +@RunWithLooper(setAsMainLooper = true) +class MediaOutputAvailabilityCriteriaTest : SysuiTestCase() { + + private val kosmos = testKosmos() + + private lateinit var underTest: MediaOutputAvailabilityCriteria + + @Before + fun setup() { + with(kosmos) { + whenever(mediaController.packageName).thenReturn("test.pkg") + whenever(mediaController.sessionToken).thenReturn(MediaSession.Token(0, mock {})) + whenever(mediaController.playbackState).thenReturn(PlaybackState.Builder().build()) + + mediaControllerRepository.setActiveLocalMediaController(mediaController) + + underTest = MediaOutputAvailabilityCriteria(mediaOutputInteractor, audioModeInteractor) + } + } + + @Test + fun notInCallAndHasDevices_isAvailable_true() { + with(kosmos) { + testScope.runTest { + audioRepository.setMode(AudioManager.MODE_NORMAL) + localMediaRepository.updateMediaDevices(listOf(mock {})) + + val isAvailable by collectLastValue(underTest.isAvailable()) + runCurrent() + + assertThat(isAvailable).isTrue() + } + } + } + @Test + fun inCallAndHasDevices_isAvailable_false() { + with(kosmos) { + testScope.runTest { + audioRepository.setMode(AudioManager.MODE_IN_CALL) + localMediaRepository.updateMediaDevices(listOf(mock {})) + + val isAvailable by collectLastValue(underTest.isAvailable()) + runCurrent() + + assertThat(isAvailable).isFalse() + } + } + } + + @Test + fun notInCallAndHasDevices_isAvailable_false() { + with(kosmos) { + testScope.runTest { + audioRepository.setMode(AudioManager.MODE_NORMAL) + localMediaRepository.updateMediaDevices(emptyList()) + + val isAvailable by collectLastValue(underTest.isAvailable()) + runCurrent() + + assertThat(isAvailable).isFalse() + } + } + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt new file mode 100644 index 000000000000..243aab24b07d --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.component.mediaoutput.ui.viewmodel + +import android.content.applicationContext +import android.media.session.MediaSession +import android.media.session.PlaybackState +import android.testing.TestableLooper +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.kosmos.testScope +import com.android.systemui.res.R +import com.android.systemui.testKosmos +import com.android.systemui.util.mockito.mock +import com.android.systemui.util.mockito.whenever +import com.android.systemui.volume.localMediaRepository +import com.android.systemui.volume.mediaController +import com.android.systemui.volume.mediaControllerRepository +import com.android.systemui.volume.mediaOutputInteractor +import com.android.systemui.volume.panel.mediaOutputActionsInteractor +import com.android.systemui.volume.panel.volumePanelViewModel +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidJUnit4::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class MediaOutputViewModelTest : SysuiTestCase() { + + private val kosmos = testKosmos() + private val playbackStateBuilder = PlaybackState.Builder() + + private lateinit var underTest: MediaOutputViewModel + + @Before + fun setup() { + with(kosmos) { + underTest = + MediaOutputViewModel( + applicationContext, + testScope.backgroundScope, + volumePanelViewModel, + mediaOutputActionsInteractor, + mediaOutputInteractor, + ) + + with(context.orCreateTestableResources) { + addOverride(R.string.media_output_label_title, "media_output_label_title") + addOverride( + R.string.media_output_title_without_playing, + "media_output_title_without_playing" + ) + } + + whenever(mediaController.packageName).thenReturn("test.pkg") + whenever(mediaController.sessionToken).thenReturn(MediaSession.Token(0, mock {})) + whenever(mediaController.playbackState).then { playbackStateBuilder.build() } + + mediaControllerRepository.setActiveLocalMediaController(mediaController) + } + } + + @Test + fun playingSession_connectedDeviceViewMode_hasTheDevice() { + with(kosmos) { + testScope.runTest { + playbackStateBuilder.setState(PlaybackState.STATE_PLAYING, 0, 0f) + localMediaRepository.updateCurrentConnectedDevice( + mock { whenever(name).thenReturn("test_device") } + ) + + val connectedDeviceViewModel by collectLastValue(underTest.connectedDeviceViewModel) + runCurrent() + + assertThat(connectedDeviceViewModel!!.label).isEqualTo("media_output_label_title") + assertThat(connectedDeviceViewModel!!.deviceName).isEqualTo("test_device") + } + } + } + + @Test + fun notPlaying_connectedDeviceViewMode_hasTheDevice() { + with(kosmos) { + testScope.runTest { + playbackStateBuilder.setState(PlaybackState.STATE_STOPPED, 0, 0f) + localMediaRepository.updateCurrentConnectedDevice( + mock { whenever(name).thenReturn("test_device") } + ) + + val connectedDeviceViewModel by collectLastValue(underTest.connectedDeviceViewModel) + runCurrent() + + assertThat(connectedDeviceViewModel!!.label) + .isEqualTo("media_output_title_without_playing") + assertThat(connectedDeviceViewModel!!.deviceName).isEqualTo("test_device") + } + } + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/DefaultComponentsLayoutManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/DefaultComponentsLayoutManagerTest.kt index 7c993603b810..71866b3957b6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/DefaultComponentsLayoutManagerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/DefaultComponentsLayoutManagerTest.kt @@ -50,7 +50,7 @@ class DefaultComponentsLayoutManagerTest : SysuiTestCase() { val component4 = ComponentState(COMPONENT_4, kosmos.mockVolumePanelUiComponent, false) val layout = underTest.layout( - VolumePanelState(0, false), + VolumePanelState(0, false, false), setOf(bottomBarComponentState, component1, component2, component3, component4) ) @@ -71,7 +71,7 @@ class DefaultComponentsLayoutManagerTest : SysuiTestCase() { val component1State = ComponentState(COMPONENT_1, kosmos.mockVolumePanelUiComponent, false) val component2State = ComponentState(COMPONENT_2, kosmos.mockVolumePanelUiComponent, false) underTest.layout( - VolumePanelState(0, false), + VolumePanelState(0, false, false), setOf( component1State, component2State, diff --git a/packages/SystemUI/plugin/proguard_plugins.flags b/packages/SystemUI/plugin/proguard_plugins.flags index abac27f0cbe6..23ba8d066bb2 100644 --- a/packages/SystemUI/plugin/proguard_plugins.flags +++ b/packages/SystemUI/plugin/proguard_plugins.flags @@ -7,3 +7,13 @@ -keep class com.android.systemui.log.core.** { *; } + +# This type is used in the plugin API boundary, so ensure the used public methods are kept. +-keepclassmembers class androidx.constraintlayout.widget.ConstraintSet { + public void connect(int, int, int, int, int); + public void constrainWidth(int, int); + public void constrainHeight(int, int); + public int getHeight(int); + public int getWidth(int); + public void setGoneMargin(int, int, int); +} diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml index 5db9eee6a908..109e63c6167a 100644 --- a/packages/SystemUI/res/layout/media_session_view.xml +++ b/packages/SystemUI/res/layout/media_session_view.xml @@ -67,6 +67,18 @@ android:background="@drawable/qs_media_outline_layout_bg" /> + <com.android.systemui.surfaceeffects.loadingeffect.LoadingEffectView + android:id="@+id/loading_effect_view" + android:layout_width="match_parent" + android:layout_height="@dimen/qs_media_session_height_expanded" + app:layout_constraintStart_toStartOf="@id/album_art" + app:layout_constraintEnd_toEndOf="@id/album_art" + app:layout_constraintTop_toTopOf="@id/album_art" + app:layout_constraintBottom_toBottomOf="@id/album_art" + android:clipToOutline="true" + android:background="@drawable/qs_media_outline_layout_bg" + /> + <!-- Guideline for output switcher --> <androidx.constraintlayout.widget.Guideline android:id="@+id/center_vertical_guideline" diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index a3174a95ee6b..d05a1fcfaaf4 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Tik om te bekyk"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Kon nie skermopname stoor nie"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Kon nie skermopname begin nie"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Kwessieopnemer"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Verwerk tans kwessieopname"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Deurlopende kennisgewing vir ’n kwessieversamelingsessie"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Opnamekwessie"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Deel"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Kwessieopname is gestoor"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Tik om te bekyk"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Kon nie kwessieopname stoor nie"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Kon nie kwessieopname begin nie"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Bekyk tans volskerm"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Swiep van bo af as jy wil uitgaan."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Het dit"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gestoor"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ontkoppel"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiveer"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterykrag"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Oudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Kopstuk"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktiveer"</string> <string name="sound_settings" msgid="8874581353127418308">"Klank en vibrasie"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Instellings"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume is verlaag na ’n veiliger vlak"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Oorfoonvolume was langer as wat aanbeveel word hoog"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Oorfoonvolume het die veilige limiet vir hierdie week oorskry"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"om <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"op <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Warmkol"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelliet, geen verbinding nie"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliet, swak verbinding"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliet, goeie toestand"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliet, verbinding is beskikbaar"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Werkprofiel"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Pret vir party mense, maar nie vir almal nie"</string> <string name="tuner_warning" msgid="1861736288458481650">"Stelsel-UI-ontvanger gee jou ekstra maniere om die Android-gebruikerkoppelvlak in te stel en te pasmaak. Hierdie eksperimentele kenmerke kan in toekomstige uitreikings verander, breek of verdwyn. Gaan versigtig voort."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Maak instellings oop"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Maak Assistent oop"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Sluit skerm"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Maak notas oop"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Maak ’n nota"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Verrig veelvuldige stelseltake"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Gaan by verdeelde skerm in met huidige app aan die regterkant"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Gaan by verdeelde skerm in met huidige app aan die linkerkant"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index b4c68e22ef34..6ee6c996e70b 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"ለመመልከት መታ ያድርጉ"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"የማያ ገጽ ቀረጻን ማስቀመጥ ላይ ስህተት"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"የማያ ገፅ ቀረጻን መጀመር ላይ ስህተት"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"ችግር መመዝገቢያ"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"የአሰራር ችግር አመዘጋገብ"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"ለችግር መሰብሰብ ክፍለ ጊዜ ቀጣይነት ያለው ማሳወቂያ"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"የቀረጻ ችግር"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"አጋራ"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"የችግር ምዝገባ ቀምጧል"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"ለመመልከት መታ ያድርጉ"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"የችግር ምዝገባ ማስቀመጥ ላይ ስህተት"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"ችግር ምዝገባ ማስጀመር ላይ ስህተት"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"በሙሉ ገጽ ዕይታ በማየት ላይ"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"ለመውጣት፣ ከላይ ወደታች ያንሸራትቱ።"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"ገባኝ"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ተቀምጧል"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ግንኙነትን አቋርጥ"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ያግብሩ"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ባትሪ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ኦዲዮ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ማዳመጫ"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"አሰናክል"</string> <string name="sound_settings" msgid="8874581353127418308">"ድምፅ እና ንዝረት"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ቅንብሮች"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"የቀጥታ መግለጫ ጽሑፍ"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"የድምፅ መጠን ይበልጥ ደህንነቱ ወደተጠበቀ ደረጃ ዝቅ ተደርጓል"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"የራስ ላይ ማዳመጫ የድምፅ መጠን ከሚመከረው በላይ ረዘም ላለ ጊዜ ከፍተኛ ነበር"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"የራስ ላይ ማዳመጫ የድምፅ መጠን ለዚህ ሳምንት ደህንነቱ ከተጠበቀው ገደብ አልፏል"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"በ<xliff:g id="WHEN">%1$s</xliff:g> ላይ"</string> <string name="alarm_template_far" msgid="3561752195856839456">"በ<xliff:g id="WHEN">%1$s</xliff:g> ላይ"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"መገናኛ ነጥብ"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"ሳተላይት፣ ግንኙነት የለም"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ሳተላይት፣ ደካማ ግንኙነት"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ሳተላይት፣ ጥሩ ግንኙነት"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ሳተላይት፣ ግንኙነት አለ"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"የስራ መገለጫ"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"ለአንዳንዶች አስደሳች ቢሆንም ለሁሉም አይደለም"</string> <string name="tuner_warning" msgid="1861736288458481650">"የስርዓት በይነገጽ መቃኛ የAndroid ተጠቃሚ በይነገጹን የሚነካኩበት እና የሚያበጁበት ተጨማሪ መንገዶች ይሰጠዎታል። እነዚህ የሙከራ ባህሪዎች ወደፊት በሚኖሩ ልቀቶች ላይ ሊለወጡ፣ ሊሰበሩ ወይም ሊጠፉ ይችላሉ። ከጥንቃቄ ጋር ወደፊት ይቀጥሉ።"</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"ቅንብሮችን ክፈት"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"ረዳትን ክፈት"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"ማያ ገፅ ቁልፍ"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"ማስታወሻዎችን ክፈት"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"ማስታወሻ ይውሰዱ"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"የሥርዓት ብዙ ተግባራትን በተመሳሳይ ጊዜ ማከናወን"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"ለአርኤችኤስ በአሁኑ መተግበሪያ ወደ የተከፈለ ማያ ገጽ ግባ"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"ለኤልኤችኤስ በአሁኑ መተግበሪያ ወደ የተከፈለ ማያ ገጽ ይግቡ"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 7cd07fd0f47a..fdad1cfe9b38 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"انقر لعرض التسجيل."</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"حدث خطأ أثناء حفظ تسجيل محتوى الشاشة."</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"حدث خطأ في بدء تسجيل الشاشة"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"مسجّلة المشاكل"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"يجري معالجة تسجيل المشكلة."</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"إشعار بنشاط مستمر في الخلفية لجلسة جمع البيانات حول المشكلة"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"يجري تسجيل المشكلة."</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"مشاركة"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"تم حفظ تسجيل المشكلة."</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"انقر لعرض التسجيل."</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"حدث خطأ أثناء حفظ تسجيل المشكلة."</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"حدث خطأ أثناء بدء تسجيل المشكلة."</string> <string name="immersive_cling_title" msgid="8372056499315585941">"جارٍ العرض بملء الشاشة"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"للخروج، مرِّر سريعًا من أعلى الشاشة لأسفلها."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"حسنًا"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"محفوظ"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"إلغاء الربط"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"تفعيل"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"مستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"صوت"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"سماعة الرأس"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"إيقاف"</string> <string name="sound_settings" msgid="8874581353127418308">"الصوت والاهتزاز"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"الإعدادات"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"النسخ النصي التلقائي"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"تم خفض مستوى الصوت إلى مستوى أكثر أمانًا"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"كان مستوى صوت سمّاعة الرأس مرتفعًا لمدة أطول مما يُنصَح به."</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"تجاوز مستوى صوت سمّاعة الرأس الحد الآمن هذا الأسبوع."</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"في <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"يوم <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"نقطة اتصال"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"قمر صناعي، لا يتوفّر اتصال بالإنترنت"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"قمر صناعي، الاتصال ضعيف"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"قمر صناعي، الاتصال جيد"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"قمر صناعي، الاتصال متوفّر"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"الملف الشخصي للعمل"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"متعة للبعض وليس للجميع"</string> <string name="tuner_warning" msgid="1861736288458481650">"توفر لك أداة ضبط واجهة مستخدم النظام طرقًا إضافية لتعديل واجهة مستخدم Android وتخصيصها. ويمكن أن تطرأ تغييرات على هذه الميزات التجريبية أو يمكن أن تتعطل هذه الميزات أو تختفي في الإصدارات المستقبلية. عليك متابعة الاستخدام مع توخي الحذر."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"فتح الإعدادات"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"فتح \"مساعد Google\""</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"شاشة القفل"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"فتح تطبيق تدوين الملاحظات"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"تدوين ملاحظة"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"تعدُّد المهام في النظام"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"تفعيل وضع \"تقسيم الشاشة\" مع عرض التطبيق الحالي على يسار الشاشة"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"تفعيل وضع \"تقسيم الشاشة\" مع عرض التطبيق الحالي على يمين الشاشة"</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 1752f97fd52f..34141ebde3df 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"চাবলৈ টিপক"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"ৰেকৰ্ড কৰা স্ক্ৰীন ছেভ কৰোঁতে আসোঁৱাহ হৈছে"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রীন ৰেকৰ্ড কৰা আৰম্ভ কৰোঁতে আসোঁৱাহ হৈছে"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"সমস্যা ৰেকৰ্ডাৰ"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"সমস্যা ৰেকৰ্ড কৰি থকা হৈছে"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"সমস্যা সংগ্ৰহ কৰা এটা ছেশ্বনৰ বাবে চলিত জাননী"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"সমস্যাটো ৰেকৰ্ড কৰি থকা হৈছে"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"শ্বেয়াৰ কৰক"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"সমস্যাৰ ৰেকৰ্ডিং ছেভ কৰা হৈছে"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"চাবলৈ টিপক"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"সমস্যাৰ ৰেকৰ্ডিং ছেভ কৰাত আসোঁৱাহ"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"সমস্যাৰ ৰেকৰ্ডিং আৰম্ভ কৰোঁতে আসোঁৱাহ হৈছে"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"পূৰ্ণ স্ক্ৰীনত চাই আছে"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"বাহিৰ হ’বলৈ ওপৰৰ পৰা তললৈ ছোৱাইপ কৰক।"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"বুজি পালোঁ"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ছেভ কৰা হৈছে"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"সংযোগ বিচ্ছিন্ন কৰক"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"সক্ৰিয় কৰক"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"বেটাৰী <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"অডিঅ’"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"হেডছেট"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"অক্ষম কৰক"</string> <string name="sound_settings" msgid="8874581353127418308">"ধ্বনি আৰু কম্পন"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ছেটিং"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"লাইভ কেপশ্বন"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ভলিউম সুৰক্ষিত স্তৰলৈ কম কৰা হৈছে"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"চুপাৰিছ কৰাতকৈ দীঘলীয়া সময়ৰ বাবে হেডফ’নৰ ভলিউম উচ্চ হৈ আছে"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"হেডফ’নৰ ভলিউমে এই সপ্তাহৰ বাবে সুৰক্ষিত সীমা অতিক্ৰম কৰিছে"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> বজাত"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> বজাত"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"হটস্পট"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"উপগ্ৰহ, সংযোগ নাই"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"উপগ্ৰহ, বেয়া সংযোগ"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"উপগ্ৰহ, ভাল সংযোগ"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"উপগ্ৰহ, সংযোগ উপলব্ধ"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"কিছুমানৰ বাবে আমোদজনক হয় কিন্তু সকলোৰে বাবে নহয়"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tunerএ আপোনাক Android ব্যৱহাৰকাৰী ইণ্টাৰফেইচ সলনি কৰিবলৈ আৰু নিজৰ উপযোগিতা অনুসৰি ব্যৱহাৰ কৰিবলৈ অতিৰিক্ত সুবিধা প্ৰদান কৰে। এই পৰীক্ষামূলক সুবিধাসমূহ সলনি হ\'ব পাৰে, সেইবোৰে কাম নকৰিব পাৰে বা আগন্তুক সংস্কৰণসমূহত সেইবোৰ অন্তৰ্ভুক্ত কৰা নহ’ব পাৰে। সাৱধানেৰে আগবাঢ়ক।"</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"ছেটিং খোলক"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant খোলক"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"লক স্ক্ৰীন"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Notes এপ্ খোলক"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"টোকা লিখক"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ছিষ্টেম মাল্টিটাস্কিং"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"বৰ্তমানৰ এপৰ জৰিয়তে বিভাজিত স্ক্ৰীনৰ সোঁফালৰ স্ক্ৰীনখনত সোমাওক"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"বৰ্তমানৰ এপৰ জৰিয়তে বিভাজিত স্ক্ৰীনৰ বাওঁফালৰ স্ক্ৰীনখনত সোমাওক"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 4a79b70d31ae..46dcc95db646 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Baxmaq üçün toxunun"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran çəkimini yadda saxlayarkən xəta oldu"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranın yazılması ilə bağlı xəta"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Problem qeydə alan"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Problem qeydi emal edilir"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Problemin əldə edilməsi sessiyası üçün davam edən bildiriş"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Problem qeydə alınır"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Paylaşın"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Problem qeydi yadda saxlandı"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Baxmaq üçün toxunun"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Problem qeydini yadda saxlayarkən xəta"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Problemi qeydə almağa başlayarkən xəta"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Tam ekran rejimi"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Çıxmaq üçün yuxarıdan aşağı sürüşdürün."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Anladım"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Yadda saxlandı"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"əlaqəni kəsin"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivləşdirin"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batareya"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Qulaqlıq"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktiv edin"</string> <string name="sound_settings" msgid="8874581353127418308">"Səs və vibrasiya"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ayarlar"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Canlı Altyazı"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Səs təhlükəsiz səviyyəyə azaldıldı"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Qulaqlığın səsi tövsiyə ediləndən uzun müddət yüksək olub"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Bu həftə qulaqlığın səsi təhlükəsiz limiti keçib"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Peyk, bağlantı yoxdur"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Peyk, bağlantı zəifdir"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Peyk, bağlantı yaxşıdır"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Peyk, bağlantı var"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"İş profili"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Hamı üçün deyil, bəziləri üçün əyləncəli"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner Android istifadəçi interfeysini dəyişdirmək və fərdiləşdirmək üçün Sizə ekstra yollar təklif edir."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ayarları açın"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistenti açın"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Kilid ekranı"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Qeydləri açın"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Qeyd götürün"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Sistemdə çoxsaylı tapşırıq icrası"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Cari tətbiq sağda olmaqla bölünmüş ekrana daxil olun"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Cari tətbiq solda olmaqla bölünmüş ekrana daxil olun"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index eceedc144706..8e49279b4af6 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da biste pregledali"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Greška pri čuvanju snimka ekrana"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Snimač problema"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Obrađuje se snimak problema"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"obaveštenje o aktivnosti u toku za sesiju prikupljanja podataka o problemu"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Snimamo problem"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Deli"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Snimak problema je sačuvan"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Dodirnite da biste pregledali"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Greška pri čuvanju snimka problema"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Greška pri pokretanju snimanja problema"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Prikazuje se ceo ekran"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Da biste izašli, prevucite nadole odozgo."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Važi"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sačuvano"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekinite vezu"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivirajte"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatski ponovo uključi sutra"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funkcije kao što su Quick Share, Pronađi moj uređaj i lokacija uređaja koriste Bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"onemogućite"</string> <string name="sound_settings" msgid="8874581353127418308">"Zvuk i vibriranje"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Podešavanja"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Titl uživo"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Zvuk je smanjen na bezbednu jačinu"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Zvuk u slušalicama je bio glasan duže nego što se preporučuje"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Jačina zvuka u slušalicama je premašila bezbednosno ograničenje za ovu nedelju"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelit, niste povezani"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, veza je loša"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, veza je dobra"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Poslovni profil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string> <string name="tuner_warning" msgid="1861736288458481650">"Tjuner za korisnički interfejs sistema vam pruža dodatne načine za podešavanje i prilagođavanje Android korisničkog interfejsa. Ove eksperimentalne funkcije mogu da se promene, otkažu ili nestanu u budućim izdanjima. Budite oprezni."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvori podešavanja"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvori pomoćnika"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaključavanje ekrana"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Otvori beleške"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Napravite belešku"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Obavljanje više zadataka sistema istovremeno"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Pokreni podeljeni ekran za aktuelnu aplikaciju na desnoj strani"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Pokreni podeljeni ekran za aktuelnu aplikaciju na levoj strani"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 666d2895066e..c4a1a66a2351 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Націсніце для прагляду"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Памылка захавання запісу экрана"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Памылка пачатку запісу экрана"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Запіс праблемы"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Ідзе апрацоўка запісу праблемы"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Бягучае апавяшчэнне пра сеанс збору даных аб праблеме"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Ідзе запіс праблемы"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Абагуліць"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Запіс праблемы захаваны"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Націсніце, каб праглядзець"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Пры захаванні запісу праблемы адбылася памылка"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Пры спробе пачаць запіс праблемы адбылася памылка"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Прагляд у поўнаэкранным рэжыме"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Каб выйсці, правядзіце пальцам па экране зверху ўніз."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Зразумела"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Захавана"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"адключыць"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"актываваць"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Аўтаматычнае ўключэнне заўтра"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Такія функцыі, як вызначэнне месцазнаходжання прылады, Хуткае абагульванне і Знайсці прыладу, выкарыстоўваюць Bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Узровень зараду: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Гук"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнітура"</string> @@ -546,6 +539,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"адключыць"</string> <string name="sound_settings" msgid="8874581353127418308">"Гук і вібрацыя"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Налады"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Гучнасць паніжана да больш бяспечнага ўзроўню"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Гучнасць у навушніках была вялікай больш часу, чым рэкамендавана"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Гучнасць у навушніках перавысіла ліміт бяспечнага праслухоўвання на гэтым тыдні"</string> @@ -612,14 +607,10 @@ <string name="alarm_template" msgid="2234991538018805736">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Хот-спот"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Спадарожнікавая сувязь, няма падключэння"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Спадарожнікавая сувязь, дрэннае падключэнне"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спадарожнікавая сувязь, добрае падключэнне"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Спадарожнікавая сувязь, падключэнне даступнае"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Працоўны профіль"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Цікава для некаторых, але не для ўсіх"</string> <string name="tuner_warning" msgid="1861736288458481650">"Наладка сістэмнага інтэрфейсу карыстальніка дае вам дадатковыя спосабы наладжвання і дапасоўвання карыстальніцкага інтэрфейсу Android. Гэтыя эксперыментальныя функцыі могуць змяніцца, перастаць працаваць або знікнуць у будучых версіях. Карыстайцеся з асцярожнасцю."</string> @@ -741,7 +732,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Адкрыць налады"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Выклікаць Памочніка"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Экран блакіроўкі"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Адкрыць нататкі"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Стварыць нататку"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Шматзадачнасць сістэмы"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Перайсці ў рэжым падзеленага экрана з бягучай праграмай справа"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Перайсці ў рэжым падзеленага экрана з бягучай праграмай злева"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index b27f0e4a0597..b75a7dfd5972 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Докоснете за преглед"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при запазването на записа на екрана"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"При стартирането на записа на екрана възникна грешка"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Записване на проблем"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Записът се обработва"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Текущо известие за сесия за събиране на данни за проблем"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Проблемът се записва"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Споделяне"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Записът на проблема е запазен"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Докоснете за преглед"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Грешка при запазването на записа на проблема"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Грешка при стартирането на записа на проблема"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Изглед на цял екран"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"За изход прекарайте пръст надолу от горната част."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Разбрах"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Запазено"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"прекратяване на връзката"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активиране"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалки"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"деактивиране"</string> <string name="sound_settings" msgid="8874581353127418308">"Звук и вибриране"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Настройки"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Силата на звука е намалена до по-безопасно ниво"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Нивото на силата на звука на слушалките е било високо по-дълго, отколкото е препоръчително"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Нивото на силата на звука на слушалките е надвишило безопасния лимит за тази седмица"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"в <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"в/ъв <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Точка за достъп"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Сателит, няма връзка"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Сателит, лоша връзка"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Сателит, добра връзка"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Сателит, налице е връзка"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Потребителски профил в Work"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Забавно – но не за всички"</string> <string name="tuner_warning" msgid="1861736288458481650">"Тунерът на системния потребителски интерфейс ви предоставя допълнителни възможности за прецизиране и персонализиране на практическата работа с Android. Тези експериментални функции може да се променят, повредят или да изчезнат в бъдещите версии. Действайте внимателно."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Отваряне на настройките"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Отваряне на Асистент"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Заключване на екрана"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Отваряне на бележките"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Създаване на бележка"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Едновременно изпълняване на няколко задачи в системата"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Преминаване към разделен екран с текущото приложение отдясно"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Преминаване към разделен екран с текущото приложение отляво"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 8da62b2e9fc5..54cf758c5613 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"দেখতে ট্যাপ করুন"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"স্ক্রিন রেকর্ডিং সেভ করার সময় কোনও সমস্যা হয়েছে"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রিন রেকর্ডিং শুরু করার সময় সমস্যা হয়েছে"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Recorder-এ সমস্যা হয়েছে"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"সমস্যা সংক্রান্ত রেকর্ডিং প্রসেস করা হচ্ছে"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"সমস্যা সংগ্রহ সেশনের জন্য অনগোইং নোটিফিকেশন"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"রেকর্ডিং সংক্রান্ত সমস্যা"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"শেয়ার করুন"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"রেকর্ডিং সেভ করতে সমস্যা হয়েছে"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"দেখার জন্য ট্যাপ করুন"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"সমস্যা সংক্রান্ত রেকর্ডিং সেভ করার সময় সমস্যা হয়েছে"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"সমস্যা সংক্রান্ত রেকর্ডিং শুরু করতে সমস্যা হয়েছে"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"ফুল-স্ক্রিনে দেখা হচ্ছে"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"বেরিয়ে যেতে উপর থেকে নিচের দিকে সোয়াইপ করুন।"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"বুঝেছি"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"সেভ করা আছে"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ডিসকানেক্ট করুন"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"চালু করুন"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"অডিও"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"হেডসেট"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"বন্ধ হবে"</string> <string name="sound_settings" msgid="8874581353127418308">"সাউন্ড ও ভাইব্রেশন"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"সেটিংস"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ভলিউম কমিয়ে আরও নিরাপদ মাত্রায় নামানো হয়েছে"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"সাজেস্ট করা সময়ের চেয়ে অতিরিক্ত সময় ধরে হেডফোনের ভলিউম বেশি করা আছে"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"এই সপ্তাহে হেডফোনের ভলিউম নিরাপদ মাত্রা ছাড়িয়ে গেছে"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> -তে"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"হটস্পট"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"স্যাটেলাইট, কোনও কানেকশন নেই"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"স্যাটেলাইট, খারাপ কানেকশন"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"স্যাটেলাইট, ভালো কানেকশন"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"স্যাটেলাইট, কানেকশন উপলভ্য আছে"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"কাজের প্রোফাইল"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"কিছু ব্যক্তির জন্য মজাদার কিন্তু সকলের জন্য নয়"</string> <string name="tuner_warning" msgid="1861736288458481650">"এই পরীক্ষামূলক বৈশিষ্ট্যগুলি ভবিষ্যতের সংস্করণগুলির মধ্যে পরিবর্তিত, বিভাজিত এবং অদৃশ্য হয়ে যেতে পারে৷ সাবধানতার সাথে এগিয়ে যান৷ সিস্টেম UI টিউনার আপনাকে Android ব্যবহারকারী ইন্টারফেসের সূক্ষ্ম সমন্বয় এবং কাস্টমাইজ করার অতিরিক্ত উপায়গুলি প্রদান করে৷"</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"সেটিংস খুলুন"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant খুলুন"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"লক স্ক্রিন"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"নোট খুলুন"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"একটি নোট লিখুন"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"সিস্টেম মাল্টিটাস্কিং"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"ডানদিকে থাকা বর্তমান অ্যাপ ব্যবহার করে \'স্প্লিট স্ক্রিন\' যোগ করুন"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"বাঁদিকে থাকা বর্তমান অ্যাপ ব্যবহার করে \'স্প্লিট স্ক্রিন\' যোগ করুন"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 67bd504b7b9d..989daf970d7d 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da vidite"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Greška prilikom pohranjivanja snimka ekrana"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Snimač problema"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Obrada snimka problema"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Obavještenje o aktivnosti u pozadini za sesiju prikupljanja podataka o problemu"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Snimanje problema"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Dijelite"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Snimak problema je sačuvan"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Dodirnite da pregledate"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Došlo je do greške prilikom pohranjivanja snimka problema"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Došlo je do greške prilikom pokretanja snimanja problema"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Prikazivanje preko cijelog ekrana"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Da izađete, prevucite s vrha nadolje."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Razumijem"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sačuvano"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekid veze"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviranje"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"onemogući"</string> <string name="sound_settings" msgid="8874581353127418308">"Zvuk i vibracija"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Postavke"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Automatski titlovi"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Zvuk je smanjen na sigurniju jačinu"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Jačina zvuka slušalica je bila visoka duže od preporučenog"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Jačina zvuka slušalica je premašila sigurno ograničenje za ovu sedmicu"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Pristupna tačka"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelit, nema veze"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slaba veza"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra veza"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Radni profil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string> <string name="tuner_warning" msgid="1861736288458481650">"Podešavač za korisnički interfejs sistema vam omogućava dodatne načine da podesite i prilagodite Androidov interfejs. Ove eksperimentalne funkcije se u budućim verzijama mogu mijenjati, kvariti ili nestati. Budite oprezni."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvaranje postavki"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvaranje Asistenta"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaključavanje ekrana"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Otvaranje Bilješki"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Pisanje bilješke"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking sistema"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Otvaranje podijeljenog ekrana s trenutnom aplikacijom na desnoj strani"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Otvaranje podijeljenog ekrana s trenutnom aplikacijom na lijevoj strani"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 23e4ed4e48f9..6b0eabc50b69 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Toca per veure-la"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"S\'ha produït un error en desar la gravació de la pantalla"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"S\'ha produït un error en iniciar la gravació de pantalla"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Gravadora de problemes"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processant gravació del problema"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificació en curs d\'una sessió de recollida de dades del problema"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"S\'està gravant el problema"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Comparteix"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"S\'ha desat la gravació del problema"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Toca per veure"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"S\'ha produït un error en desar la gravació del problema"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"S\'ha produït un error en iniciar la gravació del problema"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Visualització en pantalla completa"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Per sortir, llisca cap avall des de la part superior."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Entesos"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Desat"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconnecta"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activa"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Torna\'l a activar automàticament demà"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funcions com ara Quick Share, Troba el meu dispositiu i la ubicació del dispositiu utilitzen el Bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Àudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculars"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desactivar"</string> <string name="sound_settings" msgid="8874581353127418308">"So i vibració"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Configuració"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Subtítols instantanis"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"El volum s\'ha abaixat a un nivell més segur"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"El volum dels auriculars ha estat elevat durant més temps del recomanat"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"El volum dels auriculars ha superat el límit de seguretat d\'aquesta setmana"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"Hora: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"Dia: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Punt d\'accés Wi-Fi"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satèl·lit, sense connexió"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satèl·lit, connexió deficient"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satèl·lit, bona connexió"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satèl·lit, connexió disponible"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de treball"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Diversió per a uns quants, però no per a tothom"</string> <string name="tuner_warning" msgid="1861736288458481650">"El Personalitzador d\'interfície d\'usuari presenta opcions addicionals per canviar i personalitzar la interfície d\'usuari d\'Android. És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Obre la configuració"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Obre l\'Assistent"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Pantalla de bloqueig"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Obre les notes"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Crea una nota"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasques del sistema"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Entra al mode de pantalla dividida amb l\'aplicació actual a la dreta"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Entra al mode de pantalla dividida amb l\'aplicació actual a l\'esquerra"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 9805e011130e..71c8a35fa08b 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Klepnutím nahrávku zobrazíte"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Při ukládání záznamu obrazovky došlo k chybě"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Při spouštění nahrávání obrazovky došlo k chybě"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Rekordér problémů"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Zpracování záznamu problému"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Upozornění na probíhající shromažďování dat o problému"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Záznam problému"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Sdílet"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Záznam problému byl uložen"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Zobrazíte ho klepnutím"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Při ukládání záznamu problému došlo k chybě"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Při zahájení záznamu problému došlo k chybě"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Zobrazování přes celou obrazovku"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Režim ukončíte přejetím prstem shora dolů."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Rozumím"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Uloženo"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"odpojit"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivovat"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Zítra znovu automaticky zapnout"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funkce jako Quick Share, Najdi moje zařízení a vyhledávání zařízení používají Bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Sluchátka"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktivovat"</string> <string name="sound_settings" msgid="8874581353127418308">"Zvuk a vibrace"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Nastavení"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Živý přepis"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Hlasitost byla snížena na bezpečnou úroveň"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Hlasitost sluchátek byla vysoká déle, než je doporučeno"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Hlasitost sluchátek překročila bezpečný limit pro tento týden"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"v <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelit, bez připojení"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, špatné připojení"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobré připojení"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, připojení je k dispozici"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Pracovní profil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Zábava, která není pro každého"</string> <string name="tuner_warning" msgid="1861736288458481650">"Nástroj na ladění uživatelského rozhraní systému vám nabízí další způsoby, jak si vyladit a přizpůsobit uživatelské rozhraní Android. Tyto experimentální funkce mohou v dalších verzích chybět, nefungovat nebo být změněny. Postupujte proto prosím opatrně."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otevřít nastavení"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otevřít Asistenta"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Uzamknout obrazovku"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Otevřít poznámky"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Vytvořit poznámku"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Systémový multitasking"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Přepnout na rozdělenou obrazovku s aktuálními aplikacemi napravo"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Přepnout na rozdělenou obrazovku s aktuálními aplikacemi nalevo"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 084ce0a54a51..ab436790cc1b 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Tryk for at se"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Skærmoptagelsen kunne ikke gemmes"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Skærmoptagelsen kunne ikke startes"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Problemoptagelse"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Behandler optagelse af problem"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Igangværende notifikation om en session med problemindsamling"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Optager problem"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Del"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Optagelse af problem er gemt"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Tryk for at se"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Kunne ikke gemme optagelse af problem"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Fejl under forsøg på at starte optagelse af problem"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Visning i fuld skærm"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Stryg ned fra toppen for at afslutte."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gemt"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"afbryd forbindelse"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivér"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Lyd"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktiver"</string> <string name="sound_settings" msgid="8874581353127418308">"Lyd og vibration"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Indstillinger"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Lydstyrken blev reduceret til et mere sikkert niveau"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Høretelefonernes lydstyrke har været høj i længere tid end anbefalet"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Høretelefonernes lydstyrke har overskredet sikkerhedsgrænsen for denne uge"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"på <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satellit – ingen forbindelse"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellit – dårlig forbindelse"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit – god forbindelse"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit – forbindelsen er tilgængelig"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Arbejdsprofil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Sjovt for nogle, men ikke for alle"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner giver dig flere muligheder for at justere og tilpasse Android-brugerfladen. Disse eksperimentelle funktioner kan ændres, gå i stykker eller forsvinde i fremtidige udgivelser. Vær forsigtig, hvis du fortsætter."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Åbn indstillinger"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Åbn Assistent"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Lås skærm"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Åbn noter"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Skriv en note"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Systemmultitasking"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Start opdelt skærm med aktuel app til højre"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Start opdelt skærm med aktuel app til venstre"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index b3d3712671db..3c4730038040 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Zum Ansehen tippen"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Fehler beim Speichern der Bildschirmaufzeichnung"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Fehler beim Start der Bildschirmaufzeichnung"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Problem aufzeichnen"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Aufzeichnung wird verarbeitet"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Benachrichtigung über laufende Aufzeichnung eines Problems"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Problem wird aufgezeichnet"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Teilen"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Aufzeichnung des Problems wurde gespeichert"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Zum Ansehen tippen"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Fehler beim Speichern der Aufzeichnung des Problems"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Fehler beim Starten der Aufzeichnung des Problems"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Vollbildmodus wird aktiviert"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Zum Beenden von oben nach unten wischen."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Ok"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gespeichert"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"Verknüpfung aufheben"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivieren"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktivieren"</string> <string name="sound_settings" msgid="8874581353127418308">"Ton & Vibration"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Einstellungen"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Auf verträglichere Lautstärke eingestellt"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Die Kopfhörerlautstärke war länger als empfohlen hoch eingestellt"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Die Kopfhörerlautstärke hat für diese Woche das Sicherheitslimit überschritten"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"um <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"am <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satellit, keine Verbindung"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellit, Verbindung schlecht"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit, Verbindung gut"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit, Verbindung verfügbar"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Arbeitsprofil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Für einige ein Vergnügen, aber nicht für alle"</string> <string name="tuner_warning" msgid="1861736288458481650">"Mit System UI Tuner erhältst du zusätzliche Möglichkeiten, die Android-Benutzeroberfläche anzupassen. Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Einstellungen öffnen"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant öffnen"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Sperrbildschirm"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Notizen öffnen"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Notiz machen"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System-Multitasking"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Splitscreen aktivieren, aktuelle App rechts"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Splitscreen aktivieren, aktuelle App links"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 825994acda6a..a7a300f391e1 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Πατήστε για προβολή"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Σφάλμα κατά την αποθήκευση της εγγραφής οθόνης"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Σφάλμα κατά την έναρξη της εγγραφής οθόνης"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Εργαλείο καταγραφής προβλημάτων"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Επεξερ. καταγραφής προβλήματος"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Ειδοποίηση σε εξέλιξη για μια περίοδο λειτουργίας συλλογής προβλημάτων"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Πρόβλημα καταγραφής"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Κοινοποίηση"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Η καταγραφή του προβλήματος αποθηκεύτηκε"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Πατήστε για προβολή"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Σφάλμα κατά την αποθήκευση της καταγραφής του προβλήματος"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Σφάλμα κατά την έναρξη της καταγραφής του προβλήματος"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Προβολή σε πλήρη οθόνη"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Για έξοδο, σύρετε προς τα κάτω από το επάνω μέρος."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Το κατάλαβα"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Αποθηκεύτηκε"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"αποσύνδεση"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ενεργοποίηση"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ήχος"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ακουστικά"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"απενεργοποίηση"</string> <string name="sound_settings" msgid="8874581353127418308">"Ήχος και δόνηση"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ρυθμίσεις"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Ζωντανοί υπότιτλοι"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Η ένταση ήχου μειώθηκε σε πιο ασφαλές επίπεδο"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Η ένταση ήχου των ακουστικών ήταν σε υψηλό επίπεδο για μεγαλύτερο διάστημα από αυτό που συνιστάται"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Η ένταση ήχου των ακουστικών ξεπέρασε το ασφαλές όριο για αυτή την εβδομάδα"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"στις <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"στις <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Σημείο πρόσβασης Wi-Fi"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Δορυφορική, δεν υπάρχει σύνδεση"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Δορυφορική, κακή σύνδεση"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Δορυφορική, καλή σύνδεση"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Δορυφορική, διαθέσιμη σύνδεση"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Προφίλ εργασίας"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Διασκέδαση για ορισμένους, αλλά όχι για όλους"</string> <string name="tuner_warning" msgid="1861736288458481650">"Το System UI Tuner σάς προσφέρει επιπλέον τρόπους για να τροποποιήσετε και να προσαρμόσετε τη διεπαφή χρήστη Android. Αυτές οι πειραματικές λειτουργίες ενδέχεται να τροποποιηθούν, να παρουσιάσουν σφάλματα ή να καταργηθούν σε μελλοντικές εκδόσεις. Συνεχίστε με προσοχή."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Άνοιγμα ρυθμίσεων"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Άνοιγμα Βοηθού"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Κλείδωμα οθόνης"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Άνοιγμα σημειώσεων"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Δημιουργία σημείωσης"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Πολυδιεργασία συστήματος"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Ενεργοποίηση διαχωρισμού οθόνης με την τρέχουσα εφαρμογή στα δεξιά"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Ενεργοποίηση διαχωρισμού οθόνης με την τρέχουσα εφαρμογή στα αριστερά"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index f2fcb035db77..40ad5af31440 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Issue Recorder"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processing issue recording"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Ongoing notification for an issue collection session"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Recording issue"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Share"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Issue recording saved"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Tap to view"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Error saving issue recording"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Error starting issue recording"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Viewing full screen"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"To exit, swipe down from the top."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Got it"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disable"</string> <string name="sound_settings" msgid="8874581353127418308">"Sound and vibration"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Settings"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume lowered to safer level"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Headphone volume has been high for longer than recommended"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Headphone volume has exceeded the safe limit for this week"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"at <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"on <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satellite, no connection"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Open settings"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Open Assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Lock screen"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Open notes"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Take a note"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System multitasking"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 863acb1e0c26..a51225a1b26f 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -268,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatically turn on again tomorrow"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Features like Quick Share, Find My Device, and device location use Bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -537,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disable"</string> <string name="sound_settings" msgid="8874581353127418308">"Sound and vibration"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Settings"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Live Caption"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume lowered to safer level"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Headphone volume has been high for longer than recommended"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Headphone volume has exceeded the safe limit for this week"</string> @@ -728,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Open settings"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Open assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Lock screen"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Open notes"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Take a note"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System multitasking"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index f2fcb035db77..40ad5af31440 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Issue Recorder"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processing issue recording"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Ongoing notification for an issue collection session"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Recording issue"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Share"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Issue recording saved"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Tap to view"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Error saving issue recording"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Error starting issue recording"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Viewing full screen"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"To exit, swipe down from the top."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Got it"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disable"</string> <string name="sound_settings" msgid="8874581353127418308">"Sound and vibration"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Settings"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume lowered to safer level"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Headphone volume has been high for longer than recommended"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Headphone volume has exceeded the safe limit for this week"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"at <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"on <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satellite, no connection"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Open settings"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Open Assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Lock screen"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Open notes"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Take a note"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System multitasking"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index f2fcb035db77..40ad5af31440 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Issue Recorder"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processing issue recording"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Ongoing notification for an issue collection session"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Recording issue"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Share"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Issue recording saved"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Tap to view"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Error saving issue recording"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Error starting issue recording"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Viewing full screen"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"To exit, swipe down from the top."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Got it"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disable"</string> <string name="sound_settings" msgid="8874581353127418308">"Sound and vibration"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Settings"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume lowered to safer level"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Headphone volume has been high for longer than recommended"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Headphone volume has exceeded the safe limit for this week"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"at <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"on <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satellite, no connection"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Open settings"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Open Assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Lock screen"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Open notes"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Take a note"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System multitasking"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 6dc6d3b27cf7..d98ef62cad85 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -268,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatically turn on again tomorrow"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Features like Quick Share, Find My Device, and device location use Bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -537,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disable"</string> <string name="sound_settings" msgid="8874581353127418308">"Sound & vibration"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Settings"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Live Caption"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume lowered to safer level"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Headphone volume has been high for longer than recommended"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Headphone volume has exceeded the safe limit for this week"</string> @@ -728,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Open settings"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Open assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Lock screen"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Open notes"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Take a note"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System multitasking"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index be60c7e30794..c3ade659938d 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Presiona para ver"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Se produjo un error al guardar la grabación de pantalla"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Error al iniciar la grabación de pantalla"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Grabadora de errores"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Procesando grabación del error"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificación continua por un error durante la sesión de recopilación de datos"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Error de grabación"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Compartir"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Se guardó la grabación del error"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Presiona para verla"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Se produjo un error al guardar la grabación del problema"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Se produjo un error al iniciar la grabación del problema"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Visualización en pantalla completa"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Para salir, desliza el dedo hacia abajo desde la parte superior."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Entendido"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activar"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Volver a activar automáticamente mañana"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Las funciones como Quick Share, Encontrar mi dispositivo y la ubicación del dispositivo usan Bluetooth."</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string> @@ -546,6 +539,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"inhabilitar"</string> <string name="sound_settings" msgid="8874581353127418308">"Sonido y vibración"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Configuración"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Se bajó el volumen a un nivel seguro"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"El volumen de los auriculares se mantuvo elevado por más tiempo del recomendado"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Se excedió el límite seguro de volumen de los auriculares para esta semana"</string> @@ -612,14 +607,10 @@ <string name="alarm_template" msgid="2234991538018805736">"a la(s) <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"el <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satélite, sin conexión"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, conexión inestable"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, buena conexión"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión disponible"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabajo"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Diversión para algunos, pero no para todos"</string> <string name="tuner_warning" msgid="1861736288458481650">"El sintonizador de IU del sistema te brinda más formas para editar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, dejar de funcionar o no incluirse en futuras versiones. Procede con precaución."</string> @@ -741,7 +732,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir configuración"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir Asistente"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Bloquear la pantalla"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir notas"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Crear una nota"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Tareas múltiples del sistema"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Activar pantalla dividida con la app actual en el lado derecho (RHS)"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Activar pantalla dividida con la app actual en el lado izquierdo (LHS)"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 2f8f1cf2a6dc..73dcea18ebc2 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Toca para verla"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"No se ha podido guardar la grabación de pantalla"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"No se ha podido empezar a grabar la pantalla"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Grabadora de problemas"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Procesando grabación de problema"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificación continua de una sesión de obtención de datos del problema"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Grabando problema"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Compartir"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Grabación del problema guardada"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Toca para ver"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"No se ha podido guardar la grabación del problema"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"No se ha podido iniciar la grabación del problema"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Visualización en pantalla completa"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Para salir, desliza de arriba abajo."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Entendido"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activar"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Volver a activar automáticamente mañana"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funciones como Quick Share, Encontrar mi dispositivo y la ubicación del dispositivo usan Bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desactivar"</string> <string name="sound_settings" msgid="8874581353127418308">"Sonido y vibración"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ajustes"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Subtítulos automáticos"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volumen bajado a un nivel más seguro"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"El volumen de los auriculares ha estado alto durante más tiempo del recomendado"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"El volumen de los auriculares ha superado el límite de seguridad de esta semana"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"a las <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Compartir Internet"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satélite, sin conexión"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, mala conexión"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, buena conexión"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión disponible"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabajo"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Diversión solo para algunos"</string> <string name="tuner_warning" msgid="1861736288458481650">"El configurador de UI del sistema te ofrece otras formas de modificar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir ajustes"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir el Asistente"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Pantalla de bloqueo"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir notas"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Escribe una nota"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Función multitarea del sistema"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Iniciar pantalla dividida con esta aplicación en el lado derecho"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Iniciar pantalla dividida con esta aplicación en el lado izquierdo"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 9aa753cc37ca..0e1e690b2733 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Puudutage kuvamiseks"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Viga ekraanisalvestise salvestamisel"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Viga ekraanikuva salvestamise alustamisel"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Probleemisalvesti"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Probleemisalvestise töötlemine"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Probleemikogumise seansi taustamärguanne"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Probleemi salvestamine"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Jaga"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Probleemisalvestis on salvestatud"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Kuvamiseks puudutage"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Viga probleemisalvestise salvestamisel"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Viga probleemi salvestamise alustamisel"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Kuvamine täisekraanil"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Väljumiseks pühkige ülevalt alla."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Selge"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvestatud"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"katkesta ühendus"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiveeri"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> akut"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Heli"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Peakomplekt"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"keela"</string> <string name="sound_settings" msgid="8874581353127418308">"Heli ja vibreerimine"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Seaded"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Reaalajas subtiitrid"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Helitugevust vähendati ohutumale tasemele"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Kõrvaklappide helitugevus on olnud suur soovitatavast ajast kauem"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Kõrvaklappide helitugevus on ületanud selle nädala ohutuspiirangu"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"kell <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"kell <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Kuumkoht"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelliit, ühendus puudub"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliit, kehv ühendus"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliit, hea ühendus"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliit, ühendus on saadaval"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Tööprofiil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Kõik ei pruugi sellest rõõmu tunda"</string> <string name="tuner_warning" msgid="1861736288458481650">"Süsteemi kasutajaliidese tuuner pakub täiendavaid võimalusi Androidi kasutajaliidese muutmiseks ja kohandamiseks. Need katselised funktsioonid võivad muutuda, rikki minna või tulevastest versioonidest kaduda. Olge jätkamisel ettevaatlik."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Seadete avamine"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistendi avamine"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Lukustuskuva"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Märkmete avamine"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Kirjuta märkus"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Süsteemi multitegumtöö"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Ekraanikuva jagamine, nii et praegune rakendus on paremal"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Ekraanikuva jagamine, nii et praegune rakendus on vasakul"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 0c1880a717ce..f6a4f395c055 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Sakatu ikusteko"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Errore bat gertatu da pantaila-grabaketa gordetzean"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Errore bat gertatu da pantaila grabatzen hastean"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Arazo-grabagailua"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Arazoaren grabaketa prozesatzen"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Arazo bat biltzeko saio baten aktibo dagoen jakinarazpena"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Arazoa grabatzen"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Partekatu"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Gorde da arazoaren grabaketa"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Sakatu ikusteko"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Errore bat gertatu da arazoa grabatzean"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Errore bat gertatu da arazoa grabatzen hastean"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Pantaila osoa ikusgai"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Irteteko, pasatu hatza goitik behera."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Ados"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gordeta"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"deskonektatu"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktibatu"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audioa"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Entzungailua"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desgaitu"</string> <string name="sound_settings" msgid="8874581353127418308">"Audioa eta dardara"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ezarpenak"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Bolumena maila seguruago batera jaitsi da"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Entzungailuen bolumena gomendatutako denbora baino luzaroago egon da ozen"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Entzungailuen bolumenak aste honetarako muga segurua gainditu du"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"ordua: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"data: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Wifi-gunea"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelitea, konexiorik ez"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelitea, konexio ahula"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelitea, konexio ona"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelitea, konexioa erabilgarri"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Laneko profila"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Dibertsioa batzuentzat, baina ez guztientzat"</string> <string name="tuner_warning" msgid="1861736288458481650">"Sistemaren erabiltzaile-interfazearen konfiguratzaileak Android erabiltzaile-interfazea moldatzeko eta pertsonalizatzeko modu gehiago eskaintzen dizkizu. Baliteke eginbide esperimental horiek hurrengo kaleratzeetan aldatuta, etenda edo desagertuta egotea. Kontuz erabili."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ireki ezarpenak"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Ireki Laguntzailea"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Blokeatu pantaila"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Ireki oharrak"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Egin ohar bat"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Zereginen aldibereko sistemaren exekuzioa"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Sartu pantaila zatituaren eskuineko aldean oraingo aplikazioarekin"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Sartu pantaila zatituaren ezkerreko aldean oraingo aplikazioarekin"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index c0dafa40319d..7a29b27ca705 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"برای مشاهده ضربه بزنید"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"خطا در ذخیرهسازی ضبط صفحهنمایش"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"خطا هنگام شروع ضبط صفحهنمایش"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"ضبطکننده مشکل"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"درحال پردازش کردن ضبط مشکل"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"اعلان جاری مربوط به جلسه جمعآوری مشکل"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"درحال ضبط کردن مشکل"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"همرسانی"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"ضبط مشکل ذخیره شد"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"برای مشاهده ضربه بزنید"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"هنگام ذخیره کردن ضبط مشکل، خطایی پیش آمد"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"هنگام شروع ضبط مشکل، خطایی پیش آمد"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"درحال مشاهده در حالت تمامصفحه"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"برای خروج، از بالای صفحه تند بهپایین بکشید."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"متوجهام"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ذخیرهشده"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"قطع اتصال"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"فعال کردن"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"شارژ باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"صوت"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"هدست"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"غیرفعال کردن"</string> <string name="sound_settings" msgid="8874581353127418308">"صدا و لرزش"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"تنظیمات"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"زیرنویس ناشنوایان زنده"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"صدا به سطح ایمنتر کاهش یافت"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"صدای هدفون برای مدتی طولانیتر از حد توصیهشده بلند بوده است"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"صدای هدفون از حد ایمن برای این هفته فراتر رفته است"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"در <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"در <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"نقطه اتصال"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"ماهواره، اتصال وجود ندارد"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ماهواره، اتصال ضعیف است"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ماهواره، اتصال خوب است"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ماهواره، اتصال دردسترس است"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"نمایه کاری"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"برای بعضی افراد سرگرمکننده است اما نه برای همه"</string> <string name="tuner_warning" msgid="1861736288458481650">"«تنظیمکننده واسط کاربری سیستم» روشهای بیشتری برای تنظیم دقیق و سفارشی کردن واسط کاربری Android در اختیار شما قرار میدهد. ممکن است این ویژگیهای آزمایشی تغییر کنند، خراب شوند یا در نسخههای آینده جود نداشته باشند. با احتیاط ادامه دهید."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"باز کردن تنظیمات"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"باز کردن «دستیار»"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"قفل صفحه"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"باز کردن یادداشتها"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"یادداشتبرداری"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"چندوظیفگی سیستم"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"وارد شدن به صفحهٔ دونیمه با برنامه فعلی در سمت راست"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"وارد شدن به صفحهٔ دونیمه با برنامه فعلی در سمت چپ"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 4b45aabfbf93..8f85edfd309b 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Napauta näyttääksesi"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Virhe näyttötallenteen tallentamisessa"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Virhe näytön tallennuksen aloituksessa"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Ongelman tallentaja"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Käsittely: Ongelman tallennus"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Ongelmankeräykseen liittyvä ilmoitus taustalla jatkuvasta toiminnasta"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Tallennusongelma"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Jaa"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Ongelman tallennus tallennettiin"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Näytä napauttamalla"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Virhe ongelman tallenteen tallentamisessa"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Virhe ongelman tallentamisen aloituksessa"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Koko näytön tilassa"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Sulje palkki pyyhkäisemällä alas ruudun ylälaidasta."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Selvä"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Tallennettu"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"katkaise yhteys"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivoi"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ääni"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"poista käytöstä"</string> <string name="sound_settings" msgid="8874581353127418308">"Ääni ja värinä"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Asetukset"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Äänenvoimakkuus laskettu turvalliselle tasolle"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Äänenvoimakkuus on ollut suuri suositeltua kauemmin"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Kuulokkeiden äänenvoimakkuus on ylittänyt tämän viikon turvarajan"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"kello <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"ajankohtana <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelliitti, ei yhteyttä"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliitti, huono yhteys"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliitti, hyvä yhteys"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliitti, yhteys saatavilla"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Työprofiili"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Ei sovellu kaikkien käyttöön"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner antaa lisämahdollisuuksia Android-käyttöliittymän muokkaamiseen. Nämä kokeelliset ominaisuudet voivat muuttua, lakata toimimasta tai kadota milloin tahansa. Jatka omalla vastuullasi."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Avaa asetukset"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Avaa Assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Lukitusnäyttö"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Avaa muistiinpanot"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Tee muistiinpano"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Järjestelmän monikäyttö"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Siirry jaettuun näyttöön (sovellus oikeanpuoleiseen näyttöön)"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Siirry jaettuun näyttöön (sovellus vasemmanpuoleiseen näyttöön)"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 8d0e2774632b..e95955589a22 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Touchez pour afficher"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Erreur d\'enregistrement de l\'écran"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Une erreur s\'est produite lors du démarrage de l\'enregistrement d\'écran"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Enregistreur de problèmes"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Trait. de l\'enreg. du problème"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notification continue pour une session de collecte d\'un problème"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Enregistrement du problème"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Partager"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"L\'enregistrement du problème a été enregistré"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Touchez ici pour afficher l\'enregistrement"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Erreur lors de l\'enregistrement du problème"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Erreur lors du démarrage de l\'enregistrement du problème"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Affichage plein écran"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Pour quitter, balayez du haut vers le bas."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Enregistré"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"Déconnecter"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"Activer"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Écouteurs"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"désactiver"</string> <string name="sound_settings" msgid="8874581353127418308">"Son et vibration"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Paramètres"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume réduit à un niveau plus sécuritaire"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Le niveau du volume des écouteurs est resté élevé au-delà de la durée recommandée"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Le niveau du volume des écouteurs a dépassé la limite de sécurité pour cette semaine"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"à <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"le <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Point d\'accès sans fil"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Aucune connexion satellite"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Connexion satellite faible"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Bonne connexion satellite"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Connexion satellite accessible"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil professionnel"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Divertissant pour certains, mais pas pour tous"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner vous propose de nouvelles manières d\'adapter et de personnaliser l\'interface utilisateur d\'Android. Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou disparaître dans les versions futures. À utiliser avec prudence."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ouvrir les paramètres"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Ouvrir l\'Assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Écran de verrouillage"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Ouvrir les notes"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Prendre une note"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitâche du système"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Passer à l\'écran divisé avec l\'application actuelle à droite"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Passer à l\'écran divisé avec l\'application actuelle à gauche"</string> @@ -1242,7 +1235,7 @@ <string name="assistant_attention_content_description" msgid="4166330881435263596">"La présence d\'un utilisateur est détectée"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir l\'application de prise de notes par défaut dans les Paramètres"</string> <string name="install_app" msgid="5066668100199613936">"Installer l\'application"</string> - <string name="dismissible_keyguard_swipe" msgid="8377597870094949432">"Balayez vers le haut pour continuer"</string> + <string name="dismissible_keyguard_swipe" msgid="8377597870094949432">"Balayer vers le haut pour continuer"</string> <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Dupliquer l\'écran sur un moniteur externe?"</string> <string name="connected_display_dialog_dual_display_stop_warning" msgid="4174707498892447947">"Votre écran intérieur sera dupliqué. Votre écran frontal sera désactivé."</string> <string name="mirror_display" msgid="2515262008898122928">"Dupliquer l\'écran"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 49e6d08feaab..a04f6e8800ee 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Appuyez pour afficher"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Erreur lors de l\'enregistrement de l\'écran"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Erreur lors du démarrage de l\'enregistrement de l\'écran"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Enregistreur de problèmes"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Enregistrement du problème"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notification d\'activité en cours concernant la session d\'enregistrement d\'un problème"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Problème d\'enregistrement"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Partager"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Problème enregistré"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Appuyez pour afficher"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Erreur lors de l\'enregistrement du problème"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Erreur lors du démarrage de l\'enregistrement du problème"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Affichage en plein écran"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Pour quitter, balayez l\'écran du haut vers le bas."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Enregistré"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"dissocier"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activer"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Réactiver automatiquement demain"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Certaines fonctionnalités telles que Quick Share, Localiser mon appareil ou encore la position de l\'appareil utilisent le Bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batterie"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Casque"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"désactiver"</string> <string name="sound_settings" msgid="8874581353127418308">"Son et vibreur"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Paramètres"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Sous-titres instantanés"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume réduit à un niveau plus sûr"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Le volume du casque est élevé depuis plus longtemps que recommandé"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Le volume du casque a dépassé la limite de sécurité pour cette semaine"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"à <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"le <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Point d\'accès"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Pas de connexion satellite"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Mauvaise connexion satellite"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Bonne connexion satellite"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Connexion satellite disponible"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil professionnel"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Divertissant pour certains, mais pas pour tous"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner vous propose de nouvelles manières d\'adapter et de personnaliser l\'interface utilisateur Android. Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou disparaître dans les versions futures. À utiliser avec prudence."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ouvrir les paramètres"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Ouvrir l\'Assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Verrouiller l\'écran"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Ouvrir les notes"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Créer une note"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitâche du système"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Passer en écran partagé avec l\'appli actuelle affichée à droite"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Passer en écran partagé avec l\'appli actuelle affichée à gauche"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index a03adbf97837..2adb759cc555 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Toca para ver o contido"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Produciuse un erro ao gardar a gravación da pantalla"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Produciuse un erro ao iniciar a gravación da pantalla"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Gravadora de problemas"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Procesando gravación problema"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificación de actividade en curso para unha sesión de rexistro dun problema"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Gravando problema"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Compartir"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Gardouse a gravación do problema"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Toca para ver o contido"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Produciuse un erro ao gardar a gravación do problema"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Produciuse un erro ao iniciar a gravación do problema"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Vendo pantalla completa"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Para saír, pasa o dedo cara abaixo desde a parte superior."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Entendido"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gardouse"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activar"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desactiva"</string> <string name="sound_settings" msgid="8874581353127418308">"Son e vibración"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Configuración"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"O volume baixouse ata un nivel máis seguro"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Usaches os auriculares cun volume alto durante máis tempo do recomendado"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"O volume dos auriculares superou o límite de seguranza desta semana"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"ás <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"o <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Zona wifi"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satélite, sen conexión"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, mala conexión"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, boa conexión"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión dispoñible"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de traballo"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Diversión só para algúns"</string> <string name="tuner_warning" msgid="1861736288458481650">"O configurador da IU do sistema ofréceche formas adicionais de modificar e personalizar a interface de usuario de Android. Estas funcións experimentais poden cambiar, interromperse ou desaparecer en futuras versións. Continúa con precaución."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir configuración"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir Asistente"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Pantalla de bloqueo"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir notas"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Crear nota"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitarefa do sistema"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Activar pantalla dividida con esta aplicación no lado dereito"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Activar pantalla dividida con esta aplicación no lado esquerdo"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index a74ad24f0164..e61a5b52beb9 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"જોવા માટે ટૅપ કરો"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"સ્ક્રીન રેકોર્ડિંગ સાચવવામાં ભૂલ આવી"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"સ્ક્રીનને રેકૉર્ડ કરવાનું શરૂ કરવામાં ભૂલ"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"સમસ્યા રેકોર્ડર"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"સમસ્યા રેકોર્ડિંગ ચાલુ છે"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"કોઈ સમસ્યા સંગ્રહના સત્ર માટે ચાલુ નોટિફિકેશન"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"રેકોર્ડિંગની સમસ્યા"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"શેર કરો"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"સમસ્યા રેકોર્ડિંગ સાચવવામાં આવ્યું"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"જોવા માટે ટૅપ કરો"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"સમસ્યા રેકોર્ડિંગને સાચવવામાં ભૂલ આવી"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"સમસ્યા રેકોર્ડિંગને શરૂ કરવામાં ભૂલ આવી"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"પૂર્ણ સ્ક્રીન જોઈ રહ્યાં છે"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"બહાર નીકળવા માટે, સૌથી ઉપરથી નીચેની તરફ સ્વાઇપ કરો."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"સમજાઈ ગયું"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"સાચવેલું"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ડિસ્કનેક્ટ કરો"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"સક્રિય કરો"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> બૅટરી"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ઑડિયો"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"હૅડસેટ"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"બંધ કરો"</string> <string name="sound_settings" msgid="8874581353127418308">"સાઉન્ડ અને વાઇબ્રેશન"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"સેટિંગ"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"વૉલ્યૂમને વધુ સલામત લેવલ સુધી ઘટાડ્યું"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"હૅડફોનનું વૉલ્યૂમ સુઝાવ આપેલા સમય કરતાં વધારે સમય સુધી ઊંચા વૉલ્યૂમ પર રહ્યું છે"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"હૅડફોનનું વૉલ્યૂમ આ અઠવાડિયા માટેની સુરક્ષિત મર્યાદા કરતાં વધારે છે"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> વાગ્યે"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> એ"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"હૉટસ્પૉટ"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"સૅટલાઇટ, કોઈ કનેક્શન નથી"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"સૅટલાઇટ, નબળું કનેક્શન"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"સૅટલાઇટ, સારું કનેક્શન"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"સૅટલાઇટ, કનેક્શન ઉપલબ્ધ છે"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"ઑફિસની પ્રોફાઇલ"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"કેટલાક માટે મજા પરંતુ બધા માટે નહીં"</string> <string name="tuner_warning" msgid="1861736288458481650">"સિસ્ટમ UI ટ્યૂનર તમને Android વપરાશકર્તા ઇન્ટરફેસને ટ્વીક અને કસ્ટમાઇઝ કરવાની વધારાની રીતો આપે છે. ભાવિ રીલિઝેસમાં આ પ્રાયોગિક સુવિધાઓ બદલાઈ, ભંગ અથવા અદૃશ્ય થઈ શકે છે. સાવધાની સાથે આગળ વધો."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"સેટિંગ ખોલો"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant ખોલો"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"લૉક સ્ક્રીન"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"નોંધ ખોલો"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"નોંધ લો"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"સિસ્ટમ દ્વારા એકથી વધુ કાર્યો કરવા"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"જમણી બાજુ પર હાલની ઍપ સાથે વિભાજિત સ્ક્રીનમાં દાખલ થાઓ"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"ડાબી બાજુ પર હાલની ઍપ સાથે વિભાજિત સ્ક્રીનમાં દાખલ થાઓ"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 372d83d4769a..cf029e0bc64d 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"देखने के लिए टैप करें"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रीन रिकॉर्डिंग सेव करते समय गड़बड़ी हुई"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन को रिकॉर्ड करने में गड़बड़ी आ रही है"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"समस्या का डेटा सेव करने वाला टूल"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"समस्या का डेटा प्रोसेस हो रहा"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"समस्या का डेटा इकट्ठा करने के लिए बैकग्राउंड में जारी गतिविधि की सूचना"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"समस्या का डेटा इकट्ठा किया जा रहा है"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"शेयर करें"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"समस्या का डेटा सेव किया गया"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"देखने के लिए टैप करें"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"समस्या का डेटा सेव करते समय गड़बड़ी हुई"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"समस्या का डेटा सेव करने की प्रोसेस शुरू करते समय गड़बड़ी हुई"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"फ़ुल स्क्रीन मोड पर देखा जा रहा है"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"बाहर निकलने के लिए, सबसे ऊपर से नीचे की ओर स्वाइप करें."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"ठीक है"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेव किया गया"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"डिसकनेक्ट करें"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"चालू करें"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> बैटरी"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ऑडियो"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"बंद करें"</string> <string name="sound_settings" msgid="8874581353127418308">"आवाज़ और वाइब्रेशन"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"सेटिंग"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"आवाज़ को कम करके, सुरक्षित लेवल पर सेट कर दिया गया है"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"हेडफ़ोन की आवाज़ सुझाए गए समय से देर तक ज़्यादा रही"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"इस हफ़्ते के लिए हेडफ़ोन की आवाज़, सुझाई गई सीमा से ज़्यादा हो गई है"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> बजे"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> पर"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"हॉटस्पॉट"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"सैटलाइट कनेक्शन उपलब्ध नहीं है"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"सैटलाइट कनेक्शन खराब है"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"सैटलाइट कनेक्शन अच्छा है"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"सैटलाइट कनेक्शन उपलब्ध है"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"वर्क प्रोफ़ाइल"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"कुछ के लिए मज़ेदार लेकिन सबके लिए नहीं"</string> <string name="tuner_warning" msgid="1861736288458481650">"सिस्टम यूज़र इंटरफ़ेस (यूआई) ट्यूनर, आपको Android यूज़र इंटरफ़ेस में सुधार लाने और उसे अपनी पसंद के हिसाब से बदलने के कुछ और तरीके देता है. प्रयोग के तौर पर इस्तेमाल हो रहीं ये सुविधाएं आगे चल कर रिलीज़ की जा सकती हैं, रोकी जा सकती हैं या दिखाई देना बंद हो सकती हैं. सावधानी से आगे बढ़ें."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"सेटिंग खोलें"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Google Assistant खोलें"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"लॉक स्क्रीन"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Notes ऐप्लिकेशन खोलें"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"नोट करें"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"सिस्टम मल्टीटास्किंग"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"स्प्लिट स्क्रीन का इस्तेमाल करके, मौजूदा ऐप्लिकेशन को दाईं ओर ले जाएं"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"स्प्लिट स्क्रीन का इस्तेमाल करके, मौजूदा ऐप्लिकेशन को बाईं ओर ले जाएं"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 196cddb0c896..3dc70879f4a4 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite za prikaz"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Pogreška prilikom spremanja snimke zaslona"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Pogreška prilikom pokretanja snimanja zaslona"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Snimač poteškoća"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Obrada snimke poteškoće"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Obavijest o aktivnosti u pozadini za sesiju prikupljanja poteškoća"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Snimanje poteškoće"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Dijeljenje"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Snimka poteškoće spremljena"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Dodirnite za prikaz"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Pogreška pri spremanju snimke poteškoće"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Pogreška pri pokretanju snimke poteškoće"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Gledanje preko cijelog zaslona"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Za izlaz prijeđite prstom od vrha prema dolje."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Shvaćam"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Spremljeno"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekini vezu"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviraj"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"onemogući"</string> <string name="sound_settings" msgid="8874581353127418308">"Zvuk i vibracija"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Postavke"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Automatski titlovi"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Glasnoća je stišana na sigurniju razinu"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Glasnoća u slušalicama pojačana je dulje nego što se preporučuje"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Glasnoća slušalica premašila je sigurno ograničenje za ovaj tjedan"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Žarišna točka"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelit, nije uspostavljena veza"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slaba veza"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra veza"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Poslovni profil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string> <string name="tuner_warning" msgid="1861736288458481650">"Ugađanje korisničkog sučelja sustava pruža vam dodatne načine za prilagodbu korisničkog sučelja Androida. Te se eksperimentalne značajke mogu promijeniti, prekinuti ili nestati u budućim izdanjima. Nastavite uz oprez."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvori postavke"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvori Asistenta"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaključavanje zaslona"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Otvori bilješke"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Zapišite bilješku"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Obavljanje više zadataka sustava"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Otvori podijeljeni zaslon s trenutačnom aplikacijom s desne strane"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Otvori podijeljeni zaslon s trenutačnom aplikacijom s lijeve strane"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 47f740eeddaf..9b37701f6d84 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Koppintson a megtekintéshez"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Hiba történt a képernyőrögzítés mentése során"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Hiba a képernyőrögzítés indításakor"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Problémafelvevő"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Problémafelvétel feldolgozása…"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Folyamatban lévő értesítés egy problémagyűjtési munkamenethez"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Problémafelvétel folyamatban…"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Megosztás"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Problémafelvétel mentve"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Koppintson a megtekintéshez"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Hiba történt a problémafelvétel mentésekor"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Hiba történt a problémafelvétel elindításakor"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Megtekintése teljes képernyőn"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Kilépéshez csúsztassa ujját fentről lefelé."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Értem"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Mentve"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"leválasztás"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiválás"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Hang"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"letiltás"</string> <string name="sound_settings" msgid="8874581353127418308">"Hang és rezgés"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Beállítások"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Élő feliratozás"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Hangerő biztonságos szintre csökkentve"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"A fejhallgató hangereje az ajánlottnál hosszabb ideig volt nagy"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"A fejhallgató hangereje túllépte a biztonságos határt a hétre vonatkozóan"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"ekkor: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"ezen a napon: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Műhold, nincs kapcsolat"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Műhold, gyenge kapcsolat"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Műhold, jó kapcsolat"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Műhold, van rendelkezésre álló kapcsolat"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Munkaprofil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Egyeseknek tetszik, másoknak nem"</string> <string name="tuner_warning" msgid="1861736288458481650">"A Kezelőfelület-hangoló az Android felhasználói felületének szerkesztéséhez és testreszabásához nyújt további megoldásokat. Ezek a kísérleti funkciók változhatnak vagy megsérülhetnek a későbbi kiadásokban, illetve eltűnhetnek azokból. Körültekintően járjon el."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Beállítások megnyitása"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"A Segéd megnyitása"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Lezárási képernyő"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Jegyzetek megnyitása"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Jegyzetelés"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Rendszermultitasking"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Osztott képernyő aktiválása; az aktuális alkalmazás kerüljön jobbra"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Osztott képernyő aktiválása; az aktuális alkalmazás kerüljön balra"</string> @@ -1242,7 +1234,7 @@ <string name="assistant_attention_content_description" msgid="4166330881435263596">"Felhasználói jelenlét észlelve"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Állítson be alapértelmezett jegyzetkészítő alkalmazást a Beállításokban"</string> <string name="install_app" msgid="5066668100199613936">"Alkalmazás telepítése"</string> - <string name="dismissible_keyguard_swipe" msgid="8377597870094949432">"A folytatáshoz csúsztassa gyorsan fel az ujját"</string> + <string name="dismissible_keyguard_swipe" msgid="8377597870094949432">"A folytatáshoz csúsztassa felfelé az ujját"</string> <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Tükrözi a kijelzőt a külső képernyőre?"</string> <string name="connected_display_dialog_dual_display_stop_warning" msgid="4174707498892447947">"A belső kijelző tükrözve lesz. Az elülső kijelző ki lesz kapcsolva."</string> <string name="mirror_display" msgid="2515262008898122928">"Kijelző tükrözése"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index f8f30cd1ea45..db2b3ce6ca05 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Հպեք՝ դիտելու համար"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Չհաջողվեց պահել էկրանի տեսագրությունը"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Չհաջողվեց սկսել տեսագրումը"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Խնդիրների տեսագրիչ"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Մշակում ենք տեսագրությունը"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Խնդրի տեսագրման մասին ընթացիկ ծանուցում"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Տեսագրում ենք խնդիրը"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Կիսվել"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Տեսագրությունը պահվեց"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Հպեք՝ դիտելու համար"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Չհաջողվեց պահել տեսագրությունը"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Չհաջողվեց սկսել տեսագրումը"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Լիաէկրան դիտակերպ"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Դուրս գալու համար վերևից մատը սահեցրեք դեպի ներքև։"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Եղավ"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Պահված է"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"անջատել"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ակտիվացնել"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Աուդիո"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ականջակալ"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"անջատել"</string> <string name="sound_settings" msgid="8874581353127418308">"Ձայն և թրթռոց"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Կարգավորումներ"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Ձայնն իջեցվեց անվտանգ մակարդակի"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Ձայնը բարձր է եղել առաջարկված ժամանակահատվածից ավելի երկար"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Ականջակալների ձայնի ուժգնությունը այս շաբաթ գերազանցել է անվտանգ մակարդակի շեմը"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>-ին"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>-ին"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Թեժ կետ"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Արբանյակային կապ չկա"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Արբանյակային թույլ կապ"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Արբանյակային լավ կապ"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Հասանելի է արբանյակային կապ"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Աշխատանքային պրոֆիլ"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Զվարճանք մեկ՝ որոշակի մարդու համար"</string> <string name="tuner_warning" msgid="1861736288458481650">"Համակարգի ՕՄ-ի կարգավորիչը հնարավորություն է տալիս հարմարեցնել Android-ի օգտատիրոջ միջերեսը: Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Բացել կարգավորումները"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Բացել Օգնականը"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Կողպէկրան"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Բացել նշումները"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Ստեղծել նշում"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Համակարգի բազմախնդրության ռեժիմ"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Միացնել էկրանի տրոհումը՝ ընթացիկ հավելվածն աջ կողմում"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Միացնել էկրանի տրոհումը՝ ընթացիկ հավելվածը ձախ կողմում"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 8fca71fb6f1d..44f9bfc3705b 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Ketuk untuk melihat"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Terjadi error saat menyimpan rekaman layar"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Terjadi error saat memulai perekaman layar"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Perekam Masalah"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Memproses rekaman masalah"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notifikasi berkelanjutan untuk sesi pengumpulan masalah"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Merekam masalah"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Bagikan"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Rekaman masalah disimpan"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Ketuk untuk melihat"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Terjadi error saat menyimpan rekaman masalah"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Terjadi error saat memulai perekaman masalah"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Melihat layar penuh"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Untuk keluar, geser layar ke bawah dari atas."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Oke"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Disimpan"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"putuskan koneksi"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktifkan"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"nonaktifkan"</string> <string name="sound_settings" msgid="8874581353127418308">"Suara & getaran"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Setelan"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume diturunkan ke level yang lebih aman"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volume headphone tinggi untuk waktu lebih lama dari yang direkomendasikan"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volume headphone telah melampaui batas aman untuk minggu ini"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"pukul <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"pada <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelit, tidak ada koneksi"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, koneksi buruk"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, koneksi baik"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, koneksi tersedia"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil kerja"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Tidak semua orang menganggapnya baik"</string> <string name="tuner_warning" msgid="1861736288458481650">"Penyetel Antarmuka Pengguna Sistem memberikan cara tambahan untuk mengubah dan menyesuaikan antarmuka pengguna Android. Fitur eksperimental ini dapat berubah, rusak, atau menghilang dalam rilis di masa mendatang. Lanjutkan dengan hati-hati."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Buka setelan"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Buka Asisten"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Kunci layar"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Buka catatan"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Buat catatan"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking sistem"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Masuk ke layar terpisah dengan aplikasi saat ini ke RHS"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Masuk ke layar terpisah dengan aplikasi saat ini ke LHS"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 7cec52355331..8cfe4e834304 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Ýttu til að skoða"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Villa við að vista skjáupptöku"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Villa við að hefja upptöku skjás"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Upptökutæki fyrir vandamál"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Vinnur úr upptöku af vandamáli"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Áframhaldandi tilkynning fyrir lotu vandamálasafns"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Tekur upp vandamál"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Deila"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Upptaka af vandamáli var vistuð"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Ýttu til að skoða"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Villa kom upp við að vista upptöku af vandamáli"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Villa kom upp við að hefja upptöku af vandamáli"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Notar allan skjáinn"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Strjúktu niður frá efsta hluta skjásins til að hætta."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Ég skil"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Vistað"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"aftengja"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"virkja"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> rafhlöðuhleðsla"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Hljóð"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Höfuðtól"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"slökkva"</string> <string name="sound_settings" msgid="8874581353127418308">"Hljóð og titringur"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Stillingar"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Hljóð lækkað í öruggari hljóðstyrk"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Hljóðstyrkur í heyrnartólum hefur verið hár í lengri tíma en mælt er með"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Hljóðstyrkur í heyrnartólum hefur náð öryggismörkum fyrir þessa viku"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Heitur reitur"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Gervihnöttur, engin tenging"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Gervihnöttur, léleg tenging"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Gervihnöttur, góð tenging"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Gervihnöttur, tenging tiltæk"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Vinnusnið"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Þetta er ekki allra"</string> <string name="tuner_warning" msgid="1861736288458481650">"Fínstillingar kerfisviðmóts gera þér kleift að fínstilla og sérsníða notendaviðmót Android. Þessir tilraunaeiginleikar geta breyst, bilað eða horfið í síðari útgáfum. Gakktu því hægt um gleðinnar dyr."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Opna stillingar"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Opna Hjálpara"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Lásskjár"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Opna glósur"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Skrifa glósu"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Fjölvinnsla kerfis"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Opna skjáskiptingu hægra megin með núverandi forriti"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Opna skjáskiptingu vinstra megin með núverandi forriti"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index f95ce26c9a93..268925f629ad 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Tocca per visualizzare"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Errore durante il salvataggio della registrazione dello schermo"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Errore durante l\'avvio della registrazione dello schermo"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Registratore dei problemi"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Elaborazione registrazione…"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notifica continua per una sessione di raccolta di problemi"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Problema con la registrazione"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Condividi"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Registrazione del problema salvata"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Tocca per visualizzare"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Impossibile salvare la registrazione del problema"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Impossibile avviare la registrazione del problema"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Visualizzazione a schermo intero"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Per uscire, scorri dall\'alto verso il basso."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Dispositivo salvato"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnetti"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"attiva"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auricolare"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disattiva"</string> <string name="sound_settings" msgid="8874581353127418308">"Suoni e vibrazione"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Impostazioni"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Sottotitoli in tempo reale"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume abbassato a un livello più sicuro"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Il volume delle cuffie è rimasto alto per un periodo superiore a quello consigliato"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Il volume delle cuffie ha superato il limite di sicurezza per questa settimana"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"alle <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satellitare, nessuna connessione"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellitare, connessione debole"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellitare, connessione buona"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellitare, connessione disponibile"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profilo di lavoro"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Il divertimento riservato a pochi eletti"</string> <string name="tuner_warning" msgid="1861736288458481650">"L\'Ottimizzatore UI di sistema mette a disposizione altri metodi per modificare e personalizzare l\'interfaccia utente di Android. Queste funzioni sperimentali potrebbero cambiare, interrompersi o scomparire nelle versioni successive. Procedi con cautela."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Apri impostazioni"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Apri l\'assistente"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Blocca lo schermo"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Apri note"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Scrivi una nota"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking di sistema"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Attiva lo schermo diviso con l\'app corrente a destra"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Attiva lo schermo diviso con l\'app corrente a sinistra"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index bad575c17677..2b8e153402b9 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"יש להקיש כדי להציג"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"שגיאה בשמירה של הקלטת המסך"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"שגיאה בהפעלה של הקלטת המסך"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"בעיה במכשיר ההקלטה"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"מתבצע עיבוד של בעיית ההקלטה"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"התראה מתמשכת לסשן איסוף הבעיה"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"בעיית הקלטה"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"שיתוף"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"בעיית ההקלטה נשמרה"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"אפשר להקיש כדי להציג"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"שגיאה בשמירה של בעיית ההקלטה"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"שגיאה בהפעלה של בעיית ההקלטה"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"צפייה במסך מלא"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"כדי לצאת, מחליקים למטה מהחלק העליון של המסך."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"הבנתי"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"נשמר"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ניתוק"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"הפעלה"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> סוללה"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"אודיו"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"אוזניות"</string> @@ -299,7 +294,7 @@ <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"אין רשתות זמינות"</string> <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"אין רשתות Wi-Fi זמינות"</string> <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"בתהליך הפעלה…"</string> - <string name="quick_settings_cast_title" msgid="2279220930629235211">"העברת מסך"</string> + <string name="quick_settings_cast_title" msgid="2279220930629235211">"הפעלת Cast למסך"</string> <string name="quick_settings_casting" msgid="1435880708719268055">"מתבצעת העברה (cast)"</string> <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"מכשיר ללא שם"</string> <string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"אין מכשירים זמינים"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"השבתה"</string> <string name="sound_settings" msgid="8874581353127418308">"צליל ורטט"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"הגדרות"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"עוצמת הקול הוחלשה לרמה בטוחה יותר"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"עוצמת הקול של האוזניות הייתה גבוהה במשך יותר זמן מהמומלץ"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"עוצמת הקול של האוזניות חרגה ממגבלת הבטיחות לשבוע הזה"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"בשעה <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"ב-<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"נקודת אינטרנט (hotspot)"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"לוויין, אין חיבור"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"לוויין, חיבור באיכות ירודה"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"לוויין, חיבור באיכות טובה"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"לוויין, יש חיבור זמין"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"פרופיל עבודה"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"מהנה בשביל חלק מהאנשים, אבל לא בשביל כולם"</string> <string name="tuner_warning" msgid="1861736288458481650">"התכונה System UI Tuner מספקת לך דרכים נוספות להתאים אישית את ממשק המשתמש של Android. התכונות הניסיוניות האלה עשויות להשתנות, לא לעבוד כראוי או להיעלם בגרסאות עתידיות. יש להמשיך בזהירות."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"פתיחת ההגדרות"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"לפתיחת Google Assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"מסך הנעילה"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"פתיחה של אפליקציית הפתקים"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"כתיבת הערה"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ריבוי משימות מערכת"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"כניסה למסך מפוצל עם האפליקציה הנוכחית ל-RHS"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"כניסה למסך מפוצל עם האפליקציה הנוכחית ל-LHS"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 89ca0761ed93..5b42737d2ab5 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -268,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"保存しました"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"接続を解除"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"有効化"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"明日自動的に ON に戻す"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"クイック共有、デバイスを探す、デバイスの位置情報などの機能は Bluetooth を使用します"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"オーディオ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ヘッドセット"</string> @@ -537,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"無効にする"</string> <string name="sound_settings" msgid="8874581353127418308">"音とバイブレーション"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"設定"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"自動字幕起こし"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"音量を安全なレベルまで下げました"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"推奨時間よりも長くヘッドフォンが大音量で設定されています"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ヘッドフォンの音量が今週一週間の安全基準とされる音量、時間を超えています"</string> @@ -603,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"アクセスポイント"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"衛生、接続利用不可"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"衛生、接続不安定"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛生、接続状態良好"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛生、接続利用可能"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"仕事用プロファイル"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"一部の方のみお楽しみいただける限定公開ツール"</string> <string name="tuner_warning" msgid="1861736288458481650">"システムUI調整ツールでは、Androidユーザーインターフェースの調整やカスタマイズを行えます。これらの試験運用機能は今後のリリースで変更となったり、中止となったり、削除されたりする可能性がありますのでご注意ください。"</string> @@ -732,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"設定を開く"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"アシスタントを開く"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"画面をロック"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"メモを開く"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"メモを入力する"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"システム マルチタスク"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"分割画面にして現在のアプリを右側に設定する"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"分割画面にして現在のアプリを左側に設定する"</string> @@ -1233,7 +1232,7 @@ <string name="assistant_attention_content_description" msgid="4166330881435263596">"会話を始められます"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"[設定] でデフォルトのメモアプリを設定してください"</string> <string name="install_app" msgid="5066668100199613936">"アプリをインストール"</string> - <string name="dismissible_keyguard_swipe" msgid="8377597870094949432">"上にスワイプして続行"</string> + <string name="dismissible_keyguard_swipe" msgid="8377597870094949432">"上にスワイプして継続"</string> <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"外部ディスプレイにミラーリングしますか?"</string> <string name="connected_display_dialog_dual_display_stop_warning" msgid="4174707498892447947">"インナー ディスプレイがミラーリングされます。フロント ディスプレイはオフになります。"</string> <string name="mirror_display" msgid="2515262008898122928">"ディスプレイをミラーリングする"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 774dfe469602..fef2fe11016f 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"შეეხეთ სანახავად"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"ეკრანის ჩანაწერის შენახვისას შეცდომა მოხდა"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"ეკრანის ჩაწერის დაწყებისას წარმოიქმნა შეცდომა"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"ჩანაწერის რეკორდერი"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"პრობლემის ჩანაწერის დამუშავება"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"მიმდინარე შეტყობინება პრობლემების შეგროვების სესიისთვის"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"ჩანაწერთან დაკავშირებული პრობლემა"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"გაზიარება"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"პრობლემის ჩანაწერი შენახულია"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"შეეხეთ სანახავად"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"პრობლემის ჩანაწერის შენახვისას წარმოიქმნა შეცდომა"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"პრობლემის ჩაწერის დაწყებისას წარმოიქმნა შეცდომა"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"მიმდინარეობს სრულ ეკრანზე ნახვა"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"გასვლისთვის გადაფურცლეთ ზემოდან ქვემოთ."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"გასაგებია"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"შენახული"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"კავშირის გაწყვეტა"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"გააქტიურება"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ბატარეა"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"აუდიო"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ყურსაცვამი"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"გამორთვა"</string> <string name="sound_settings" msgid="8874581353127418308">"ხმა და ვიბრაცია"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"პარამეტრები"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"ავტოსუბტიტრები"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ხმა დაწეულია უსაფრთხო დონემდე"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ხმა მაღალი იყო რეკომენდებულზე მეტი ხნის განმავლობაში"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ყურსასმენების ხმამ ამ კვირაში უსაფრთხოების ლიმიტს გადააჭარბა"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>-ზე"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>-ზე"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"წვდომის წერტილი"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"სატელიტური კავშირი არ არის"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"სუსტი სატელიტური კავშირი"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"კარგი სატელიტური კავშირი"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ხელმისაწვდომია სატელიტური კავშირი"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"სამსახურის პროფილი"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"ზოგისთვის გასართობია, მაგრამ არა ყველასთვის"</string> <string name="tuner_warning" msgid="1861736288458481650">"სისტემის UI ტუნერი გაძლევთ დამატებით გზებს Android-ის სამომხმარებლო ინტერფეისის პარამეტრების დაყენებისთვის. ეს ექსპერიმენტული მახასიათებლები შეიძლება შეიცვალოს, შეწყდეს ან გაქრეს მომავალ ვერსიებში. სიფრთხილით გააგრძელეთ."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"პარამეტრების გახსნა"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"ასისტენტის გახსნა"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"ჩაკეტილი ეკრანი"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"ჩანიშვნების გახსნა"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"ჩაინიშნეთ"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"სისტემის მრავალამოცანიანი რეჟიმი"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"ეკრანის გაყოფის შეყვანა მიმდინარე აპით RHS-ში"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"ეკრანის გაყოფის შეყვანა მიმდინარე აპით LHS-ში"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 24dda1b542b6..cf5a560870b6 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Көру үшін түртіңіз."</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Экран жазбасын сақтау кезінде қате шықты."</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Экрандағы бейнені жазу кезінде қате шықты."</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Мәселені жазу құралы"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Мәселе жазбасы өңделіп жатыр"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Мәселе туралы дерек жинау сеансына арналған ағымдағы хабарландыру"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Мәселе жазылып жатыр"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Бөлісу"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Мәселе жазбасы сақталды"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Көру үшін түртіңіз."</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Мәселе жазбасын сақтау кезінде қате шықты."</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Мәселені жазуды бастау кезінде қате шықты."</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Толық экранда көру"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Шығу үшін жоғарыдан төмен қарай сырғытыңыз."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Түсінікті"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сақталды"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ажырату"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"іске қосу"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Aудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string> @@ -435,10 +430,8 @@ <string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Осы бөлмеде виджеттер қосыңыз, оларды өшіріңіз және ретін өзгертіңіз."</string> <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Басқа виджеттер қосыңыз."</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджеттерді бейімдеу үшін ұзақ басып тұрыңыз."</string> - <!-- no translation found for button_to_configure_widgets_text (4191862850185256901) --> - <skip /> - <!-- no translation found for edit_widget (9030848101135393954) --> - <skip /> + <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджеттерді реттеу"</string> + <string name="edit_widget" msgid="9030848101135393954">"Виджетті өзгерту"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Өшіру"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Виджет қосу"</string> <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Дайын"</string> @@ -548,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"өшіру"</string> <string name="sound_settings" msgid="8874581353127418308">"Дыбыс және діріл"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Параметрлер"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Дыбыс қауіпсіз деңгейге түсірілді"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Құлақаспаптың жоғары дыбыс деңгейі ұсынылған уақыттан ұзақ қосылып тұрды."</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Құлақаспаптың дыбыс деңгейі осы аптадағы қауіпсіз шектен асып кетті."</string> @@ -614,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Хотспот"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Жерсерік, байланыс жоқ."</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Жерсерік, байланыс нашар."</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Жерсерік, байланыс жақсы."</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Жерсерік, байланыс бар."</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Жұмыс профилі"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Кейбіреулерге қызық, бірақ барлығына емес"</string> <string name="tuner_warning" msgid="1861736288458481650">"Жүйелік пайдаланушылық интерфейс тюнері Android пайдаланушылық интерфейсін реттеудің қосымша жолдарын береді. Бұл эксперименттік мүмкіндіктер болашақ шығарылымдарда өзгеруі, бұзылуы немесе жоғалуы мүмкін. Сақтықпен жалғастырыңыз."</string> @@ -743,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Параметрлерді ашу"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant-ті ашу"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Экранды құлыптау"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Ескертпелерді ашу"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Ескертпе жазу"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Жүйе мультитаскингі"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Бөлінген экран режиміне кіру (ағымдағы қолданбаны оңға орналастыру)"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Бөлінген экран режиміне кіру (ағымдағы қолданбаны солға орналастыру)"</string> @@ -975,8 +966,7 @@ <string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Шетке жылжыту және көрсету"</string> <string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Өшіру"</string> <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ауыстыру"</string> - <!-- no translation found for accessibility_floating_button_action_edit (1688227814600463987) --> - <skip /> + <string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Өзгерту"</string> <string name="quick_controls_title" msgid="6839108006171302273">"Құрылғыны басқару элементтері"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Басқару элементтері қосылатын қолданбаны таңдаңыз"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# басқару элементі қосылды.}other{# басқару элементі қосылды.}}"</string> @@ -1245,8 +1235,7 @@ <string name="assistant_attention_content_description" msgid="4166330881435263596">"Пайдаланушы анықталды."</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Параметрлерден әдепкі жазба қолданбасын орнатыңыз."</string> <string name="install_app" msgid="5066668100199613936">"Қолданбаны орнату"</string> - <!-- no translation found for dismissible_keyguard_swipe (8377597870094949432) --> - <skip /> + <string name="dismissible_keyguard_swipe" msgid="8377597870094949432">"Жалғастыру үшін жоғары қарай сырғытыңыз."</string> <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Сыртқы экран арқылы да көрсету керек пе?"</string> <string name="connected_display_dialog_dual_display_stop_warning" msgid="4174707498892447947">"Ішкі экран көшірмесі көрсетіледі. Алдыңғы экран өшіріледі."</string> <string name="mirror_display" msgid="2515262008898122928">"Көрсету"</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 81d2cef3c38f..480a0e5d2d8d 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"ចុចដើម្បីមើល"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"មានបញ្ហាក្នុងការរក្សាទុកការថតវីដេអូអេក្រង់"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"មានបញ្ហាក្នុងការចាប់ផ្ដើមថតអេក្រង់"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"កម្មវិធីកត់ត្រាបញ្ហា"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"កំពុងដំណើរការការកត់ត្រាបញ្ហា"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"ការជូនដំណឹងដែលកំពុងបន្តសម្រាប់វគ្គប្រមូលបញ្ហា"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"កំពុងកត់ត្រាបញ្ហា"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"ចែករំលែក"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"បានរក្សាទុកកំណត់ត្រាបញ្ហា"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"ចុចដើម្បីមើល"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"មានបញ្ហាក្នុងការរក្សាទុកកំណត់ត្រាបញ្ហា"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"មានបញ្ហាក្នុងការចាប់ផ្ដើមកត់ត្រាបញ្ហា"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"កំពុងមើលពេញអេក្រង់"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"ដើម្បីចាកចេញ សូមអូសពីលើចុះក្រោម។"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"យល់ហើយ"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"បានរក្សាទុក"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ផ្ដាច់"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"បើកដំណើរការ"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"សំឡេង"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"កាស"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"បិទ"</string> <string name="sound_settings" msgid="8874581353127418308">"សំឡេង និងការញ័រ"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ការកំណត់"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"អក្សររត់ក្នុងពេលជាក់ស្ដែង"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"បានបន្ថយកម្រិតសំឡេងមកកម្រិតដែលកាន់តែមានសុវត្ថិភាព"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"កម្រិតសំឡេងកាសមានកម្រិតខ្ពស់យូរជាងរយៈពេលដែលបានណែនាំ"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"កម្រិតសំឡេងកាសបានលើសដែនកំណត់សុវត្ថិភាពសម្រាប់សប្ដាហ៍នេះ"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"នៅ <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"នៅ <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ហតស្ប៉ត"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"ផ្កាយរណប មិនមានការតភ្ជាប់ទេ"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ផ្កាយរណប ការតភ្ជាប់ខ្សោយ"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ផ្កាយរណប មានការតភ្ជាប់ល្អ"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ផ្កាយរណប អាចតភ្ជាប់បាន"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"កម្រងព័ត៌មានការងារ"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"ល្អសម្រាប់អ្នកប្រើមួយចំនួន តែមិនសម្រាប់គ្រប់គ្នាទេ"</string> <string name="tuner_warning" msgid="1861736288458481650">"កម្មវិធីសម្រួល UI ប្រព័ន្ធផ្តល់ជូនអ្នកនូវមធ្យោបាយបន្ថែមទៀតដើម្បីកែសម្រួល និងប្តូរចំណុចប្រទាក់អ្នកប្រើ Android តាមបំណង។ លក្ខណៈពិសេសសាកល្បងនេះអាចនឹងផ្លាស់ប្តូរ បំបែក ឬបាត់បង់បន្ទាប់ពីការចេញផ្សាយនាពេលអនាគត។ សូមបន្តដោយប្រុងប្រយ័ត្ន។"</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"បើកការកំណត់"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"បើកជំនួយការ"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"ចាក់សោអេក្រង់"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"បើកកំណត់ចំណាំ"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"កត់ចំណាំ"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ការដំណើរការបានច្រើននៃប្រព័ន្ធ"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"ចូលក្នុងមុខងារបំបែកអេក្រង់ដោយប្រើកម្មវិធីបច្ចុប្បន្ននៅខាងស្ដាំដៃ"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"ចូលក្នុងមុខងារបំបែកអេក្រង់ដោយប្រើកម្មវិធីបច្ចុប្បន្ននៅខាងឆ្វេងដៃ"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 31dbbb55994c..1f9156afc073 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೇವ್ ಮಾಡುವಾಗ ದೋಷ ಎದುರಾಗಿದೆ"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"ಸಮಸ್ಯೆ ರೆಕಾರ್ಡರ್"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ಸಮಸ್ಯೆ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಕ್ರಿಯೆ…"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"ಸಮಸ್ಯೆ ಸಂಗ್ರಹಣೆಯ ಸೆಶನ್ಗಾಗಿ ಜರುಗುತ್ತಿರುವ ನೋಟಿಫಿಕೇಶನ್"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"ರೆಕಾರ್ಡಿಂಗ್ ಸಮಸ್ಯೆ"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"ಹಂಚಿಕೊಳ್ಳಿ"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"ಸಮಸ್ಯೆಯ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ಸೇವ್ ಮಾಡಲಾಗಿದೆ"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"ಸಮಸ್ಯೆಯ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ಸೇವ್ ಮಾಡುವಾಗ ದೋಷ ಎದುರಾಗಿದೆ"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"ಸಮಸ್ಯೆಯ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುವಲ್ಲಿ ದೋಷ ಎದುರಾಗಿದೆ"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"ಪೂರ್ಣ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ವೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"ನಿರ್ಗಮಿಸಲು, ಮೇಲಿನಿಂದ ಕೆಳಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"ಅರ್ಥವಾಯಿತು"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ಸೇವ್ ಮಾಡಲಾಗಿದೆ"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ಡಿಸ್ಕನೆಕ್ಟ್ ಮಾಡಿ"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ಸಕ್ರಿಯಗೊಳಿಸಿ"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ಬ್ಯಾಟರಿ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ಆಡಿಯೋ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ಹೆಡ್ಸೆಟ್"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string> <string name="sound_settings" msgid="8874581353127418308">"ಧ್ವನಿ & ವೈಬ್ರೇಷನ್"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"ಲೈವ್ ಕ್ಯಾಪ್ಶನ್"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ವಾಲ್ಯೂಮ್ ಅನ್ನು ಸುರಕ್ಷಿತ ಮಟ್ಟಕ್ಕೆ ತಗ್ಗಿಸಲಾಗಿದೆ"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ಶಿಫಾರಸು ಮಾಡಿದ್ದಕ್ಕಿಂತಲೂ ದೀರ್ಘಕಾಲ ಹೆಡ್ಫೋನ್ನ ವಾಲ್ಯೂಮ್ ಹೆಚ್ಚಿಗೆ ಇದೆ"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ಹೆಡ್ಫೋನ್ನ ವಾಲ್ಯೂಮ್ ಈ ವಾರದ ಮಟ್ಟಿಗೆ ಸುರಕ್ಷಿತ ಮಿತಿಯನ್ನು ಮೀರಿದೆ"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> ರಲ್ಲಿ"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> ರಂದು"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ಹಾಟ್ಸ್ಪಾಟ್"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"ಸ್ಯಾಟಲೈಟ್, ಯಾವುದೇ ಕನೆಕ್ಷನ್ ಇಲ್ಲ"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ಸ್ಯಾಟಲೈಟ್, ಕನೆಕ್ಷನ್ ಕಳಪೆಯಾಗಿದೆ"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ಸ್ಯಾಟಲೈಟ್, ಕನೆಕ್ಷನ್ ಉತ್ತಮವಾಗಿದೆ"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ಸ್ಯಾಟಲೈಟ್, ಕನೆಕ್ಷನ್ ಲಭ್ಯವಿದೆ"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"ಕೆಲವರಿಗೆ ಮೋಜು ಆಗಿದೆ ಎಲ್ಲರಿಗೆ ಇಲ್ಲ"</string> <string name="tuner_warning" msgid="1861736288458481650">"ಸಿಸ್ಟಂ UI ಟ್ಯೂನರ್ ನಿಮಗೆ Android ಬಳಕೆದಾರ ಅಂತರಸಂಪರ್ಕವನ್ನು ಸರಿಪಡಿಸಲು ಮತ್ತು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ಹೆಚ್ಚುವರಿ ಮಾರ್ಗಗಳನ್ನು ನೀಡುತ್ತದೆ. ಈ ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯಗಳು ಭವಿಷ್ಯದ ಬಿಡುಗಡೆಗಳಲ್ಲಿ ಬದಲಾಗಬಹುದು, ವಿರಾಮವಾಗಬಹುದು ಅಥವಾ ಕಾಣಿಸಿಕೊಳ್ಳದಿರಬಹುದು. ಎಚ್ಚರಿಕೆಯಿಂದ ಮುಂದುವರಿಯಿರಿ."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"assistant ಅನ್ನು ತೆರೆಯಿರಿ"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಮಾಡಿ"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"ಟಿಪ್ಪಣಿಗಳನ್ನು ತೆರೆಯಿರಿ"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"ಟಿಪ್ಪಣಿಯನ್ನು ತೆಗೆದುಕೊಳ್ಳಿ"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ಸಿಸ್ಟಂ ಮಲ್ಟಿಟಾಸ್ಕಿಂಗ್"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHS ಗೆ ಇರುವ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಸಹಾಯದಿಂದ ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ನಮೂದಿಸಿ"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHS ಗೆ ಇರುವ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಸಹಾಯದಿಂದ ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ನಮೂದಿಸಿ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index fe6ce1323366..c0c8b32237f7 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"탭하여 보기"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"화면 녹화 저장 중에 오류가 발생했습니다."</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"화면 녹화 시작 중 오류 발생"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"문제 녹화 도구"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"문제 녹화 처리 중"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"문제 수집 섹션에 대한 진행 중 알림"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"녹화 문제"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"공유"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"문제 녹화가 저장되었습니다."</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"탭하여 보기"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"문제 녹화 저장 중에 오류가 발생했습니다."</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"문제 녹화 시작 중에 오류가 발생했습니다."</string> <string name="immersive_cling_title" msgid="8372056499315585941">"전체 화면 모드"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"종료하려면 위에서 아래로 스와이프합니다."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"확인"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"저장됨"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"연결 해제"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"실행"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"오디오"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"헤드셋"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"사용 중지"</string> <string name="sound_settings" msgid="8874581353127418308">"소리 및 진동"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"설정"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"볼륨을 안전한 수준으로 낮춤"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"헤드폰 볼륨이 권장 시간보다 오래 높은 상태였습니다."</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"헤드폰 볼륨이 이번 주 안전 한도를 초과했습니다."</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"시간: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"일시: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"핫스팟"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"위성, 연결되지 않음"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"위성, 연결 상태 나쁨"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"위성, 연결 상태 양호"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"위성, 연결 가능"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"직장 프로필"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"마음에 들지 않을 수도 있음"</string> <string name="tuner_warning" msgid="1861736288458481650">"시스템 UI 튜너를 사용하면 Android 사용자 인터페이스를 변경 및 맞춤설정할 수 있습니다. 이러한 실험실 기능은 향후 출시 버전에서는 변경되거나 다운되거나 사라질 수 있습니다. 신중하게 진행하시기 바랍니다."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"설정 열기"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"어시스턴트 열기"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"잠금 화면"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"메모 열기"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"메모 작성"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"시스템 멀티태스킹"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"현재 앱을 오른쪽으로 보내는 화면 분할 입력"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"현재 앱을 왼쪽으로 보내는 화면 분할 입력"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index d3803ecfdb20..b442f2ea255f 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Көрүү үчүн таптаңыз"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Экран тартылган жок"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Экранды жаздырууну баштоодо ката кетти"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Маселе жаздыргыч"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Маселе жаздырылууда"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Маселе тууралуу маалымат чогултулуп жатканы жөнүндө учурдагы билдирме"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Жаздыруу маселеси"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Бөлүшүү"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Жаздырылган маселе сакталды"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Көрүү үчүн таптаңыз"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Жаздырылган маселе сакталган жок"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Маселени жаздыруу башталбай койду"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Толук экран режимин көрүү"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Чыгуу үчүн экранды ылдый сүрүп коюңуз."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Түшүндүм"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сакталды"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ажыратуу"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"иштетүү"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"өчүрүү"</string> <string name="sound_settings" msgid="8874581353127418308">"Үн жана дирилдөө"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Параметрлер"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Үндүн катуулугу коопсуз деңгээлге чейин акырындатылды"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Гарнитуранын үнүн катуу чыгарып, сунушталгандан узагыраак угуп жатасыз"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Гарнитуранын үнүнүн катуулугу бул аптада коопсуз деңгээлден жогору болду"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> болгондо"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> болгондо"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Байланыш түйүнү"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Спутник, байланыш жок"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Спутник, байланыш начар"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спутник, байланыш жакшы"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Спутник, байланыш бар"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Жумуш профили"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Баарына эле жага бербейт"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner Android колдонуучу интерфейсин жөнгө салып жана ыңгайлаштыруунун кошумча ыкмаларын сунуштайт. Бул сынамык функциялар кийинки чыгарылыштарда өзгөрүлүп, бузулуп же жоголуп кетиши мүмкүн. Абайлап колдонуңуз."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Параметрлерди ачуу"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Жардамчыны ачуу"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Экранды кулпулоо"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Кыска жазууларды ачуу"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Кыска жазуу түзүү"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Системанын бир нече тапшырма аткаруусу"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Учурда оң жактагы колдонмо менен экранды бөлүүнү иштетүү"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Учурда сол жактагы колдонмо менен экранды бөлүүнү иштетүү"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 35094938a297..ee170ce44f8e 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"ແຕະເພື່ອເບິ່ງ"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"ເກີດຂໍ້ຜິດພາດໃນການບັນທຶກໜ້າຈໍ"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"ເກີດຄວາມຜິດພາດໃນການບັນທຶກໜ້າຈໍ"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"ຕົວບັນທຶກບັນຫາ"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ກຳລັງປະມວນຜົນການບັນທຶກບັນຫາ"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"ການແຈ້ງເຕືອນທີ່ດຳເນີນຢູ່ສຳລັບເຊດຊັນການຮວບຮວມບັນຫາ"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"ບັນຫາການບັນທຶກ"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"ແບ່ງປັນ"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"ການບັນທຶກບັນຫາຖືກບັນທຶກໄວ້ແລ້ວ"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"ແຕະເພື່ອເບິ່ງ"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"ເກີດຂໍ້ຜິດພາດໃນການບັນທຶກບັນຫາ"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"ເກີດຂໍ້ຜິດພາດໃນການເລີ່ມຕົ້ນການບັນທຶກບັນຫາ"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"ກຳລັງເບິ່ງເຕັມຈໍ"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"ເພື່ອອອກ, ໃຫ້ປັດລົງຈາກເທິງສຸດ."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"ເຂົ້າໃຈແລ້ວ"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ບັນທຶກແລ້ວ"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ຕັດການເຊື່ອມຕໍ່"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ເປີດນຳໃຊ້"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"ເປີດໃຊ້ໂດຍອັດຕະໂນມັດອີກຄັ້ງມື້ອື່ນ"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ຄຸນສົມບັດຕ່າງໆເຊັ່ນ: ການແຊຣ໌ດ່ວນ, ຊອກຫາອຸປະກອນຂອງຂ້ອຍ ແລະ ສະຖານທີ່ອຸປະກອນໃຊ້ Bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ສຽງ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ຊຸດຫູຟັງ"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ປິດນຳໃຊ້"</string> <string name="sound_settings" msgid="8874581353127418308">"ສຽງ ແລະ ການສັ່ນເຕືອນ"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ການຕັ້ງຄ່າ"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"ຄຳບັນຍາຍສົດ"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ຫຼຸດລະດັບສຽງໃຫ້ຢູ່ໃນລະດັບທີ່ປອດໄພຂຶ້ນແລ້ວ"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ຫູຟັງຢູ່ໃນລະດັບສຽງທີ່ດັງເປັນໄລຍະເວລາດົນກວ່າທີ່ແນະນຳ"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ລະດັບສຽງຂອງຫູຟັງໄດ້ເກີນຂີດຈຳກັດທີ່ປອດໄພສຳລັບອາທິດນີ້"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"ເວລາ <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"ວັນ <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ຮັອດສະປອດ"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"ດາວທຽມ, ບໍ່ມີການເຊື່ອມຕໍ່"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ດາວທຽມ, ການເຊື່ອມຕໍ່ບໍ່ດີ"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ດາວທຽມ, ການເຊື່ອມຕໍ່ດີ"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ດາວທຽມ, ການເຊື່ອມຕໍ່ທີ່ພ້ອມນຳໃຊ້"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"ມ່ວນຊື່ນສຳລັບບາງຄົນ ແຕ່ບໍ່ແມ່ນສຳລັບທຸກຄົນ"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner ໃຫ້ທ່ານມີວິທີພິເສດຕື່ມອີກໃນການປັບປ່ຽນ ແລະຕົບແຕ່ງສ່ວນຕໍ່ປະສານຜູ້ໃຊ້ຂອງ Android. ຄຸນສົມບັດທົດລອງໃຊ້ເຫຼົ່ານີ້ອາດຈະປ່ຽນແປງ, ຢຸດເຊົາ ຫຼືຫາຍໄປໃນການວາງຈຳໜ່າຍໃນອະນາຄົດ. ຈົ່ງດຳເນີນຕໍ່ດ້ວຍຄວາມລະມັດລະວັງ."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"ເປີດການຕັ້ງຄ່າ"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"ເປີດຜູ້ຊ່ວຍ"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"ໜ້າຈໍລັອກ"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"ເປີດບັນທຶກ"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"ຈົດບັນທຶກ"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ການເຮັດຫຼາຍໜ້າວຽກພ້ອມກັນຂອງລະບົບ"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"ເຂົ້າສູ່ແບ່ງໜ້າຈໍດ້ວຍແອັບປັດຈຸບັນໄປຫາ RHS"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"ເຂົ້າສູ່ແບ່ງໜ້າຈໍດ້ວຍແອັບປັດຈຸບັນໄປຫາ LHS"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index c773f257945a..5b71259382a0 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Palieskite, kad peržiūrėtumėte"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Išsaugant ekrano įrašą įvyko klaida"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Pradedant ekrano vaizdo įrašymą iškilo problema"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Problemų įrašytuvas"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Apdorojamas problemos įrašas"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Šiuo metu rodomas problemos duomenų rinkimo seanso pranešimas"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Įrašoma problema"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Bendrinti"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Problemos įrašas išsaugotas"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Palieskite, kad peržiūrėtumėte"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Išsaugant problemos įrašą įvyko klaida"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Pradedant problemos įrašą įvyko klaida"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Peržiūrima viso ekrano režimu"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Jei norite išeiti, perbraukite žemyn iš viršaus."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Supratau"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Išsaugota"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"atjungti"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"suaktyvinti"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatiškai vėl įjungti rytoj"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Tokioms funkcijoms kaip „Spartusis bendrinimas“, „Rasti įrenginį“ ir įrenginio vietovė naudojamas „Bluetooth“ ryšys"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumuliatorius: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Garsas"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Virtualiosios realybės įrenginys"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"išjungti"</string> <string name="sound_settings" msgid="8874581353127418308">"Garsas ir vibravimas"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Nustatymai"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Subtitrai realiuoju laiku"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Garsumas sumažintas iki saugesnio lygio"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Ausinių garsumo lygis buvo aukštas ilgiau, nei rekomenduojama"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Ausinių garsumo lygis viršijo šios savaitės saugaus garsumo lygio apribojimą"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Viešosios interneto prieigos taškas"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Palydovas, nėra ryšio"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Palydovas, prastas ryšys"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Palydovas, geras ryšys"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Palydovas, pasiekiamas ryšys"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Darbo profilis"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Smagu, bet ne visada"</string> <string name="tuner_warning" msgid="1861736288458481650">"Sistemos naudotojo sąsajos derinimo priemonė suteikia papildomų galimybių pagerinti ir tinkinti „Android“ naudotojo sąsają. Šios eksperimentinės funkcijos gali pasikeisti, nutrūkti ar išnykti iš būsimų laidų. Tęskite atsargiai."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Atidaryti nustatymus"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Atidaryti Padėjėją"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Užrakinti ekraną"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Atidaryti pastabas"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Sukurti pastabą"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Kelių užduočių atlikimas sistemoje"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Eiti į išskaidyto ekrano režimą su dabartine programa dešinėje"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Eiti į išskaidyto ekrano režimą su dabartine programa kairėje"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index a26c7444b71a..b4dae4c71a95 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Pieskarieties, lai skatītu"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Saglabājot ekrāna ierakstu, radās kļūda."</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Sākot ierakstīt ekrāna saturu, radās kļūda."</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Problēmu ierakstītājs"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Apstrādā problēmas ierakstu"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Aktīvs paziņojums par problēmu vākšanas sesiju"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Notiek problēmas reģistrēšana"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Kopīgot"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Problēmas ieraksts ir saglabāts."</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Pieskarieties, lai skatītu"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Saglabājot problēmas ierakstu, radās kļūda."</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Sākot problēmas ierakstīšanu, radās kļūda."</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Skatīšanās pilnekrāna režīmā"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Lai izietu, no augšdaļas velciet lejup."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Labi"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saglabāta"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"atvienot"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivizēt"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumulators: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Austiņas"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"atspējot"</string> <string name="sound_settings" msgid="8874581353127418308">"Skaņa un vibrācija"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Iestatījumi"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Skaļums samazināts līdz drošākam līmenim"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Austiņu skaļums ir bijis liels ilgāk, nekā ieteicams."</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Austiņu skaļums ir pārsniedzis šīs nedēļas drošo ierobežojumu."</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"plkst. <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Tīklājs"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelīts, nav savienojuma"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelīts, vājš savienojums"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelīts, labs savienojums"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelīts, ir pieejams savienojums"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Darba profils"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Jautri dažiem, bet ne visiem"</string> <string name="tuner_warning" msgid="1861736288458481650">"Sistēmas saskarnes regulators sniedz papildu veidus, kā mainīt un pielāgot Android lietotāja saskarni. Nākamajās versijās šīs eksperimentālās funkcijas var tikt mainītas, bojātas vai to darbība var tikt pārtraukta. Turpinot esiet uzmanīgs."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Atvērt iestatījumus"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Atvērt Asistentu"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Bloķēt ekrānu"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Atvērt piezīmes"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Piezīmes izveide"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Sistēmas vairākuzdevumu režīms"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Pāriet ekrāna sadalīšanas režīmā ar pašreizējo lietotni pa labi"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Pāriet ekrāna sadalīšanas režīmā ar pašreizējo lietotni pa kreisi"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 4add5808a81a..38ed5a70ad3c 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Допрете за прегледување"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при зачувувањето на снимката од екранот"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при почетокот на снимањето на екранот"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Проблем со „Диктафон“"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Се обработува проб. со снимање"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Тековно известување за сесија за проблем со прибирање"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Проблем со снимање"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Споделување"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Проблемот со снимање е зачуван"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Допрете за да прегледате"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Грешка при зачувување на проблемот со снимање"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Грешка при започнување на проблемот со снимање"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Се прикажува на цел екран"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"За да излезете, повлечете одозгора надолу."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Сфатив"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Зачувано"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"прекини врска"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активирај"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батерија"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалки"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"оневозможи"</string> <string name="sound_settings" msgid="8874581353127418308">"Звук и вибрации"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Поставки"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Јачината на звукот е намалена на побезбедно ниво"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Јачината на звукот на слушалките беше висока подолго од препорачаното"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Јачината на звукот на слушалките го надмина безбедното ограничување за седмицава"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"во <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"во <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Точка на пристап"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Нема сателитска врска"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Слаба сателитска врска"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Добра сателитска врска"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Достапна е сателитска врска"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Работен профил"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Забава за некои, но не за сите"</string> <string name="tuner_warning" msgid="1861736288458481650">"Адаптерот на УИ на системот ви дава дополнителни начини за дотерување и приспособување на корисничкиот интерфејс на Android. Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Отворете „Поставки“"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Отворете го „Помошникот“"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Заклучен екран"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Отворете „Белешки“"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Фатете белешка"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Системски мултитаскинг"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Активирајте поделен екран со тековната апликација десно"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Активирајте поделен екран со тековната апликација лево"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 3208b20c7e98..a20417da5660 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"കാണാൻ ടാപ്പ് ചെയ്യുക"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"സ്ക്രീൻ റെക്കോർഡിംഗ് സംരക്ഷിക്കുന്നതിൽ പിശക്"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"സ്ക്രീൻ റെക്കോർഡിംഗ് ആരംഭിക്കുന്നതിൽ പിശക്"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"പ്രശ്ന റെക്കോർഡർ"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"പ്രശ്ന റെക്കോർഡിംഗ് പ്രോസസ് ചെയ്യുന്നു"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"ഒരു പ്രശ്ന ശേഖരണ സെഷന്റെ ഓൺഗോയിംഗ് അറിയിപ്പ്"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"റെക്കോർഡിംഗിൽ പ്രശ്നം"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"പങ്കിടുക"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"പ്രശ്ന റെക്കോർഡിംഗ് സംരക്ഷിച്ചു"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"കാണാൻ ടാപ്പ് ചെയ്യുക"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"പ്രശ്ന റെക്കോർഡിംഗ് സംരക്ഷിക്കുന്നതിൽ പിശക്"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"പ്രശ്ന റെക്കോർഡിംഗ് ആരംഭിക്കുന്നതിൽ പിശക്"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"പൂർണ്ണ സ്ക്രീനിൽ കാണുന്നു"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"പുറത്തുകടക്കാൻ, മുകളിൽ നിന്ന് താഴോട്ട് സ്വൈപ്പ് ചെയ്യുക."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"മനസ്സിലായി"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"സംരക്ഷിച്ചു"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"വിച്ഛേദിക്കുക"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"സജീവമാക്കുക"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"നാളെ വീണ്ടും സ്വയമേവ ഓണാക്കുക"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ക്വിക്ക് ഷെയർ, Find My Device, ഉപകരണ ലൊക്കേഷൻ എന്നിവ പോലുള്ള ഫീച്ചറുകൾ Bluetooth ഉപയോഗിക്കുന്നു"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ബാറ്ററി"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ഓഡിയോ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ഹെഡ്സെറ്റ്"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"പ്രവർത്തനരഹിതമാക്കുക"</string> <string name="sound_settings" msgid="8874581353127418308">"ശബ്ദവും വൈബ്രേഷനും"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ക്രമീകരണം"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"തത്സമയ ക്യാപ്ഷൻ"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"സുരക്ഷിതമായ തലത്തിലേക്ക് വോളിയം കുറച്ചു"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"നിർദ്ദേശിച്ചിരിക്കുന്നതിനേക്കാൾ കൂടുതൽ സമയം ഹെഡ്ഫോണിന്റെ വോളിയം ഉയർന്ന നിലയിലായിരുന്നു"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ഹെഡ്ഫോണിന്റെ വോളിയം ഈ ആഴ്ചത്തെ സുരക്ഷിത പരിധി കവിഞ്ഞു"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>-ന്"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>-ന്"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ഹോട്ട്സ്പോട്ട്"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"സാറ്റലൈറ്റ്, കണക്ഷൻ ഇല്ല"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"സാറ്റലൈറ്റ്, മോശം കണക്ഷൻ"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"സാറ്റലൈറ്റ്, മികച്ച കണക്ഷൻ"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"സാറ്റലൈറ്റ്, കണക്ഷൻ ലഭ്യമാണ്"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"ചിലർക്ക് വിനോദം, എന്നാൽ എല്ലാവർക്കുമില്ല"</string> <string name="tuner_warning" msgid="1861736288458481650">"Android ഉപയോക്തൃ ഇന്റർഫേസ് ആവശ്യമുള്ള രീതിയിൽ മാറ്റുന്നതിനും ഇഷ്ടാനുസൃതമാക്കുന്നതിനും സിസ്റ്റം UI ട്യൂണർ നിങ്ങൾക്ക് അധിക വഴികൾ നൽകുന്നു. ഭാവി റിലീസുകളിൽ ഈ പരീക്ഷണാത്മക ഫീച്ചറുകൾ മാറ്റുകയോ നിർത്തുകയോ അപ്രത്യക്ഷമാവുകയോ ചെയ്തേക്കാം. ശ്രദ്ധയോടെ മുന്നോട്ടുപോകുക."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"ക്രമീകരണം തുറക്കുക"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant തുറക്കുക"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"ലോക്ക് സ്ക്രീൻ"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"കുറിപ്പുകൾ തുറക്കുക"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"ഒരു കുറിപ്പെടുക്കുക"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"സിസ്റ്റം മൾട്ടിടാസ്കിംഗ്"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"നിലവിലെ ആപ്പ് വലതുവശത്ത് വരുന്ന രീതിയിൽ സ്ക്രീൻ വിഭജന മോഡിൽ കടക്കുക"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"നിലവിലെ ആപ്പ് ഇടതുവശത്ത് വരുന്ന രീതിയിൽ സ്ക്രീൻ വിഭജന മോഡിൽ കടക്കുക"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 93c22c4dfcc2..378f330f5435 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Харахын тулд товшино уу"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Дэлгэцийн бичлэгийг хадгалахад алдаа гарлаа"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Дэлгэцийн бичлэгийг эхлүүлэхэд алдаа гарлаа"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Асуудал бичигч"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Асуудлын бичлэгийг боловсруулж байна"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Асуудал цуглуулах харилцан үйлдлийн үргэлжилж буй мэдэгдэл"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Асуудлыг бичиж байна"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Хуваалцах"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Асуудлын бичлэгийг хадгалсан"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Товшиж харна уу"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Асуудлын бичлэгийг хадгалахад алдаа гарлаа"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Асуудлын бичлэгийг эхлүүлэхэд алдаа гарлаа"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Бүтэн дэлгэцээр үзэж байна"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Гарах бол дээрээс доош шударна уу."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Ойлголоо"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Хадгалсан"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"салгах"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"идэвхжүүлэх"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батарей"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Чихэвч"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"идэвхгүй болгох"</string> <string name="sound_settings" msgid="8874581353127418308">"Дуу, чичиргээ"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Тохиргоо"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Дууны түвшнийг илүү аюулгүй түвшин рүү багасгасан"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Чихэвчийн дууны түвшин санал болгосноос удаан хугацааны туршид өндөр байсан"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Чихэвчийн дууны түвшин энэ долоо хоногийн аюулгүй хязгаараас хэтэрсэн"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> цагт"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>-т"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Сүлжээний цэг"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Хиймэл дагуул, холболт байхгүй"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Хиймэл дагуул, холболт муу байна"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Хиймэл дагуул, холболт сайн байна"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Хиймэл дагуул, холболт боломжтой"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Ажлын профайл"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Зарим хүнд хөгжилтэй байж болох ч бүх хүнд тийм биш"</string> <string name="tuner_warning" msgid="1861736288458481650">"Системийн UI Tохируулагч нь Android хэрэглэгчийн интерфэйсийг тааруулах, өөрчлөх нэмэлт аргыг зааж өгөх болно. Эдгээр туршилтын тохиргоо нь цаашид өөрчлөгдөх, эвдрэх, алга болох магадлалтай. Үйлдлийг болгоомжтой хийнэ үү."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Тохиргоог нээх"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Туслахыг нээх"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Түгжээтэй дэлгэц"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Тэмдэглэлүүдийг нээх"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Тэмдэглэл хөтлөх"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Систем олон ажил зэрэг хийх"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Одоогийн аппаар баруун гар талд дэлгэц хуваахад орох"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Одоогийн аппаар зүүн гар талд дэлгэц хуваахад орох"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 40f88178fd8e..940a7e6692e9 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"पाहण्यासाठी टॅप करा"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रीन रेकॉर्डिंग सेव्ह करताना एरर आली"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन रेकॉर्डिंग सुरू करताना एरर आली"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"समस्या रेकॉर्डर"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"प्रक्रियेच्या समस्येचे रेकॉर्डिंग"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"समस्या गोळा करण्याच्या सेशनसाठीची सद्य सूचना"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"समस्या रेकॉर्ड करत आहे"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"शेअर करा"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"समस्येचे रेकॉर्डिंग सेव्ह केले"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"पाहण्यासाठी टॅप करा"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"समस्येचे रेकॉर्डिंग सेव्ह करताना एरर आली"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"समस्येचे रेकॉर्डिंग सुरू करताना एरर आली"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"पूर्ण स्क्रीन पाहत आहात"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"बाहेर पडण्यासाठी, वरून खाली स्वाइप करा."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"समजले"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेव्ह केले"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"डिस्कनेक्ट करा"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ॲक्टिव्हेट करा"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> बॅटरी"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ऑडिओ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"बंद करा"</string> <string name="sound_settings" msgid="8874581353127418308">"आवाज आणि व्हायब्रेशन"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"सेटिंग्ज"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"लाइव्ह कॅप्शन"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"व्हॉल्यूम सुरक्षित पातळीपर्यंत कमी केला"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"व्हॉल्यूम हा शिफारस केलेल्या वेळेपेक्षा जास्त वेळ उच्च आहे"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"हेडफोनच्या व्हॉल्यूमने या आठवड्यासाठीची सुरक्षिततेची मर्यादा ओलांडली आहे"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> वाजता"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> रोजी"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"हॉटस्पॉट"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"सॅटेलाइट, कनेक्शन नाही"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"सॅटेलाइट, खराब कनेक्शन"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"सॅटेलाइट, चांगले कनेक्शन"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"सॅटेलाइट, कनेक्शन उपलब्ध"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"कार्य प्रोफाईल"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"सर्वांसाठी नाही तर काहींसाठी मजेदार असू शकते"</string> <string name="tuner_warning" msgid="1861736288458481650">"सिस्टम UI ट्युनर आपल्याला Android यूझर इंटरफेस ट्विक आणि कस्टमाइझ करण्याचे अनेक प्रकार देते. ही प्रयोगात्मक वैशिष्ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्यातील रिलीज मध्ये कदाचित दिसणार नाहीत. सावधगिरी बाळगून पुढे सुरू ठेवा."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"सेटिंग्ज उघडा"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant उघडा"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"लॉक स्क्रीन"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"टिपा उघडा"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"नोंद घ्या"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"सिस्टीम मल्टिटास्किंग"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"उजव्या बाजूला सध्याचे अॅप असलेल्या स्प्लिट स्क्रीनवर जा"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"डाव्या बाजूला सध्याचे अॅप असलेल्या स्प्लिट स्क्रीनवर जा"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 72e44ff4afd8..fdffdb7265fd 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Ketik untuk lihat"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Ralat semasa menyimpan rakaman skrin"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Ralat semasa memulakan rakaman skrin"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Perakam Masalah"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Memproses rakaman masalah"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Pemberitahuan sedang berlangsung untuk sesi pengumpulan masalah"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Merakamkan masalah"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Kongsi"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Rakaman masalah disimpan"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Ketik untuk lihat"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Ralat menyimpan rakaman masalah"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Ralat memulakan rakaman masalah"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Melihat skrin penuh"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Untuk keluar, leret ke bawah dari bahagian atas."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Disimpan"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"putuskan sambungan"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktifkan"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Dihidupkan sekali lagi esok secara automatik"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Ciri seperti Quick Share, Find My Device dan lokasi peranti menggunakan Bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Set Kepala"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"lumpuhkan"</string> <string name="sound_settings" msgid="8874581353127418308">"Bunyi & getaran"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Tetapan"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Sari Kata Langsung"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Kelantangan dikurangkan kepada tahap yang lebih selamat"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Kelantangan fon kepala tinggi melebihi tempoh yang disyorkan"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Kelantangan fon kepala anda telah melebihi had selamat untuk minggu ini"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"pada <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"pada <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Tempat liputan"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelit, tiada sambungan"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, sambungan yang lemah"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, sambungan yang baik"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, sambungan tersedia"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil kerja"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Menarik untuk sesetengah orang tetapi bukan untuk semua"</string> <string name="tuner_warning" msgid="1861736288458481650">"Penala UI Sistem memberi anda cara tambahan untuk mengolah dan menyesuaikan antara muka Android. Ciri eksperimen ini boleh berubah, rosak atau hilang dalam keluaran masa hadapan. Teruskan dengan berhati-hati."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Buka tetapan"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Buka Assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Kunci skrin"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Buka nota"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Catat nota"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Berbilang tugas sistem"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Masuk skrin pisah dengan apl semasa pada sisi kanan"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Masuk skrin pisah dengan apl semasa pada sisi kiri"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index f475621ab80e..99e2a3fcd53c 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"ကြည့်ရှုရန် တို့ပါ"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"ဖန်သားပြင်ရိုက်ကူးမှုကို သိမ်းရာတွင် အမှားရှိသည်"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"ဖန်သားပြင် ရိုက်ကူးမှု စတင်ရာတွင် အမှားအယွင်းရှိနေသည်"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"ပြဿနာရိုက်ကူးစနစ်"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ပြဿနာရိုက်ကူးမှု လုပ်နေသည်"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"ပြဿနာစုစည်းခြင်း စက်ရှင်အတွက် လုပ်ဆောင်နေဆဲ အကြောင်းကြားချက်"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"ပြဿနာကို ရိုက်ကူးနေသည်"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"မျှဝေရန်"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"ပြဿနာရိုက်ကူးမှုကို သိမ်းလိုက်ပါပြီ"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"ကြည့်ရန်တို့ပါ"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"ပြဿနာရိုက်ကူးမှုကို သိမ်း၍မရပါ"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"ပြဿနာရိုက်ကူးမှုကို စတင်၍မရပါ"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"ဖန်သားပြင်အပြည့် ကြည့်နေသည်"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"ထွက်ရန် အပေါ်မှ အောက်သို့ ပွတ်ဆွဲပါ။"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"နားလည်ပြီ"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"သိမ်းထားသည်"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ချိတ်ဆက်မှုဖြုတ်ရန်"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"စသုံးရန်"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ဘက်ထရီ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"အသံ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"မိုက်ခွက်ပါနားကြပ်"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ပိတ်ရန်"</string> <string name="sound_settings" msgid="8874581353127418308">"အသံနှင့် တုန်ခါမှု"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ဆက်တင်များ"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"အသံကို ဘေးကင်းသည့်အဆင့်သို့ လျှော့ချလိုက်သည်"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"နားကြပ်အသံသည် အကြံပြုထားသည်ထက် အချိန်ကြာရှည်စွာ ကျယ်လောင်နေသည်"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"နားကြပ်အသံသည် ဤအပတ်အတွက် ဘေးကင်းသည့်ကန့်သတ်ချက်ထက် ကျော်သွားပါပြီ"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> ၌"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> တွင်"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ဟော့စပေါ့"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု မရှိပါ"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု မကောင်းပါ"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု ကောင်းသည်"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု ရနိုင်သည်"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"အလုပ် ပရိုဖိုင်"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"အချို့သူများ အတွက် ပျော်စရာ ဖြစ်ပေမဲ့ အားလုံး အတွက် မဟုတ်ပါ"</string> <string name="tuner_warning" msgid="1861736288458481650">"စနစ် UI Tuner က သင့်အတွက် Android အသုံးပြုသူ အင်တာဖေ့စ်ကို ပြောင်းရန်နှင့် စိတ်ကြိုက်ပြုလုပ်ရန် နည်းလမ်း အပိုများကို သင့်အတွက် စီစဉ်ပေးသည်။ အနာဂတ်ဗားရှင်းများတွင် ဤစမ်းသပ်အင်္ဂါရပ်များမှာ ပြောင်းလဲ၊ ပျက်စီး သို့မဟုတ် ပျောက်ကွယ်သွားနိုင်သည်။ သတိဖြင့် ရှေ့ဆက်ပါ။"</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"ဆက်တင်များ ဖွင့်ရန်"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant ဖွင့်ရန်"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"လော့ခ်မျက်နှာပြင်"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"မှတ်စုများ ဖွင့်ရန်"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"မှတ်စုရေးရန်"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"စနစ်က တစ်ပြိုင်နက် များစွာလုပ်ခြင်း"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"လက်ရှိအက်ပ်ကို မျက်နှာပြင် ခွဲ၍ပြသမှု၏ ညာဘက်တွင်ထည့်ရန်"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"လက်ရှိအက်ပ်ကို မျက်နှာပြင် ခွဲ၍ပြသမှု၏ ဘယ်ဘက်တွင်ထည့်ရန်"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 48f0aee75afa..67f44e9c72c2 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Trykk for å se"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Feil ved lagring av skjermopptaket"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Feil ved start av skjermopptaket"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Funksjon for opptak av problemer"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Opptak, databehandlingsproblem"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Pågående varsel for en innsamlingsøkt for et problem"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Tar opp problem"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Del"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Problemopptaket er lagret"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Trykk for å se"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Feil ved lagring av problemopptaket"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Feil ved start av problemopptaket"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Visning i fullskjerm"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Sveip ned fra toppen for å avslutte."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Greit"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Lagret"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"koble fra"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiver"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Lyd"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Hodetelefoner"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktiver"</string> <string name="sound_settings" msgid="8874581353127418308">"Lyd og vibrering"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Innstillinger"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volumet er senket til et tryggere nivå"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volumet på hodetelefonene har vært høyt lenger enn anbefalt"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volumet på hodetelefonene har overskredet sikkerhetsgrensen for denne uken"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Wifi-sone"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satellitt – ingen tilkobling"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellitt – dårlig tilkobling"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellitt – god tilkobling"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellitt – tilkobling tilgjengelig"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work-profil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Gøy for noen – ikke for alle"</string> <string name="tuner_warning" msgid="1861736288458481650">"Med System UI Tuner har du flere måter å justere og tilpasse Android-brukergrensesnittet på. Disse eksperimentelle funksjonene kan endres, avbrytes eller fjernes i fremtidige utgivelser. Fortsett med forbehold."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Åpne innstillingene"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Åpne assistenten"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Låseskjerm"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Åpne notatene"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Ta et notat"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking på systemet"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Åpne delt skjerm med den aktive appen til høyre"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Åpne delt skjerm med den aktive appen til venstre"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index d6f1cb4b6eeb..f9fc6a65edb4 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"हेर्नका लागि ट्याप गर्नुहोस्"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रिन रेकर्डिङ सेभ गर्ने क्रममा त्रुटि भयो"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रिन रेकर्ड गर्न थाल्ने क्रममा त्रुटि भयो"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"समस्यासम्बन्धी जानकारी रेकर्ड गर्ने रेकर्डर"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"समस्याको रेकर्डिङ प्रोसेस गरिँदै छ"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"समस्यासम्बन्धी जानकारी सङ्कलन गर्ने जारी सत्रसम्बन्धी सूचना"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"रेकर्डिङसम्बन्धी समस्या"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"सेयर गर्नुहोस्"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"समस्याको रेकर्डिङ सेभ गरिएको छ"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"हेर्नका लागि ट्याप गर्नुहोस्"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"समस्याको रेकर्डिङ सेभ गर्ने क्रममा त्रुटि भयो"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"समस्यासम्बन्धी जानकारी रेकर्ड गर्न थाल्ने क्रममा त्रुटि भयो"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"फुल स्क्रिन हेरिँदै छ"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"बाहिरिन सिरानबाट तलतिर स्वाइप गर्नुहोस्।"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"बुझेँ"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेभ गरिएको छ"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"डिस्कनेक्ट गर्नुहोस्"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"एक्टिभेट गर्नुहोस्"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ब्याट्री"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"अडियो"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"असक्षम पार्नुहोस्"</string> <string name="sound_settings" msgid="8874581353127418308">"साउन्ड तथा भाइब्रेसन"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"सेटिङ"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"लाइभ क्याप्सन"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"भोल्युम घटाएर सुरक्षित स्तरमा पुर्याइएको छ"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"हेडफोनको भोल्युम धेरै बेरदेखि उच्च छ"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"यो हप्ता हेडफोनको भोल्युमले सुरक्षित स्तरको सीमा नाघेको छ"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> मा"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> मा"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"स्याटलाइट कनेक्सन उपलब्ध छैन"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"स्याटलाइट, खराब कनेक्सन"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"स्याटलाइट, राम्रो कनेक्सन"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"स्याटलाइट, कनेक्सन उपलब्ध छ"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"कार्य प्रोफाइल"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"केहीका लागि रमाइलो हुन्छ तर सबैका लागि होइन"</string> <string name="tuner_warning" msgid="1861736288458481650">"सिस्टम UI ट्युनरले तपाईँलाई Android प्रयोगकर्ता इन्टरफेस आफू अनुकूल गर्न र ट्विक गर्न थप तरिकाहरू प्रदान गर्छ। यी प्रयोगात्मक सुविधाहरू भावी विमोचनमा परिवर्तन हुन, बिग्रिन वा हराउन सक्ने छन्। सावधानीपूर्वक अगाडि बढ्नुहोस्।"</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"सेटिङ खोल्नुहोस्"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"एसिस्टेन्ट खोल्नुहोस्"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"स्क्रिन लक गर्नुहोस्"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"नोटहरू खोल्नुहोस्"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"नोट लेख"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"सिस्टम मल्टिटास्किङ"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"हालको एप दायाँतर्फ रहने गरी स्प्लिट स्क्रिन मोड सुरु गर्नुहोस्"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"हालको एप बायाँतर्फ रहने गरी स्प्लिट स्क्रिन मोड सुरु गर्नुहोस्"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 55f43f88ca6f..668dd0eea310 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Tik om te bekijken"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Fout bij opslaan van schermopname"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Fout bij starten van schermopname"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Problemen opnemen"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Probleemopname verwerken"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Melding over actieve activiteit voor een sessie voor probleemverzameling"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Probleem opnemen"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Delen"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Probleemopname opgeslagen"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Tik om te bekijken"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Fout bij opslaan van probleemopname"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Fout bij starten van probleemopname"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Volledig scherm wordt getoond"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Swipe omlaag vanaf de bovenkant van het scherm om af te sluiten."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Opgeslagen"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"loskoppelen"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activeren"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Morgen weer automatisch aanzetten"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Functies zoals Quick Share, Vind mijn apparaat en apparaatlocatie maken gebruik van bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterijniveau"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"uitzetten"</string> <string name="sound_settings" msgid="8874581353127418308">"Geluid en trillen"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Instellingen"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Live ondertiteling"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume verlaagd naar een veiliger niveau"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Het hoofdtelefoonvolume is langer dan de aanbevolen tijd hoog geweest"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Het hoofdtelefoonvolume overschrijdt de veiligheidslimiet voor deze week"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"om <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"op <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelliet, geen verbinding"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliet, slechte verbinding"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliet, goede verbinding"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliet, verbinding beschikbaar"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Werkprofiel"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Leuk voor sommige gebruikers, maar niet voor iedereen"</string> <string name="tuner_warning" msgid="1861736288458481650">"Met Systeem-UI-tuner beschikt u over extra manieren om de Android-gebruikersinterface aan te passen. Deze experimentele functies kunnen veranderen, vastlopen of verdwijnen in toekomstige releases. Ga voorzichtig verder."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Instellingen openen"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistent openen"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Scherm vergrendelen"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Notities openen"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Notitie maken"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Systeem-multitasking"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Gesplitst scherm openen met huidige app rechts"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Gesplitst scherm openen met huidige app links"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 0c51f5d2a1bd..ee9a5fd3c721 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"ସ୍କ୍ରିନ ରେକର୍ଡିଂ ସେଭ କରିବାରେ ତ୍ରୁଟି"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବାରେ ତ୍ରୁଟି"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"ସମସ୍ୟା ରେକର୍ଡର"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ସମସ୍ୟାର ରେକର୍ଡିଂର ପ୍ରକ୍ରିୟାକରଣ"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"ଏକ ସମସ୍ୟା ସଂଗ୍ରହ ସେସନ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"ରେକର୍ଡିଂରେ ସମସ୍ୟା"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"ସେୟାର କରନ୍ତୁ"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"ସମସ୍ୟାର ରେକର୍ଡିଂକୁ ସେଭ କରାଯାଇଛି"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"ସମସ୍ୟାର ରେକର୍ଡିଂ କରିବାରେ ତ୍ରୁଟି"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"ସମସ୍ୟାର ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବାରେ ତ୍ରୁଟି"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନରେ ଦେଖିବା"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"ବାହାରି ଯିବା ପାଇଁ, ଶୀର୍ଷରୁ ତଳକୁ ସ୍ୱାଇପ କରନ୍ତୁ।"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"ବୁଝିଗଲି"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ସେଭ କରାଯାଇଛି"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ଡିସକନେକ୍ଟ କରନ୍ତୁ"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ଚାଲୁ କରନ୍ତୁ"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ବ୍ୟାଟେରୀ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ଅଡିଓ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ହେଡସେଟ୍"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ଅକ୍ଷମ କରନ୍ତୁ"</string> <string name="sound_settings" msgid="8874581353127418308">"ସାଉଣ୍ଡ ଓ ଭାଇବ୍ରେସନ"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ସେଟିଂସ"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ଭଲ୍ୟୁମକୁ ସୁରକ୍ଷିତ ଲେଭେଲକୁ କମ କରାଯାଇଛି"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ସୁପାରିଶ ଭଲ୍ୟୁମ ଠାରୁ ହେଡଫୋନର ଭଲ୍ୟୁମ ଅଧିକ ଅଛି"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ଏହି ସପ୍ତାହ ପାଇଁ ହେଡଫୋନର ଭଲ୍ୟୁମ ସୁରକ୍ଷିତ ସୀମାକୁ ଅତିକ୍ରମ କରିଛି"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> ହେଲେ"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> ବେଳେ"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ହଟସ୍ପଟ୍"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"ସାଟେଲାଇଟ, କୌଣସି କନେକ୍ସନ ନାହିଁ"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ସାଟେଲାଇଟ, ଦୁର୍ବଳ କନେକ୍ସନ"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ସାଟେଲାଇଟ, ଭଲ କନେକ୍ସନ"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ସାଟେଲାଇଟ, କନେକ୍ସନ ଉପଲବ୍ଧ"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"ୱର୍କ ପ୍ରୋଫାଇଲ୍"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"କେତେକଙ୍କ ପାଇଁ ମଜାଦାର, କିନ୍ତୁ ସମସ୍ତଙ୍କ ପାଇଁ ନୁହେଁ"</string> <string name="tuner_warning" msgid="1861736288458481650">"Android ୟୁଜର୍ ଇଣ୍ଟରଫେସ୍ ବଦଳାଇବାକୁ ତଥା ନିଜ ପସନ୍ଦ ଅନୁଯାୟୀ କରିବାକୁ ସିଷ୍ଟମ୍ UI ଟ୍ୟୁନର୍ ଆପଣଙ୍କୁ ଅତିରିକ୍ତ ଉପାୟ ପ୍ରଦାନ କରେ। ଏହି ପରୀକ୍ଷାମୂଳକ ସୁବିଧାମାନ ବଦଳିପାରେ, ଭାଙ୍ଗିପାରେ କିମ୍ବା ଭବିଷ୍ୟତର ରିଲିଜ୍ଗୁଡ଼ିକରେ ନଦେଖାଯାଇପାରେ। ସତର୍କତାର ସହ ଆଗକୁ ବଢ଼ନ୍ତୁ।"</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"ସେଟିଂସ ଖୋଲନ୍ତୁ"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant ଖୋଲନ୍ତୁ"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"ଲକ ସ୍କ୍ରିନ"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Notes ଖୋଲନ୍ତୁ"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"ଏକ ନୋଟ ଲେଖନ୍ତୁ"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ସିଷ୍ଟମ ମଲ୍ଟିଟାସ୍କିଂ"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHSରେ ବର୍ତ୍ତମାନର ଆପ ସହ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ପ୍ରବେଶ କରାନ୍ତୁ"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHSରେ ବର୍ତ୍ତମାନର ଆପ ସହ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ପ୍ରବେଶ କରାନ୍ତୁ"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 79bd8d59d2dc..f81b3b49cc81 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋ ਗਈ"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋਈ"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"ਸਮੱਸਿਆ ਰਿਕਾਰਡਰ"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ਸਮੱਸਿਆ ਰਿਕਾਰਡਿੰਗ ਪ੍ਰਕਿਰਿਆ-ਅਧੀਨ ਹੈ"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"ਸਮੱਸਿਆ ਬਾਰੇ ਜਾਣਕਾਰੀ ਇਕੱਤਰ ਕਰਨ ਵਾਲੇ ਸੈਸ਼ਨ ਸੰਬੰਧੀ ਨਿਰੰਤਰ ਸੂਚਨਾ"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"ਸਮੱਸਿਆ ਨੂੰ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"ਸਾਂਝਾ ਕਰੋ"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"ਸਮੱਸਿਆ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"ਸਮੱਸਿਆ ਰਿਕਾਰਡਿੰਗ ਰੱਖਿਅਤ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋ ਗਈ"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"ਸਮੱਸਿਆ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋ ਗਈ"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"ਪੂਰੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦੇਖਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"ਬਾਹਰ ਜਾਣ ਲਈ, ਉਪਰੋਂ ਹੇਠਾਂ ਵੱਲ ਸਵਾਈਪ ਕਰੋ।"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"ਸਮਝ ਲਿਆ"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ਕਿਰਿਆਸ਼ੀਲ ਕਰੋ"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ਬੈਟਰੀ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ਆਡੀਓ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ਹੈੱਡਸੈੱਟ"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ਬੰਦ ਕਰੋ"</string> <string name="sound_settings" msgid="8874581353127418308">"ਧੁਨੀ ਅਤੇ ਥਰਥਰਾਹਟ"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ਸੈਟਿੰਗਾਂ"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ਅਵਾਜ਼ ਨੂੰ ਜ਼ਿਆਦਾ ਸੁਰੱਖਿਅਤ ਪੱਧਰ ਤੱਕ ਘੱਟ ਕੀਤਾ ਗਿਆ"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ਹੈੱਡਫ਼ੋਨ ਦੀ ਅਵਾਜ਼ ਸਿਫ਼ਾਰਸ਼ੀ ਪੱਧਰ ਨਾਲੋਂ ਜ਼ਿਆਦਾ ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਉੱਚੀ ਰਹੀ"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ਹੈੱਡਫ਼ੋਨ ਦੀ ਅਵਾਜ਼ ਇਸ ਹਫ਼ਤੇ ਦੀ ਸੁਰੱਖਿਅਤ ਸੀਮਾ ਨੂੰ ਪਾਰ ਕਰ ਗਈ"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> ਵਜੇ"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> ਵਜੇ"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ਹੌਟਸਪੌਟ"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਨਹੀਂ ਹੈ"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਖਰਾਬ ਹੈ"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਵਧੀਆ ਹੈ"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਉਪਲਬਧ ਹੈ"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"ਕੁਝ ਵਾਸਤੇ ਤਾਂ ਮਜ਼ੇਦਾਰ ਹੈ ਲੇਕਿਨ ਸਾਰਿਆਂ ਵਾਸਤੇ ਨਹੀਂ"</string> <string name="tuner_warning" msgid="1861736288458481650">"ਸਿਸਟਮ UI ਟਿਊਨਰ ਤੁਹਾਨੂੰ Android ਵਰਤੋਂਕਾਰ ਇੰਟਰਫ਼ੇਸ ਤਬਦੀਲ ਕਰਨ ਅਤੇ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਵਾਧੂ ਤਰੀਕੇ ਦਿੰਦਾ ਹੈ। ਇਹ ਪ੍ਰਯੋਗਾਤਮਿਕ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਭਵਿੱਖ ਦੀ ਰੀਲੀਜ਼ ਵਿੱਚ ਬਦਲ ਸਕਦੀਆਂ ਹਨ, ਟੁੱਟ ਸਕਦੀਆਂ ਹਨ, ਜਾਂ ਅਲੋਪ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਸਾਵਧਾਨੀ ਨਾਲ ਅੱਗੇ ਵੱਧੋ।"</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant ਖੋਲ੍ਹੋ"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"ਲਾਕ ਸਕ੍ਰੀਨ"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"ਨੋਟਸ ਖੋਲ੍ਹੋ"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"ਨੋਟ ਲਿਖੋ"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ਸਿਸਟਮ ਮਲਟੀਟਾਸਕਿੰਗ"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHS ਲਈ ਮੌਜੂਦਾ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHS ਲਈ ਮੌਜੂਦਾ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 019127dd0634..a22d77c17b2f 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Kliknij, aby wyświetlić"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Podczas zapisywania nagrania ekranu wystąpił błąd"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Błąd podczas rozpoczynania rejestracji zawartości ekranu"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Rejestrator problemów"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Przetwarzam nagranie problemu"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Powiadomienie o trwającej aktywności sesji nagrywania ekranu"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Nagrywanie problemu"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Udostępnij"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Zapisano nagranie problemu"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Kliknij, aby wyświetlić"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Błąd podczas zapisywania nagrania problemu"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Błąd podczas rozpoczynania nagrania problemu"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Włączony pełny ekran"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Aby wyjść, przesuń palcem z góry na dół."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Zapisane"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"rozłącz"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktywuj"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> naładowania baterii"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Dźwięk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Zestaw słuchawkowy"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"wyłącz"</string> <string name="sound_settings" msgid="8874581353127418308">"Dźwięk i wibracje"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ustawienia"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Głośność obniżona do bezpieczniejszego poziomu"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Głośność na słuchawkach jest zbyt duża przez czas dłuższy niż zalecany"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Głośność na słuchawkach przekroczyła limit bezpieczeństwa na ten tydzień"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"o <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"w: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelita – brak połączenia"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelita – połączenie słabe"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelita – połączenie dobre"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelita – połączenie dostępne"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil służbowy"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Dobra zabawa, ale nie dla każdego"</string> <string name="tuner_warning" msgid="1861736288458481650">"Kalibrator System UI udostępnia dodatkowe sposoby dostrajania i dostosowywania interfejsu Androida. Te eksperymentalne funkcje mogą się zmienić, popsuć lub zniknąć w przyszłych wersjach. Zachowaj ostrożność."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otwieranie ustawień"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otwieranie asystenta"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Blokada ekranu"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Otwieranie notatek"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Zanotuj"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Wielozadaniowość w systemie"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Uruchamianie trybu podzielonego ekranu z bieżącą aplikacją po prawej"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Uruchamianie trybu podzielonego ekranu z bieżącą aplikacją po lewej"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index a6341cc3f628..c4e2d3fd063e 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao salvar a gravação da tela"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Gravador de problemas"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processando a gravação do problema"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificação em andamento para uma sessão de coleta de problemas"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Gravando o problema"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Compartilhar"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"A gravação do problema foi salva"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Toque para ver"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Erro ao salvar a gravação do problema"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Erro ao iniciar a gravação do problema"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Visualização em tela cheia"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Para sair, deslize de cima para baixo."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Entendi"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvo"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Fone de ouvido"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desativar"</string> <string name="sound_settings" msgid="8874581353127418308">"Som e vibração"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Configurações"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume diminuído para um nível mais seguro"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"O volume dos fones de ouvido está alto há mais tempo que o recomendado"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"O volume dos fones de ouvido excedeu o limite de segurança para esta semana"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"às <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Ponto de acesso"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satélite, sem conexão"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, conexão ruim"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, conexão boa"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexão disponível"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string> <string name="tuner_warning" msgid="1861736288458481650">"O sintonizador System UI fornece maneiras adicionais de ajustar e personalizar a interface do usuário do Android. Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir configurações"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir o Google Assistente"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Tela de bloqueio"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir observações"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Crie uma nota"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitarefa do sistema"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Usar a tela dividida com o app atual à direita"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Usar a tela dividida com o app atual à esquerda"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 72cc01e52476..267c8cd64bb8 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao guardar a gravação de ecrã"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Ocorreu um erro ao iniciar a gravação do ecrã."</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Registador de problemas"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"A proc. registo de problemas"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificação em curso de uma sessão de recolha de problemas"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Problema na gravação"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Partilhar"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Registo de problemas guardado"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Toque para ver"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Erro ao guardar o registo de problemas"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Erro ao iniciar o registo de problemas"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Visualização de ecrã inteiro"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Para sair, deslize rapidamente para baixo a partir da parte superior."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desassociar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ausc. c/ mic. integ."</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desativar"</string> <string name="sound_settings" msgid="8874581353127418308">"Som e vibração"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Definições"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Legendas instantâneas"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume reduzido para um nível mais seguro"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"O volume dos auscultadores está elevado há mais tempo do que o recomendado"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"O volume dos auscultadores excedeu o limite seguro para esta semana"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"às <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"em <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Zona Wi-Fi"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satélite, sem ligação"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, ligação fraca"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, boa ligação"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, ligação disponível"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string> <string name="tuner_warning" msgid="1861736288458481650">"O Sintonizador da interface do sistema disponibiliza-lhe formas adicionais ajustar e personalizar a interface do utilizador do Android. Estas funcionalidades experimentais podem ser alteradas, deixar de funcionar ou desaparecer em versões futuras. Prossiga com cuidado."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir definições"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir Assistente"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Ecrã de bloqueio"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir notas"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Tire uma nota"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Execução de várias tarefas em simultâneo no sistema"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Aceder ao ecrã dividido com a app atual para RHS"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Aceder ao ecrã dividido com a app atual para LHS"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index a6341cc3f628..c4e2d3fd063e 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao salvar a gravação da tela"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Gravador de problemas"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processando a gravação do problema"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificação em andamento para uma sessão de coleta de problemas"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Gravando o problema"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Compartilhar"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"A gravação do problema foi salva"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Toque para ver"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Erro ao salvar a gravação do problema"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Erro ao iniciar a gravação do problema"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Visualização em tela cheia"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Para sair, deslize de cima para baixo."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Entendi"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvo"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Fone de ouvido"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desativar"</string> <string name="sound_settings" msgid="8874581353127418308">"Som e vibração"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Configurações"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume diminuído para um nível mais seguro"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"O volume dos fones de ouvido está alto há mais tempo que o recomendado"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"O volume dos fones de ouvido excedeu o limite de segurança para esta semana"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"às <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Ponto de acesso"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satélite, sem conexão"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, conexão ruim"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, conexão boa"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexão disponível"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string> <string name="tuner_warning" msgid="1861736288458481650">"O sintonizador System UI fornece maneiras adicionais de ajustar e personalizar a interface do usuário do Android. Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir configurações"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir o Google Assistente"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Tela de bloqueio"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir observações"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Crie uma nota"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitarefa do sistema"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Usar a tela dividida com o app atual à direita"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Usar a tela dividida com o app atual à esquerda"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index fc420a02aa2e..91a5f82fdab9 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Atinge pentru a afișa"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Eroare la salvarea înregistrării ecranului"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Eroare la începerea înregistrării ecranului"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Instrument de înregistrare a problemelor"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Se procesează înregistrarea problemei"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Notificare în curs pentru o sesiune de înregistrare a problemei"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Se înregistrează problema"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Trimite"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Înregistrarea problemei a fost salvată"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Atinge pentru a afișa"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Eroare la salvarea înregistrării problemei"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Eroare la începerea înregistrării problemei"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Vizualizare pe ecran complet"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Pentru a ieși, glisează de sus în jos."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvat"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"deconectează"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activează"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Căști"</string> @@ -307,7 +302,7 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Luminozitate"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversarea culorilor"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Corecția culorii"</string> - <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Dimensiunea fontului"</string> + <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Mărimea fontului"</string> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gestionează"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Terminat"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Închide"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"dezactivează"</string> <string name="sound_settings" msgid="8874581353127418308">"Sunete și vibrații"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Setări"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volumul a fost redus la un nivel mai sigur"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volumul căștilor a fost ridicat mai mult timp decât este recomandat"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volumul căștilor a depășit limita de siguranță pentru săptămâna aceasta"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"la <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelit, fără conexiune"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, conexiune slabă"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, conexiune bună"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, conexiune disponibilă"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil de serviciu"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Distractiv pentru unii, dar nu pentru toată lumea"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner oferă modalități suplimentare de a ajusta și a personaliza interfața de utilizare Android. Aceste funcții experimentale pot să se schimbe, să se blocheze sau să dispară din versiunile viitoare. Continuă cu prudență."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Deschide setările"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Deschide Asistentul"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Ecranul de blocare"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Deschide notele"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Creează o notă"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking pe sistem"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Accesează ecranul împărțit cu aplicația actuală în dreapta"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Accesează ecranul împărțit cu aplicația actuală în stânga"</string> @@ -918,7 +911,7 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"înregistrare de ecran"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"Fără titlu"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> - <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Dimensiunea fontului"</string> + <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Mărimea fontului"</string> <string name="font_scaling_smaller" msgid="1012032217622008232">"Micșorează"</string> <string name="font_scaling_larger" msgid="5476242157436806760">"Mărește"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Fereastra de mărire"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index a24039bf9c5a..bc8e2f7fd097 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Нажмите, чтобы посмотреть."</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Не удалось сохранить запись видео с экрана."</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Не удалось начать запись видео с экрана."</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Запись проблем на видео"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Обрабатываем запись"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Текущее уведомление о записи проблемы на видео"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Записываем проблему на видео"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Поделиться"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Запись сохранена."</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Нажмите, чтобы посмотреть."</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Не удалось сохранить запись."</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Не удалось начать запись."</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Полноэкранный режим"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Чтобы выйти, проведите по экрану сверху вниз."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"ОК"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сохранено"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"отключить"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активировать"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудиоустройство"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"отключить"</string> <string name="sound_settings" msgid="8874581353127418308">"Звук и вибрация"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Открыть настройки"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Громкость уменьшена до безопасного уровня"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Вы используете наушники при высоком уровне громкости дольше, чем рекомендуется."</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Превышен безопасный лимит громкости наушников на этой неделе."</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Точка доступа"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Спутниковая связь, нет соединения"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Спутниковая связь, плохое качество соединения"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спутниковая связь, хорошее качество соединения"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Доступно соединение по спутниковой связи"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Рабочий профиль"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Внимание!"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner позволяет настраивать интерфейс устройства Android по вашему вкусу. В будущем эта экспериментальная функция может измениться, перестать работать или исчезнуть."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Открыть настройки"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Открыть Ассистента"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Заблокировать экран"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Открыть заметки"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Создать заметку"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Режим многозадачности"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Включить разделение экрана с текущим приложением справа"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Включить разделение экрана с текущим приложением слева"</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index de347ad273e7..1e2c69546ee2 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"බැලීමට තට්ටු කරන්න"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"තිර පටිගත කිරීම සුරැකීමේ දෝෂයකි"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"තිර පටිගත කිරීම ආරම්භ කිරීමේ දෝෂයකි"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"ගැටලු රෙකෝඩරය"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ගැටලු වාර්තාව සැකසුම් කිරීම"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"ගැටලු එකතු කිරීමේ සැසියක් සඳහා දැනට පවතින දැනුම්දීම"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"ගැටලුව සටහන් කිරීම"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"බෙදා ගන්න"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"ගැටලු පටිගත කිරීම සුරැකිණි"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"බැලීමට තට්ටු කරන්න"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"ගැටලුව සටහන් කිරීම සුරැකීමේ දෝෂය"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"ගැටලුව වාර්තා කිරීම ආරම්භ කිරීමේ දෝෂය"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"මුළු තිරය බලමින්"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"ඉවත් වීමට, ඉහළ සිට පහළට ස්වයිප් කරන්න"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"තේරුණා"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"සුරැකිණි"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"විසන්ධි කරන්න"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"සක්රිය කරන්න"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ශ්රව්ය"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"හෙඩ්සෙටය"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"අබල කරන්න"</string> <string name="sound_settings" msgid="8874581353127418308">"ශබ්ද සහ කම්පනය"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"සැකසීම්"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"හඬ පරිමාව සුරක්ෂිත මට්ටමට අඩු කරන ලදි"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"නිර්දේශිත ප්රමාණයට වඩා වැඩි කාලයක් හෙඩ්ෆෝන් හඬ පරිමාව ඉහළ මට්ටමක පවතී"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"හෙඩ්ෆෝන් හඬ පරිමාව මෙම සතිය සඳහා සුරක්ෂිත සීමාව ඉක්මවා ඇත"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> ට"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> දී"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"හොට්ස්පොට්"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"චන්ද්රිකාව, සම්බන්ධයක් නැත"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"චන්ද්රිකාව, දුර්වල සම්බන්ධතාවය"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"චන්ද්රිකාව, හොඳ සම්බන්ධතාවයක්"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"චන්ද්රිකාව, සම්බන්ධතාවය තිබේ"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"කාර්යාල පැතිකඩ"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"සමහරක් දේවල් වලට විනෝදයි, නමුත් සියල්ලටම නොවේ"</string> <string name="tuner_warning" msgid="1861736288458481650">"පද්ධති UI සුසරකය ඔබට Android පරිශීලක අතුරු මුහුණත වෙනස් කිරීමට හෝ අභිරුචිකරණය කිරීමට අමතර ක්රම ලබා දේ. මෙම පර්යේෂණාත්මක අංග ඉදිරි නිකුත් වීම් වල වෙනස් වීමට, වැඩ නොකිරීමට, හෝ නැතිවීමට හැක. ප්රවේශමෙන් ඉදිරියට යන්න."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"සැකසීම් විවෘත කරන්න"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"සහායක විවෘත කරන්න"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"තිරය අගුළු දමන්න"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"සටහන් විවෘත කරන්න"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"සටහනක් ගන්න"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"පද්ධති බහු කාර්ය"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHS වෙත වත්මන් යෙදුම සමග බෙදුම් තිරයට ඇතුළු වන්න"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHS වෙත වත්මන් යෙදුම සමග බෙදුම් තිරයට ඇතුළු වන්න"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 60d3200e497e..1a3cac13bc5d 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Zobrazte klepnutím"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Pri ukladaní nahrávky obrazovky sa vyskytla chyba"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Pri spustení nahrávania obrazovky sa vyskytla chyba"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Nástroj na zaznamenávanie problémov"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Záznam problému sa spracúva"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Upozornenie na prebiehajúcu aktivitu týkajúcu sa relácie zhromažďovania problémov"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Problém sa zaznamenáva"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Zdieľať"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Záznam problému bol uložený"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Zobrazíte ho klepnutím"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Pri ukladaní záznamu problému sa vyskytla chyba"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Pri spúšťaní záznamu problému sa vyskytla chyba"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Zobrazenie na celú obrazovku"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Ukončíte potiahnutím zhora nadol."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Dobre"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Uložené"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"odpojiť"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivovať"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Náhlavná súprava"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"zakázať"</string> <string name="sound_settings" msgid="8874581353127418308">"Zvuk a vibrácie"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Nastavenia"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Hlasitosť bola znížená na bezpečnejšiu úroveň"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Hlasitosť slúchadiel bola vysoká dlhšie, ako sa odporúča"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Hlasitosť slúchadiel prekročila bezpečný limit pre tento týždeň"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"o <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelit, bez pripojenia"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slabá kvalita pripojenia"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobrá kvalita pripojenia"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, pripojenie je k dispozícii"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Pracovný profil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Pri používaní tuneru postupujte opatrne"</string> <string name="tuner_warning" msgid="1861736288458481650">"Tuner používateľského rozhrania systému poskytujte ďalšie spôsoby ladenia a prispôsobenia používateľského rozhrania Android. Tieto experimentálne funkcie sa môžu v budúcich verziách zmeniť, ich poskytovanie môže byť prerušené alebo môžu byť odstránené. Pokračujte opatrne."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvorenie nastavení"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvorenie Asistenta"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Zamknúť obrazovku"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Otvorenie poznámok"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Napísanie poznámky"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking systému"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Rozdelenie obrazovky s aktuálnou aplikáciou vpravo"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Rozdelenie obrazovky s aktuálnou aplikáciou vľavo"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 29f023f4844c..0611b601725c 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Dotaknite se za ogled."</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Napaka pri shranjevanju posnetka zaslona"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Napaka pri začenjanju snemanja zaslona"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Snemalnik težav"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Obdelovanje posnetka težave"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Obvestilo o aktivni dejavnosti za sejo zbiranja težav"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Snemanje težave"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Deli"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Posnetek težave je shranjen"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Dotaknite se za ogled"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Napaka pri shranjevanju posnetka težave"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Napaka pri zagonu snemanja težave"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Vklopljen je celozaslonski način."</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Zaprete ga tako, da z vrha s prstom povlečete navzdol."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Razumem"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Shranjeno"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekinitev povezave"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviranje"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterija na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvok"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalke z mikrofonom"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"onemogoči"</string> <string name="sound_settings" msgid="8874581353127418308">"Zvok in vibriranje"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Nastavitve"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Samodejni podnapisi"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Glasnost je bila zmanjšana na varnejšo raven"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Glasnost v slušalkah je bila visoka dalj časa, kot je priporočeno."</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Visoka glasnost v slušalkah je presegla varno omejitev za ta teden"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"ob <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"ob tem času: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Dostopna točka"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satelit, ni povezave"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slaba povezava"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra povezava"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, povezava je na voljo"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Delovni profil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Zabavno za nekatere, a ne za vse"</string> <string name="tuner_warning" msgid="1861736288458481650">"Uglaševalnik uporabniškega vmesnika sistema vam omogoča dodatne načine za spreminjanje in prilagajanje uporabniškega vmesnika Android. Te poskusne funkcije lahko v prihodnjih izdajah kadar koli izginejo, se spremenijo ali pokvarijo. Bodite previdni."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Odpiranje nastavitev"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Odpiranje Pomočnika"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaklepanje zaslona"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Odpiranje zapiskov"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Ustvarjanje zapiska"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Sistemska večopravilnost"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Vklop razdeljenega zaslona s trenutno aplikacijo na desni"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Vklop razdeljenega zaslona s trenutno aplikacijo na levi"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index c8f6f0eedd6b..447f162a653c 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Trokit për të parë"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Gabim gjatë ruajtjes së regjistrimit të ekranit"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Gabim gjatë nisjes së regjistrimit të ekranit"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Regjistruesi i problemeve"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Regjistrimi i problemeve me përpunimin"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Njoftim në vazhdim për një seancë për mbledhjen e problemeve"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Problemi po regjistrohet"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Ndaj"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Regjistrimi i problemit u ruajt"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Trokit për të parë"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Gabim gjatë ruajtjes së regjistrimit të problemit"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Gabim gjatë nisjes së regjistrimit të problemit"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Po shikon ekranin e plotë"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Për të dalë, rrëshqit shpejt poshtë."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"E kuptova"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Ruajtur"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"shkëput"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivizo"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Kufje me mikrofon"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"çaktivizo"</string> <string name="sound_settings" msgid="8874581353127418308">"Tingulli dhe dridhjet"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Cilësimet"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volumi është ulur në një nivel më të sigurt"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volumi i kufjeve ka qenë i lartë për një kohë më të gjatë nga sa rekomandohet"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volumi i kufjeve ka tejkaluar kufirin e sigurisë për këtë javë"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"në <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"në <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Zona e qasjes për internet"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Sateliti. Nuk ka lidhje"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Sateliti. Lidhje e dobët"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Sateliti. Lidhje e mirë"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Sateliti. Ofrohet lidhje"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profili i punës"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Argëtim për disa, por jo për të gjithë!"</string> <string name="tuner_warning" msgid="1861736288458481650">"Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit të jep mënyra shtesë për të tërhequr dhe personalizuar ndërfaqen Android të përdoruesit. Këto funksione eksperimentale mund të ndryshojnë, prishen ose zhduken në versionet e ardhshme. Vazhdo me kujdes."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Hap cilësimet"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Hap \"Asistentin\""</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Ekrani i kyçjes"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Hap \"Shënimet\""</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Mbaj një shënim"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Kryerja e shumë detyrave nga sistemi"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Hyr në ekranin e ndarë me aplikacionin aktual në anën e djathtë"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Hyr në ekranin e ndarë me aplikacionin aktual në anën e majtë"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 26548721881f..5bc9db78f84d 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Додирните да бисте прегледали"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при чувању снимка екрана"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при покретању снимања екрана"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Снимач проблема"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Обрађује се снимак проблема"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"обавештење о активности у току за сесију прикупљања података о проблему"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Снимамо проблем"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Дели"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Снимак проблема је сачуван"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Додирните да бисте прегледали"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Грешка при чувању снимка проблема"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Грешка при покретању снимања проблема"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Приказује се цео екран"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Да бисте изашли, превуците надоле одозго."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Важи"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сачувано"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"прекините везу"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активирајте"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Аутоматски поново укључи сутра"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Функције као што су Quick Share, Пронађи мој уређај и локација уређаја користе Bluetooth"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалице"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"онемогућите"</string> <string name="sound_settings" msgid="8874581353127418308">"Звук и вибрирање"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Подешавања"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Титл уживо"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Звук је смањен на безбедну јачину"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Звук у слушалицама је био гласан дуже него што се препоручује"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Јачина звука у слушалицама је премашила безбедносно ограничење за ову недељу"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Хотспот"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Сателит, нисте повезани"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Сателит, веза је лоша"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Сателит, веза је добра"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Сателит, веза је доступна"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Пословни профил"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Забава за неке, али не за све"</string> <string name="tuner_warning" msgid="1861736288458481650">"Тјунер за кориснички интерфејс система вам пружа додатне начине за подешавање и прилагођавање Android корисничког интерфејса. Ове експерименталне функције могу да се промене, откажу или нестану у будућим издањима. Будите опрезни."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Отвори подешавања"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Отвори помоћника"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Закључавање екрана"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Отвори белешке"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Направите белешку"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Обављање више задатака система истовремено"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Покрени подељени екран за актуелну апликацију на десној страни"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Покрени подељени екран за актуелну апликацију на левој страни"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 34078dac243d..bbc9fd63a235 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Tryck för att visa"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Det gick inte att spara skärminspelningen"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Det gick inte att starta skärminspelningen"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Probleminspelare"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Behandlar probleminspelning"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Avisering om pågående probleminsamlingssession"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Spelar in problem"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Dela"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Probleminspelning har sparats"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Visa genom att trycka här"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Det gick inte att spara probleminspelning"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Det gick inte att starta probleminspelning"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Visar på fullskärm"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Svep nedåt från skärmens överkant för att avsluta."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sparad"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"koppla från"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivera"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ljud"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"inaktivera"</string> <string name="sound_settings" msgid="8874581353127418308">"Ljud och vibration"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Inställningar"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volymen har sänkts till en säkrare nivå"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volymen i hörlurarna har varit hög längre än vad som rekommenderas"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volymen i hörlurarna har överskridit den säkra gränsen för veckan"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Surfzon"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satellit, ingen anslutning"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellit, dålig anslutning"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit, bra anslutning"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit, anslutning tillgänglig"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Jobbprofil"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Kul för vissa, inte för alla"</string> <string name="tuner_warning" msgid="1861736288458481650">"Du kan använda inställningarna för systemgränssnitt för att justera användargränssnittet i Android. Dessa experimentfunktioner kan när som helst ändras, sluta fungera eller försvinna. Använd med försiktighet."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Öppna inställningarna"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Öppna assistenten"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Lås skärmen"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Öppna anteckningar"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Anteckna"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Systemets multikörning"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Öppna delad skärm med aktuell app till höger"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Öppna delad skärm med aktuell app till vänster"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 74b6c8842b47..4a735682491a 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Gusa ili uangalie"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Hitilafu imetokea wakati wa kuhifadhi rekodi ya skrini"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Hitilafu imetokea wakati wa kuanza kurekodi skrini"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Kifaa cha Kurekodi Hitilafu"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Mchakato wa kurekodi hitilafu unaendelea"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Arifa inayoendelea kuhusu kipindi cha ukusanyaji wa data ya hitilafu"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Inarekodi hitilafu"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Tuma"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Imehifadhi rekodi ya hitilafu"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Gusa ili uangalie"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Hitilafu imetokea wakati wa kuhifadhi rekodi ya hitilafu"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Hitilafu imetokea wakati wa kuanza kurekodi hitilafu"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Unatazama kwenye skrini nzima"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Ili uondoke, telezesha kidole kutoka juu hadi chini."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Nimeelewa"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Imehifadhiwa"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ondoa"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"anza kutumia"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Sauti"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Vifaa vya sauti"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"zima"</string> <string name="sound_settings" msgid="8874581353127418308">"Sauti na mtetemo"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Mipangilio"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Manukuu Papo Hapo"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Kiwango cha sauti kimepunguzwa hadi kiwango salama"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Kiwango cha sauti ya vipokea sauti vya kichwani kimekuwa juu kwa muda mrefu kuliko inavyopendekezwa"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Kiwango cha sauti ya vipokea sauti vya kichwani kimezidi kikomo cha kiwango salama kwa wiki hii"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"saa <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"siku ya <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Mtandaopepe"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Setilaiti, hakuna muunganisho"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Setilaiti, muunganisho hafifu"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Setilaiti, muunganisho thabiti"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Setilaiti, muunganisho unapatikana"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Wasifu wa kazini"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Kinafurahisha kwa baadhi ya watu lakini si wote"</string> <string name="tuner_warning" msgid="1861736288458481650">"Kirekebishi cha kiolesura cha mfumo kinakupa njia zaidi za kugeuza na kubadilisha kiolesura cha Android ili kikufae. Vipengele hivi vya majaribio vinaweza kubadilika, kuharibika au kupotea katika matoleo ya siku zijazo. Endelea kwa uangalifu."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Fungua mipangilio"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Fungua programu ya Mratibu wa Google"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Funga skrini"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Fungua madokezo"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Andika dokezo"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Majukumu mengi ya mfumo"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Tumia programu kwenye skrini iliyogawanywa upande wa kulia"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Tumia programu kwenye skrini iliyogawanywa upande wa kushoto"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index cbf7f77f721f..6a1e64eb49e4 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"பார்க்கத் தட்டவும்"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"ஸ்கிரீன் ரெக்கார்டிங்கைச் சேமிப்பதில் பிழை ஏற்பட்டது"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"ஸ்கிரீன் ரெக்கார்டிங்கைத் தொடங்குவதில் பிழை"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"சிக்கல் ரெக்கார்டர்"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"சிக்கல் ரெக்கார்டிங்கைச் செயலாக்குகிறது"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"சிக்கல் சேகரிப்பு அமர்வுக்கான பின்னணிச் செயல்பாட்டின் அறிவிப்பு"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"சிக்கல் ரெக்கார்டு செய்யப்படுகிறது"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"பகிர்"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"சிக்கல் தொடர்பான ரெக்கார்டிங் சேமிக்கப்பட்டது"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"பார்க்க தட்டவும்"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"சிக்கல் தொடர்பான ரெக்கார்டிங்கைச் சேமிப்பதில் பிழை ஏற்பட்டது"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"சிக்கலை ரெக்கார்டிங் செய்யத் தொடங்குவதில் பிழை ஏற்பட்டது"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"முழுத் திரையில் காட்டுகிறது"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"வெளியேற, மேலிருந்து கீழே ஸ்வைப் செய்யவும்."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"சரி"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"சேமிக்கப்பட்டது"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"இணைப்பு நீக்கும்"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"செயல்படுத்தும்"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> பேட்டரி"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ஆடியோ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ஹெட்செட்"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"முடக்கும்"</string> <string name="sound_settings" msgid="8874581353127418308">"ஒலி & அதிர்வு"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"அமைப்புகள்"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"பாதுகாப்பான நிலைக்கு ஒலியளவு குறைக்கப்பட்டது"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ஹெட்ஃபோன் ஒலியளவு பரிந்துரைக்கப்பட்டதைவிட அதிகளவில் நீண்ட நேரமாக உள்ளது"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"இந்த வாரம் ஹெட்ஃபோன் ஒலியளவு பாதுகாப்பு வரம்பைக் கடந்துவிட்டது"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> மணிக்கு"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> மணிக்கு"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ஹாட்ஸ்பாட்"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"சாட்டிலைட், இணைப்பு இல்லை"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"சாட்டிலைட், மோசமான இணைப்பு"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"சாட்டிலைட், நிலையான இணைப்பு"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"சாட்டிலைட், இணைப்பு கிடைக்கிறது"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"பணிக் கணக்கு"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"சில வேடிக்கையாக இருந்தாலும் கவனம் தேவை"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner, Android பயனர் இடைமுகத்தை மாற்றவும் தனிப்பயனாக்கவும் கூடுதல் வழிகளை வழங்குகிறது. இந்தப் பரிசோதனைக்குரிய அம்சங்கள் எதிர்கால வெளியீடுகளில் மாற்றப்படலாம், இடைநிறுத்தப்படலாம் அல்லது தோன்றாமல் போகலாம். கவனத்துடன் தொடரவும்."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"அமைப்புகளைத் திறத்தல்"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistantடைத் திறத்தல்"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"பூட்டுத் திரை"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"குறிப்புகளைத் திறத்தல்"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"குறிப்பெடுத்தல்"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"சிஸ்டம் பல வேலைகளைச் செய்தல்"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"வலதுபுறத்தில் தற்போதைய ஆப்ஸ் தோன்றுமாறு திரைப் பிரிப்பை அமைத்தல்"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"இடதுபுறத்தில் தற்போதைய ஆப்ஸ் தோன்றுமாறு திரைப் பிரிப்பை அமைத்தல்"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 5234125d2183..4a494ceca1b3 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"చూడటానికి ట్యాప్ చేయండి"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"స్క్రీన్ రికార్డింగ్ను సేవ్ చేయడంలో ఎర్రర్ ఏర్పడింది"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"స్క్రీన్ రికార్డింగ్ ప్రారంభించడంలో ఎర్రర్ ఏర్పడింది"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"సమస్య రికార్డర్"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"సమస్య రికార్డింగ్ ప్రాసెసింగ్"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"సమస్య సేకరణ సెషన్ కోసం కొనసాగుతోన్న నోటిఫికేషన్"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"సమస్యను రికార్డ్ చేస్తోంది"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"షేర్ చేయండి"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"రికార్డింగ్ సంబంధిత సమస్య సేవ్ చేయబడింది"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"చూడటానికి ట్యాప్ చేయండి"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"సమస్య రికార్డింగ్ను సేవ్ చేయడంలో ఎర్రర్ ఏర్పడింది"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"సమస్య రికార్డింగ్ను ప్రారంభించడంలో ఎర్రర్ ఏర్పడింది"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"ఫుల్ స్క్రీన్లో చూస్తున్నారు"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"నిష్క్రమించడానికి, పై నుండి కిందికి స్వైప్ చేయండి."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"సరే"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"సేవ్ చేయబడింది"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"డిస్కనెక్ట్ చేయండి"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"యాక్టివేట్ చేయండి"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> బ్యాటరీ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ఆడియో"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"హెడ్సెట్"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"నిలిపివేయండి"</string> <string name="sound_settings" msgid="8874581353127418308">"సౌండ్ & వైబ్రేషన్"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"సెట్టింగ్లు"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"లైవ్ క్యాప్షన్"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"వాల్యూమ్ను సురక్షిత స్థాయికి తగ్గించడం జరిగింది"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"హెడ్ఫోన్ వాల్యూమ్, సిఫార్సు చేసిన సమయం కంటే ఎక్కువసేపు అధిక వాల్యూమ్లో ఉంది"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"హెడ్ఫోన్ వాల్యూమ్ ఈ వారం సురక్షిత పరిమితిని మించిపోయింది"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>కి"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>కి"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"హాట్స్పాట్"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"శాటిలైట్, కనెక్షన్ లేదు"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"శాటిలైట్, కనెక్షన్ సరిగా లేదు"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"శాటిలైట్, కనెక్షన్ బాగుంది"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"శాటిలైట్, కనెక్షన్ అందుబాటులో ఉంది"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"ఆఫీస్ ప్రొఫైల్"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"కొందరికి సరదాగా ఉంటుంది కానీ అందరికీ అలాగే ఉండదు"</string> <string name="tuner_warning" msgid="1861736288458481650">"సిస్టమ్ UI ట్యూనర్ Android వినియోగదారు ఇంటర్ఫేస్ను మెరుగుపరచడానికి మరియు అనుకూలంగా మార్చడానికి మీకు మరిన్ని మార్గాలను అందిస్తుంది. ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"సెట్టింగ్లను తెరవండి"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"అసిస్టెంట్ను తెరవండి"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"లాక్ స్క్రీన్"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"నోట్స్ను తెరవండి"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"గమనికను రాయండి"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"సిస్టమ్ మల్టీ-టాస్కింగ్"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHSకు ప్రస్తుత యాప్తో స్ప్లిట్ స్క్రీన్ను ఎంటర్ చేయండి"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHSకు ప్రస్తుత యాప్తో స్ప్లిట్ స్క్రీన్ను ఎంటర్ చేయండి"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 9316f1687eec..fd4bead3ec43 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"แตะเพื่อดู"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"เกิดข้อผิดพลาดในการบันทึกหน้าจอ"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"เกิดข้อผิดพลาดขณะเริ่มบันทึกหน้าจอ"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"โปรแกรมบันทึกปัญหา"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"กำลังประมวลผลการบันทึกปัญหา"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการรวบรวมปัญหา"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"กำลังบันทึกปัญหา"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"แชร์"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"บันทึกไฟล์บันทึกปัญหาแล้ว"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"แตะเพื่อดู"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"เกิดข้อผิดพลาดในการบันทึกไฟล์บันทึกปัญหา"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"เกิดข้อผิดพลาดในการเริ่มบันทึกปัญหา"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"กำลังดูแบบเต็มหน้าจอ"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"หากต้องการออก ให้ปัดลงจากด้านบน"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"รับทราบ"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"บันทึกแล้ว"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ยกเลิกการเชื่อมต่อ"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"เปิดใช้งาน"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"เปิดอีกครั้งโดยอัตโนมัติในวันพรุ่งนี้"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ฟีเจอร์ต่างๆ เช่น Quick Share, หาอุปกรณ์ของฉัน และตำแหน่งของอุปกรณ์ ใช้บลูทูธ"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"เสียง"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ชุดหูฟัง"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ปิดใช้"</string> <string name="sound_settings" msgid="8874581353127418308">"เสียงและการสั่น"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"การตั้งค่า"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"คำบรรยายสด"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ลดเสียงให้อยู่ในระดับที่ปลอดภัยยิ่งขึ้น"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"เสียงของหูฟังอยู่ในระดับที่ดังเป็นระยะเวลานานกว่าที่แนะนำ"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"เสียงของหูฟังอยู่ในระดับที่ดังเกินขีดจำกัดความปลอดภัยสำหรับสัปดาห์นี้"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"เวลา <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"ในวันที่ <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ฮอตสปอต"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"ดาวเทียม, ไม่มีการเชื่อมต่อ"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ดาวเทียม, การเชื่อมต่อไม่ดี"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ดาวเทียม, การเชื่อมต่อดี"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ดาวเทียม, การเชื่อมต่อที่พร้อมใช้งาน"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"โปรไฟล์งาน"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"เพลิดเพลินกับบางส่วนแต่ไม่ใช่ทั้งหมด"</string> <string name="tuner_warning" msgid="1861736288458481650">"ตัวรับสัญญาณ UI ระบบช่วยให้คุณมีวิธีพิเศษในการปรับแต่งและกำหนดค่าส่วนติดต่อผู้ใช้ Android ฟีเจอร์รุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"เปิดการตั้งค่า"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"เปิด Assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"ล็อกหน้าจอ"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"เปิดโน้ต"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"จดโน้ต"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"การทํางานหลายอย่างพร้อมกันของระบบ"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"เข้าสู่โหมดแยกหน้าจอโดยแอปปัจจุบันอยู่ด้านขวา"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"เข้าสู่โหมดแยกหน้าจอโดยแอปปัจจุบันอยู่ด้านซ้าย"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 9c7b1bfc0f2d..5388d7a9ebd0 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"I-tap para tingnan"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Nagka-error sa pag-save ng recording ng screen"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Nagkaroon ng error sa pagsisimula ng pag-record ng screen"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Recorder ng Isyu"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Pinoproseso: recording ng isyu"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Kasalukuyang notification para sa session ng pangongolekta ng isyu"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Isyu sa pag-record"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Ibahagi"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Na-save ang recording ng isyu"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"I-tap para tingnan"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Nagkaroon ng error sa pag-save ng recording ng isyu"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Nagkaroon ng error sa pagsisimula ng pag-record ng isyu"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Nanonood sa full screen"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Para lumabas, mag-swipe mula sa itaas pababa."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,8 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Na-save"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"idiskonekta"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"i-activate"</string> + <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Awtomatikong i-on ulit bukas"</string> + <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Guamgamit ng Bluetooth ang mga feature tulad ng Quick Share, Hanapin ang Aking Device, at lokasyon ng device"</string> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> na baterya"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -546,6 +539,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"i-disable"</string> <string name="sound_settings" msgid="8874581353127418308">"Tunog at pag-vibrate"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Mga Setting"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Instant Caption"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Ibinaba sa mas ligtas na level ang volume"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Naging malakas ang volume ng headphones nang mas matagal sa inirerekomenda"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Lampas na sa ligtas na limitasyon para sa linggong ito ang volume ng headphone"</string> @@ -612,14 +606,10 @@ <string name="alarm_template" msgid="2234991538018805736">"ng <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"sa <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Satellite, walang koneksyon"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, mahina ang koneksyon"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, malakas ang koneksyon"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, may koneksyon"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profile sa trabaho"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Masaya para sa ilan ngunit hindi para sa lahat"</string> <string name="tuner_warning" msgid="1861736288458481650">"Nagbibigay sa iyo ang Tuner ng System UI ng mga karagdagang paraan upang baguhin at i-customize ang user interface ng Android. Ang mga pang-eksperimentong feature na ito ay maaaring magbago, masira o mawala sa mga pagpapalabas sa hinaharap. Magpatuloy nang may pag-iingat."</string> @@ -741,7 +731,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Buksan ang mga setting"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Buksan ang assistant"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"I-lock ang screen"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Buksan ang mga tala"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Magtala"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking ng system"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Lumipat sa split screen nang nasa RHS ang kasalukuyang app"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Lumipat sa split screen nang nasa LHS ang kasalukuyang app"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 6ff03a965a58..fbced87dea31 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Görüntülemek için dokunun"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran kaydı saklanırken hata oluştu"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Ekran kaydı başlatılırken hata oluştu"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Sorun Kaydedici"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Sorun kaydı işleniyor"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Sorun toplama oturumuyla ilgili devam eden görev bildirimi"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Kayıt sorunu"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Paylaş"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Sorun kaydı saklandı"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Görüntülemek için dokunun"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Sorun kaydı saklanırken hata oluştu"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Sorun kaydı başlatılırken hata oluştu"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Tam ekran olarak görüntüleme"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Çıkmak için yukarıdan aşağıya doğru hızlıca kaydırın."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Anladım"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Kaydedildi"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"bağlantıyı kes"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"etkinleştir"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pil düzeyi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ses"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Mikrofonlu kulaklık"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"devre dışı bırak"</string> <string name="sound_settings" msgid="8874581353127418308">"Ses ve titreşim"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ayarlar"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"Canlı Altyazı"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Ses düzeyi daha güvenli bir düzeye indirildi"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Ses, önerilenden daha uzun süredir yüksek düzeydeydi"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Bu hafta kulaklığın ses düzeyi güvenli sınırı aştı"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"saat: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"gün ve saat: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Uydu, bağlantı yok"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Uydu, bağlantı zayıf"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Uydu, bağlantı güçlü"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Uydu, bağlantı mevcut"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"İş profili"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Bazıları için eğlenceliyken diğerleri için olmayabilir"</string> <string name="tuner_warning" msgid="1861736288458481650">"Sistem Kullanıcı Arayüzü Ayarlayıcı, Android kullanıcı arayüzünde değişiklikler yapmanız ve arayüzü özelleştirmeniz için ekstra yollar sağlar. Bu deneysel özellikler değişebilir, bozulabilir veya gelecekteki sürümlerde yer almayabilir. Dikkatli bir şekilde devam edin."</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ayarları aç"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Asistan\'ı aç"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Kilit ekranı"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Notları aç"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Not al"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Sistem çoklu görevi"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Mevcut uygulamayı sağ tarafa alarak bölünmüş ekrana geç"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Mevcut uygulamayı sol tarafa alarak bölünmüş ekrana geç"</string> @@ -963,7 +955,7 @@ <string name="accessibility_floating_button_undo" msgid="511112888715708241">"Geri al"</string> <string name="accessibility_floating_button_hidden_notification_title" msgid="4115036997406994799">"Erişilebilirlik düğmesi gizlendi"</string> <string name="accessibility_floating_button_hidden_notification_text" msgid="1457021647040915658">"Erişilebilirlik düğmesini göstermek için dokunun"</string> - <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"<xliff:g id="FEATURE_NAME">%s</xliff:g> kısayol kaldırıldı"</string> + <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"<xliff:g id="FEATURE_NAME">%s</xliff:g> kısayolu kaldırıldı"</string> <string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{# kısayol kaldırıldı}other{# kısayol kaldırıldı}}"</string> <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Sol üste taşı"</string> <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Sağ üste taşı"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 1bc422eb1658..c972090dc888 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Натисніть, щоб переглянути"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Не вдалося зберегти запис відео з екрана"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Не вдалося почати запис екрана"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Засіб запису проблем"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Обробка запису проблеми"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Поточне сповіщення про сеанс збирання даних про проблему"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Триває запис проблеми"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Поділитися"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Запис проблеми збережено"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Натисніть, щоб переглянути"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Не вдалося зберегти запис проблеми"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Не вдалося почати запис проблеми"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Перегляд на весь екран"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Щоб вийти, проведіть пальцем униз від верху екрана."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Збережено"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"від’єднати"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активувати"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> заряду акумулятора"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудіопристрій"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнітура"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"вимкнути"</string> <string name="sound_settings" msgid="8874581353127418308">"Звук і вібрація"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Налаштування"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Гучність знижено до безпечнішого рівня"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Аудіо в навушниках відтворювалося з високою гучністю довше, ніж рекомендується"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Гучність навушників перевищила безпечний рівень, допустимий протягом тижня"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Точка доступу"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Немає з’єднання із супутником"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Погане з’єднання із супутником"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Хороше з’єднання із супутником"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Доступне з’єднання із супутником"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Робочий профіль"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Це цікаво, але будьте обачні"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner пропонує нові способи налаштувати та персоналізувати інтерфейс користувача Android. Ці експериментальні функції можуть змінюватися, не працювати чи зникати в майбутніх версіях. Будьте обачні."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Відкрити налаштування"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Відкрити додаток Асистент"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Заблокувати екран"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Відкрити нотатки"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Створити нотатку"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Багатозадачність системи"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Розділити екран із поточним додатком праворуч"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Розділити екран із поточним додатком ліворуч"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 18a90dd6b90e..ede87fc2bf30 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"دیکھنے کے لیے تھپتھپائیں"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"اسکرین ریکارڈنگ محفوظ کرنے میں خرابی"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"اسکرین ریکارڈنگ شروع کرنے میں خرابی"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"ایشو ریکارڈر"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"ایشو ریکارڈنگ پروسیس ہو رہی ہے"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"ایشو کلیکشن سیشن کے لیے جاری اطلاع"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"ریکارڈنگ ایشو"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"اشتراک کریں"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"ایشو ریکارڈنگ محفوظ ہو گئی"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"دیکھنے کیلئے تھپتھپائیں"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"ایشو ریکارڈنگ محفوظ کرنے میں خرابی"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"ایشو ریکارڈنگ شروع کرنے میں خرابی"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"فُل اسکرین میں دیکھ رہے ہیں"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"باہر نکلنے کیلئے اوپر سے نیچے کی طرف سوائپ کریں۔"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"سمجھ آ گئی"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"محفوظ ہے"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"غیر منسلک کریں"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"فعال کریں"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> بیٹری"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"آڈیو"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ہیڈ سیٹ"</string> @@ -546,6 +541,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"غیر فعال کریں"</string> <string name="sound_settings" msgid="8874581353127418308">"آواز اور وائبریشن"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ترتیبات"</string> + <string name="volume_panel_captioning_title" msgid="5984936949147684357">"لائیو کیپشن"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"والیوم کو محفوظ سطح تک کم کر دیا گیا"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ہیڈ فون کا والیوم تجویز کردہ وقت سے زیادہ دیر تک بلند رہا ہے"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ہیڈ فون والیوم اس ہفتے محفوظ حد سے تجاوز کر گیا ہے"</string> @@ -612,14 +608,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> بجے"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> بجے"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"ہاٹ اسپاٹ"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"سیٹلائٹ، کوئی کنکشن نہیں ہے"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"سیٹلائٹ، کنکشن خراب ہے"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"سیٹلائٹ، کنکشن اچھا ہے"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"سیٹلائٹ، کنکشن دستیاب ہے"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"دفتری پروفائل"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"کچھ کیلئے دلچسپ لیکن سبھی کیلئے نہیں"</string> <string name="tuner_warning" msgid="1861736288458481650">"سسٹم UI ٹیونر Android صارف انٹر فیس میں ردوبدل کرنے اور اسے حسب ضرورت بنانے کیلئے آپ کو اضافی طریقے دیتا ہے۔ یہ تجرباتی خصوصیات مستقبل کی ریلیزز میں تبدیل ہو سکتی، رک سکتی یا غائب ہو سکتی ہیں۔ احتیاط کے ساتھ آگے بڑھیں۔"</string> @@ -741,7 +733,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"ترتیبات کھولیں"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"اسسٹنٹ کھولیں"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"مقفل اسکرین"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"نوٹس کھولیں"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"نوٹ لیں"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"سسٹم ملٹی ٹاسکنگ"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"موجودہ ایپ کے ساتھ دائیں جانب اسپلٹ اسکرین انٹر کریں"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"موجودہ ایپ کے ساتھ بائیں جانب اسپلٹ اسکرین انٹر کریں"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 762ce9302c49..6c36d3575d58 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Koʻrish uchun bosing"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran yozuvi saqlanmadi"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranni yozib olish boshlanmadi"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Muammoni yozib olish vositasi"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Yozuv qayta ishlanmoqda"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Muammo toʻplash seansi uchun faol bildirishnoma"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Muammo yozib olinmoqda"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Ulashish"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Muammo yozuvi saqlandi"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Ochish uchun bosing"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Yozuv saqlanmadi"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Yozib olish boshlanmadi"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Butun ekran rejimi"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Chiqish uchun tepadan pastga torting."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"OK"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saqlangan"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"uzish"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"faollashtirish"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Garnitura"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"faolsizlantirish"</string> <string name="sound_settings" msgid="8874581353127418308">"Tovush va tebranish"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Sozlamalar"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Tovush xavfsiz darajaga pasaytirildi"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Quloqlik tavsiya etilganidan uzoqroq vaqt baland tovushda ishladi"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Quloqlik tovushi bu hafta xavfsiz balandlik limitidan oshib ketdi"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Sputnik, ulanmagan"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Sputnik, aloqa sifati past"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Sputnik, aloqa sifati yaxshi"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Sputnik, aloqa mavjud"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Ish profili"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Diqqat!"</string> <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner yordamida siz Android foydalanuvchi interfeysini tuzatish va o‘zingizga moslashtirishingiz mumkin. Ushbu tajribaviy funksiyalar o‘zgarishi, buzilishi yoki keyingi versiyalarda olib tashlanishi mumkin. Ehtiyot bo‘lib davom eting."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Sozlamalarni ochish"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistentni ochish"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Ekran qulfi"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Qaydlarni ochish"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Qayd yaratish"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Tizimdagi multi-vazifalik"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Oʻng tomondagi ajratilgan ekran rejimiga kirish"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Chap tomondagi ajratilgan ekran rejimiga kirish"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index f2a49eab252e..3a970fb3e625 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Nhấn để xem"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Có lỗi xảy ra khi lưu video ghi màn hình"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Lỗi khi bắt đầu ghi màn hình"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Trình ghi sự cố"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Đang xử lý bản ghi sự cố"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Thông báo hiển thị liên tục cho một phiên thu thập sự cố"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Ghi sự cố"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Chia sẻ"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Đã lưu bản ghi sự cố"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Nhấn để xem"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Đã xảy ra lỗi khi lưu bản ghi sự cố"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Đã xảy ra lỗi khi bắt đầu ghi sự cố"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Xem toàn màn hình"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Để thoát, hãy vuốt từ trên cùng xuống dưới."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Tôi hiểu"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Đã lưu"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ngắt kết nối"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"kích hoạt"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> pin"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Âm thanh"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Tai nghe"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"tắt"</string> <string name="sound_settings" msgid="8874581353127418308">"Âm thanh và chế độ rung"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Cài đặt"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Âm lượng đã giảm xuống mức an toàn hơn"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Bạn đã dùng tai nghe ở mức âm lượng cao lâu hơn khoảng thời gian khuyến nghị, điều này có thể gây tổn hại đến thính giác của bạn"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Âm lượng tai nghe đã vượt quá giới hạn an toàn của tuần này"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"lúc <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"vào <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Điểm phát sóng"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Không có kết nối vệ tinh"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Kết nối vệ tinh kém"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Kết nối vệ tinh tốt"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Hiện có kết nối vệ tinh"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Hồ sơ công việc"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Thú vị đối với một số người nhưng không phải tất cả"</string> <string name="tuner_warning" msgid="1861736288458481650">"Bộ điều hướng giao diện người dùng hệ thống cung cấp thêm cho bạn những cách chỉnh sửa và tùy chỉnh giao diện người dùng Android. Những tính năng thử nghiệm này có thể thay đổi, hỏng hoặc biến mất trong các phiên bản tương lai. Hãy thận trọng khi tiếp tục."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Mở phần cài đặt"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Mở Trợ lý"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Màn hình khoá"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Mở ghi chú"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Tạo ghi chú"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Xử lý đa nhiệm trong hệ thống"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Vào chế độ chia đôi màn hình, ứng dụng hiện tại ở màn hình bên phải"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Vào chế độ chia đôi màn hình, ứng dụng hiện tại ở màn hình bên trái"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 54cc8d8ec4fa..fbdc86c90868 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"点按即可查看"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"保存屏幕录制内容时出错"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"启动屏幕录制时出错"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"问题录制器"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"正在处理问题录制"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"针对问题收集会话的持续性通知"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"录制问题"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"分享"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"已保存问题录制内容"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"点按即可查看"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"保存问题录制内容时出错"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"启动问题录制时出错"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"目前处于全屏模式"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"要退出,请从顶部向下滑动。"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"知道了"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已保存"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"断开连接"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"启用"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> 的电量"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"音频"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"耳机"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"停用"</string> <string name="sound_settings" msgid="8874581353127418308">"声音和振动"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"设置"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"音量已降至较安全的水平"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"您以高音量使用耳机的时长超过了建议值"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"耳机音量已超出这周的安全上限"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"热点"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"卫星,无连接"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"卫星,连接质量不佳"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"卫星,连接质量良好"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"卫星,可连接"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"工作资料"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"并不适合所有用户"</string> <string name="tuner_warning" msgid="1861736288458481650">"系统界面调节工具可让您以更多方式调整及定制 Android 界面。在日后推出的版本中,这些实验性功能可能会变更、失效或消失。操作时请务必谨慎。"</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"打开设置"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"打开 Google 助理"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"锁定屏幕"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"打开笔记"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"添加记事"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"系统多任务处理"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"进入分屏模式,当前应用显示于右侧"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"进入分屏模式,当前应用显示于左侧"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index c65307c92842..4579ca2436cb 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"輕按即可查看"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"儲存螢幕錄影時發生錯誤"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄影畫面時發生錯誤"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"問題記錄工具"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"正在處理問題記錄"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"問題收集工作階段的持續通知"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"錄影問題"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"分享"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"問題記錄已儲存"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"輕按即可查看"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"儲存錄影問題時發生錯誤"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"開始記錄問題時發生錯誤"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"以全螢幕檢視"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"如要退出,請從螢幕頂部向下滑動。"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"知道了"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已儲存"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"解除連結"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"啟動"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"音訊"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"耳機"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"停用"</string> <string name="sound_settings" msgid="8874581353127418308">"音效和震動"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"設定"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"音量已降至較安全的水平"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"以高音量使用耳機的時間已超過建議範圍"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"耳機音量已超過本週安全限制"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"在 <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"在<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"熱點"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"衛星,冇連線"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"衛星,連線質素唔好"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛星,連線質素好"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛星,可以連線"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"工作設定檔"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"這只是測試版本,並不包含完整功能"</string> <string name="tuner_warning" msgid="1861736288458481650">"使用者介面調諧器讓你以更多方法修改和自訂 Android 使用者介面。但請小心,這些實驗功能可能會在日後發佈時更改、分拆或消失。"</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"開啟設定"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"開啟「Google 助理」"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"上鎖畫面"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"開啟筆記"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"寫筆記"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"系統多工處理"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"進入分割螢幕模式,並將目前的應用程式顯示在右側"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"進入分割螢幕模式,並將目前的應用程式顯示在左側"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index fcd6a1349040..05d9ec319f09 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"輕觸即可查看"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"儲存螢幕錄影內容時發生錯誤"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄製螢幕畫面時發生錯誤"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"問題記錄工具"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"正在處理問題記錄"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"問題收集工作階段的持續性通知"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"正在記錄問題"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"分享"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"問題記錄已儲存"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"輕觸即可查看"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"儲存問題記錄時發生錯誤"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"開始記錄問題時發生錯誤"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"以全螢幕檢視"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"如要退出,請從螢幕頂端向下滑動。"</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"我知道了"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已儲存"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"取消連結"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"啟用"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"音訊"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"耳機"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"停用"</string> <string name="sound_settings" msgid="8874581353127418308">"音效與震動"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"設定"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"音量已調低至安全範圍"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"耳機以高音量播放已超過建議時間"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"耳罩式耳機的音量已超過本週的安全限制"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"於<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"於<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"無線基地台"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"衛星,沒有連線"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"衛星,連線品質不佳"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛星,連線品質良好"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛星,可連線"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"工作資料夾"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"有趣與否,見仁見智"</string> <string name="tuner_warning" msgid="1861736288458481650">"系統使用者介面調整精靈可讓你透過其他方式,調整及自訂 Android 使用者介面。這些實驗性功能隨著版本更新可能會變更、損壞或消失,執行時請務必謹慎。"</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"開啟設定"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"開啟 Google 助理"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"螢幕鎖定"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"開啟記事"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"新增記事"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"系統多工處理"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"進入分割畫面模式,並將目前的應用程式顯示於右側"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"進入分割畫面模式,並將目前的應用程式顯示於左側"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index aafa61a460ca..46ec239ed950 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -120,24 +120,15 @@ <string name="screenrecord_save_text" msgid="3008973099800840163">"Thepha ukuze ubuke"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"Iphutha lokulondoloza okokuqopha iskrini"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"Iphutha lokuqala ukurekhoda isikrini"</string> - <!-- no translation found for issuerecord_title (286627115110121849) --> - <skip /> - <!-- no translation found for issuerecord_background_processing_label (1666840264959336876) --> - <skip /> - <!-- no translation found for issuerecord_channel_description (6142326363431474632) --> - <skip /> - <!-- no translation found for issuerecord_ongoing_screen_only (6248206059935015722) --> - <skip /> - <!-- no translation found for issuerecord_share_label (3992657993619876199) --> - <skip /> - <!-- no translation found for issuerecord_save_title (4161043023696751591) --> - <skip /> - <!-- no translation found for issuerecord_save_text (1205985304551521495) --> - <skip /> - <!-- no translation found for issuerecord_save_error (6913040083446722726) --> - <skip /> - <!-- no translation found for issuerecord_start_error (3402782952722871190) --> - <skip /> + <string name="issuerecord_title" msgid="286627115110121849">"Ushicilelo Lokurekhoda"</string> + <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Icubungula ushicilelo lokurekhoda"</string> + <string name="issuerecord_channel_description" msgid="6142326363431474632">"Isaziso esiqhubekayo seqoqo leseshini yoshicilelo"</string> + <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"Inkinga yokurekhoda"</string> + <string name="issuerecord_share_label" msgid="3992657993619876199">"Yabelana"</string> + <string name="issuerecord_save_title" msgid="4161043023696751591">"Ushicilelo lokurekhoda lilondoloziwe"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"Thepha ukuze ubuke"</string> + <string name="issuerecord_save_error" msgid="6913040083446722726">"Iphutha ekulondolozeni ushicilelo lokurekhoda"</string> + <string name="issuerecord_start_error" msgid="3402782952722871190">"Iphutha lokuqalisa ushicilelo lokurekhoda"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"Ukubuka isikrini esigcwele"</string> <string name="immersive_cling_description" msgid="6913958856085185775">"Ukuze uphume, swayiphela phansi kusuka phezulu."</string> <string name="immersive_cling_positive" msgid="3076681691468978568">"Ngiyezwa"</string> @@ -277,6 +268,10 @@ <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Ilondoloziwe"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"nqamula"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"yenza kusebenze"</string> + <!-- no translation found for turn_on_bluetooth_auto_tomorrow (414836329962473906) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info (8831410009251539988) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ibhethri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Umsindo"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ihedisethi"</string> @@ -546,6 +541,8 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"khubaza"</string> <string name="sound_settings" msgid="8874581353127418308">"Umsindo nokudlidliza"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Amasethingi"</string> + <!-- no translation found for volume_panel_captioning_title (5984936949147684357) --> + <skip /> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Ivolumu yehliselwe kuleveli ephephile"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Ivolumu yama-headphone beyiphezulu isikhathi eside kunokunconyiwe"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Ivolumu yama-headphone ibe phezulu kunokunconyiwe, okungalimaza ukuzwa kwakho"</string> @@ -612,14 +609,10 @@ <string name="alarm_template" msgid="2234991538018805736">"ngo-<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"nge-<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"I-Hotspot"</string> - <!-- no translation found for accessibility_status_bar_satellite_no_connection (3001571744269917762) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_poor_connection (5231478574952724160) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_good_connection (308079391708578704) --> - <skip /> - <!-- no translation found for accessibility_status_bar_satellite_available (6514855015496916829) --> - <skip /> + <string name="accessibility_status_bar_satellite_no_connection" msgid="3001571744269917762">"Isethelayithi, alukho uxhumano"</string> + <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Isathelayithi, uxhumano olungalungile"</string> + <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Isethelayithi, uxhumano oluhle"</string> + <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Isethelayithi, uxhumano luyatholakala"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Iphrofayela yomsebenzi"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Kuyajabulisa kwabanye kodwa hhayi bonke"</string> <string name="tuner_warning" msgid="1861736288458481650">"Isishuni se-UI sesistimu sikunika izindlela ezingeziwe zokuhlobisa nokwenza ngezifiso isixhumanisi sokubona se-Android. Lezi zici zesilingo zingashintsha, zephuke, noma zinyamalale ekukhishweni kwangakusasa. Qhubeka ngokuqaphela."</string> @@ -741,7 +734,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Vula amasethingi"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Vula umsizi"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Khiya isikrini"</string> - <string name="group_system_quick_memo" msgid="6257072703041301265">"Vula amanothi"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Thatha inothi"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Ukwenza imisebenzi eminingi yesistimu"</string> <string name="system_multitasking_rhs" msgid="2454557648974553729">"Faka ukuhlukanisa isikrini nge-app yamanje kuya ku-RHS"</string> <string name="system_multitasking_lhs" msgid="3516599774920979402">"Faka ukuhlukanisa isikrini nge-app yamanje kuya ku-LHS"</string> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 7537a003275d..a681da3adc4e 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -608,7 +608,6 @@ <dimen name="volume_panel_slice_horizontal_padding">24dp</dimen> <dimen name="volume_panel_corner_radius">52dp</dimen> - <dimen name="volume_panel_content_padding">24dp</dimen> <dimen name="volume_panel_bottom_bar_horizontal_padding">24dp</dimen> <dimen name="volume_panel_bottom_bar_bottom_padding">20dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index e401c71b3716..a7d93e70fda3 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1416,6 +1416,9 @@ <!-- Indication on the keyguard that appears when a trust agents unlocks the device. [CHAR LIMIT=40] --> <string name="keyguard_indication_trust_unlocked">Kept unlocked by TrustAgent</string> + <!-- Message asking the user to authenticate with primary authentication methods (PIN/pattern/password) or biometrics after the device is locked by adaptive auth. [CHAR LIMIT=60] --> + <string name="kg_prompt_after_adaptive_auth_lock">Theft protection\nDevice locked, too many unlock attempts</string> + <!-- Accessibility string for current zen mode and selected exit condition. A template that simply concatenates existing mode string and the current condition description. [CHAR LIMIT=20] --> <string name="zen_mode_and_condition"><xliff:g id="zen_mode" example="Priority interruptions only">%1$s</xliff:g>. <xliff:g id="exit_condition" example="For one hour">%2$s</xliff:g></string> @@ -1532,6 +1535,12 @@ <string name="volume_dialog_ringer_guidance_ring">Calls and notifications will ring (<xliff:g id="volume level" example="56">%1$s</xliff:g>)</string> + <!-- Title with application label for media output settings. [CHAR LIMIT=20] --> + <string name="media_output_label_title">Playing <xliff:g id="label" example="Music Player">%s</xliff:g> on</string> + + <!-- Title for media output settings without media is playing. [CHAR LIMIT=20] --> + <string name="media_output_title_without_playing">Audio will play on</string> + <!-- Name of special SystemUI debug settings --> <string name="system_ui_tuner">System UI Tuner</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index ab3cacb27191..f1d4d71d1cc4 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -953,13 +953,13 @@ <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item> </style> - <style name="Theme.VolumePanelActivity" parent="@style/Theme.SystemUI"> + <style name="Theme.VolumePanelActivity" + parent="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen"> <item name="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@android:color/transparent</item> - <item name="android:windowActionBar">false</item> - <item name="android:windowNoTitle">true</item> - <!-- Setting a placeholder will avoid using the SystemUI icon on the splash screen. --> - <item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_blank</item> + <item name="android:backgroundDimEnabled">true</item> + <item name="android:windowCloseOnTouchOutside">true</item> + <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> </style> <style name="Theme.UserSwitcherFullscreenDialog" parent="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen"> diff --git a/packages/SystemUI/res/xml/media_session_collapsed.xml b/packages/SystemUI/res/xml/media_session_collapsed.xml index c053b33b4c63..2f2b10f8dc0c 100644 --- a/packages/SystemUI/res/xml/media_session_collapsed.xml +++ b/packages/SystemUI/res/xml/media_session_collapsed.xml @@ -55,6 +55,15 @@ app:layout_constraintBottom_toBottomOf="@+id/album_art" /> <Constraint + android:id="@+id/loading_effect_view" + android:layout_width="match_parent" + android:layout_height="@dimen/qs_media_session_height_collapsed" + app:layout_constraintStart_toStartOf="@+id/album_art" + app:layout_constraintEnd_toEndOf="@+id/album_art" + app:layout_constraintTop_toTopOf="@+id/album_art" + app:layout_constraintBottom_toBottomOf="@+id/album_art" /> + + <Constraint android:id="@+id/header_title" android:layout_width="wrap_content" android:layout_height="wrap_content" diff --git a/packages/SystemUI/res/xml/media_session_expanded.xml b/packages/SystemUI/res/xml/media_session_expanded.xml index 8bf7560d6ddb..0140d52bd175 100644 --- a/packages/SystemUI/res/xml/media_session_expanded.xml +++ b/packages/SystemUI/res/xml/media_session_expanded.xml @@ -48,6 +48,15 @@ app:layout_constraintBottom_toBottomOf="@+id/album_art" /> <Constraint + android:id="@+id/loading_effect_view" + android:layout_width="match_parent" + android:layout_height="@dimen/qs_media_session_height_expanded" + app:layout_constraintStart_toStartOf="@+id/album_art" + app:layout_constraintEnd_toEndOf="@+id/album_art" + app:layout_constraintTop_toTopOf="@+id/album_art" + app:layout_constraintBottom_toBottomOf="@+id/album_art" /> + + <Constraint android:id="@+id/header_title" android:layout_width="wrap_content" android:layout_height="wrap_content" diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt index ee260e16dc56..8b2a0ec27011 100644 --- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt +++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt @@ -43,7 +43,6 @@ import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags.REGION_SAMPLING import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.log.core.Logger @@ -316,7 +315,7 @@ constructor( object : KeyguardUpdateMonitorCallback() { override fun onKeyguardVisibilityChanged(visible: Boolean) { isKeyguardVisible = visible - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { if (!isKeyguardVisible) { clock?.run { smallClock.animations.doze(if (isDozing) 1f else 0f) @@ -410,7 +409,7 @@ constructor( parent.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { listenForDozing(this) - if (KeyguardShadeMigrationNssl.isEnabled) { + if (migrateClocksToBlueprint()) { listenForDozeAmountTransition(this) listenForAnyStateToAodTransition(this) } else { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java index 2db3795cbad7..e621ffe4cbc4 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java @@ -47,7 +47,6 @@ import com.android.systemui.flags.FeatureFlagsClassic; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager; import com.android.systemui.log.LogBuffer; import com.android.systemui.log.core.LogLevel; @@ -349,7 +348,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } int getNotificationIconAreaHeight() { - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { return 0; } else if (NotificationIconContainerRefactor.isEnabled()) { return mAodIconContainer != null ? mAodIconContainer.getHeight() : 0; @@ -597,7 +596,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } private void updateAodIcons() { - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { NotificationIconContainer nic = (NotificationIconContainer) mView.findViewById( com.android.systemui.res.R.id.left_aligned_notification_icon_container); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java index 3585feb3442d..84c8ea708031 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java @@ -19,6 +19,7 @@ package com.android.keyguard; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.view.WindowInsets.Type.ime; +import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_ADAPTIVE_AUTH_REQUEST; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NONE; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT; @@ -126,6 +127,8 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView { return R.string.kg_prompt_reason_timeout_password; case PROMPT_REASON_TRUSTAGENT_EXPIRED: return R.string.kg_prompt_reason_timeout_password; + case PROMPT_REASON_ADAPTIVE_AUTH_REQUEST: + return R.string.kg_prompt_after_adaptive_auth_lock; case PROMPT_REASON_NONE: return 0; default: diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java index db7ff888356c..bf8900da887a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java @@ -331,6 +331,9 @@ public class KeyguardPatternViewController case PROMPT_REASON_TRUSTAGENT_EXPIRED: resId = R.string.kg_prompt_reason_timeout_pattern; break; + case PROMPT_REASON_ADAPTIVE_AUTH_REQUEST: + resId = R.string.kg_prompt_after_adaptive_auth_lock; + break; case PROMPT_REASON_NONE: break; default: diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java index fcff0dbc0878..bcab6f054dd6 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -16,6 +16,7 @@ package com.android.keyguard; +import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_ADAPTIVE_AUTH_REQUEST; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NONE; import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT; @@ -138,6 +139,8 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView return R.string.kg_prompt_reason_timeout_pin; case PROMPT_REASON_TRUSTAGENT_EXPIRED: return R.string.kg_prompt_reason_timeout_pin; + case PROMPT_REASON_ADAPTIVE_AUTH_REQUEST: + return R.string.kg_prompt_after_adaptive_auth_lock; case PROMPT_REASON_NONE: return 0; default: diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java index 83b1a2cbbf52..3e87c1b60581 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java @@ -67,6 +67,11 @@ public interface KeyguardSecurityView { int PROMPT_REASON_TRUSTAGENT_EXPIRED = 8; /** + * Some auth is required because adaptive auth has determined risk + */ + int PROMPT_REASON_ADAPTIVE_AUTH_REQUEST = 9; + + /** * Strong auth is required because the device has just booted because of an automatic * mainline update. */ diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java index 1758831203d6..9421f150a38a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java @@ -54,7 +54,6 @@ import com.android.systemui.animation.ViewHierarchyAnimator; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; import com.android.systemui.keyguard.shared.model.TransitionState; import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.plugins.clocks.ClockController; @@ -231,7 +230,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV } mDumpManager.registerDumpable(getInstanceName(), this); - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { startCoroutines(EmptyCoroutineContext.INSTANCE); } } @@ -511,7 +510,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV ConstraintSet constraintSet = new ConstraintSet(); constraintSet.clone(layout); int guideline; - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { guideline = R.id.split_shade_guideline; } else { guideline = R.id.qs_edge_guideline; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 536f3afdd575..38c2829e27f6 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -35,6 +35,7 @@ import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT; import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN; import static android.os.BatteryManager.CHARGING_POLICY_DEFAULT; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT; @@ -382,6 +383,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private List<SubscriptionInfo> mSubscriptionInfo; @VisibleForTesting protected int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED; + private boolean mFingerprintDetectRunning; private boolean mIsDreaming; private boolean mLogoutEnabled; private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID; @@ -1003,6 +1005,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab final boolean wasCancellingRestarting = mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING; mFingerprintRunningState = BIOMETRIC_STATE_STOPPED; + mFingerprintDetectRunning = false; if (wasCancellingRestarting) { KeyguardUpdateMonitor.this.updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE); } else { @@ -1111,6 +1114,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab boolean wasRunning = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING; boolean isRunning = fingerprintRunningState == BIOMETRIC_STATE_RUNNING; mFingerprintRunningState = fingerprintRunningState; + if (mFingerprintRunningState == BIOMETRIC_STATE_STOPPED) { + mFingerprintDetectRunning = false; + } mLogger.logFingerprintRunningState(mFingerprintRunningState); // Clients of KeyguardUpdateMonitor don't care about the internal state about the // asynchronousness of the cancel cycle. So only notify them if the actually running state @@ -1570,6 +1576,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab return isEncrypted || isLockDown; } + /** + * Whether the device is locked by adaptive auth + */ + public boolean isDeviceLockedByAdaptiveAuth(int userId) { + return containsFlag(mStrongAuthTracker.getStrongAuthForUser(userId), + SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST); + } + private boolean containsFlag(int haystack, int needle) { return (haystack & needle) != 0; } @@ -1835,8 +1849,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab @Override public void onFingerprintDetected(int sensorId, int userId, boolean isStrongBiometric) { - handleBiometricDetected(userId, FINGERPRINT, isStrongBiometric); + // Fingerprint lifecycle ends + if (mHandler.hasCallbacks(mFpCancelNotReceived)) { + mLogger.d("onFingerprintDetected()" + + " triggered while waiting for cancellation, removing watchdog"); + mHandler.removeCallbacks(mFpCancelNotReceived); + } + // Don't send cancel if detect succeeds + mFingerprintCancelSignal = null; setFingerprintRunningState(BIOMETRIC_STATE_STOPPED); + handleBiometricDetected(userId, FINGERPRINT, isStrongBiometric); } }; @@ -2099,6 +2121,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab @VisibleForTesting void resetBiometricListeningState() { mFingerprintRunningState = BIOMETRIC_STATE_STOPPED; + mFingerprintDetectRunning = false; } @VisibleForTesting @@ -2537,8 +2560,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab return; } final boolean shouldListenForFingerprint = shouldListenForFingerprint(isUdfpsSupported()); - final boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING + final boolean running = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING; + final boolean runningOrRestarting = running || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING; + final boolean runDetect = !isUnlockingWithFingerprintAllowed(); + if (runningOrRestarting && !shouldListenForFingerprint) { if (action == BIOMETRIC_ACTION_START) { mLogger.v("Ignoring stopListeningForFingerprint()"); @@ -2550,7 +2576,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mLogger.v("Ignoring startListeningForFingerprint()"); return; } - startListeningForFingerprint(); + startListeningForFingerprint(runDetect); + } else if (running && (runDetect != mFingerprintDetectRunning)) { + if (action == BIOMETRIC_ACTION_STOP) { + if (runDetect) { + mLogger.v("Allowing startListeningForFingerprint(detect) despite" + + " BIOMETRIC_ACTION_STOP since auth was running before."); + } else { + mLogger.v("Ignoring startListeningForFingerprint() switch detect -> auth"); + return; + } + } + startListeningForFingerprint(runDetect); } } @@ -2809,7 +2846,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab && biometricEnabledForUser && !isUserInLockdown(user); final boolean strongerAuthRequired = !isUnlockingWithFingerprintAllowed(); - final boolean isSideFps = isSfpsSupported() && isSfpsEnrolled(); final boolean shouldListenBouncerState = !strongerAuthRequired || !mPrimaryBouncerIsOrWillBeShowing; @@ -2872,7 +2908,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } - private void startListeningForFingerprint() { + private void startListeningForFingerprint(boolean runDetect) { final int userId = mSelectedUserInteractor.getSelectedUserId(); final boolean unlockPossible = isUnlockWithFingerprintPossible(userId); if (mFingerprintCancelSignal != null) { @@ -2902,18 +2938,20 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mFingerprintInteractiveToAuthProvider.getVendorExtension(userId)); } - if (!isUnlockingWithFingerprintAllowed()) { + if (runDetect) { mLogger.v("startListeningForFingerprint - detect"); mFpm.detectFingerprint( mFingerprintCancelSignal, mFingerprintDetectionCallback, fingerprintAuthenticateOptions); + mFingerprintDetectRunning = true; } else { mLogger.v("startListeningForFingerprint"); mFpm.authenticate(null /* crypto */, mFingerprintCancelSignal, mFingerprintAuthenticationCallback, null /* handler */, fingerprintAuthenticateOptions); + mFingerprintDetectRunning = false; } setFingerprintRunningState(BIOMETRIC_STATE_RUNNING); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java index ce03072e2f0b..c3c42399f1f7 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java @@ -24,7 +24,7 @@ import androidx.annotation.Nullable; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.shade.ShadeExpansionStateManager; -import com.android.systemui.shade.ShadeViewController; +import com.android.systemui.shade.ShadeLockscreenInteractor; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.KeyguardBypassController; @@ -186,7 +186,7 @@ public interface KeyguardViewController { * Registers the CentralSurfaces to which this Keyguard View is mounted. */ void registerCentralSurfaces(CentralSurfaces centralSurfaces, - ShadeViewController shadeViewController, + ShadeLockscreenInteractor shadeLockscreenInteractor, @Nullable ShadeExpansionStateManager shadeExpansionStateManager, BiometricUnlockController biometricUnlockController, View notificationContainer, diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java index 9ebae9023d44..2000028dff41 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java @@ -16,6 +16,7 @@ package com.android.keyguard; +import static com.android.systemui.Flags.migrateClocksToBlueprint; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.StatusBarState.SHADE; @@ -23,7 +24,6 @@ import android.util.Property; import android.view.View; import com.android.app.animation.Interpolators; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; import com.android.systemui.log.LogBuffer; import com.android.systemui.log.core.LogLevel; import com.android.systemui.statusbar.StatusBarState; @@ -109,7 +109,7 @@ public class KeyguardVisibilityHelper { animProps.setDelay(0).setDuration(160); log("goingToFullShade && !keyguardFadingAway"); } - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { log("Using LockscreenToGoneTransition 1"); } else { PropertyAnimator.setProperty( @@ -167,7 +167,7 @@ public class KeyguardVisibilityHelper { animProps, true /* animate */); } else if (mScreenOffAnimationController.shouldAnimateInKeyguard()) { - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { log("Using GoneToAodTransition"); mKeyguardViewVisibilityAnimating = false; } else { @@ -183,7 +183,7 @@ public class KeyguardVisibilityHelper { mView.setVisibility(View.VISIBLE); } } else { - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { log("Using LockscreenToGoneTransition 2"); } else { log("Direct set Visibility to GONE"); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt index 7b4be0220ff2..9c28f1c16546 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt @@ -115,17 +115,11 @@ constructor( } private var overlayView: View? = null - private var lottie: LottieAnimationView? = null /** Show the side fingerprint sensor indicator */ private fun show() { - overlayView?.let { - if (it.isAttachedToWindow) { - lottie = it.requireViewById<LottieAnimationView>(R.id.sidefps_animation) - lottie?.pauseAnimation() - lottie?.removeAllLottieOnCompositionLoadedListener() - windowManager.get().removeView(it) - } + if (overlayView?.isAttachedToWindow == true) { + return } overlayView = layoutInflater.get().inflate(R.layout.sidefps_view, null, false) diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractor.kt index 8197145f9646..c25e748f8668 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractor.kt @@ -50,6 +50,7 @@ import com.android.systemui.res.R.string.kg_fp_not_recognized import com.android.systemui.res.R.string.kg_primary_auth_locked_out_password import com.android.systemui.res.R.string.kg_primary_auth_locked_out_pattern import com.android.systemui.res.R.string.kg_primary_auth_locked_out_pin +import com.android.systemui.res.R.string.kg_prompt_after_adaptive_auth_lock import com.android.systemui.res.R.string.kg_prompt_after_dpm_lock import com.android.systemui.res.R.string.kg_prompt_after_update_password import com.android.systemui.res.R.string.kg_prompt_after_update_pattern @@ -208,6 +209,11 @@ constructor( } else { faceLockedOut(currentSecurityMode, isFingerprintAuthCurrentlyAllowed.value) } + } else if (flags.isSomeAuthRequiredAfterAdaptiveAuthRequest) { + authRequiredAfterAdaptiveAuthRequest( + currentSecurityMode, + isFingerprintAuthCurrentlyAllowed.value + ) } else if ( trustOrBiometricsAvailable && flags.strongerAuthRequiredAfterNonStrongBiometricsTimeout @@ -464,6 +470,34 @@ private fun authRequiredAfterAdminLockdown(securityMode: SecurityMode): BouncerM }.toMessage() } +private fun authRequiredAfterAdaptiveAuthRequest( + securityMode: SecurityMode, + fpAuthIsAllowed: Boolean +): BouncerMessageModel { + return if (fpAuthIsAllowed) authRequiredAfterAdaptiveAuthRequestFingerprintAllowed(securityMode) + else + return when (securityMode) { + SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_adaptive_auth_lock) + SecurityMode.Password -> + Pair(keyguard_enter_password, kg_prompt_after_adaptive_auth_lock) + SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_adaptive_auth_lock) + else -> Pair(0, 0) + }.toMessage() +} + +private fun authRequiredAfterAdaptiveAuthRequestFingerprintAllowed( + securityMode: SecurityMode +): BouncerMessageModel { + return when (securityMode) { + SecurityMode.Pattern -> + Pair(kg_unlock_with_pattern_or_fp, kg_prompt_after_adaptive_auth_lock) + SecurityMode.Password -> + Pair(kg_unlock_with_password_or_fp, kg_prompt_after_adaptive_auth_lock) + SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_prompt_after_adaptive_auth_lock) + else -> Pair(0, 0) + }.toMessage() +} + private fun authRequiredAfterUserLockdown(securityMode: SecurityMode): BouncerMessageModel { return when (securityMode) { SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_user_lockdown_pattern) diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt index 0bad33b8f920..82d943796e2a 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt @@ -23,6 +23,7 @@ import com.android.systemui.communal.data.repository.CommunalRepositoryModule import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryModule import com.android.systemui.communal.data.repository.CommunalTutorialRepositoryModule import com.android.systemui.communal.data.repository.CommunalWidgetRepositoryModule +import com.android.systemui.communal.widgets.CommunalWidgetModule import com.android.systemui.communal.widgets.EditWidgetsActivityStarter import com.android.systemui.communal.widgets.EditWidgetsActivityStarterImpl import dagger.Binds @@ -36,6 +37,7 @@ import dagger.Module CommunalTutorialRepositoryModule::class, CommunalWidgetRepositoryModule::class, CommunalDatabaseModule::class, + CommunalWidgetModule::class, CommunalPrefsRepositoryModule::class, CommunalSettingsRepositoryModule::class, ] diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt b/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt index 3b727d2a7ade..9cd77c4713fa 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt @@ -23,8 +23,8 @@ import androidx.room.Query import androidx.room.RoomDatabase import androidx.room.Transaction import androidx.sqlite.db.SupportSQLiteDatabase -import com.android.systemui.communal.data.repository.CommunalWidgetRepositoryModule.Companion.DEFAULT_WIDGETS -import com.android.systemui.communal.shared.CommunalWidgetHost +import com.android.systemui.communal.widgets.CommunalWidgetHost +import com.android.systemui.communal.widgets.CommunalWidgetModule.Companion.DEFAULT_WIDGETS import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.log.LogBuffer diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetCategories.kt b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetCategories.kt new file mode 100644 index 000000000000..03f54c8b25d7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetCategories.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.communal.data.model + +import android.appwidget.AppWidgetProviderInfo + +/** + * The widget categories to display on communal hub (where categories is a bitfield with values that + * match those in {@link AppWidgetProviderInfo}). + */ +@JvmInline +value class CommunalWidgetCategories( + // The default is keyguard widgets. + val categories: Int = AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD +) { + fun contains(category: Int) = (categories and category) == category +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt index 201b04927ea3..7c65d21e2814 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt @@ -18,11 +18,13 @@ package com.android.systemui.communal.data.repository import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL +import android.appwidget.AppWidgetProviderInfo import android.content.IntentFilter import android.content.pm.UserInfo import com.android.systemui.Flags.communalHub import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.communal.data.model.CommunalEnabledState +import com.android.systemui.communal.data.model.CommunalWidgetCategories import com.android.systemui.communal.data.model.DisabledReason import com.android.systemui.communal.data.model.DisabledReason.DISABLED_REASON_DEVICE_POLICY import com.android.systemui.communal.data.model.DisabledReason.DISABLED_REASON_FLAG @@ -48,6 +50,12 @@ import kotlinx.coroutines.flow.onStart interface CommunalSettingsRepository { /** A [CommunalEnabledState] for the specified user. */ fun getEnabledState(user: UserInfo): Flow<CommunalEnabledState> + + /** + * A flow that reports the widget categories to show on the hub as selected by the user in + * Settings. + */ + fun getWidgetCategories(user: UserInfo): Flow<CommunalWidgetCategories> } @SysUISingleton @@ -89,6 +97,23 @@ constructor( .flowOn(bgDispatcher) } + override fun getWidgetCategories(user: UserInfo): Flow<CommunalWidgetCategories> = + secureSettings + .observerFlow(userId = user.id, names = arrayOf(GLANCEABLE_HUB_CONTENT_SETTING)) + // Force an update + .onStart { emit(Unit) } + .map { + CommunalWidgetCategories( + // The default is to show only keyguard widgets. + secureSettings.getIntForUser( + GLANCEABLE_HUB_CONTENT_SETTING, + AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD, + user.id + ) + ) + } + .flowOn(bgDispatcher) + private fun getEnabledByUser(user: UserInfo): Flow<Boolean> = secureSettings .observerFlow(userId = user.id, names = arrayOf(GLANCEABLE_HUB_ENABLED)) @@ -114,6 +139,7 @@ constructor( companion object { const val GLANCEABLE_HUB_ENABLED = "glanceable_hub_enabled" + const val GLANCEABLE_HUB_CONTENT_SETTING = "glanceable_hub_content_setting" private const val ENABLED_SETTING_DEFAULT = 1 } } diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt index e4c91957ee56..e395ca9bf314 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt @@ -18,13 +18,14 @@ package com.android.systemui.communal.data.repository import android.appwidget.AppWidgetManager import android.content.ComponentName +import android.os.UserHandle import androidx.annotation.WorkerThread import com.android.systemui.communal.data.db.CommunalItemRank import com.android.systemui.communal.data.db.CommunalWidgetDao import com.android.systemui.communal.data.db.CommunalWidgetItem -import com.android.systemui.communal.shared.CommunalWidgetHost import com.android.systemui.communal.shared.model.CommunalWidgetContentModel import com.android.systemui.communal.widgets.CommunalAppWidgetHost +import com.android.systemui.communal.widgets.CommunalWidgetHost import com.android.systemui.communal.widgets.WidgetConfigurator import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background @@ -50,6 +51,7 @@ interface CommunalWidgetRepository { /** Add a widget at the specified position in the app widget service and the database. */ fun addWidget( provider: ComponentName, + user: UserHandle, priority: Int, configurator: WidgetConfigurator? = null ) {} @@ -99,11 +101,12 @@ constructor( override fun addWidget( provider: ComponentName, + user: UserHandle, priority: Int, configurator: WidgetConfigurator? ) { bgScope.launch { - val id = communalWidgetHost.allocateIdAndBindWidget(provider) + val id = communalWidgetHost.allocateIdAndBindWidget(provider, user) if (id == null) { logger.e("Failed to allocate widget id to ${provider.flattenToString()}") return@launch diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryModule.kt index d7f163bad2e9..b502fb11d7ac 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryModule.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryModule.kt @@ -17,75 +17,11 @@ package com.android.systemui.communal.data.repository -import android.appwidget.AppWidgetManager -import android.content.Context -import android.content.res.Resources -import android.os.Looper -import com.android.systemui.communal.shared.CommunalWidgetHost -import com.android.systemui.communal.widgets.CommunalAppWidgetHost -import com.android.systemui.communal.widgets.WidgetInteractionHandler -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.Application -import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.log.LogBuffer -import com.android.systemui.log.dagger.CommunalLog -import com.android.systemui.res.R import dagger.Binds import dagger.Module -import dagger.Provides -import java.util.Optional -import javax.inject.Named -import kotlinx.coroutines.CoroutineScope @Module interface CommunalWidgetRepositoryModule { - companion object { - private const val APP_WIDGET_HOST_ID = 116 - const val DEFAULT_WIDGETS = "default_widgets" - - @SysUISingleton - @Provides - fun provideAppWidgetManager(@Application context: Context): Optional<AppWidgetManager> { - return Optional.ofNullable(AppWidgetManager.getInstance(context)) - } - - @SysUISingleton - @Provides - fun provideCommunalAppWidgetHost( - @Application context: Context, - @Background backgroundScope: CoroutineScope, - interactionHandler: WidgetInteractionHandler, - @Main looper: Looper, - @CommunalLog logBuffer: LogBuffer, - ): CommunalAppWidgetHost { - return CommunalAppWidgetHost( - context, - backgroundScope, - APP_WIDGET_HOST_ID, - interactionHandler, - looper, - logBuffer, - ) - } - - @SysUISingleton - @Provides - fun provideCommunalWidgetHost( - appWidgetManager: Optional<AppWidgetManager>, - appWidgetHost: CommunalAppWidgetHost, - @CommunalLog logBuffer: LogBuffer, - ): CommunalWidgetHost { - return CommunalWidgetHost(appWidgetManager, appWidgetHost, logBuffer) - } - - @Provides - @Named(DEFAULT_WIDGETS) - fun provideDefaultWidgets(@Main resources: Resources): Array<String> { - return resources.getStringArray(R.array.config_communalWidgetAllowlist) - } - } - @Binds fun communalWidgetRepository(impl: CommunalWidgetRepositoryImpl): CommunalWidgetRepository } diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt index b4f4099af124..636ea42ac88e 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt @@ -18,6 +18,7 @@ package com.android.systemui.communal.domain.interactor import android.app.smartspace.SmartspaceTarget import android.content.ComponentName +import android.os.UserHandle import com.android.systemui.communal.data.repository.CommunalMediaRepository import com.android.systemui.communal.data.repository.CommunalPrefsRepository import com.android.systemui.communal.data.repository.CommunalRepository @@ -231,9 +232,10 @@ constructor( /** Add a widget at the specified position. */ fun addWidget( componentName: ComponentName, + user: UserHandle, priority: Int, configurator: WidgetConfigurator?, - ) = widgetRepository.addWidget(componentName, priority, configurator) + ) = widgetRepository.addWidget(componentName, user, priority, configurator) /** * Delete a widget by id. Called when user deletes a widget from the hub or a widget is diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt index 0b096ce67fc5..20f60b79c784 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt @@ -17,6 +17,7 @@ package com.android.systemui.communal.domain.interactor import com.android.systemui.communal.data.model.CommunalEnabledState +import com.android.systemui.communal.data.model.CommunalWidgetCategories import com.android.systemui.communal.data.repository.CommunalSettingsRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background @@ -55,4 +56,16 @@ constructor( .map { model -> model.enabled } // Start this eagerly since the value is accessed synchronously in many places. .stateIn(scope = bgScope, started = SharingStarted.Eagerly, initialValue = false) + + /** What widget categories to show on the hub. */ + val communalWidgetCategories: StateFlow<Int> = + userInteractor.selectedUserInfo + .flatMapLatest { user -> repository.getWidgetCategories(user) } + .map { categories -> categories.categories } + .stateIn( + scope = bgScope, + // Start this eagerly since the value can be accessed synchronously. + started = SharingStarted.Eagerly, + initialValue = CommunalWidgetCategories().categories + ) } diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt index a87ebd7e8e9f..dee7a0c4f717 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt @@ -17,6 +17,7 @@ package com.android.systemui.communal.ui.viewmodel import android.content.ComponentName +import android.os.UserHandle import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.shared.model.CommunalSceneKey @@ -62,10 +63,11 @@ abstract class BaseCommunalViewModel( */ open fun onAddWidget( componentName: ComponentName, + user: UserHandle, priority: Int, configurator: WidgetConfigurator? = null ) { - communalInteractor.addWidget(componentName, priority, configurator) + communalInteractor.addWidget(componentName, user, priority, configurator) } /** A list of all the communal content to be displayed in the communal hub. */ diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt index 0b355cc10db5..efbb11e824c9 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt @@ -18,6 +18,7 @@ package com.android.systemui.communal.ui.viewmodel import com.android.internal.logging.UiEventLogger import com.android.systemui.communal.domain.interactor.CommunalInteractor +import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.shared.log.CommunalUiEvent import com.android.systemui.dagger.SysUISingleton @@ -40,6 +41,7 @@ class CommunalEditModeViewModel @Inject constructor( private val communalInteractor: CommunalInteractor, + private val communalSettingsInteractor: CommunalSettingsInteractor, @Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost, private val uiEventLogger: UiEventLogger, @CommunalLog logBuffer: LogBuffer, @@ -84,6 +86,10 @@ constructor( uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_REORDER_WIDGET_CANCEL) } + /** Returns the widget categories to show on communal hub. */ + val getCommunalWidgetCategories: Int + get() = communalSettingsInteractor.communalWidgetCategories.value + /** Sets whether edit mode is currently open */ fun setEditModeOpen(isOpen: Boolean) = communalInteractor.setEditModeOpen(isOpen) } diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/WidgetPickerIntentUtils.kt b/packages/SystemUI/src/com/android/systemui/communal/util/WidgetPickerIntentUtils.kt new file mode 100644 index 000000000000..94ec8f300da7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/util/WidgetPickerIntentUtils.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.communal.util + +import android.content.ComponentName +import android.content.Intent +import android.os.UserHandle + +/** Provides util functions for the intent of adding widgets from the Communal widget picker. */ +object WidgetPickerIntentUtils { + fun getWidgetExtraFromIntent(intent: Intent) = + WidgetExtra( + intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME, ComponentName::class.java), + intent.getParcelableExtra(Intent.EXTRA_USER, UserHandle::class.java) + ) + data class WidgetExtra(val componentName: ComponentName?, val user: UserHandle?) +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/CommunalWidgetHost.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalWidgetHost.kt index 965c1e873279..080dbedcb350 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/shared/CommunalWidgetHost.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalWidgetHost.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,23 +14,24 @@ * limitations under the License. */ -package com.android.systemui.communal.shared +package com.android.systemui.communal.widgets import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetProviderInfo import android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_CONFIGURATION_OPTIONAL import android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_RECONFIGURABLE import android.content.ComponentName -import com.android.systemui.communal.widgets.CommunalAppWidgetHost +import android.os.UserHandle import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.Logger import com.android.systemui.log.dagger.CommunalLog +import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.kotlin.getOrNull import java.util.Optional import javax.inject.Inject /** - * Widget host that interacts with AppWidget service and host to manage and provide info for widgets + * Widget host that interacts with AppWidget service and host to bind and provide info for widgets * shown in the glanceable hub. */ class CommunalWidgetHost @@ -38,6 +39,7 @@ class CommunalWidgetHost constructor( private val appWidgetManager: Optional<AppWidgetManager>, private val appWidgetHost: CommunalAppWidgetHost, + private val selectedUserInteractor: SelectedUserInteractor, @CommunalLog logBuffer: LogBuffer, ) { companion object { @@ -57,13 +59,21 @@ constructor( private val logger = Logger(logBuffer, TAG) /** - * Allocate an app widget id and binds the widget. + * Allocate an app widget id and binds the widget with the provider and associated user. * + * @param provider The component name of the provider. + * @param user User handle in which the provider resides. Default value is the current user. * @return widgetId if binding is successful; otherwise return null */ - fun allocateIdAndBindWidget(provider: ComponentName): Int? { + fun allocateIdAndBindWidget(provider: ComponentName, user: UserHandle? = null): Int? { val id = appWidgetHost.allocateAppWidgetId() - if (bindWidget(id, provider)) { + if ( + bindWidget( + widgetId = id, + user = user ?: UserHandle(selectedUserInteractor.getSelectedUserId()), + provider = provider + ) + ) { logger.d("Successfully bound the widget $provider") return id } @@ -72,9 +82,11 @@ constructor( return null } - private fun bindWidget(widgetId: Int, provider: ComponentName): Boolean { + private fun bindWidget(widgetId: Int, user: UserHandle, provider: ComponentName): Boolean { if (appWidgetManager.isPresent) { - return appWidgetManager.get().bindAppWidgetIdIfAllowed(widgetId, provider) + return appWidgetManager + .get() + .bindAppWidgetIdIfAllowed(widgetId, user, provider, /* options */ null) } return false } diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalWidgetModule.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalWidgetModule.kt new file mode 100644 index 000000000000..60fb8d4840cb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalWidgetModule.kt @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.systemui.communal.widgets + +import android.appwidget.AppWidgetManager +import android.content.Context +import android.content.res.Resources +import android.os.Looper +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.dagger.CommunalLog +import com.android.systemui.res.R +import com.android.systemui.user.domain.interactor.SelectedUserInteractor +import dagger.Module +import dagger.Provides +import java.util.Optional +import javax.inject.Named +import kotlinx.coroutines.CoroutineScope + +@Module +interface CommunalWidgetModule { + companion object { + private const val APP_WIDGET_HOST_ID = 116 + const val DEFAULT_WIDGETS = "default_widgets" + + @SysUISingleton + @Provides + fun provideAppWidgetManager(@Application context: Context): Optional<AppWidgetManager> { + return Optional.ofNullable(AppWidgetManager.getInstance(context)) + } + + @SysUISingleton + @Provides + fun provideCommunalAppWidgetHost( + @Application context: Context, + @Background backgroundScope: CoroutineScope, + interactionHandler: WidgetInteractionHandler, + @Main looper: Looper, + @CommunalLog logBuffer: LogBuffer, + ): CommunalAppWidgetHost { + return CommunalAppWidgetHost( + context, + backgroundScope, + APP_WIDGET_HOST_ID, + interactionHandler, + looper, + logBuffer, + ) + } + + @SysUISingleton + @Provides + fun provideCommunalWidgetHost( + appWidgetManager: Optional<AppWidgetManager>, + appWidgetHost: CommunalAppWidgetHost, + selectedUserInteractor: SelectedUserInteractor, + @CommunalLog logBuffer: LogBuffer, + ): CommunalWidgetHost { + return CommunalWidgetHost( + appWidgetManager, + appWidgetHost, + selectedUserInteractor, + logBuffer + ) + } + + @Provides + @Named(DEFAULT_WIDGETS) + fun provideDefaultWidgets(@Main resources: Resources): Array<String> { + return resources.getStringArray(R.array.config_communalWidgetAllowlist) + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt index 92e8153840eb..a5a390d7683b 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt @@ -16,7 +16,7 @@ package com.android.systemui.communal.widgets -import android.content.ComponentName +import android.appwidget.AppWidgetManager import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle @@ -31,6 +31,7 @@ import com.android.internal.logging.UiEventLogger import com.android.systemui.communal.shared.log.CommunalUiEvent import com.android.systemui.communal.shared.model.CommunalSceneKey import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel +import com.android.systemui.communal.util.WidgetPickerIntentUtils.getWidgetExtraFromIntent import com.android.systemui.compose.ComposeFacade.setCommunalEditWidgetActivityContent import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.Logger @@ -51,7 +52,6 @@ constructor( companion object { private const val EXTRA_IS_PENDING_WIDGET_DRAG = "is_pending_widget_drag" private const val EXTRA_DESIRED_WIDGET_WIDTH = "desired_widget_width" - private const val EXTRA_DESIRED_WIDGET_HEIGHT = "desired_widget_height" private const val TAG = "EditWidgetsActivity" @@ -75,13 +75,17 @@ constructor( // target in the communal grid will receive the widget to be added (if // the user drops it over). if (!isPendingWidgetDrag) { - intent - .getParcelableExtra( - Intent.EXTRA_COMPONENT_NAME, - ComponentName::class.java + val (componentName, user) = getWidgetExtraFromIntent(intent) + if (componentName != null && user != null) { + communalViewModel.onAddWidget( + componentName, + user, + 0, + widgetConfigurator ) - ?.let { communalViewModel.onAddWidget(it, 0, widgetConfigurator) } - ?: run { Log.w(TAG, "No AppWidgetProviderInfo found in result.") } + } else { + run { Log.w(TAG, "No AppWidgetProviderInfo found in result.") } + } } } ?: run { Log.w(TAG, "No data in result.") } @@ -134,6 +138,10 @@ constructor( R.dimen.communal_widget_picker_desired_height ) ) + putExtra( + AppWidgetManager.EXTRA_CATEGORY_FILTER, + communalViewModel.getCommunalWidgetCategories + ) } ) } catch (e: Exception) { diff --git a/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt index 8178adef49b2..a0aaa906802a 100644 --- a/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt +++ b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt @@ -79,7 +79,7 @@ interface BaseComposeFacade { fun setVolumePanelActivityContent( activity: ComponentActivity, viewModel: VolumePanelViewModel, - onDismissAnimationFinished: () -> Unit, + onDismiss: () -> Unit, ) /** Create a [View] to represent [viewModel] on screen. */ diff --git a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt index 41ce3fd11e8a..7a24d7693035 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt @@ -29,7 +29,6 @@ import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW import com.android.systemui.keyguard.shared.ComposeLockscreen -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor import com.android.systemui.statusbar.notification.interruption.VisualInterruptionRefactor @@ -52,15 +51,11 @@ class FlagDependencies @Inject constructor(featureFlags: FeatureFlagsClassic, ha FooterViewRefactor.token dependsOn NotificationIconContainerRefactor.token NotificationAvalancheSuppression.token dependsOn VisualInterruptionRefactor.token - // Internal keyguard dependencies - KeyguardShadeMigrationNssl.token dependsOn keyguardBottomAreaRefactor - // SceneContainer dependencies SceneContainerFlag.getFlagDependencies().forEach { (alpha, beta) -> alpha dependsOn beta } SceneContainerFlag.getMainStaticFlag() dependsOn MIGRATE_KEYGUARD_STATUS_BAR_VIEW // ComposeLockscreen dependencies - ComposeLockscreen.token dependsOn KeyguardShadeMigrationNssl.token ComposeLockscreen.token dependsOn keyguardBottomAreaRefactor ComposeLockscreen.token dependsOn migrateClocksToBlueprint } diff --git a/packages/SystemUI/src/com/android/systemui/flags/FlagDependenciesBase.kt b/packages/SystemUI/src/com/android/systemui/flags/FlagDependenciesBase.kt index 14fda5e96a9c..efbd59f6ce17 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FlagDependenciesBase.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/FlagDependenciesBase.kt @@ -48,10 +48,14 @@ abstract class FlagDependenciesBase( private var unmetDependencies = emptyList<Dependency>() override fun start() { + if (!handler.enableDependencies) { + return + } defineDependencies() allDependencies = workingDependencies.toList() unmetDependencies = workingDependencies.filter { !it.isMet } workingDependencies.clear() + handler.onCollected(allDependencies) if (unmetDependencies.isNotEmpty()) { handler.warnAboutBadFlagConfiguration(all = allDependencies, unmet = unmetDependencies) } @@ -106,14 +110,24 @@ abstract class FlagDependenciesBase( /** Add a dependency to the working list */ private fun addDependency(first: FlagToken, second: FlagToken) { - if (!Compile.IS_DEBUG) return // `user` builds should omit all this code + if (!handler.enableDependencies) return workingDependencies.add( Dependency(first.name, first.isEnabled, second.name, second.isEnabled) ) } - /** An interface which handles a warning about a bad flag configuration. */ + /** An interface which handles dependency collection. */ interface Handler { + /** + * Should FlagDependencies do anything? + * + * @return false for user builds so that we skip this overhead. + */ + val enableDependencies: Boolean + get() = Compile.IS_DEBUG + /** Handle the complete list of dependencies. */ + fun onCollected(all: List<Dependency>) {} + /** Handle a bad flag configuration. */ fun warnAboutBadFlagConfiguration(all: List<Dependency>, unmet: List<Dependency>) } } @@ -133,7 +147,7 @@ constructor( all: List<FlagDependenciesBase.Dependency>, unmet: List<FlagDependenciesBase.Dependency> ) { - val title = "Invalid flag dependencies: ${unmet.size} of ${all.size}" + val title = "Invalid flag dependencies: ${unmet.size}" val details = unmet.joinToString("\n") { it.shortUnmetString() } Log.e("FlagDependencies", "$title:\n$details") val channel = NotificationChannel("FLAGS", "Flags", NotificationManager.IMPORTANCE_DEFAULT) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java index e23ec894f8f3..00ec1a14bb93 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java @@ -404,6 +404,7 @@ public class KeyguardIndicationRotateTextViewController extends public static final int INDICATION_TYPE_BIOMETRIC_MESSAGE = 11; public static final int INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP = 12; public static final int INDICATION_IS_DISMISSIBLE = 13; + public static final int INDICATION_TYPE_ADAPTIVE_AUTH = 14; @IntDef({ INDICATION_TYPE_NONE, @@ -419,7 +420,8 @@ public class KeyguardIndicationRotateTextViewController extends INDICATION_TYPE_REVERSE_CHARGING, INDICATION_TYPE_BIOMETRIC_MESSAGE, INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, - INDICATION_IS_DISMISSIBLE + INDICATION_IS_DISMISSIBLE, + INDICATION_TYPE_ADAPTIVE_AUTH }) @Retention(RetentionPolicy.SOURCE) public @interface IndicationType{} @@ -455,6 +457,8 @@ public class KeyguardIndicationRotateTextViewController extends return "biometric_message"; case INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP: return "biometric_message_followup"; + case INDICATION_TYPE_ADAPTIVE_AUTH: + return "adaptive_auth"; default: return "unknown[" + type + "]"; } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt index 86b99ecac66c..e35c5a636bde 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt @@ -53,6 +53,7 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel +import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel import com.android.systemui.keyguard.ui.viewmodel.OccludingAppDeviceEntryMessageViewModel import com.android.systemui.plugins.FalsingManager @@ -98,6 +99,7 @@ constructor( private val falsingManager: FalsingManager, private val aodAlphaViewModel: AodAlphaViewModel, private val keyguardClockViewModel: KeyguardClockViewModel, + private val smartspaceViewModel: KeyguardSmartspaceViewModel, private val lockscreenContentViewModel: LockscreenContentViewModel, private val lockscreenSceneBlueprintsLazy: Lazy<Set<LockscreenSceneBlueprint>>, private val keyguardBlueprintViewBinder: KeyguardBlueprintViewBinder, @@ -148,6 +150,7 @@ constructor( keyguardRootView, keyguardBlueprintViewModel, keyguardClockViewModel, + smartspaceViewModel, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 63fd6087e587..c6b99528b2ba 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -30,6 +30,7 @@ import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NAV_BA import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_OCCLUSION; import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_TRANSITION_FROM_AOD; import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_UNLOCK_ANIMATION; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; @@ -152,7 +153,7 @@ import com.android.systemui.res.R; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.ShadeController; import com.android.systemui.shade.ShadeExpansionStateManager; -import com.android.systemui.shade.ShadeViewController; +import com.android.systemui.shade.ShadeLockscreenInteractor; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationShadeDepthController; @@ -920,15 +921,17 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST; } else if ((strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) { return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN; + } else if (any && ((strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0 + || mUpdateMonitor.isFingerprintLockedOut())) { + return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT; + } else if ((strongAuth & SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST) != 0) { + return KeyguardSecurityView.PROMPT_REASON_ADAPTIVE_AUTH_REQUEST; } else if (trustAgentsEnabled && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) { return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST; } else if (trustAgentsEnabled && (strongAuth & SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED) != 0) { return KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED; - } else if (any && ((strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0 - || mUpdateMonitor.isFingerprintLockedOut())) { - return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT; } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE) != 0) { return KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE; } else if (any && (strongAuth @@ -3526,14 +3529,14 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, * @return the View Controller for the Keyguard View this class is mediating. */ public KeyguardViewController registerCentralSurfaces(CentralSurfaces centralSurfaces, - ShadeViewController panelView, + ShadeLockscreenInteractor shadeLockscreenInteractor, @Nullable ShadeExpansionStateManager shadeExpansionStateManager, BiometricUnlockController biometricUnlockController, View notificationContainer, KeyguardBypassController bypassController) { mCentralSurfaces = centralSurfaces; mKeyguardViewControllerLazy.get().registerCentralSurfaces( centralSurfaces, - panelView, + shadeLockscreenInteractor, shadeExpansionStateManager, biometricUnlockController, notificationContainer, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt index 405d1d46456c..78749ead7ef9 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt @@ -241,6 +241,9 @@ constructor( /** * When the lockscreen can be dismissed, emit an alpha value as the user swipes up. This is * useful just before the code commits to moving to GONE. + * + * This uses legacyShadeExpansion to process swipe up events. In the future, the touch input + * signal should be sent directly to transitions. */ val dismissAlpha: Flow<Float?> = combine( diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/KeyguardShadeMigrationNssl.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/KeyguardShadeMigrationNssl.kt deleted file mode 100644 index 23642a741fb8..000000000000 --- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/KeyguardShadeMigrationNssl.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.systemui.keyguard.shared - -import com.android.systemui.Flags -import com.android.systemui.flags.FlagToken -import com.android.systemui.flags.RefactorFlagUtils - -/** Helper for reading or using the keyguard shade migration nssl flag state. */ -@Suppress("NOTHING_TO_INLINE") -object KeyguardShadeMigrationNssl { - /** The aconfig flag name */ - const val FLAG_NAME = Flags.FLAG_KEYGUARD_SHADE_MIGRATION_NSSL - - /** A token used for dependency declaration */ - val token: FlagToken - get() = FlagToken(FLAG_NAME, isEnabled) - - /** Is the refactor enabled */ - @JvmStatic - inline val isEnabled - get() = Flags.keyguardShadeMigrationNssl() - - /** - * Called to ensure code is only run when the flag is enabled. This protects users from the - * unintended behaviors caused by accidentally running new logic, while also crashing on an eng - * build to ensure that the refactor author catches issues in testing. - */ - @JvmStatic - inline fun isUnexpectedlyInLegacyMode() = - RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME) - - /** - * Called to ensure code is only run when the flag is disabled. This will throw an exception if - * the flag is enabled to ensure that the refactor author catches issues in testing. - */ - @JvmStatic - inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME) -} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/AuthenticationFlags.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/AuthenticationFlags.kt index cf5b88fde3dc..08904b6ffa86 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/AuthenticationFlags.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/AuthenticationFlags.kt @@ -60,6 +60,12 @@ data class AuthenticationFlags(val userId: Int, val flag: Int) { LockPatternUtils.StrongAuthTracker .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT ) + + val isSomeAuthRequiredAfterAdaptiveAuthRequest = + containsFlag( + flag, + LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST + ) } private fun containsFlag(haystack: Int, needle: Int): Boolean { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt index 6e70368476ed..66fc99567d42 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt @@ -34,6 +34,7 @@ import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.Intra import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Config import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel +import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel import com.android.systemui.lifecycle.repeatWhenAttached import javax.inject.Inject import kotlin.math.max @@ -84,6 +85,7 @@ constructor( constraintLayout: ConstraintLayout, viewModel: KeyguardBlueprintViewModel, clockViewModel: KeyguardClockViewModel, + smartspaceViewModel: KeyguardSmartspaceViewModel, ) { constraintLayout.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { @@ -108,10 +110,18 @@ constructor( ) { BaseBlueprintTransition(clockViewModel) .addTransition( - IntraBlueprintTransition(Config.DEFAULT, clockViewModel) + IntraBlueprintTransition( + Config.DEFAULT, + clockViewModel, + smartspaceViewModel + ) ) } else { - IntraBlueprintTransition(Config.DEFAULT, clockViewModel) + IntraBlueprintTransition( + Config.DEFAULT, + clockViewModel, + smartspaceViewModel + ) } runTransition(constraintLayout, transition, Config.DEFAULT) { @@ -136,7 +146,11 @@ constructor( runTransition( constraintLayout, - IntraBlueprintTransition(transition, clockViewModel), + IntraBlueprintTransition( + transition, + clockViewModel, + smartspaceViewModel + ), transition, ) { cs.applyTo(constraintLayout) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt index 5604ef23a142..c58a03c05a09 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt @@ -43,7 +43,6 @@ import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.TintedIcon import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel @@ -146,7 +145,7 @@ object KeyguardRootViewBinder { } } - if (KeyguardShadeMigrationNssl.isEnabled) { + if (migrateClocksToBlueprint()) { launch { viewModel.burnInLayerVisibility.collect { visibility -> childViews[burnInLayerId]?.visibility = visibility @@ -316,7 +315,7 @@ object KeyguardRootViewBinder { } } - if (KeyguardShadeMigrationNssl.isEnabled) { + if (migrateClocksToBlueprint()) { burnInParams.update { current -> current.copy(translationY = { childViews[burnInLayerId]?.translationY }) } @@ -415,7 +414,9 @@ object KeyguardRootViewBinder { configuration: ConfigurationState, screenOffAnimationController: ScreenOffAnimationController, ) { - KeyguardShadeMigrationNssl.assertInLegacyMode() + if (migrateClocksToBlueprint()) { + throw IllegalStateException("should only be called in legacy code paths") + } if (NotificationIconContainerRefactor.isUnexpectedlyInLegacyMode()) return coroutineScope { val iconAppearTranslationPx = @@ -444,7 +445,7 @@ object KeyguardRootViewBinder { } when { !isVisible.isAnimating -> { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { translationY = 0f } visibility = @@ -494,7 +495,7 @@ object KeyguardRootViewBinder { animatorListener: Animator.AnimatorListener, ) { if (animate) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { translationY = -iconAppearTranslation.toFloat() } alpha = 0f @@ -502,19 +503,19 @@ object KeyguardRootViewBinder { .alpha(1f) .setInterpolator(Interpolators.LINEAR) .setDuration(AOD_ICONS_APPEAR_DURATION) - .apply { if (KeyguardShadeMigrationNssl.isEnabled) animateInIconTranslation() } + .apply { if (migrateClocksToBlueprint()) animateInIconTranslation() } .setListener(animatorListener) .start() } else { alpha = 1.0f - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { translationY = 0f } } } private fun View.animateInIconTranslation() { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { animate().animateInIconTranslation().setDuration(AOD_ICONS_APPEAR_DURATION).start() } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt index bc9671e65f24..77f7ac8571dd 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt @@ -33,6 +33,7 @@ import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusBarSec import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusViewSection import com.android.systemui.keyguard.ui.view.layout.sections.DefaultUdfpsAccessibilityOverlaySection import com.android.systemui.keyguard.ui.view.layout.sections.KeyguardSectionsModule.Companion.KEYGUARD_AMBIENT_INDICATION_AREA_SECTION +import com.android.systemui.keyguard.ui.view.layout.sections.KeyguardSliceViewSection import com.android.systemui.keyguard.ui.view.layout.sections.SmartspaceSection import java.util.Optional import javax.inject.Inject @@ -65,6 +66,7 @@ constructor( communalTutorialIndicatorSection: CommunalTutorialIndicatorSection, clockSection: ClockSection, smartspaceSection: SmartspaceSection, + keyguardSliceViewSection: KeyguardSliceViewSection, udfpsAccessibilityOverlaySection: DefaultUdfpsAccessibilityOverlaySection, ) : KeyguardBlueprint { override val id: String = DEFAULT @@ -83,6 +85,7 @@ constructor( aodBurnInSection, communalTutorialIndicatorSection, clockSection, + keyguardSliceViewSection, defaultDeviceEntrySection, udfpsAccessibilityOverlaySection, // Add LAST: Intentionally has z-order above others ) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt index d118d4d11948..55b2381c79e4 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt @@ -33,6 +33,7 @@ import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusBarSec import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusViewSection import com.android.systemui.keyguard.ui.view.layout.sections.DefaultUdfpsAccessibilityOverlaySection import com.android.systemui.keyguard.ui.view.layout.sections.KeyguardSectionsModule +import com.android.systemui.keyguard.ui.view.layout.sections.KeyguardSliceViewSection import com.android.systemui.keyguard.ui.view.layout.sections.SmartspaceSection import com.android.systemui.util.kotlin.getOrNull import java.util.Optional @@ -60,6 +61,7 @@ constructor( communalTutorialIndicatorSection: CommunalTutorialIndicatorSection, clockSection: ClockSection, smartspaceSection: SmartspaceSection, + keyguardSliceViewSection: KeyguardSliceViewSection, udfpsAccessibilityOverlaySection: DefaultUdfpsAccessibilityOverlaySection, ) : KeyguardBlueprint { override val id: String = SHORTCUTS_BESIDE_UDFPS @@ -78,6 +80,7 @@ constructor( aodBurnInSection, communalTutorialIndicatorSection, clockSection, + keyguardSliceViewSection, defaultDeviceEntrySection, udfpsAccessibilityOverlaySection, // Add LAST: Intentionally has z-order above others ) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/transitions/IntraBlueprintTransition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/transitions/IntraBlueprintTransition.kt index a7075d97459e..3adeb2aeb283 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/transitions/IntraBlueprintTransition.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/transitions/IntraBlueprintTransition.kt @@ -20,10 +20,12 @@ import android.transition.TransitionSet import com.android.systemui.keyguard.ui.view.layout.sections.transitions.ClockSizeTransition import com.android.systemui.keyguard.ui.view.layout.sections.transitions.DefaultClockSteppingTransition import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel +import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel class IntraBlueprintTransition( config: IntraBlueprintTransition.Config, clockViewModel: KeyguardClockViewModel, + smartspaceViewModel: KeyguardSmartspaceViewModel, ) : TransitionSet() { enum class Type( @@ -56,7 +58,7 @@ class IntraBlueprintTransition( Type.NoTransition -> {} Type.DefaultClockStepping -> addTransition(clockViewModel.clock?.let { DefaultClockSteppingTransition(it) }) - else -> addTransition(ClockSizeTransition(config, clockViewModel)) + else -> addTransition(ClockSizeTransition(config, clockViewModel, smartspaceViewModel)) } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInLayer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInLayer.kt index 67a20e588198..dc2eeac872f5 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInLayer.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInLayer.kt @@ -18,9 +18,12 @@ package com.android.systemui.keyguard.ui.view.layout.sections import android.content.Context import android.view.View +import android.view.ViewTreeObserver.OnPreDrawListener import androidx.constraintlayout.helper.widget.Layer -class AodBurnInLayer(context: Context) : Layer(context) { +class AodBurnInLayer( + context: Context, +) : Layer(context) { // For setScale in Layer class, it stores it in mScaleX/Y and directly apply scale to // referenceViews instead of keeping the value in fields of View class // when we try to clone ConstraintSet, it will call getScaleX from View class and return 1.0 @@ -28,13 +31,32 @@ class AodBurnInLayer(context: Context) : Layer(context) { // which cause the flicker from AOD to LS private var _scaleX = 1F private var _scaleY = 1F + // As described for _scaleX and _scaleY, we have similar issue with translation - private var _translationX = 1F - private var _translationY = 1F + private var _translationX = 0F + private var _translationY = 0F + + private val _predrawListener = OnPreDrawListener { + super.setScaleX(_scaleX) + super.setScaleY(_scaleY) + super.setTranslationX(_translationX) + super.setTranslationY(_translationY) + true + } + // avoid adding views with same ids override fun addView(view: View?) { view?.let { if (it.id !in referencedIds) super.addView(view) } } + + fun registerListener(rootView: View) { + rootView.viewTreeObserver.addOnPreDrawListener(_predrawListener) + } + + fun unregisterListener(rootView: View) { + rootView.viewTreeObserver.removeOnPreDrawListener(_predrawListener) + } + override fun setScaleX(scaleX: Float) { _scaleX = scaleX super.setScaleX(scaleX) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt index 9a1fcc1a6a51..98bebd091f1a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt @@ -22,8 +22,8 @@ import android.view.View import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import com.android.systemui.Flags.migrateClocksToBlueprint -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.shared.model.KeyguardSection +import com.android.systemui.keyguard.ui.view.KeyguardRootView import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.res.R import javax.inject.Inject @@ -33,11 +33,12 @@ class AodBurnInSection @Inject constructor( private val context: Context, + private val rootView: KeyguardRootView, private val clockViewModel: KeyguardClockViewModel, ) : KeyguardSection() { private lateinit var burnInLayer: AodBurnInLayer override fun addViews(constraintLayout: ConstraintLayout) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { return } @@ -47,6 +48,7 @@ constructor( burnInLayer = AodBurnInLayer(context).apply { id = R.id.burn_in_layer + registerListener(rootView) addView(emptyView) if (!migrateClocksToBlueprint()) { val statusView = @@ -58,21 +60,20 @@ constructor( } override fun bindData(constraintLayout: ConstraintLayout) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { return } - if (migrateClocksToBlueprint()) { - clockViewModel.burnInLayer = burnInLayer - } + clockViewModel.burnInLayer = burnInLayer } override fun applyConstraints(constraintSet: ConstraintSet) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { return } } override fun removeViews(constraintLayout: ConstraintLayout) { + burnInLayer.unregisterListener(rootView) constraintLayout.removeView(R.id.burn_in_layer) } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt index ad589dfcff9e..3d9c04e39679 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt @@ -28,7 +28,6 @@ import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.TOP import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.common.ui.ConfigurationState -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.res.R import com.android.systemui.statusbar.notification.icon.ui.viewbinder.AlwaysOnDisplayNotificationIconViewStore @@ -59,7 +58,7 @@ constructor( private lateinit var nic: NotificationIconContainer override fun addViews(constraintLayout: ConstraintLayout) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { return } nic = @@ -78,7 +77,7 @@ constructor( } override fun bindData(constraintLayout: ConstraintLayout) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { return } @@ -99,7 +98,7 @@ constructor( } override fun applyConstraints(constraintSet: ConstraintSet) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { return } val bottomMargin = @@ -114,12 +113,9 @@ constructor( BOTTOM } constraintSet.apply { - if (migrateClocksToBlueprint()) { - connect(nicId, TOP, R.id.smart_space_barrier_bottom, BOTTOM, bottomMargin) - setGoneMargin(nicId, BOTTOM, bottomMargin) - } else { - connect(nicId, TOP, R.id.keyguard_status_view, topAlignment, bottomMargin) - } + connect(nicId, TOP, R.id.smart_space_barrier_bottom, BOTTOM, bottomMargin) + setGoneMargin(nicId, BOTTOM, bottomMargin) + connect( nicId, START, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt index 75132a59eb88..218af2994f4a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt @@ -27,7 +27,6 @@ import androidx.constraintlayout.widget.ConstraintSet.TOP import com.android.systemui.Flags.centralizedStatusBarDimensRefactor import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.shade.LargeScreenHeaderHelper @@ -71,7 +70,7 @@ constructor( mainDispatcher, ) { override fun applyConstraints(constraintSet: ConstraintSet) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { return } constraintSet.apply { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt index 851a45f31705..390b39f1e202 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt @@ -31,8 +31,8 @@ import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.TOP import com.android.keyguard.KeyguardStatusView import com.android.keyguard.dagger.KeyguardStatusViewComponent +import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.keyguard.KeyguardViewConfigurator -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.media.controls.ui.KeyguardMediaController import com.android.systemui.res.R @@ -58,7 +58,7 @@ constructor( private val statusViewId = R.id.keyguard_status_view override fun addViews(constraintLayout: ConstraintLayout) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { return } // At startup, 2 views with the ID `R.id.keyguard_status_view` will be available. @@ -83,7 +83,7 @@ constructor( } override fun bindData(constraintLayout: ConstraintLayout) { - if (KeyguardShadeMigrationNssl.isEnabled) { + if (migrateClocksToBlueprint()) { constraintLayout.findViewById<KeyguardStatusView?>(R.id.keyguard_status_view)?.let { val statusViewComponent = keyguardStatusViewComponentFactory.build(it, context.display) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSliceViewSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSliceViewSection.kt new file mode 100644 index 000000000000..d572c51d1146 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSliceViewSection.kt @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.systemui.keyguard.ui.view.layout.sections + +import android.view.View +import android.view.ViewGroup +import androidx.constraintlayout.widget.Barrier +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet +import com.android.systemui.Flags.migrateClocksToBlueprint +import com.android.systemui.keyguard.shared.model.KeyguardSection +import com.android.systemui.res.R +import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController +import javax.inject.Inject + +class KeyguardSliceViewSection +@Inject +constructor( + val smartspaceController: LockscreenSmartspaceController, +) : KeyguardSection() { + override fun addViews(constraintLayout: ConstraintLayout) { + if (!migrateClocksToBlueprint()) return + if (smartspaceController.isEnabled()) return + + constraintLayout.findViewById<View?>(R.id.keyguard_slice_view)?.let { + (it.parent as ViewGroup).removeView(it) + constraintLayout.addView(it) + } + } + + override fun bindData(constraintLayout: ConstraintLayout) {} + + override fun applyConstraints(constraintSet: ConstraintSet) { + if (!migrateClocksToBlueprint()) return + if (smartspaceController.isEnabled()) return + + constraintSet.apply { + connect( + R.id.keyguard_slice_view, + ConstraintSet.START, + ConstraintSet.PARENT_ID, + ConstraintSet.START + ) + connect( + R.id.keyguard_slice_view, + ConstraintSet.END, + ConstraintSet.PARENT_ID, + ConstraintSet.END + ) + constrainHeight(R.id.keyguard_slice_view, ConstraintSet.WRAP_CONTENT) + + connect( + R.id.keyguard_slice_view, + ConstraintSet.TOP, + R.id.lockscreen_clock_view, + ConstraintSet.BOTTOM + ) + + createBarrier( + R.id.smart_space_barrier_bottom, + Barrier.BOTTOM, + 0, + *intArrayOf(R.id.keyguard_slice_view) + ) + } + } + + override fun removeViews(constraintLayout: ConstraintLayout) { + if (!migrateClocksToBlueprint()) return + if (smartspaceController.isEnabled()) return + + constraintLayout.removeView(R.id.keyguard_slice_view) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt index 52d94a087110..d0f57c7f9ded 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt @@ -25,8 +25,8 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.ConstraintSet.BOTTOM import androidx.constraintlayout.widget.ConstraintSet.TOP +import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlags @@ -83,7 +83,7 @@ constructor( } override fun addViews(constraintLayout: ConstraintLayout) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { return } // This moves the existing NSSL view to a different parent, as the controller is a @@ -99,7 +99,7 @@ constructor( } override fun bindData(constraintLayout: ConstraintLayout) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { return } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt index 8255bcc87400..b0f7a258a4e6 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt @@ -57,6 +57,7 @@ constructor( override fun addViews(constraintLayout: ConstraintLayout) { if (!migrateClocksToBlueprint()) return + if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) return smartspaceView = smartspaceController.buildAndConnectView(constraintLayout) weatherView = smartspaceController.buildAndConnectWeatherView(constraintLayout) dateView = smartspaceController.buildAndConnectDateView(constraintLayout) @@ -83,6 +84,7 @@ constructor( override fun bindData(constraintLayout: ConstraintLayout) { if (!migrateClocksToBlueprint()) return + if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) return KeyguardSmartspaceViewBinder.bind( constraintLayout, keyguardClockViewModel, @@ -93,6 +95,7 @@ constructor( override fun applyConstraints(constraintSet: ConstraintSet) { if (!migrateClocksToBlueprint()) return + if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) return val horizontalPaddingStart = context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_start) + context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal) @@ -189,6 +192,7 @@ constructor( override fun removeViews(constraintLayout: ConstraintLayout) { if (!migrateClocksToBlueprint()) return + if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) return listOf(smartspaceView, dateView, weatherView).forEach { it?.let { if (it.parent == constraintLayout) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt index 3e35ae4b2dc3..2545302ccaa1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt @@ -23,8 +23,8 @@ import androidx.constraintlayout.widget.ConstraintSet.END import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.TOP +import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlags @@ -67,7 +67,7 @@ constructor( mainDispatcher, ) { override fun applyConstraints(constraintSet: ConstraintSet) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { return } constraintSet.apply { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt index 64cbb3229a57..f65f3760f082 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt @@ -31,8 +31,10 @@ import com.android.app.animation.Interpolators import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Type import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel +import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel import com.android.systemui.res.R import com.android.systemui.shared.R as sharedR +import com.google.android.material.math.MathUtils import kotlin.math.abs internal fun View.setRect(rect: Rect) = @@ -41,12 +43,13 @@ internal fun View.setRect(rect: Rect) = class ClockSizeTransition( config: IntraBlueprintTransition.Config, clockViewModel: KeyguardClockViewModel, + smartspaceViewModel: KeyguardSmartspaceViewModel, ) : TransitionSet() { init { ordering = ORDERING_TOGETHER if (config.type != Type.SmartspaceVisibility) { - addTransition(ClockFaceOutTransition(config, clockViewModel)) - addTransition(ClockFaceInTransition(config, clockViewModel)) + addTransition(ClockFaceOutTransition(config, clockViewModel, smartspaceViewModel)) + addTransition(ClockFaceInTransition(config, clockViewModel, smartspaceViewModel)) } addTransition(SmartspaceMoveTransition(config, clockViewModel)) } @@ -57,15 +60,6 @@ class ClockSizeTransition( override fun captureEndValues(transition: TransitionValues) = captureValues(transition) override fun captureStartValues(transition: TransitionValues) = captureValues(transition) override fun getTransitionProperties(): Array<String> = TRANSITION_PROPERTIES - open fun mutateBounds( - view: View, - fromVis: Int, - toVis: Int, - fromBounds: Rect, - toBounds: Rect, - fromSSBounds: Rect?, - toSSBounds: Rect? - ) {} private fun captureValues(transition: TransitionValues) { val view = transition.view @@ -79,6 +73,16 @@ class ClockSizeTransition( transition.values[SMARTSPACE_BOUNDS] = Rect(ss.left, ss.top, ss.right, ss.bottom) } + open fun mutateBounds( + view: View, + fromIsVis: Boolean, + toIsVis: Boolean, + fromBounds: Rect, + toBounds: Rect, + fromSSBounds: Rect?, + toSSBounds: Rect? + ) {} + override fun createAnimator( sceenRoot: ViewGroup, startValues: TransitionValues?, @@ -86,7 +90,6 @@ class ClockSizeTransition( ): Animator? { if (startValues == null || endValues == null) return null - val fromView = startValues.view var fromVis = startValues.values[PROP_VISIBILITY] as Int var fromIsVis = fromVis == View.VISIBLE var fromAlpha = startValues.values[PROP_ALPHA] as Float @@ -109,7 +112,7 @@ class ClockSizeTransition( fromVis = View.INVISIBLE } - mutateBounds(toView, fromVis, toVis, fromBounds, toBounds, fromSSBounds, toSSBounds) + mutateBounds(toView, fromIsVis, toIsVis, fromBounds, toBounds, fromSSBounds, toSSBounds) if (fromIsVis == toIsVis && fromBounds.equals(toBounds)) { if (DEBUG) { Log.w( @@ -125,7 +128,7 @@ class ClockSizeTransition( val sendToBack = fromIsVis && !toIsVis fun lerp(start: Int, end: Int, fract: Float): Int = - (start * (1f - fract) + end * fract).toInt() + MathUtils.lerp(start.toFloat(), end.toFloat(), fract).toInt() fun computeBounds(fract: Float): Rect = Rect( lerp(fromBounds.left, toBounds.left, fract), @@ -134,9 +137,14 @@ class ClockSizeTransition( lerp(fromBounds.bottom, toBounds.bottom, fract) ) - fun assignAnimValues(src: String, alpha: Float, fract: Float, vis: Int? = null) { + fun assignAnimValues(src: String, fract: Float, vis: Int? = null) { val bounds = computeBounds(fract) - if (DEBUG) Log.i(TAG, "$src: $toView; alpha=$alpha; vis=$vis; bounds=$bounds;") + val alpha = MathUtils.lerp(fromAlpha, toAlpha, fract) + if (DEBUG) + Log.i( + TAG, + "$src: $toView; fract=$fract; alpha=$alpha; vis=$vis; bounds=$bounds;" + ) toView.setVisibility(vis ?: View.VISIBLE) toView.setAlpha(alpha) toView.setRect(bounds) @@ -152,12 +160,12 @@ class ClockSizeTransition( ) } - return ValueAnimator.ofFloat(fromAlpha, toAlpha).also { anim -> + return ValueAnimator.ofFloat(0f, 1f).also { anim -> // We enforce the animation parameters on the target view every frame using a // predraw listener. This is suboptimal but prevents issues with layout passes // overwriting the animation for individual frames. val predrawCallback = OnPreDrawListener { - assignAnimValues("predraw", anim.animatedValue as Float, anim.animatedFraction) + assignAnimValues("predraw", anim.animatedFraction) return@OnPreDrawListener true } @@ -167,16 +175,18 @@ class ClockSizeTransition( anim.addListener( object : AnimatorListenerAdapter() { override fun onAnimationStart(anim: Animator) { - assignAnimValues("start", fromAlpha, 0f) + assignAnimValues("start", 0f, fromVis) } override fun onAnimationEnd(anim: Animator) { - assignAnimValues("end", toAlpha, 1f, toVis) + assignAnimValues("end", 1f, toVis) if (sendToBack) toView.translationZ = 0f toView.viewTreeObserver.removeOnPreDrawListener(predrawCallback) } } ) + + assignAnimValues("init", 0f, fromVis) toView.viewTreeObserver.addOnPreDrawListener(predrawCallback) } } @@ -197,12 +207,13 @@ class ClockSizeTransition( class ClockFaceInTransition( config: IntraBlueprintTransition.Config, val viewModel: KeyguardClockViewModel, + val smartspaceViewModel: KeyguardSmartspaceViewModel, ) : VisibilityBoundsTransition() { init { duration = CLOCK_IN_MILLIS startDelay = CLOCK_IN_START_DELAY_MILLIS interpolator = CLOCK_IN_INTERPOLATOR - captureSmartspace = !viewModel.useLargeClock + captureSmartspace = !viewModel.useLargeClock && smartspaceViewModel.isSmartspaceEnabled if (viewModel.useLargeClock) { viewModel.clock?.let { it.largeClock.layout.views.forEach { addTarget(it) } } @@ -213,13 +224,16 @@ class ClockSizeTransition( override fun mutateBounds( view: View, - fromVis: Int, - toVis: Int, + fromIsVis: Boolean, + toIsVis: Boolean, fromBounds: Rect, toBounds: Rect, fromSSBounds: Rect?, toSSBounds: Rect? ) { + // Move normally if clock is not changing visibility + if (fromIsVis == toIsVis) return + fromBounds.left = toBounds.left fromBounds.right = toBounds.right if (viewModel.useLargeClock) { @@ -252,11 +266,12 @@ class ClockSizeTransition( class ClockFaceOutTransition( config: IntraBlueprintTransition.Config, val viewModel: KeyguardClockViewModel, + val smartspaceViewModel: KeyguardSmartspaceViewModel, ) : VisibilityBoundsTransition() { init { duration = CLOCK_OUT_MILLIS interpolator = CLOCK_OUT_INTERPOLATOR - captureSmartspace = viewModel.useLargeClock + captureSmartspace = viewModel.useLargeClock && smartspaceViewModel.isSmartspaceEnabled if (viewModel.useLargeClock) { addTarget(R.id.lockscreen_clock_view) @@ -267,13 +282,16 @@ class ClockSizeTransition( override fun mutateBounds( view: View, - fromVis: Int, - toVis: Int, + fromIsVis: Boolean, + toIsVis: Boolean, fromBounds: Rect, toBounds: Rect, fromSSBounds: Rect?, toSSBounds: Rect? ) { + // Move normally if clock is not changing visibility + if (fromIsVis == toIsVis) return + toBounds.left = fromBounds.left toBounds.right = fromBounds.right if (!viewModel.useLargeClock) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/DefaultClockSteppingTransition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/DefaultClockSteppingTransition.kt index 60ab40c0a16b..f60115517111 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/DefaultClockSteppingTransition.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/DefaultClockSteppingTransition.kt @@ -78,8 +78,8 @@ class DefaultClockSteppingTransition( } companion object { - private const val PROP_BOUNDS_LEFT = "splitShadeTransitionAdapter:boundsLeft" - private const val PROP_X_IN_WINDOW = "splitShadeTransitionAdapter:xInWindow" + private const val PROP_BOUNDS_LEFT = "DefaultClockSteppingTransition:boundsLeft" + private const val PROP_X_IN_WINDOW = "DefaultClockSteppingTransition:xInWindow" private val TRANSITION_PROPERTIES = arrayOf(PROP_BOUNDS_LEFT, PROP_X_IN_WINDOW) private const val KEYGUARD_STATUS_VIEW_CUSTOM_CLOCK_MOVE_DURATION_MS = 1000L } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt index a3888c3341db..9fa14236ee77 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt @@ -102,7 +102,6 @@ constructor( override val deviceEntryParentViewAlpha: Flow<Float> = transitionAnimation.sharedFlow( duration = 500.milliseconds, - onStart = { 1f }, onStep = { 1f }, ) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt index 85885b065264..9fc759b8eca1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt @@ -53,7 +53,6 @@ constructor( return transitionAnimation.sharedFlowWithState( startTime = 600.milliseconds, duration = 500.milliseconds, - onStart = { translatePx }, onStep = { translatePx + it * -translatePx }, onFinish = { 0f }, onCancel = { 0f }, @@ -66,7 +65,6 @@ constructor( transitionAnimation.sharedFlow( startTime = 700.milliseconds, duration = 400.milliseconds, - onStart = { 0f }, onStep = { it }, onFinish = { 1f }, onCancel = { 1f }, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModel.kt index c61b1f5cc3be..d7ba46b6e708 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModel.kt @@ -54,7 +54,6 @@ constructor( startTime = 233.milliseconds, duration = 250.milliseconds, onStep = { it }, - onStart = { 0f }, ) override val deviceEntryParentViewAlpha: Flow<Float> = diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt index 19c11a947fe2..3a19780c7017 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt @@ -78,7 +78,6 @@ constructor( startTime = 233.milliseconds, duration = 250.milliseconds, onStep = { it }, - onStart = { 0f }, name = "OCCLUDED->LOCKSCREEN: lockscreenAlpha", ) diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt index 1b14f75d54ef..898eacff6246 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt @@ -25,8 +25,9 @@ import android.widget.SeekBar import android.widget.TextView import androidx.constraintlayout.widget.Barrier import com.android.internal.widget.CachingIconView -import com.android.systemui.res.R import com.android.systemui.media.controls.models.GutsViewHolder +import com.android.systemui.res.R +import com.android.systemui.surfaceeffects.loadingeffect.LoadingEffectView import com.android.systemui.surfaceeffects.ripple.MultiRippleView import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView import com.android.systemui.util.animation.TransitionLayout @@ -42,6 +43,7 @@ class MediaViewHolder constructor(itemView: View) { val multiRippleView = itemView.requireViewById<MultiRippleView>(R.id.touch_ripple_view) val turbulenceNoiseView = itemView.requireViewById<TurbulenceNoiseView>(R.id.turbulence_noise_view) + val loadingEffectView = itemView.requireViewById<LoadingEffectView>(R.id.loading_effect_view) val appIcon = itemView.requireViewById<ImageView>(R.id.icon) val titleText = itemView.requireViewById<TextView>(R.id.header_title) val artistText = itemView.requireViewById<TextView>(R.id.header_artist) @@ -171,6 +173,7 @@ class MediaViewHolder constructor(itemView: View) { setOf( R.id.album_art, R.id.turbulence_noise_view, + R.id.loading_effect_view, R.id.touch_ripple_view, ) } diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt index c87fd14a943d..952f9b8711f0 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt @@ -29,6 +29,7 @@ import com.android.internal.annotations.VisibleForTesting import com.android.settingslib.Utils import com.android.systemui.media.controls.models.player.MediaViewHolder import com.android.systemui.monet.ColorScheme +import com.android.systemui.surfaceeffects.loadingeffect.LoadingEffect import com.android.systemui.surfaceeffects.ripple.MultiRippleController import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController @@ -118,6 +119,7 @@ internal constructor( turbulenceNoiseController, ::AnimatingColorTransition ) + var loadingEffect: LoadingEffect? = null val bgColor = context.getColor(com.google.android.material.R.color.material_dynamic_neutral20) val surfaceColor = @@ -128,7 +130,6 @@ internal constructor( mediaViewHolder.albumView.backgroundTintList = colorList mediaViewHolder.gutsViewHolder.setSurfaceColor(surfaceColor) } - val accentPrimary = animatingColorTransitionFactory( loadDefaultColor(R.attr.textColorPrimary), @@ -139,6 +140,7 @@ internal constructor( mediaViewHolder.gutsViewHolder.setAccentPrimaryColor(accentPrimary) multiRippleController.updateColor(accentPrimary) turbulenceNoiseController.updateNoiseColor(accentPrimary) + loadingEffect?.updateColor(accentPrimary) } val accentSecondary = diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java index aa92814a584d..e97c9d3d8c0b 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java @@ -41,6 +41,7 @@ import android.graphics.Color; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Matrix; +import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Animatable; import android.graphics.drawable.BitmapDrawable; @@ -81,6 +82,7 @@ import com.android.internal.logging.InstanceId; import com.android.internal.widget.CachingIconView; import com.android.settingslib.widget.AdaptiveIcon; import com.android.systemui.ActivityIntentHelper; +import com.android.systemui.Flags; import com.android.systemui.animation.ActivityTransitionAnimator; import com.android.systemui.animation.GhostedViewTransitionAnimatorController; import com.android.systemui.bluetooth.BroadcastDialogController; @@ -111,6 +113,9 @@ import com.android.systemui.res.R; import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.surfaceeffects.loadingeffect.LoadingEffect; +import com.android.systemui.surfaceeffects.loadingeffect.LoadingEffect.Companion.AnimationState; +import com.android.systemui.surfaceeffects.loadingeffect.LoadingEffectView; import com.android.systemui.surfaceeffects.ripple.MultiRippleController; import com.android.systemui.surfaceeffects.ripple.MultiRippleView; import com.android.systemui.surfaceeffects.ripple.RippleAnimation; @@ -248,13 +253,34 @@ public class MediaControlPanel { private String mCurrentBroadcastApp; private MultiRippleController mMultiRippleController; private TurbulenceNoiseController mTurbulenceNoiseController; + private LoadingEffect mLoadingEffect; private final GlobalSettings mGlobalSettings; - + private final Random mRandom = new Random(); private TurbulenceNoiseAnimationConfig mTurbulenceNoiseAnimationConfig; private boolean mWasPlaying = false; private boolean mButtonClicked = false; - private final Random mRandom = new Random(); + private final LoadingEffect.Companion.PaintDrawCallback mNoiseDrawCallback = + new LoadingEffect.Companion.PaintDrawCallback() { + @Override + public void onDraw(@NonNull Paint loadingPaint) { + mMediaViewHolder.getLoadingEffectView().draw(loadingPaint); + } + }; + private final LoadingEffect.Companion.AnimationStateChangedCallback mStateChangedCallback = + new LoadingEffect.Companion.AnimationStateChangedCallback() { + @Override + public void onStateChanged(@NonNull AnimationState oldState, + @NonNull AnimationState newState) { + LoadingEffectView loadingEffectView = + mMediaViewHolder.getLoadingEffectView(); + if (newState == AnimationState.NOT_PLAYING) { + loadingEffectView.setVisibility(View.INVISIBLE); + } else { + loadingEffectView.setVisibility(View.VISIBLE); + } + } + }; /** * Initialize a new control panel @@ -456,6 +482,10 @@ public class MediaControlPanel { TurbulenceNoiseView turbulenceNoiseView = vh.getTurbulenceNoiseView(); turbulenceNoiseView.setBlendMode(BlendMode.SCREEN); + LoadingEffectView loadingEffectView = vh.getLoadingEffectView(); + loadingEffectView.setBlendMode(BlendMode.SCREEN); + loadingEffectView.setVisibility(View.INVISIBLE); + mTurbulenceNoiseController = new TurbulenceNoiseController(turbulenceNoiseView); mColorSchemeTransition = new ColorSchemeTransition( @@ -587,22 +617,41 @@ public class MediaControlPanel { } } - // Turbulence noise if (shouldPlayTurbulenceNoise()) { + // Need to create the config here to get the correct view size and color. if (mTurbulenceNoiseAnimationConfig == null) { mTurbulenceNoiseAnimationConfig = - createTurbulenceNoiseAnimation(); + createTurbulenceNoiseConfig(); + } + + if (Flags.shaderlibLoadingEffectRefactor()) { + if (mLoadingEffect == null) { + mLoadingEffect = new LoadingEffect( + Type.SIMPLEX_NOISE, + mTurbulenceNoiseAnimationConfig, + mNoiseDrawCallback, + mStateChangedCallback + ); + mColorSchemeTransition.setLoadingEffect(mLoadingEffect); + } + + mLoadingEffect.play(); + mMainExecutor.executeDelayed( + mLoadingEffect::finish, + TURBULENCE_NOISE_PLAY_DURATION + ); + } else { + mTurbulenceNoiseController.play( + Type.SIMPLEX_NOISE, + mTurbulenceNoiseAnimationConfig + ); + mMainExecutor.executeDelayed( + mTurbulenceNoiseController::finish, + TURBULENCE_NOISE_PLAY_DURATION + ); } - // Color will be correctly updated in ColorSchemeTransition. - mTurbulenceNoiseController.play( - Type.SIMPLEX_NOISE, - mTurbulenceNoiseAnimationConfig - ); - mMainExecutor.executeDelayed( - mTurbulenceNoiseController::finish, - TURBULENCE_NOISE_PLAY_DURATION - ); } + mButtonClicked = false; mWasPlaying = isPlaying(); @@ -1232,7 +1281,13 @@ public class MediaControlPanel { return mButtonClicked && !mWasPlaying && isPlaying(); } - private TurbulenceNoiseAnimationConfig createTurbulenceNoiseAnimation() { + private TurbulenceNoiseAnimationConfig createTurbulenceNoiseConfig() { + View targetView = Flags.shaderlibLoadingEffectRefactor() + ? mMediaViewHolder.getLoadingEffectView() : + mMediaViewHolder.getTurbulenceNoiseView(); + int width = targetView.getWidth(); + int height = targetView.getHeight(); + return new TurbulenceNoiseAnimationConfig( /* gridCount= */ 2.14f, TurbulenceNoiseAnimationConfig.DEFAULT_LUMINOSITY_MULTIPLIER, @@ -1242,10 +1297,11 @@ public class MediaControlPanel { /* noiseMoveSpeedX= */ 0.42f, /* noiseMoveSpeedY= */ 0f, TurbulenceNoiseAnimationConfig.DEFAULT_NOISE_SPEED_Z, + // Color will be correctly updated in ColorSchemeTransition. /* color= */ mColorSchemeTransition.getAccentPrimary().getCurrentColor(), /* backgroundColor= */ Color.BLACK, - /* width= */ mMediaViewHolder.getTurbulenceNoiseView().getWidth(), - /* height= */ mMediaViewHolder.getTurbulenceNoiseView().getHeight(), + width, + height, TurbulenceNoiseAnimationConfig.DEFAULT_MAX_DURATION_IN_MILLIS, /* easeInDuration= */ 1350f, /* easeOutDuration= */ 1350f, diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt index 25d89fac1af5..02be0c1a6c2d 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt @@ -35,10 +35,10 @@ import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection import javax.inject.Inject -/** - * Factory to create [MediaOutputDialog] objects. - */ -open class MediaOutputDialogFactory @Inject constructor( +/** Factory to create [MediaOutputDialog] objects. */ +open class MediaOutputDialogFactory +@Inject +constructor( private val context: Context, private val mediaSessionManager: MediaSessionManager, private val lbm: LocalBluetoothManager?, @@ -55,46 +55,93 @@ open class MediaOutputDialogFactory @Inject constructor( private val userTracker: UserTracker ) { companion object { - private const val INTERACTION_JANK_TAG = "media_output" + const val INTERACTION_JANK_TAG = "media_output" var mediaOutputDialog: MediaOutputDialog? = null } /** Creates a [MediaOutputDialog] for the given package. */ open fun create(packageName: String, aboveStatusBar: Boolean, view: View? = null) { - create(packageName, aboveStatusBar, view, includePlaybackAndAppMetadata = true) + createWithController( + packageName, + aboveStatusBar, + controller = + view?.let { + DialogTransitionAnimator.Controller.fromView( + it, + DialogCuj( + InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, + INTERACTION_JANK_TAG + ) + ) + }, + ) } - open fun createDialogForSystemRouting() { - create(packageName = null, aboveStatusBar = false, includePlaybackAndAppMetadata = false) + /** Creates a [MediaOutputDialog] for the given package. */ + open fun createWithController( + packageName: String, + aboveStatusBar: Boolean, + controller: DialogTransitionAnimator.Controller?, + ) { + create( + packageName, + aboveStatusBar, + dialogTransitionAnimatorController = controller, + includePlaybackAndAppMetadata = true + ) + } + + open fun createDialogForSystemRouting(controller: DialogTransitionAnimator.Controller? = null) { + create( + packageName = null, + aboveStatusBar = false, + dialogTransitionAnimatorController = null, + includePlaybackAndAppMetadata = false + ) } private fun create( - packageName: String?, - aboveStatusBar: Boolean, - view: View? = null, - includePlaybackAndAppMetadata: Boolean = true + packageName: String?, + aboveStatusBar: Boolean, + dialogTransitionAnimatorController: DialogTransitionAnimator.Controller?, + includePlaybackAndAppMetadata: Boolean = true ) { // Dismiss the previous dialog, if any. mediaOutputDialog?.dismiss() - val controller = MediaOutputController( - context, packageName, - mediaSessionManager, lbm, starter, notifCollection, - dialogTransitionAnimator, nearbyMediaDevicesManager, audioManager, - powerExemptionManager, keyGuardManager, featureFlags, userTracker) + val controller = + MediaOutputController( + context, + packageName, + mediaSessionManager, + lbm, + starter, + notifCollection, + dialogTransitionAnimator, + nearbyMediaDevicesManager, + audioManager, + powerExemptionManager, + keyGuardManager, + featureFlags, + userTracker + ) val dialog = - MediaOutputDialog(context, aboveStatusBar, broadcastSender, controller, - dialogTransitionAnimator, uiEventLogger, includePlaybackAndAppMetadata) + MediaOutputDialog( + context, + aboveStatusBar, + broadcastSender, + controller, + dialogTransitionAnimator, + uiEventLogger, + includePlaybackAndAppMetadata + ) mediaOutputDialog = dialog // Show the dialog. - if (view != null) { - dialogTransitionAnimator.showFromView( - dialog, view, - cuj = DialogCuj( - InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, - INTERACTION_JANK_TAG - ) + if (dialogTransitionAnimatorController != null) { + dialogTransitionAnimator.show( + dialog, + dialogTransitionAnimatorController, ) } else { dialog.show() diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java index 092f1ed7d498..152f193be3f9 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java @@ -44,6 +44,7 @@ import android.view.WindowManagerGlobal; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.RegisterStatusBarResult; import com.android.settingslib.applications.InterestingConfigChanges; @@ -89,7 +90,16 @@ public class NavigationBarControllerImpl implements private final TaskbarDelegate mTaskbarDelegate; private final NavBarHelper mNavBarHelper; private int mNavMode; + /** + * Indicates whether the active display is a large screen, e.g. tablets, foldable devices in + * the unfolded state. + */ @VisibleForTesting boolean mIsLargeScreen; + /** + * Indicates whether the device is a phone, rather than everything else (e.g. foldables, + * tablets) is considered not a handheld device. + */ + @VisibleForTesting boolean mIsPhone; /** A displayId - nav bar maps. */ @VisibleForTesting @@ -139,6 +149,8 @@ public class NavigationBarControllerImpl implements dumpManager, autoHideController, lightBarController, pipOptional, backAnimation.orElse(null), taskStackChangeListeners); mIsLargeScreen = isLargeScreen(mContext); + mIsPhone = + mContext.getResources().getIntArray(R.array.config_foldedDeviceStates).length == 0; dumpManager.registerDumpable(this); } @@ -253,9 +265,8 @@ public class NavigationBarControllerImpl implements /** @return {@code true} if taskbar is enabled, false otherwise */ private boolean initializeTaskbarIfNecessary() { - // Enable for large screens or (phone AND flag is set); assuming phone = !mIsLargeScreen - boolean taskbarEnabled = (mIsLargeScreen || enableTaskbarNavbarUnification()) - && shouldCreateNavBarAndTaskBar(mContext.getDisplayId()); + boolean taskbarEnabled = supportsTaskbar() && shouldCreateNavBarAndTaskBar( + mContext.getDisplayId()); if (taskbarEnabled) { Trace.beginSection("NavigationBarController#initializeTaskbarIfNecessary"); @@ -274,6 +285,12 @@ public class NavigationBarControllerImpl implements return taskbarEnabled; } + @VisibleForTesting + boolean supportsTaskbar() { + // Enable for tablets, unfolded state on a foldable device or (non handheld AND flag is set) + return mIsLargeScreen || (!mIsPhone && enableTaskbarNavbarUnification()); + } + private final CommandQueue.Callbacks mCommandQueueCallbacks = new CommandQueue.Callbacks() { @Override public void onDisplayRemoved(int displayId) { diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt index a755805d1872..4ccb18fced56 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt @@ -19,15 +19,16 @@ package com.android.systemui.scene.shared.flag import com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR +import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT import com.android.systemui.Flags.FLAG_SCENE_CONTAINER import com.android.systemui.Flags.keyguardBottomAreaRefactor +import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.Flags.sceneContainer import com.android.systemui.compose.ComposeFacade import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FlagToken import com.android.systemui.flags.Flags.SCENE_CONTAINER_ENABLED import com.android.systemui.flags.RefactorFlagUtils -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.media.controls.util.MediaInSceneContainerFlag import dagger.Module import dagger.Provides @@ -43,7 +44,7 @@ object SceneContainerFlag { SCENE_CONTAINER_ENABLED && // mainStaticFlag sceneContainer() && // mainAconfigFlag keyguardBottomAreaRefactor() && - KeyguardShadeMigrationNssl.isEnabled && + migrateClocksToBlueprint() && MediaInSceneContainerFlag.isEnabled && // NOTE: Changes should also be made in getSecondaryFlags and @EnableSceneContainer ComposeFacade.isComposeAvailable() @@ -63,7 +64,7 @@ object SceneContainerFlag { inline fun getSecondaryFlags(): Sequence<FlagToken> = sequenceOf( FlagToken(FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR, keyguardBottomAreaRefactor()), - KeyguardShadeMigrationNssl.token, + FlagToken(FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT, migrateClocksToBlueprint()), MediaInSceneContainerFlag.token, // NOTE: Changes should also be made in isEnabled and @EnableSceneContainer ) diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index fe45df89b526..95d9bc490caa 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -122,6 +122,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.DisplayId; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor; +import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor; import com.android.systemui.doze.DozeLog; import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpsysTableLogger; @@ -136,7 +137,6 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.keyguard.domain.interactor.NaturalScrollingSettingObserver; import com.android.systemui.keyguard.shared.ComposeLockscreen; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; import com.android.systemui.keyguard.shared.model.TransitionState; import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.keyguard.ui.binder.KeyguardLongPressViewBinder; @@ -907,7 +907,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump mKeyguardBypassController = bypassController; mUpdateMonitor = keyguardUpdateMonitor; mLockscreenShadeTransitionController = lockscreenShadeTransitionController; - lockscreenShadeTransitionController.setShadeViewController(this); shadeTransitionController.setShadeViewController(this); dynamicPrivacyController.addListener(this::onDynamicPrivacyChanged); quickSettingsController.setExpansionHeightListener(this::onQsSetExpansionHeightCalled); @@ -1021,7 +1020,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump instantCollapse(); } else { mView.animate().cancel(); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mView.animate() .alpha(0f) .setStartDelay(0) @@ -1157,7 +1156,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump // Occluded->Lockscreen collectFlow(mView, mKeyguardTransitionInteractor.getOccludedToLockscreenTransition(), mOccludedToLockscreenTransition, mMainDispatcher); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha(), setTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher); collectFlow(mView, @@ -1168,7 +1167,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump // Lockscreen->Dreaming collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToDreamingTransition(), mLockscreenToDreamingTransition, mMainDispatcher); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { collectFlow(mView, mLockscreenToDreamingTransitionViewModel.getLockscreenAlpha(), setDreamLockscreenTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher); @@ -1180,7 +1179,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump // Gone->Dreaming collectFlow(mView, mKeyguardTransitionInteractor.getGoneToDreamingTransition(), mGoneToDreamingTransition, mMainDispatcher); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { collectFlow(mView, mGoneToDreamingTransitionViewModel.getLockscreenAlpha(), setTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher); } @@ -1191,7 +1190,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump // Lockscreen->Occluded collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToOccludedTransition(), mLockscreenToOccludedTransition, mMainDispatcher); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { collectFlow(mView, mLockscreenToOccludedTransitionViewModel.getLockscreenAlpha(), setTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher); collectFlow(mView, mLockscreenToOccludedTransitionViewModel.getLockscreenTranslationY(), @@ -1199,7 +1198,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } // Primary bouncer->Gone (ensures lockscreen content is not visible on successful auth) - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { collectFlow(mView, mPrimaryBouncerToGoneTransitionViewModel.getLockscreenAlpha(), setTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher); } @@ -1277,7 +1276,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump mKeyguardStatusViewController.onDestroy(); } - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { // Need a shared controller until mKeyguardStatusViewController can be removed from // here, due to important state being set in that controller. Rebind in order to pick // up config changes @@ -1333,7 +1332,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump // Reset any left over overscroll state. It is a rare corner case but can happen. mQsController.setOverScrollAmount(0); mScrimController.setNotificationsOverScrollAmount(0); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mNotificationStackScrollLayoutController.setOverExpansion(0); mNotificationStackScrollLayoutController.setOverScrollAmount(0); } @@ -1354,7 +1353,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } updateClockAppearance(); mQsController.updateQsState(); - if (!KeyguardShadeMigrationNssl.isEnabled() && !FooterViewRefactor.isEnabled()) { + if (!migrateClocksToBlueprint() && !FooterViewRefactor.isEnabled()) { mNotificationStackScrollLayoutController.updateFooter(); } } @@ -1386,7 +1385,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump void reInflateViews() { debugLog("reInflateViews"); // Re-inflate the status view group. - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { KeyguardStatusView keyguardStatusView = mNotificationContainerParent.findViewById(R.id.keyguard_status_view); int statusIndex = mNotificationContainerParent.indexOfChild(keyguardStatusView); @@ -1506,7 +1505,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } private void updateMaxDisplayedNotifications(boolean recompute) { - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { return; } @@ -1663,7 +1662,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump mKeyguardStatusViewController.getClockBottom(mStatusBarHeaderHeightKeyguard), mKeyguardStatusViewController.isClockTopAligned()); mClockPositionAlgorithm.run(mClockPositionResult); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mKeyguardStatusViewController.setLockscreenClockY( mClockPositionAlgorithm.getExpandedPreferredClockY()); } @@ -1677,7 +1676,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump boolean animate = mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending(); boolean animateClock = (animate || mAnimateNextPositionUpdate) && shouldAnimateClockChange; - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mKeyguardStatusViewController.updatePosition( mClockPositionResult.clockX, mClockPositionResult.clockY, mClockPositionResult.clockScale, animateClock); @@ -1753,7 +1752,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump private void updateKeyguardStatusViewAlignment(boolean animate) { boolean shouldBeCentered = shouldKeyguardStatusViewBeCentered(); ConstraintLayout layout; - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { layout = mKeyguardViewConfigurator.getKeyguardRootView(); } else { layout = mNotificationContainerParent; @@ -1827,7 +1826,14 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump /** Returns space between top of lock icon and bottom of NotificationStackScrollLayout. */ private float getLockIconPadding() { float lockIconPadding = 0f; - if (mLockIconViewController.getTop() != 0f) { + if (DeviceEntryUdfpsRefactor.isEnabled()) { + View deviceEntryIconView = mKeyguardViewConfigurator.getKeyguardRootView() + .findViewById(R.id.device_entry_icon_view); + if (deviceEntryIconView != null) { + lockIconPadding = mNotificationStackScrollLayoutController.getBottom() + - deviceEntryIconView.getTop(); + } + } else if (mLockIconViewController.getTop() != 0f) { lockIconPadding = mNotificationStackScrollLayoutController.getBottom() - mLockIconViewController.getTop(); } @@ -1929,7 +1935,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha; mKeyguardStatusViewController.setAlpha(alpha); - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { // TODO (b/296373478) This is for split shade media movement. } else { mKeyguardStatusViewController @@ -2522,7 +2528,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump void requestScrollerTopPaddingUpdate(boolean animate) { float padding = mQsController.calculateNotificationsTopPadding(mIsExpandingOrCollapsing, getKeyguardNotificationStaticPadding(), mExpandedFraction); - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { mSharedNotificationContainerInteractor.setTopPosition(padding); } else { mNotificationStackScrollLayoutController.updateTopPadding(padding, animate); @@ -2704,7 +2710,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump return; } - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { float alpha = 1f; if (mClosingWithAlphaFadeOut && !mExpandingFromHeadsUp && !mHeadsUpManager.hasPinnedHeadsUp()) { @@ -2739,7 +2745,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } private void updateKeyguardBottomAreaAlpha() { - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { return; } if (mIsOcclusionTransitionRunning) { @@ -2980,7 +2986,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump @Override public void onScreenTurningOn() { - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mKeyguardStatusViewController.dozeTimeTick(); } } @@ -3232,7 +3238,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump public void dozeTimeTick() { mLockIconViewController.dozeTimeTick(); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mKeyguardStatusViewController.dozeTimeTick(); } if (mInterpolatedDarkAmount > 0) { @@ -4157,8 +4163,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump mFixedDuration = NO_FIXED_DURATION; } - @Override - public boolean postToView(Runnable action) { + boolean postToView(Runnable action) { return mView.post(action); } @@ -4448,7 +4453,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump && statusBarState == KEYGUARD) { // This means we're doing the screen off animation - position the keyguard status // view where it'll be on AOD, so we can animate it in. - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mKeyguardStatusViewController.updatePosition( mClockPositionResult.clockX, mClockPositionResult.clockYFullyDozing, @@ -4568,7 +4573,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump setDozing(true /* dozing */, false /* animate */); mStatusBarStateController.setUpcomingState(KEYGUARD); - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { mStatusBarStateController.setState(KEYGUARD); } else { mStatusBarStateListener.onStateChanged(KEYGUARD); @@ -4629,7 +4634,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump setIsFullWidth(mNotificationStackScrollLayoutController.getWidth() == mView.getWidth()); // Update Clock Pivot (used by anti-burnin transformations) - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mKeyguardStatusViewController.updatePivot(mView.getWidth(), mView.getHeight()); } @@ -4739,7 +4744,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump private Consumer<Float> setTransitionY( NotificationStackScrollLayoutController stackScroller) { return (Float translationY) -> { - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mKeyguardStatusViewController.setTranslationY(translationY, /* excludeMedia= */false); stackScroller.setTranslationY(translationY); @@ -4781,7 +4786,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump */ @Override public boolean onInterceptTouchEvent(MotionEvent event) { - if (KeyguardShadeMigrationNssl.isEnabled() && !mUseExternalTouch) { + if (migrateClocksToBlueprint() && !mUseExternalTouch) { return false; } @@ -4852,7 +4857,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mCentralSurfaces.userActivity(); } mAnimatingOnDown = mHeightAnimator != null && !mIsSpringBackAnimation; @@ -4953,7 +4958,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump */ @Override public boolean onTouchEvent(MotionEvent event) { - if (KeyguardShadeMigrationNssl.isEnabled() && !mUseExternalTouch) { + if (migrateClocksToBlueprint() && !mUseExternalTouch) { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java index aa2d606c5126..99e91c1d332f 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java @@ -16,6 +16,7 @@ package com.android.systemui.shade; +import static com.android.systemui.Flags.migrateClocksToBlueprint; import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED; import static com.android.systemui.flags.Flags.TRACKPAD_GESTURE_COMMON; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; @@ -48,7 +49,6 @@ import com.android.systemui.flags.Flags; import com.android.systemui.keyevent.domain.interactor.SysUIKeyEventHandler; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; import com.android.systemui.keyguard.shared.model.TransitionState; import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.keyguard.ui.binder.AlternateBouncerViewBinder; @@ -320,7 +320,7 @@ public class NotificationShadeWindowViewController implements Dumpable { mTouchActive = true; mTouchCancelled = false; mDownEvent = ev; - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { mService.userActivity(); } } else if (ev.getActionMasked() == MotionEvent.ACTION_UP @@ -475,7 +475,7 @@ public class NotificationShadeWindowViewController implements Dumpable { && !bouncerShowing && !mStatusBarStateController.isDozing()) { if (mDragDownHelper.isDragDownEnabled()) { - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { // When on lockscreen, if the touch originates at the top of the screen // go directly to QS and not the shade if (mStatusBarStateController.getState() == KEYGUARD @@ -488,7 +488,7 @@ public class NotificationShadeWindowViewController implements Dumpable { // This handles drag down over lockscreen boolean result = mDragDownHelper.onInterceptTouchEvent(ev); - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { if (result) { mLastInterceptWasDragDownHelper = true; if (ev.getAction() == MotionEvent.ACTION_DOWN) { @@ -520,7 +520,7 @@ public class NotificationShadeWindowViewController implements Dumpable { MotionEvent cancellation = MotionEvent.obtain(ev); cancellation.setAction(MotionEvent.ACTION_CANCEL); mStackScrollLayout.onInterceptTouchEvent(cancellation); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mNotificationPanelViewController.handleExternalInterceptTouch(cancellation); } cancellation.recycle(); @@ -535,7 +535,7 @@ public class NotificationShadeWindowViewController implements Dumpable { if (mStatusBarKeyguardViewManager.onTouch(ev)) { return true; } - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { if (mLastInterceptWasDragDownHelper && (mDragDownHelper.isDraggingDown())) { // we still want to finish our drag down gesture when locking the screen handled |= mDragDownHelper.onTouchEvent(ev) || handled; @@ -625,7 +625,7 @@ public class NotificationShadeWindowViewController implements Dumpable { } private boolean didNotificationPanelInterceptEvent(MotionEvent ev) { - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { // Since NotificationStackScrollLayout is now a sibling of notification_panel, we need // to also ask NotificationPanelViewController directly, in order to process swipe up // events originating from notifications diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt index c0afa32571e7..457b3d7e6217 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt @@ -28,10 +28,10 @@ import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.TOP import androidx.lifecycle.lifecycleScope import com.android.systemui.Flags.centralizedStatusBarDimensRefactor +import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.fragments.FragmentService -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.navigationbar.NavigationModeController import com.android.systemui.plugins.qs.QS @@ -284,7 +284,7 @@ class NotificationsQSContainerController @Inject constructor( } private fun setNotificationsConstraints(constraintSet: ConstraintSet) { - if (KeyguardShadeMigrationNssl.isEnabled) { + if (migrateClocksToBlueprint()) { return } val startConstraintId = if (splitShadeEnabled) R.id.qs_edge_guideline else PARENT_ID diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java index 25e558ee42dd..e82f2d3cbd30 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java @@ -18,6 +18,8 @@ package com.android.systemui.shade; import static androidx.constraintlayout.core.widgets.Optimizer.OPTIMIZATION_GRAPH; +import static com.android.systemui.Flags.migrateClocksToBlueprint; + import android.app.Fragment; import android.content.Context; import android.content.res.Configuration; @@ -33,7 +35,6 @@ import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; import com.android.systemui.plugins.qs.QS; import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.AboveShelfObserver; @@ -189,7 +190,7 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { - if (KeyguardShadeMigrationNssl.isEnabled()) { + if (migrateClocksToBlueprint()) { return super.drawChild(canvas, child, drawingTime); } int layoutIndex = mLayoutDrawingOrder.indexOf(child); diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java index f3e9c7503626..f86c71b9508c 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java @@ -21,6 +21,7 @@ import static android.view.WindowInsets.Type.ime; import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE; import static com.android.systemui.Flags.centralizedStatusBarDimensRefactor; +import static com.android.systemui.Flags.migrateClocksToBlueprint; import static com.android.systemui.classifier.Classifier.QS_COLLAPSE; import static com.android.systemui.shade.NotificationPanelViewController.COUNTER_PANEL_OPEN_QS; import static com.android.systemui.shade.NotificationPanelViewController.FLING_COLLAPSE; @@ -70,7 +71,6 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor; import com.android.systemui.dump.DumpManager; import com.android.systemui.fragments.FragmentHostManager; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; import com.android.systemui.media.controls.pipeline.MediaDataManager; import com.android.systemui.media.controls.ui.MediaHierarchyManager; import com.android.systemui.plugins.FalsingManager; @@ -1782,7 +1782,7 @@ public class QuickSettingsController implements Dumpable { // Dragging down on the lockscreen statusbar should prohibit other interactions // immediately, otherwise we'll wait on the touchslop. This is to allow // dragging down to expanded quick settings directly on the lockscreen. - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mPanelView.getParent().requestDisallowInterceptTouchEvent(true); } } @@ -1827,7 +1827,7 @@ public class QuickSettingsController implements Dumpable { && Math.abs(h) > Math.abs(x - mInitialTouchX) && shouldQuickSettingsIntercept( mInitialTouchX, mInitialTouchY, h)) { - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mPanelView.getParent().requestDisallowInterceptTouchEvent(true); } mShadeLog.onQsInterceptMoveQsTrackingEnabled(h); diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java index e8d9c35a893b..ea419127d7c1 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java @@ -66,7 +66,7 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { private final StatusBarWindowController mStatusBarWindowController; private final DeviceProvisionedController mDeviceProvisionedController; - private final Lazy<ShadeViewController> mShadeViewControllerLazy; + private final Lazy<NotificationPanelViewController> mNpvc; private final Lazy<AssistManager> mAssistManagerLazy; private final Lazy<NotificationGutsManager> mGutsManager; @@ -89,7 +89,7 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { DeviceProvisionedController deviceProvisionedController, NotificationShadeWindowController notificationShadeWindowController, WindowManager windowManager, - Lazy<ShadeViewController> shadeViewControllerLazy, + Lazy<NotificationPanelViewController> shadeViewControllerLazy, Lazy<AssistManager> assistManagerLazy, Lazy<NotificationGutsManager> gutsManager ) { @@ -101,7 +101,7 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { mCommandQueue = commandQueue; mMainExecutor = mainExecutor; mWindowRootViewVisibilityInteractor = windowRootViewVisibilityInteractor; - mShadeViewControllerLazy = shadeViewControllerLazy; + mNpvc = shadeViewControllerLazy; mStatusBarStateController = statusBarStateController; mStatusBarWindowController = statusBarWindowController; mDeviceProvisionedController = deviceProvisionedController; @@ -122,7 +122,7 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { public void instantExpandShade() { // Make our window larger and the panel expanded. makeExpandedVisible(true /* force */); - getShadeViewController().expand(false /* animate */); + getNpvc().expand(false /* animate */); getCommandQueue().recomputeDisableFlags(mDisplayId, false /* animate */); } @@ -134,29 +134,29 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { return; } if (getNotificationShadeWindowView() != null - && getShadeViewController().canBeCollapsed() + && getNpvc().canBeCollapsed() && (flags & CommandQueue.FLAG_EXCLUDE_NOTIFICATION_PANEL) == 0) { // release focus immediately to kick off focus change transition mNotificationShadeWindowController.setNotificationShadeFocusable(false); mNotificationShadeWindowViewController.cancelExpandHelper(); - getShadeViewController().collapse(true, delayed, speedUpFactor); + getNpvc().collapse(true, delayed, speedUpFactor); } } @Override protected void expandToNotifications() { - getShadeViewController().expandToNotifications(); + getNpvc().expandToNotifications(); } @Override protected void expandToQs() { - getShadeViewController().expandToQs(); + getNpvc().expandToQs(); } @Override public boolean closeShadeIfOpen() { - if (!getShadeViewController().isFullyCollapsed()) { + if (!getNpvc().isFullyCollapsed()) { getCommandQueue().animateCollapsePanels( CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */); notifyVisibilityChanged(false); @@ -167,12 +167,12 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { @Override public boolean isShadeFullyOpen() { - return getShadeViewController().isShadeFullyExpanded(); + return getNpvc().isShadeFullyExpanded(); } @Override public boolean isExpandingOrCollapsing() { - return getShadeViewController().isExpandingOrCollapsing(); + return getNpvc().isExpandingOrCollapsing(); } @Override public void postAnimateCollapseShade() { @@ -191,13 +191,13 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { @Override public void postOnShadeExpanded(Runnable executable) { - getShadeViewController().addOnGlobalLayoutListener( + getNpvc().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if (getNotificationShadeWindowView().isVisibleToUser()) { - getShadeViewController().removeOnGlobalLayoutListener(this); - getShadeViewController().postToView(executable); + getNpvc().removeOnGlobalLayoutListener(this); + getNpvc().postToView(executable); } } }); @@ -209,7 +209,7 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { } private boolean collapseShadeInternal() { - if (!getShadeViewController().isFullyCollapsed()) { + if (!getNpvc().isFullyCollapsed()) { // close the shade if it was open animateCollapseShadeForcedDelayed(); notifyVisibilityChanged(false); @@ -237,10 +237,10 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { @Override public void cancelExpansionAndCollapseShade() { - if (getShadeViewController().isTracking()) { + if (getNpvc().isTracking()) { mNotificationShadeWindowViewController.cancelCurrentTouch(); } - if (getShadeViewController().isPanelExpanded() + if (getNpvc().isPanelExpanded() && mStatusBarStateController.getState() == StatusBarState.SHADE) { animateCollapseShade(); } @@ -266,7 +266,7 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { @Override public void instantCollapseShade() { - getShadeViewController().instantCollapse(); + getNpvc().instantCollapse(); runPostCollapseActions(); } @@ -297,7 +297,7 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { } // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868) - getShadeViewController().collapse(false, false, 1.0f); + getNpvc().collapse(false, false, 1.0f); mExpandedVisible = false; notifyVisibilityChanged(false); @@ -319,7 +319,7 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { notifyExpandedVisibleChanged(false); getCommandQueue().recomputeDisableFlags( mDisplayId, - getShadeViewController().shouldHideStatusBarIconsWhenExpanded()); + getNpvc().shouldHideStatusBarIconsWhenExpanded()); // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in // the bouncer appear animation. @@ -368,15 +368,15 @@ public final class ShadeControllerImpl extends BaseShadeControllerImpl { return mNotificationShadeWindowViewController.getView(); } - private ShadeViewController getShadeViewController() { - return mShadeViewControllerLazy.get(); + private NotificationPanelViewController getNpvc() { + return mNpvc.get(); } @Override public void start() { super.start(); - getShadeViewController().setTrackingStartedListener(this::runPostCollapseActions); - getShadeViewController().setOpenCloseListener( + getNpvc().setTrackingStartedListener(this::runPostCollapseActions); + getNpvc().setOpenCloseListener( new OpenCloseListener() { @Override public void onClosingFinished() { diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt index 7cb3be7f159d..6a2a6a417f5a 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt @@ -241,7 +241,7 @@ constructor( } override fun onStatusBarTouch(event: MotionEvent) { - // The only call to this doesn't happen with KeyguardShadeMigrationNssl enabled + // The only call to this doesn't happen with migrateClocksToBlueprint() enabled throw UnsupportedOperationException() } } diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeEmptyImplModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeEmptyImplModule.kt index f89a9c701047..d393f0d0b72b 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeEmptyImplModule.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeEmptyImplModule.kt @@ -40,6 +40,12 @@ abstract class ShadeEmptyImplModule { @Binds @SysUISingleton + abstract fun bindsShadeLockscreenInteractor( + slsi: ShadeViewControllerEmptyImpl + ): ShadeLockscreenInteractor + + @Binds + @SysUISingleton abstract fun bindsShadeController(sc: ShadeControllerEmptyImpl): ShadeController @Binds diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeLockscreenInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeLockscreenInteractor.kt new file mode 100644 index 000000000000..a9ba6f96b7d2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeLockscreenInteractor.kt @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.shade + +/** Allows the lockscreen to control the shade. */ +interface ShadeLockscreenInteractor { + + /** + * Expand shade so that notifications are visible. Non-split shade: just expanding shade or + * collapsing QS when they're expanded. Split shade: only expanding shade, notifications are + * always visible + * + * Called when `adb shell cmd statusbar expand-notifications` is executed. + */ + @Deprecated("Use ShadeInteractor instead") fun expandToNotifications() + + /** Returns whether the shade is expanding or collapsing itself or quick settings. */ + val isExpandingOrCollapsing: Boolean + + /** + * Returns whether the shade height is greater than zero (i.e. partially or fully expanded), + * there is a HUN, the shade is animating, or the shade is instantly expanding. + */ + @Deprecated("Use ShadeInteractor instead") val isExpanded: Boolean + + /** Called before animating Keyguard dismissal, i.e. the animation dismissing the bouncer. */ + fun startBouncerPreHideAnimation() + + /** Called once every minute while dozing. */ + fun dozeTimeTick() + + /** + * Do not let the user drag the shade up and down for the current touch session. This is + * necessary to avoid shade expansion while/after the bouncer is dismissed. + */ + @Deprecated("Not supported by scenes") fun blockExpansionForCurrentTouch() + + /** Close guts, notification menus, and QS. Set scroll and overscroll to 0. */ + fun resetViews(animate: Boolean) + + /** Sets whether the screen has temporarily woken up to display notifications. */ + @Deprecated("Not supported by scenes") fun setPulsing(pulsing: Boolean) + + /** Animate to expanded shade after a delay in ms. Used for lockscreen to shade transition. */ + fun transitionToExpandedShade(delay: Long) + + /** @see ViewGroupFadeHelper.reset */ + @Deprecated("Not supported by scenes") fun resetViewGroupFade() + + /** + * Set the alpha and translationY of the keyguard elements which only show on the lockscreen, + * but not in shade locked / shade. This is used when dragging down to the full shade. + */ + @Deprecated("Not supported by scenes") + fun setKeyguardTransitionProgress(keyguardAlpha: Float, keyguardTranslationY: Int) + + /** Sets the overstretch amount in raw pixels when dragging down. */ + @Deprecated("Not supported by scenes") fun setOverStretchAmount(amount: Float) + + /** + * Sets the alpha value to be set on the keyguard status bar. + * + * @param alpha value between 0 and 1. -1 if the value is to be reset. + */ + @Deprecated("TODO(b/325072511) delete this") fun setKeyguardStatusBarAlpha(alpha: Float) +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt index e4d5d22c602c..86fdceea57ef 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt @@ -30,6 +30,7 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.domain.interactor.ShadeInteractorImpl import com.android.systemui.shade.domain.interactor.ShadeInteractorLegacyImpl import com.android.systemui.shade.domain.interactor.ShadeInteractorSceneContainerImpl +import com.android.systemui.shade.domain.interactor.ShadeLockscreenInteractorImpl import dagger.Binds import dagger.Module import dagger.Provides @@ -94,6 +95,20 @@ abstract class ShadeModule { sceneContainerOff.get() } } + + @Provides + @SysUISingleton + fun provideShadeLockscreenInteractor( + sceneContainerFlags: SceneContainerFlags, + sceneContainerOn: Provider<ShadeLockscreenInteractorImpl>, + sceneContainerOff: Provider<NotificationPanelViewController> + ): ShadeLockscreenInteractor { + return if (sceneContainerFlags.isEnabled()) { + sceneContainerOn.get() + } else { + sceneContainerOff.get() + } + } } @Binds diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt index 0befb61ff814..941c6f33bc16 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt @@ -26,7 +26,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager * this class. If any method in this class is needed outside of CentralSurfacesImpl, it must be * pulled up into ShadeViewController. */ -interface ShadeSurface : ShadeViewController, ShadeBackActionInteractor { +interface ShadeSurface : ShadeViewController, ShadeBackActionInteractor, ShadeLockscreenInteractor { /** Initialize objects instead of injecting to avoid circular dependencies. */ fun initDependencies( centralSurfaces: CentralSurfaces, diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt index 74035bd442db..44c6a82d93ca 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt @@ -37,25 +37,10 @@ interface ShadeViewController { /** Animates to an expanded shade with QS expanded. If the shade starts expanded, expands QS. */ fun expandToQs() - /** - * Expand shade so that notifications are visible. Non-split shade: just expanding shade or - * collapsing QS when they're expanded. Split shade: only expanding shade, notifications are - * always visible - * - * Called when `adb shell cmd statusbar expand-notifications` is executed. - */ - fun expandToNotifications() - /** Returns whether the shade is expanding or collapsing itself or quick settings. */ val isExpandingOrCollapsing: Boolean /** - * Returns whether the shade height is greater than zero (i.e. partially or fully expanded), - * there is a HUN, the shade is animating, or the shade is instantly expanding. - */ - val isExpanded: Boolean - - /** * Returns whether the shade height is greater than zero or the shade is expecting a synthesized * down event. */ @@ -101,12 +86,6 @@ interface ShadeViewController { /** Returns whether status bar icons should be hidden when the shade is expanded. */ fun shouldHideStatusBarIconsWhenExpanded(): Boolean - /** - * Do not let the user drag the shade up and down for the current touch session. This is - * necessary to avoid shade expansion while/after the bouncer is dismissed. - */ - fun blockExpansionForCurrentTouch() - /** Sets a listener to be notified when touch tracking begins. */ fun setTrackingStartedListener(trackingStartedListener: TrackingStartedListener) @@ -120,15 +99,6 @@ interface ShadeViewController { /** If the latency tracker is enabled, begins tracking expand latency. */ fun startExpandLatencyTracking() - /** Called before animating Keyguard dismissal, i.e. the animation dismissing the bouncer. */ - fun startBouncerPreHideAnimation() - - /** Called once every minute while dozing. */ - fun dozeTimeTick() - - /** Close guts, notification menus, and QS. Set scroll and overscroll to 0. */ - fun resetViews(animate: Boolean) - /** Returns the StatusBarState. */ val barState: Int @@ -145,9 +115,6 @@ interface ShadeViewController { */ fun setAlphaChangeAnimationEndAction(r: Runnable) - /** Sets whether the screen has temporarily woken up to display notifications. */ - fun setPulsing(pulsing: Boolean) - /** Sets Qs ScrimEnabled and updates QS state. */ fun setQsScrimEnabled(qsScrimEnabled: Boolean) @@ -166,32 +133,6 @@ interface ShadeViewController { /** Removes a global layout listener. */ fun removeOnGlobalLayoutListener(listener: ViewTreeObserver.OnGlobalLayoutListener) - /** Posts the given runnable to the view. */ - fun postToView(action: Runnable): Boolean - - // ******* Begin Keyguard Section ********* - /** Animate to expanded shade after a delay in ms. Used for lockscreen to shade transition. */ - fun transitionToExpandedShade(delay: Long) - - /** @see ViewGroupFadeHelper.reset */ - fun resetViewGroupFade() - - /** - * Set the alpha and translationY of the keyguard elements which only show on the lockscreen, - * but not in shade locked / shade. This is used when dragging down to the full shade. - */ - fun setKeyguardTransitionProgress(keyguardAlpha: Float, keyguardTranslationY: Int) - - /** Sets the overstretch amount in raw pixels when dragging down. */ - fun setOverStretchAmount(amount: Float) - - /** - * Sets the alpha value to be set on the keyguard status bar. - * - * @param alpha value between 0 and 1. -1 if the value is to be reset. - */ - fun setKeyguardStatusBarAlpha(alpha: Float) - /** * Reconfigures the shade to show the AOD UI (clock, smartspace, etc). This is called by the * screen off animation controller in order to animate in AOD without "actually" fully switching @@ -251,8 +192,6 @@ interface ShadeViewController { */ fun performHapticFeedback(constant: Int) - // ******* End Keyguard Section ********* - /** Returns the ShadeHeadsUpTracker. */ val shadeHeadsUpTracker: ShadeHeadsUpTracker diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt index 5d966ac51bc8..7a181f106514 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt @@ -27,7 +27,7 @@ import javax.inject.Inject /** Empty implementation of ShadeViewController for variants with no shade. */ class ShadeViewControllerEmptyImpl @Inject constructor() : - ShadeViewController, ShadeBackActionInteractor { + ShadeViewController, ShadeBackActionInteractor, ShadeLockscreenInteractor { override fun expand(animate: Boolean) {} override fun expandToQs() {} override fun expandToNotifications() {} @@ -70,9 +70,6 @@ class ShadeViewControllerEmptyImpl @Inject constructor() : override fun updateTouchableRegion() {} override fun addOnGlobalLayoutListener(listener: ViewTreeObserver.OnGlobalLayoutListener) {} override fun removeOnGlobalLayoutListener(listener: ViewTreeObserver.OnGlobalLayoutListener) {} - override fun postToView(action: Runnable): Boolean { - return false - } override fun transitionToExpandedShade(delay: Long) {} override fun resetViewGroupFade() {} diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorImpl.kt new file mode 100644 index 000000000000..21a782e43b78 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorImpl.kt @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shade.domain.interactor + +import com.android.keyguard.LockIconViewController +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.scene.domain.interactor.SceneInteractor +import com.android.systemui.scene.shared.model.SceneKey +import com.android.systemui.shade.ShadeLockscreenInteractor +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +class ShadeLockscreenInteractorImpl +@Inject +constructor( + @Background private val scope: CoroutineScope, + shadeInteractor: ShadeInteractor, + private val sceneInteractor: SceneInteractor, + private val lockIconViewController: LockIconViewController, +) : ShadeLockscreenInteractor { + override fun expandToNotifications() { + changeToShadeScene() + } + + override val isExpandingOrCollapsing = shadeInteractor.isUserInteracting.value + + override val isExpanded = shadeInteractor.isAnyExpanded.value + + override fun startBouncerPreHideAnimation() { + // TODO("b/324280998") Implement replacement or delete + } + + override fun dozeTimeTick() { + lockIconViewController.dozeTimeTick() + } + + override fun blockExpansionForCurrentTouch() { + // TODO("b/324280998") Implement replacement or delete + } + + override fun resetViews(animate: Boolean) { + // The existing comment to the only call to this claims it only calls it to collapse QS + changeToShadeScene() + } + + override fun setPulsing(pulsing: Boolean) { + // Now handled elsewhere. Do nothing. + } + override fun transitionToExpandedShade(delay: Long) { + scope.launch { + delay(delay) + changeToShadeScene() + } + } + + override fun resetViewGroupFade() { + // Now handled elsewhere. Do nothing. + } + + override fun setKeyguardTransitionProgress(keyguardAlpha: Float, keyguardTranslationY: Int) { + // Now handled elsewhere. Do nothing. + } + + override fun setOverStretchAmount(amount: Float) { + // Now handled elsewhere. Do nothing. + } + + override fun setKeyguardStatusBarAlpha(alpha: Float) { + // TODO(b/325072511) delete this + } + + private fun changeToShadeScene() { + sceneInteractor.changeScene( + SceneKey.Shade, + "ShadeLockscreenInteractorImpl.expandToNotifications", + ) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 14230ba43f59..19fe60a60bf5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; +import static android.adaptiveauth.Flags.enableAdaptiveAuth; import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_MANAGEMENT_DISCLOSURE; import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_NAMED_MANAGEMENT_DISCLOSURE; @@ -32,6 +33,7 @@ import static com.android.systemui.DejankUtils.whitelistIpcs; import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.IMPORTANT_MSG_MIN_DURATION; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_IS_DISMISSIBLE; +import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ADAPTIVE_AUTH; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE; @@ -454,6 +456,9 @@ public class KeyguardIndicationController { updateLockScreenAlignmentMsg(); updateLockScreenLogoutView(); updateLockScreenPersistentUnlockMsg(); + if (enableAdaptiveAuth()) { + updateLockScreenAdaptiveAuthMsg(userId); + } } private void updateOrganizedOwnedDevice() { @@ -740,6 +745,22 @@ public class KeyguardIndicationController { } } + private void updateLockScreenAdaptiveAuthMsg(int userId) { + final boolean deviceLocked = mKeyguardUpdateMonitor.isDeviceLockedByAdaptiveAuth(userId); + if (deviceLocked) { + mRotateTextViewController.updateIndication( + INDICATION_TYPE_ADAPTIVE_AUTH, + new KeyguardIndication.Builder() + .setMessage(mContext + .getString(R.string.kg_prompt_after_adaptive_auth_lock)) + .setTextColor(mInitialTextColorState) + .build(), + true); + } else { + mRotateTextViewController.hideIndication(INDICATION_TYPE_ADAPTIVE_AUTH); + } + } + private boolean isOrganizationOwnedDevice() { return mDevicePolicyManager.isDeviceManaged() || mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt index 62c9980c336c..0b470c179dbf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt @@ -3,10 +3,10 @@ package com.android.systemui.statusbar import android.content.Context import android.util.IndentingPrintWriter import android.util.MathUtils -import com.android.systemui.res.R import com.android.systemui.dump.DumpManager import com.android.systemui.media.controls.ui.MediaHierarchyManager -import com.android.systemui.shade.ShadeViewController +import com.android.systemui.res.R +import com.android.systemui.shade.ShadeLockscreenInteractor import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.SplitShadeStateController import dagger.assisted.Assisted @@ -18,7 +18,7 @@ class LockscreenShadeKeyguardTransitionController @AssistedInject constructor( private val mediaHierarchyManager: MediaHierarchyManager, - @Assisted private val notificationPanelController: ShadeViewController, + @Assisted private val shadeLockscreenInteractor: ShadeLockscreenInteractor, context: Context, configurationController: ConfigurationController, dumpManager: DumpManager, @@ -72,10 +72,10 @@ constructor( alphaProgress = MathUtils.saturate(dragDownAmount / alphaTransitionDistance) alpha = 1f - alphaProgress translationY = calculateKeyguardTranslationY(dragDownAmount) - notificationPanelController.setKeyguardTransitionProgress(alpha, translationY) + shadeLockscreenInteractor.setKeyguardTransitionProgress(alpha, translationY) statusBarAlpha = if (useSplitShade) alpha else -1f - notificationPanelController.setKeyguardStatusBarAlpha(statusBarAlpha) + shadeLockscreenInteractor.setKeyguardStatusBarAlpha(statusBarAlpha) } private fun calculateKeyguardTranslationY(dragDownAmount: Float): Int { @@ -117,7 +117,7 @@ constructor( @AssistedFactory fun interface Factory { fun create( - notificationPanelController: ShadeViewController + shadeLockscreenInteractor: ShadeLockscreenInteractor ): LockscreenShadeKeyguardTransitionController } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index ef5026538216..1dbd87e0aa97 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -15,6 +15,7 @@ import androidx.annotation.VisibleForTesting import com.android.systemui.Dumpable import com.android.systemui.ExpandHelper import com.android.systemui.Flags.nsslFalsingFix +import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.Gefingerpoken import com.android.systemui.biometrics.UdfpsKeyguardViewControllerLegacy import com.android.systemui.classifier.Classifier @@ -23,7 +24,6 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.keyguard.domain.interactor.NaturalScrollingSettingObserver -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.media.controls.ui.MediaHierarchyManager import com.android.systemui.navigationbar.gestural.Utilities.isTrackpadScroll import com.android.systemui.plugins.ActivityStarter @@ -31,9 +31,8 @@ import com.android.systemui.plugins.ActivityStarter.OnDismissAction import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.qs.QS import com.android.systemui.plugins.statusbar.StatusBarStateController -import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.res.R -import com.android.systemui.shade.ShadeViewController +import com.android.systemui.shade.ShadeLockscreenInteractor import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.notification.collection.NotificationEntry @@ -47,6 +46,7 @@ import com.android.systemui.statusbar.phone.LSShadeTransitionLogger import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.SplitShadeStateController import com.android.wm.shell.animation.Interpolators +import dagger.Lazy import java.io.PrintWriter import javax.inject.Inject @@ -81,9 +81,9 @@ constructor( qsTransitionControllerFactory: LockscreenShadeQsTransitionController.Factory, private val shadeRepository: ShadeRepository, private val shadeInteractor: ShadeInteractor, - private val powerInteractor: PowerInteractor, private val splitShadeStateController: SplitShadeStateController, - private val naturalScrollingSettingObserver: NaturalScrollingSettingObserver, + private val shadeLockscreenInteractorLazy: Lazy<ShadeLockscreenInteractor>, + naturalScrollingSettingObserver: NaturalScrollingSettingObserver, ) : Dumpable { private var pulseHeight: Float = 0f @@ -92,7 +92,6 @@ constructor( private set private var useSplitShade: Boolean = false private lateinit var nsslController: NotificationStackScrollLayoutController - lateinit var shadeViewController: ShadeViewController lateinit var centralSurfaces: CentralSurfaces lateinit var qS: QS @@ -165,7 +164,6 @@ constructor( val touchHelper = DragDownHelper( falsingManager, - falsingCollector, this, naturalScrollingSettingObserver, shadeRepository, @@ -181,7 +179,7 @@ constructor( } private val keyguardTransitionController by lazy { - keyguardTransitionControllerFactory.create(shadeViewController) + keyguardTransitionControllerFactory.create(shadeLockscreenInteractorLazy.get()) } private val qsTransitionController = qsTransitionControllerFactory.create { qS } @@ -320,7 +318,7 @@ constructor( true /* drag down is always an open */ ) } - shadeViewController.transitionToExpandedShade(delay) + shadeLockscreenInteractorLazy.get().transitionToExpandedShade(delay) callbacks.forEach { it.setTransitionToFullShadeAmount(0f, /* animated= */ true, delay) } @@ -538,7 +536,7 @@ constructor( } else { // Let's only animate notifications animationHandler = { delay: Long -> - shadeViewController.transitionToExpandedShade(delay) + shadeLockscreenInteractorLazy.get().transitionToExpandedShade(delay) } } goToLockedShadeInternal(expandedView, animationHandler, cancelAction = null) @@ -661,7 +659,7 @@ constructor( */ private fun performDefaultGoToFullShadeAnimation(delay: Long) { logger.logDefaultGoToFullShadeAnimation(delay) - shadeViewController.transitionToExpandedShade(delay) + shadeLockscreenInteractorLazy.get().transitionToExpandedShade(delay) animateAppear(delay) } @@ -686,7 +684,7 @@ constructor( } else { pulseHeight = height val overflow = nsslController.setPulseHeight(height) - shadeViewController.setOverStretchAmount(overflow) + shadeLockscreenInteractorLazy.get().setOverStretchAmount(overflow) val transitionHeight = if (keyguardBypassController.bypassEnabled) height else 0.0f transitionToShadeAmountCommon(transitionHeight) } @@ -760,7 +758,6 @@ constructor( */ class DragDownHelper( private val falsingManager: FalsingManager, - private val falsingCollector: FalsingCollector, private val dragDownCallback: LockscreenShadeTransitionController, private val naturalScrollingSettingObserver: NaturalScrollingSettingObserver, private val shadeRepository: ShadeRepository, @@ -852,7 +849,6 @@ class DragDownHelper( if (!isDraggingDown) { return false } - val x = event.x val y = event.y when (event.actionMasked) { MotionEvent.ACTION_MOVE -> { @@ -890,7 +886,7 @@ class DragDownHelper( isDraggingDown = false isTrackpadReverseScroll = false shadeRepository.setLegacyLockscreenShadeTracking(false) - if (nsslFalsingFix() || KeyguardShadeMigrationNssl.isEnabled) { + if (nsslFalsingFix() || migrateClocksToBlueprint()) { return true } } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java index 2a4753def463..9916ef6ff9ee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java @@ -749,7 +749,7 @@ public class NotificationLockscreenUserManagerImpl implements || isNotifUserRedacted; boolean notificationRequestsRedaction = - ent.getSbn().getNotification().visibility == Notification.VISIBILITY_PRIVATE; + ent.isNotificationVisibilityPrivate(); boolean userForcesRedaction = packageHasVisibilityOverride(ent.getSbn().getKey()); if (keyguardPrivateNotifications()) { @@ -767,9 +767,7 @@ public class NotificationLockscreenUserManagerImpl implements } NotificationEntry entry = mCommonNotifCollectionLazy.get().getEntry(key); if (mFeatureFlags.isEnabled(Flags.NOTIF_LS_BACKGROUND_THREAD)) { - return entry != null && entry.getRanking().getChannel() != null - && entry.getRanking().getChannel().getLockscreenVisibility() - == Notification.VISIBILITY_PRIVATE; + return entry != null && entry.isChannelVisibilityPrivate(); } else { return entry != null && entry.getRanking().getLockscreenVisibilityOverride() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index 8678f0aad181..e111525285e1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -998,6 +998,23 @@ public final class NotificationEntry extends ListEntry { return style == null ? "nostyle" : style.getSimpleName(); } + /** + * Return {@code true} if notification's visibility is {@link Notification.VISIBILITY_PRIVATE} + */ + public boolean isNotificationVisibilityPrivate() { + return getSbn().getNotification().visibility == Notification.VISIBILITY_PRIVATE; + } + + /** + * Return {@code true} if notification's channel lockscreen visibility is + * {@link Notification.VISIBILITY_PRIVATE} + */ + public boolean isChannelVisibilityPrivate() { + return getRanking().getChannel() != null + && getRanking().getChannel().getLockscreenVisibility() + == Notification.VISIBILITY_PRIVATE; + } + /** Information about a suggestion that is being edited. */ public static class EditedSuggestionInfo { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt index 54b6ad71e734..fb67f7cc0b0f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt @@ -104,7 +104,7 @@ class HeadsUpCoordinator @Inject constructor( /** * Once the pipeline starts running, we can look through posted entries and quickly process - * any that don't have groups, and thus will never gave a group alert edge case. + * any that don't have groups, and thus will never gave a group heads up edge case. */ fun onBeforeTransformGroups(list: List<ListEntry>) { mNow = mSystemClock.currentTimeMillis() @@ -125,7 +125,7 @@ class HeadsUpCoordinator @Inject constructor( /** * Once we have a nearly final shade list (not including what's pruned for inflation reasons), * we know that stability and [NotifPromoter]s have been applied, so we can use the location of - * notifications in this list to determine what kind of group alert behavior should happen. + * notifications in this list to determine what kind of group heads up behavior should happen. */ fun onBeforeFinalizeFilter(list: List<ListEntry>) = mHeadsUpManager.modifyHuns { hunMutator -> // Nothing to do if there are no other adds/updates @@ -140,7 +140,7 @@ class HeadsUpCoordinator @Inject constructor( .groupBy { it.sbn.groupKey } val groupLocationsByKey: Map<String, GroupLocation> by lazy { getGroupLocationsByKey(list) } mLogger.logEvaluatingGroups(postedEntriesByGroup.size) - // For each group, determine which notification(s) for a group should alert. + // For each group, determine which notification(s) for a group should heads up. postedEntriesByGroup.forEach { (groupKey, postedEntries) -> // get and classify the logical members val logicalMembers = logicalMembersByGroup[groupKey] ?: emptyList() @@ -149,7 +149,7 @@ class HeadsUpCoordinator @Inject constructor( // Report the start of this group's evaluation mLogger.logEvaluatingGroup(groupKey, postedEntries.size, logicalMembers.size) - // If there is no logical summary, then there is no alert to transfer + // If there is no logical summary, then there is no heads up to transfer if (logicalSummary == null) { postedEntries.forEach { handlePostedEntry(it, hunMutator, scenario = "logical-summary-missing") @@ -157,43 +157,43 @@ class HeadsUpCoordinator @Inject constructor( return@forEach } - // If summary isn't wanted to be heads up, then there is no alert to transfer + // If summary isn't wanted to be heads up, then there is no heads up to transfer if (!isGoingToShowHunStrict(logicalSummary)) { postedEntries.forEach { - handlePostedEntry(it, hunMutator, scenario = "logical-summary-not-alerting") + handlePostedEntry(it, hunMutator, scenario = "logical-summary-not-heads-up") } return@forEach } - // The group is alerting! Overall goals: - // - Maybe transfer its alert to a child - // - Also let any/all newly alerting children still alert - var childToReceiveParentAlert: NotificationEntry? + // The group is heads up! Overall goals: + // - Maybe transfer its heads up to a child + // - Also let any/all newly heads up children still heads up + var childToReceiveParentHeadsUp: NotificationEntry? var targetType = "undefined" - // If the parent is alerting, always look at the posted notification with the newest + // If the parent is heads up, always look at the posted notification with the newest // 'when', and if it is isolated with GROUP_ALERT_SUMMARY, then it should receive the - // parent's alert. - childToReceiveParentAlert = - findAlertOverride(postedEntries, groupLocationsByKey::getLocation) - if (childToReceiveParentAlert != null) { - targetType = "alertOverride" + // parent's heads up. + childToReceiveParentHeadsUp = + findHeadsUpOverride(postedEntries, groupLocationsByKey::getLocation) + if (childToReceiveParentHeadsUp != null) { + targetType = "headsUpOverride" } - // If the summary is Detached and we have not picked a receiver of the alert, then we - // need to look for the best child to alert in place of the summary. + // If the summary is Detached and we have not picked a receiver of the heads up, then we + // need to look for the best child to heads up in place of the summary. val isSummaryAttached = groupLocationsByKey.contains(logicalSummary.key) - if (!isSummaryAttached && childToReceiveParentAlert == null) { - childToReceiveParentAlert = + if (!isSummaryAttached && childToReceiveParentHeadsUp == null) { + childToReceiveParentHeadsUp = findBestTransferChild(logicalMembers, groupLocationsByKey::getLocation) - if (childToReceiveParentAlert != null) { + if (childToReceiveParentHeadsUp != null) { targetType = "bestChild" } } - // If there is no child to receive the parent alert, then just handle the posted entries - // and return. - if (childToReceiveParentAlert == null) { + // If there is no child to receive the parent heads up, then just handle the posted + // entries and return. + if (childToReceiveParentHeadsUp == null) { postedEntries.forEach { handlePostedEntry(it, hunMutator, scenario = "no-transfer-target") } @@ -203,14 +203,14 @@ class HeadsUpCoordinator @Inject constructor( // At this point we just need to initiate the transfer val summaryUpdate = mPostedEntries[logicalSummary.key] - // Because we now know for certain that some child is going to alert for this summary - // (as we have found a child to transfer the alert to), mark the group as having + // Because we now know for certain that some child is going to heads up for this summary + // (as we have found a child to transfer the heads up to), mark the group as having // interrupted. This will allow us to know in the future that the "should heads up" // state of this group has already been handled, just not via the summary entry itself. logicalSummary.setInterruption() - mLogger.logSummaryMarkedInterrupted(logicalSummary.key, childToReceiveParentAlert.key) + mLogger.logSummaryMarkedInterrupted(logicalSummary.key, childToReceiveParentHeadsUp.key) - // If the summary was not attached, then remove the alert from the detached summary. + // If the summary was not attached, then remove the heads up from the detached summary. // Otherwise we can simply ignore its posted update. if (!isSummaryAttached) { val summaryUpdateForRemoval = summaryUpdate?.also { @@ -221,60 +221,63 @@ class HeadsUpCoordinator @Inject constructor( wasUpdated = false, shouldHeadsUpEver = false, shouldHeadsUpAgain = false, - isAlerting = mHeadsUpManager.isHeadsUpEntry(logicalSummary.key), + isHeadsUpEntry = mHeadsUpManager.isHeadsUpEntry(logicalSummary.key), isBinding = isEntryBinding(logicalSummary), ) - // If we transfer the alert and the summary isn't even attached, that means we - // should ensure the summary is no longer alerting, so we remove it here. + // If we transfer the heads up notification and the summary isn't even attached, + // that means we should ensure the summary is no longer a heads up notification, + // so we remove it here. handlePostedEntry( summaryUpdateForRemoval, hunMutator, - scenario = "detached-summary-remove-alert") + scenario = "detached-summary-remove-heads-up") } else if (summaryUpdate != null) { mLogger.logPostedEntryWillNotEvaluate( summaryUpdate, reason = "attached-summary-transferred") } - // Handle all posted entries -- if the child receiving the parent's alert is in the - // list, then set its flags to ensure it alerts. - var didAlertChildToReceiveParentAlert = false + // Handle all posted entries -- if the child receiving the parent's heads up is in the + // list, then set its flags to ensure it heads up. + var didHeadsUpChildToReceiveParentHeadsUp = false postedEntries.asSequence() .filter { it.key != logicalSummary.key } .forEach { postedEntry -> - if (childToReceiveParentAlert.key == postedEntry.key) { + if (childToReceiveParentHeadsUp.key == postedEntry.key) { // Update the child's posted update so that it postedEntry.shouldHeadsUpEver = true postedEntry.shouldHeadsUpAgain = true handlePostedEntry( postedEntry, hunMutator, - scenario = "child-alert-transfer-target-$targetType") - didAlertChildToReceiveParentAlert = true + scenario = "child-heads-up-transfer-target-$targetType") + didHeadsUpChildToReceiveParentHeadsUp = true } else { handlePostedEntry( postedEntry, hunMutator, - scenario = "child-alert-non-target") + scenario = "child-heads-up-non-target") } } - // If the child receiving the alert was not updated on this tick (which can happen in a - // standard alert transfer scenario), then construct an update so that we can apply it. - if (!didAlertChildToReceiveParentAlert) { + // If the child receiving the heads up notification was not updated on this tick + // (which can happen in a standard heads up transfer scenario), then construct an update + // so that we can apply it. + if (!didHeadsUpChildToReceiveParentHeadsUp) { val posted = PostedEntry( - childToReceiveParentAlert, + childToReceiveParentHeadsUp, wasAdded = false, wasUpdated = false, shouldHeadsUpEver = true, shouldHeadsUpAgain = true, - isAlerting = mHeadsUpManager.isHeadsUpEntry(childToReceiveParentAlert.key), - isBinding = isEntryBinding(childToReceiveParentAlert), + isHeadsUpEntry = + mHeadsUpManager.isHeadsUpEntry(childToReceiveParentHeadsUp.key), + isBinding = isEntryBinding(childToReceiveParentHeadsUp), ) handlePostedEntry( posted, hunMutator, - scenario = "non-posted-child-alert-transfer-target-$targetType") + scenario = "non-posted-child-heads-up-transfer-target-$targetType") } } // After this method runs, all posted entries should have been handled (or skipped). @@ -286,9 +289,9 @@ class HeadsUpCoordinator @Inject constructor( /** * Find the posted child with the newest when, and return it if it is isolated and has - * GROUP_ALERT_SUMMARY so that it can be alerted. + * GROUP_ALERT_SUMMARY so that it can be heads uped. */ - private fun findAlertOverride( + private fun findHeadsUpOverride( postedEntries: List<PostedEntry>, locationLookupByKey: (String) -> GroupLocation, ): NotificationEntry? = postedEntries.asSequence() @@ -344,16 +347,17 @@ class HeadsUpCoordinator @Inject constructor( } } else { if (posted.isHeadsUpAlready) { - // NOTE: This might be because we're alerting (i.e. tracked by HeadsUpManager) OR - // it could be because we're binding, and that will affect the next step. + // NOTE: This might be because we're showing heads up (i.e. tracked by + // HeadsUpManager) OR it could be because we're binding, and that will affect the + // next step. if (posted.shouldHeadsUpEver) { - // If alerting, we need to post an update. Otherwise we're still binding, - // and we can just let that finish. - if (posted.isAlerting) { + // If showing heads up, we need to post an update. Otherwise we're still + // binding, and we can just let that finish. + if (posted.isHeadsUpEntry) { hunMutator.updateNotification(posted.key, posted.shouldHeadsUpAgain) } } else { - if (posted.isAlerting) { + if (posted.isHeadsUpEntry) { // We don't want this to be interrupting anymore, let's remove it hunMutator.removeNotification(posted.key, false /*removeImmediately*/) } else { @@ -408,7 +412,7 @@ class HeadsUpCoordinator @Inject constructor( wasUpdated = false, shouldHeadsUpEver = shouldHeadsUpEver, shouldHeadsUpAgain = true, - isAlerting = false, + isHeadsUpEntry = false, isBinding = false, ) @@ -418,21 +422,21 @@ class HeadsUpCoordinator @Inject constructor( /** * Notification could've updated to be heads up or not heads up. Even if it did update to - * heads up, if the notification specified that it only wants to alert once, don't heads + * heads up, if the notification specified that it only wants to heads up once, don't heads * up again. */ override fun onEntryUpdated(entry: NotificationEntry) { val shouldHeadsUpEver = mVisualInterruptionDecisionProvider.makeAndLogHeadsUpDecision(entry).shouldInterrupt val shouldHeadsUpAgain = shouldHunAgain(entry) - val isAlerting = mHeadsUpManager.isHeadsUpEntry(entry.key) + val isHeadsUpEntry = mHeadsUpManager.isHeadsUpEntry(entry.key) val isBinding = isEntryBinding(entry) val posted = mPostedEntries.compute(entry.key) { _, value -> value?.also { update -> update.wasUpdated = true update.shouldHeadsUpEver = shouldHeadsUpEver update.shouldHeadsUpAgain = update.shouldHeadsUpAgain || shouldHeadsUpAgain - update.isAlerting = isAlerting + update.isHeadsUpEntry = isHeadsUpEntry update.isBinding = isBinding } ?: PostedEntry( entry, @@ -440,15 +444,15 @@ class HeadsUpCoordinator @Inject constructor( wasUpdated = true, shouldHeadsUpEver = shouldHeadsUpEver, shouldHeadsUpAgain = shouldHeadsUpAgain, - isAlerting = isAlerting, + isHeadsUpEntry = isHeadsUpEntry, isBinding = isBinding, ) } - // Handle cancelling alerts here, rather than in the OnBeforeFinalizeFilter, so that + // Handle cancelling heads up here, rather than in the OnBeforeFinalizeFilter, so that // work can be done before the ShadeListBuilder is run. This prevents re-entrant // behavior between this Coordinator, HeadsUpManager, and VisualStabilityManager. if (posted?.shouldHeadsUpEver == false) { - if (posted.isAlerting) { + if (posted.isHeadsUpEntry) { // We don't want this to be interrupting anymore, let's remove it mHeadsUpManager.removeNotification(posted.key, false /*removeImmediately*/) } else if (posted.isBinding) { @@ -462,7 +466,7 @@ class HeadsUpCoordinator @Inject constructor( } /** - * Stop alerting HUNs that are removed from the notification collection + * Stop showing as heads up once removed from the notification collection */ override fun onEntryRemoved(entry: NotificationEntry, reason: Int) { mPostedEntries.remove(entry.key) @@ -484,7 +488,7 @@ class HeadsUpCoordinator @Inject constructor( /** * Identify notifications whose heads-up state changes when the notification rankings are - * updated, and have those changed notifications alert if necessary. + * updated, and have those changed notifications heads up if necessary. * * This method will occur after any operations in onEntryAdded or onEntryUpdated, so any * handling of ranking changes needs to take into account that we may have just made a @@ -492,7 +496,7 @@ class HeadsUpCoordinator @Inject constructor( */ override fun onRankingApplied() { // Because a ranking update may cause some notifications that are no longer (or were - // never) in mPostedEntries to need to alert, we need to check every notification + // never) in mPostedEntries to need to heads up, we need to check every notification // known to the pipeline. for (entry in mNotifPipeline.allNotifs) { // Only consider entries that are recent enough, since we want to apply a fairly @@ -500,9 +504,9 @@ class HeadsUpCoordinator @Inject constructor( // app-provided notification update. if (!isNewEnoughForRankingUpdate(entry)) continue - // The only entries we consider alerting for here are entries that have never - // interrupted and that now say they should heads up or FSI; if they've alerted in - // the past, we don't want to incorrectly alert a second time if there wasn't an + // The only entries we consider heads up for here are entries that have never + // interrupted and that now say they should heads up or FSI; if they've heads uped in + // the past, we don't want to incorrectly heads up a second time if there wasn't an // explicit notification update. if (entry.hasInterrupted()) continue @@ -561,7 +565,7 @@ class HeadsUpCoordinator @Inject constructor( } /** - * Checks whether an update for a notification warrants an alert for the user. + * Checks whether an update for a notification warrants an heads up for the user. */ private fun shouldHunAgain(entry: NotificationEntry): Boolean { return (!entry.hasInterrupted() || @@ -716,25 +720,25 @@ class HeadsUpCoordinator @Inject constructor( } /** - * Whether the notification is already alerting or binding so that it can imminently alert + * Whether the notification is already heads up or binding so that it can imminently heads up */ private fun isAttemptingToShowHun(entry: ListEntry) = mHeadsUpManager.isHeadsUpEntry(entry.key) || isEntryBinding(entry) /** - * Whether the notification is already alerting/binding per [isAttemptingToShowHun] OR if it - * has been updated so that it should alert this update. This method is permissive because it - * returns `true` even if the update would (in isolation of its group) cause the alert to be - * retracted. This is important for not retracting transferred group alerts. + * Whether the notification is already heads up/binding per [isAttemptingToShowHun] OR if it + * has been updated so that it should heads up this update. This method is permissive because + * it returns `true` even if the update would (in isolation of its group) cause the heads up to + * be retracted. This is important for not retracting transferred group heads ups. */ private fun isGoingToShowHunNoRetract(entry: ListEntry) = mPostedEntries[entry.key]?.calculateShouldBeHeadsUpNoRetract ?: isAttemptingToShowHun(entry) /** * If the notification has been updated, then whether it should HUN in isolation, otherwise - * defers to the already alerting/binding state of [isAttemptingToShowHun]. This method is - * strict because any update which would revoke the alert supersedes the current - * alerting/binding state. + * defers to the already heads up/binding state of [isAttemptingToShowHun]. This method is + * strict because any update which would revoke the heads up supersedes the current + * heads up/binding state. */ private fun isGoingToShowHunStrict(entry: ListEntry) = mPostedEntries[entry.key]?.calculateShouldBeHeadsUpStrict ?: isAttemptingToShowHun(entry) @@ -760,12 +764,12 @@ class HeadsUpCoordinator @Inject constructor( var wasUpdated: Boolean, var shouldHeadsUpEver: Boolean, var shouldHeadsUpAgain: Boolean, - var isAlerting: Boolean, + var isHeadsUpEntry: Boolean, var isBinding: Boolean, ) { val key = entry.key val isHeadsUpAlready: Boolean - get() = isAlerting || isBinding + get() = isHeadsUpEntry || isBinding val calculateShouldBeHeadsUpStrict: Boolean get() = shouldHeadsUpEver && (wasAdded || shouldHeadsUpAgain || isHeadsUpAlready) val calculateShouldBeHeadsUpNoRetract: Boolean @@ -781,7 +785,7 @@ private fun Map<String, GroupLocation>.getLocation(key: String): GroupLocation = /** * Invokes the given block with a [HunMutator] that defers all HUN removals. This ensures that the * HeadsUpManager is notified of additions before removals, which prevents a glitch where the - * HeadsUpManager temporarily believes that nothing is alerting, causing bad re-entrant behavior. + * HeadsUpManager temporarily believes that nothing is heads up, causing bad re-entrant behavior. */ private fun <R> HeadsUpManager.modifyHuns(block: (HunMutator) -> R): R { val mutator = HunMutatorImpl(this) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt index 94cc7e9d1a9f..f2b84827f3a3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt @@ -76,6 +76,6 @@ class RowAppearanceCoordinator @Inject internal constructor( // Show/hide the feedback icon controller.setFeedbackIcon(mAssistantFeedbackController.getFeedbackIcon(entry)) // Show the "alerted" bell icon - controller.setLastAudiblyAlertedMs(entry.lastAudiblyAlertedMs) + controller.setLastAudibleMs(entry.lastAudiblyAlertedMs) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/LaunchFullScreenIntentProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/LaunchFullScreenIntentProvider.kt index 74ff78e25a2f..e8c59f44da0e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/LaunchFullScreenIntentProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/LaunchFullScreenIntentProvider.kt @@ -33,7 +33,7 @@ class LaunchFullScreenIntentProvider @Inject constructor() { private val listeners = ListenerSet<Listener>() /** - * Registers a listener with this provider. These listeners will be alerted whenever a full + * Registers a listener with this provider. These listeners will be updated whenever a full * screen intent should be launched for a notification entry. */ fun registerListener(listener: Listener) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifRowController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifRowController.kt index 5ee94ba1624c..82b7e14adcc9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifRowController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifRowController.kt @@ -29,10 +29,10 @@ interface NotifRowController { fun setSystemExpanded(systemExpanded: Boolean) /** - * Sets the timestamp that the notification was last audibly alerted, which the row uses to + * Sets the timestamp that the notification was last audible, which the row uses to * show a bell icon in the header which indicates to the user which notification made a noise. */ - fun setLastAudiblyAlertedMs(lastAudiblyAlertedMs: Long) + fun setLastAudibleMs(lastAudibleMs: Long) /** Shows the given feedback icon, or hides the icon if null. */ fun setFeedbackIcon(icon: FeedbackIcon?) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java index 0afdefabd4f0..5614f3a3fcc5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java @@ -431,8 +431,8 @@ public class ExpandableNotificationRowController implements NotifViewController } @Override - public void setLastAudiblyAlertedMs(long lastAudiblyAlertedMs) { - mView.setLastAudiblyAlertedMs(lastAudiblyAlertedMs); + public void setLastAudibleMs(long lastAudibleMs) { + mView.setLastAudiblyAlertedMs(lastAudibleMs); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java index 20fae88b6f33..c90aceef6934 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java @@ -263,8 +263,8 @@ public class AmbientState implements Dumpable { return mStackHeight; } - /** Tracks the state from AlertingNotificationManager#hasNotifications() */ - private boolean mHasAlertEntries; + /** Tracks the state from HeadsUpManager#hasNotifications() */ + private boolean mHasHeadsUpEntries; @Inject public AmbientState( @@ -563,7 +563,7 @@ public class AmbientState implements Dumpable { } public boolean hasPulsingNotifications() { - return mPulsing && mHasAlertEntries; + return mPulsing && mHasHeadsUpEntries; } public void setPulsing(boolean hasPulsing) { @@ -716,8 +716,8 @@ public class AmbientState implements Dumpable { return mAppearFraction; } - public void setHasAlertEntries(boolean hasAlertEntries) { - mHasAlertEntries = hasAlertEntries; + public void setHasHeadsUpEntries(boolean hasHeadsUpEntries) { + mHasHeadsUpEntries = hasHeadsUpEntries; } public void setStackTopMargin(int stackTopMargin) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index aa9d3b23e47b..933a78009e29 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -5721,7 +5721,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable void setNumHeadsUp(long numHeadsUp) { mNumHeadsUp = numHeadsUp; - mAmbientState.setHasAlertEntries(numHeadsUp > 0); + mAmbientState.setHasHeadsUpEntries(numHeadsUp > 0); } public boolean getIsExpanded() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 830b8c1ae63e..78e6a795604a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -23,6 +23,7 @@ import static com.android.app.animation.Interpolators.STANDARD; import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING; import static com.android.server.notification.Flags.screenshareNotificationHiding; import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME; +import static com.android.systemui.Flags.migrateClocksToBlueprint; import static com.android.systemui.Flags.nsslFalsingFix; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.OnEmptySpaceClickListener; @@ -71,7 +72,6 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlagsClassic; import com.android.systemui.flags.Flags; import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; import com.android.systemui.keyguard.shared.model.KeyguardState; import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.media.controls.ui.KeyguardMediaController; @@ -2078,7 +2078,7 @@ public class NotificationStackScrollLayoutController implements Dumpable { } boolean horizontalSwipeWantsIt = false; boolean scrollerWantsIt = false; - if (nsslFalsingFix() || KeyguardShadeMigrationNssl.isEnabled()) { + if (nsslFalsingFix() || migrateClocksToBlueprint()) { // Reverse the order relative to the else statement. onScrollTouch will reset on an // UP event, causing horizontalSwipeWantsIt to be set to true on vertical swipes. if (mLongPressedView == null && !mView.isBeingDragged() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index a135802f095e..b772158b0825 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -27,6 +27,7 @@ import static androidx.lifecycle.Lifecycle.State.RESUMED; import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME; import static com.android.systemui.Flags.lightRevealMigration; +import static com.android.systemui.Flags.migrateClocksToBlueprint; import static com.android.systemui.Flags.newAodTransition; import static com.android.systemui.Flags.predictiveBackSysui; import static com.android.systemui.Flags.truncatedStatusBarIconsFix; @@ -143,7 +144,6 @@ import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; import com.android.systemui.keyguard.ui.binder.LightRevealScrimViewBinder; import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel; import com.android.systemui.navigationbar.NavigationBarController; @@ -982,7 +982,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { this, mStatusBarKeyguardViewManager, getNotificationShadeWindowViewController(), - mShadeSurface, mAmbientIndicationContainer); updateLightRevealScrimVisibility(); @@ -1468,7 +1467,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { return (v, event) -> { mAutoHideController.checkUserAutoHide(event); mRemoteInputManager.checkRemoteInputOutside(event); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mShadeController.onStatusBarTouch(event); } return getNotificationShadeWindowView().onTouchEvent(event); @@ -2505,7 +2504,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> { mDeviceInteractive = true; - boolean isFlaggedOff = newAodTransition() && KeyguardShadeMigrationNssl.isEnabled(); + boolean isFlaggedOff = newAodTransition() && migrateClocksToBlueprint(); if (!isFlaggedOff && shouldAnimateDozeWakeup()) { // If this is false, the power button must be physically pressed in order to // trigger fingerprint authentication. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java index 45005cbc28a5..442e43a9dae2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java @@ -41,7 +41,7 @@ import com.android.systemui.flags.FeatureFlagsClassic; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.domain.interactor.DozeInteractor; import com.android.systemui.shade.NotificationShadeWindowViewController; -import com.android.systemui.shade.ShadeViewController; +import com.android.systemui.shade.ShadeLockscreenInteractor; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.StatusBarState; @@ -98,7 +98,7 @@ public final class DozeServiceHost implements DozeHost { private final AuthController mAuthController; private final NotificationIconAreaController mNotificationIconAreaController; private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; - private ShadeViewController mNotificationPanel; + private final ShadeLockscreenInteractor mShadeLockscreenInteractor; private View mAmbientIndicationContainer; private CentralSurfaces mCentralSurfaces; private boolean mAlwaysOnSuppressed; @@ -121,6 +121,7 @@ public final class DozeServiceHost implements DozeHost { NotificationWakeUpCoordinator notificationWakeUpCoordinator, AuthController authController, NotificationIconAreaController notificationIconAreaController, + ShadeLockscreenInteractor shadeLockscreenInteractor, DozeInteractor dozeInteractor) { super(); mDozeLog = dozeLog; @@ -141,6 +142,7 @@ public final class DozeServiceHost implements DozeHost { mNotificationWakeUpCoordinator = notificationWakeUpCoordinator; mAuthController = authController; mNotificationIconAreaController = notificationIconAreaController; + mShadeLockscreenInteractor = shadeLockscreenInteractor; mHeadsUpManager.addListener(mOnHeadsUpChangedListener); mDozeInteractor = dozeInteractor; } @@ -154,11 +156,9 @@ public final class DozeServiceHost implements DozeHost { CentralSurfaces centralSurfaces, StatusBarKeyguardViewManager statusBarKeyguardViewManager, NotificationShadeWindowViewController notificationShadeWindowViewController, - ShadeViewController notificationPanel, View ambientIndicationContainer) { mCentralSurfaces = centralSurfaces; mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; - mNotificationPanel = notificationPanel; mNotificationShadeWindowViewController = notificationShadeWindowViewController; mAmbientIndicationContainer = ambientIndicationContainer; } @@ -290,7 +290,7 @@ public final class DozeServiceHost implements DozeHost { private void setPulsing(boolean pulsing) { mStatusBarKeyguardViewManager.setPulsing(pulsing); - mNotificationPanel.setPulsing(pulsing); + mShadeLockscreenInteractor.setPulsing(pulsing); mStatusBarStateController.setPulsing(pulsing); mIgnoreTouchWhilePulsing = false; if (mKeyguardUpdateMonitor != null && passiveAuthInterrupt) { @@ -329,7 +329,7 @@ public final class DozeServiceHost implements DozeHost { @Override public void dozeTimeTick() { mDozeInteractor.dozeTimeTick(); - mNotificationPanel.dozeTimeTick(); + mShadeLockscreenInteractor.dozeTimeTick(); mAuthController.dozeTimeTick(); if (mAmbientIndicationContainer instanceof DozeReceiver) { ((DozeReceiver) mAmbientIndicationContainer).dozeTimeTick(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java index e79f3ff19031..94f62e075a4a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; import static com.android.systemui.Flags.newAodTransition; +import static com.android.systemui.Flags.migrateClocksToBlueprint; import android.content.Context; import android.content.res.Resources; @@ -40,7 +41,6 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.demomode.DemoMode; import com.android.systemui.demomode.DemoModeController; import com.android.systemui.flags.FeatureFlags; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -545,7 +545,7 @@ public class LegacyNotificationIconAreaControllerImpl implements return; } if (mScreenOffAnimationController.shouldAnimateAodIcons()) { - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mAodIcons.setTranslationY(-mAodIconAppearTranslation); } mAodIcons.setAlpha(0); @@ -557,14 +557,14 @@ public class LegacyNotificationIconAreaControllerImpl implements .start(); } else { mAodIcons.setAlpha(1.0f); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mAodIcons.setTranslationY(0); } } } private void animateInAodIconTranslation() { - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mAodIcons.animate() .setInterpolator(Interpolators.DECELERATE_QUINT) .translationY(0) @@ -667,7 +667,7 @@ public class LegacyNotificationIconAreaControllerImpl implements } } else { mAodIcons.setAlpha(1.0f); - if (!KeyguardShadeMigrationNssl.isEnabled()) { + if (!migrateClocksToBlueprint()) { mAodIcons.setTranslationY(0); } mAodIcons.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 8ac3b4a75141..d10ca3d31de2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -38,9 +38,9 @@ import android.widget.LinearLayout; import com.android.internal.policy.SystemBarUtils; import com.android.systemui.Dependency; import com.android.systemui.Gefingerpoken; -import com.android.systemui.res.R; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; +import com.android.systemui.res.R; import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer; import com.android.systemui.statusbar.policy.Clock; import com.android.systemui.statusbar.window.StatusBarWindowController; @@ -67,6 +67,8 @@ public class PhoneStatusBarView extends FrameLayout { private int mStatusBarHeight; @Nullable private Gefingerpoken mTouchEventHandler; + private int mDensity; + private float mFontScale; /** * Draw this many pixels into the left/right side of the cutout to optimally use the space @@ -167,13 +169,23 @@ public class PhoneStatusBarView extends FrameLayout { mDisplayCutout = getRootWindowInsets().getDisplayCutout(); } - final Rect newSize = mContext.getResources().getConfiguration().windowConfiguration - .getMaxBounds(); + Configuration newConfiguration = mContext.getResources().getConfiguration(); + final Rect newSize = newConfiguration.windowConfiguration.getMaxBounds(); if (!Objects.equals(newSize, mDisplaySize)) { changed = true; mDisplaySize = newSize; } + int density = newConfiguration.densityDpi; + if (density != mDensity) { + changed = true; + mDensity = density; + } + float fontScale = newConfiguration.fontScale; + if (fontScale != mFontScale) { + changed = true; + mFontScale = fontScale; + } return changed; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 9d70f4221e3a..29fd2258b40c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -86,10 +86,9 @@ import com.android.systemui.shade.ShadeController; import com.android.systemui.shade.ShadeExpansionChangeEvent; import com.android.systemui.shade.ShadeExpansionListener; import com.android.systemui.shade.ShadeExpansionStateManager; -import com.android.systemui.shade.ShadeViewController; +import com.android.systemui.shade.ShadeLockscreenInteractor; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.SysUiStatsLog; -import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarState; @@ -269,7 +268,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb protected LockPatternUtils mLockPatternUtils; protected ViewMediatorCallback mViewMediatorCallback; @Nullable protected CentralSurfaces mCentralSurfaces; - private ShadeViewController mShadeViewController; + private ShadeLockscreenInteractor mShadeLockscreenInteractor; private BiometricUnlockController mBiometricUnlockController; private boolean mCentralSurfacesRegistered; @@ -314,7 +313,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb // Dismiss action to be launched when we stop dozing or the keyguard is gone. private DismissWithActionRequest mPendingWakeupAction; private final KeyguardStateController mKeyguardStateController; - private final NotificationMediaManager mMediaManager; private final SysuiStatusBarStateController mStatusBarStateController; private final DockManager mDockManager; private final KeyguardUpdateMonitor mKeyguardUpdateManager; @@ -363,7 +361,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb DockManager dockManager, NotificationShadeWindowController notificationShadeWindowController, KeyguardStateController keyguardStateController, - NotificationMediaManager notificationMediaManager, KeyguardMessageAreaController.Factory keyguardMessageAreaFactory, Optional<SysUIUnfoldComponent> sysUIUnfoldComponent, Lazy<ShadeController> shadeController, @@ -391,7 +388,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mNotificationShadeWindowController = notificationShadeWindowController; mDreamOverlayStateController = dreamOverlayStateController; mKeyguardStateController = keyguardStateController; - mMediaManager = notificationMediaManager; mKeyguardUpdateManager = keyguardUpdateMonitor; mStatusBarStateController = sysuiStatusBarStateController; mDockManager = dockManager; @@ -422,7 +418,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb @Override public void registerCentralSurfaces(CentralSurfaces centralSurfaces, - ShadeViewController shadeViewController, + ShadeLockscreenInteractor shadeLockscreenInteractor, ShadeExpansionStateManager shadeExpansionStateManager, BiometricUnlockController biometricUnlockController, View notificationContainer, @@ -431,7 +427,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mBiometricUnlockController = biometricUnlockController; mPrimaryBouncerCallbackInteractor.addBouncerExpansionCallback(mExpansionCallback); - mShadeViewController = shadeViewController; + mShadeLockscreenInteractor = shadeLockscreenInteractor; if (shadeExpansionStateManager != null) { ShadeExpansionChangeEvent currentState = shadeExpansionStateManager.addExpansionListener(this); @@ -565,8 +561,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb // Avoid having the shade and the bouncer open at the same time over a dream. final boolean hideBouncerOverDream = mDreamOverlayStateController.isOverlayActive() - && (mShadeViewController.isExpanded() - || mShadeViewController.isExpandingOrCollapsing()); + && (mShadeLockscreenInteractor.isExpanded() + || mShadeLockscreenInteractor.isExpandingOrCollapsing()); final boolean isUserTrackingStarted = event.getFraction() != EXPANSION_HIDDEN && event.getTracking(); @@ -834,7 +830,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb if (mKeyguardStateController.isShowing() && !bouncerIsAnimatingAway()) { final boolean isOccluded = mKeyguardStateController.isOccluded(); // Hide quick settings. - mShadeViewController.resetViews(/* animate= */ !isOccluded); + mShadeLockscreenInteractor.resetViews(/* animate= */ !isOccluded); // Hide bouncer and quick-quick settings. if (isOccluded && !mDozing) { mCentralSurfaces.hideKeyguard(); @@ -1008,7 +1004,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public void startPreHideAnimation(Runnable finishRunnable) { if (primaryBouncerIsShowing()) { mPrimaryBouncerInteractor.startDisappearAnimation(finishRunnable); - mShadeViewController.startBouncerPreHideAnimation(); + mShadeLockscreenInteractor.startBouncerPreHideAnimation(); // We update the state (which will show the keyguard) only if an animation will run on // the keyguard. If there is no animation, we wait before updating the state so that we @@ -1023,12 +1019,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } else if (finishRunnable != null) { finishRunnable.run(); } - mShadeViewController.blockExpansionForCurrentTouch(); + mShadeLockscreenInteractor.blockExpansionForCurrentTouch(); } @Override public void blockPanelExpansionFromCurrentTouch() { - mShadeViewController.blockExpansionForCurrentTouch(); + mShadeLockscreenInteractor.blockExpansionForCurrentTouch(); } @Override @@ -1125,7 +1121,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public void onKeyguardFadedAway() { mNotificationContainer.postDelayed(() -> mNotificationShadeWindowController .setKeyguardFadingAway(false), 100); - mShadeViewController.resetViewGroupFade(); + mShadeLockscreenInteractor.resetViewGroupFade(); mCentralSurfaces.finishKeyguardFadingAway(); mBiometricUnlockController.finishKeyguardFadingAway(); } @@ -1208,7 +1204,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb if (hideImmediately) { mStatusBarStateController.setLeaveOpenOnKeyguardHide(false); } else { - mShadeViewController.expandToNotifications(); + mShadeLockscreenInteractor.expandToNotifications(); } } return; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt index 665a5714e277..223eaf74e2e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt @@ -17,10 +17,10 @@ import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD import com.android.systemui.DejankUtils import com.android.app.animation.Interpolators +import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.KeyguardViewMediator import com.android.systemui.keyguard.WakefulnessLifecycle -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.shade.ShadeViewController import com.android.systemui.statusbar.CircleReveal import com.android.systemui.statusbar.LightRevealScrim @@ -286,7 +286,7 @@ class UnlockedScreenOffAnimationController @Inject constructor( // up, with unpredictable consequences. if (!powerManager.isInteractive(Display.DEFAULT_DISPLAY) && shouldAnimateInKeyguard) { - if (!KeyguardShadeMigrationNssl.isEnabled) { + if (!migrateClocksToBlueprint()) { // Tracking this state should no longer be relevant, as the isInteractive // check covers it aodUiAnimationPlaying = true diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt index a7352be8d80a..420701f026d2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt @@ -61,16 +61,16 @@ interface HeadsUpManager : Dumpable { fun getTouchableRegion(): Region? /** - * Whether or not there are any active alerting notifications. + * Whether or not there are any entries managed by HeadsUpManager. * - * @return true if there is an alert, false otherwise + * @return true if there is a heads up entry, false otherwise */ fun hasNotifications(): Boolean = false /** Returns whether there are any pinned Heads Up Notifications or not. */ fun hasPinnedHeadsUp(): Boolean - /** Returns whether or not the given notification is alerting and managed by this manager. */ + /** Returns whether or not the given notification is managed by this manager. */ fun isHeadsUpEntry(key: String): Boolean fun isHeadsUpGoingAway(): Boolean diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java index 2b0a92c6ecd7..6956a7d8a8e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java @@ -221,10 +221,15 @@ public class SensitiveNotificationProtectionControllerImpl // Exempt foreground service notifications from protection in effort to keep screen share // stop actions easily accessible StatusBarNotification sbn = entry.getSbn(); - if (sbn.getNotification().isFgsOrUij()) { - return !sbn.getPackageName().equals(projection.getPackageName()); + if (sbn.getNotification().isFgsOrUij() + && sbn.getPackageName().equals(projection.getPackageName())) { + return false; } - return true; + // Only protect/redact notifications if the developer has not explicitly set notification + // visibility as public and users has not adjusted default channel visibility to private + boolean notificationRequestsRedaction = entry.isNotificationVisibilityPrivate(); + boolean userForcesRedaction = entry.isChannelVisibilityPrivate(); + return notificationRequestsRedaction || userForcesRedaction; } } diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt index 668b1439abab..ca5ea3bc1caa 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt @@ -45,7 +45,6 @@ import com.android.wm.shell.displayareahelper.DisplayAreaHelper import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject -import java.lang.IllegalArgumentException import java.util.Optional import java.util.concurrent.Executor import java.util.function.Consumer @@ -71,7 +70,7 @@ constructor( private val displayTracker: DisplayTracker, @Background private val applicationScope: CoroutineScope, @Main private val executor: Executor, - @Assisted private val displaySelector: Sequence<DisplayInfo>.() -> DisplayInfo?, + @Assisted private val displaySelector: List<DisplayInfo>.() -> DisplayInfo?, @Assisted private val lightRevealEffectFactory: (rotation: Int) -> LightRevealEffect, @Assisted private val overlayContainerName: String ) { @@ -84,13 +83,11 @@ constructor( private var scrimView: LightRevealScrim? = null private val rotationWatcher = RotationWatcher() - private val internalDisplayInfos: Sequence<DisplayInfo> - get() = - displayManager - .getDisplays(DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED) - .asSequence() - .map { DisplayInfo().apply { it.getDisplayInfo(this) } } - .filter { it.type == Display.TYPE_INTERNAL } + private val internalDisplayInfos: List<DisplayInfo> = + displayManager + .getDisplays(DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED) + .map { DisplayInfo().apply { it.getDisplayInfo(this) } } + .filter { it.type == Display.TYPE_INTERNAL } var isTouchBlocked: Boolean = false set(value) { @@ -252,7 +249,7 @@ constructor( @AssistedFactory interface Factory { fun create( - displaySelector: Sequence<DisplayInfo>.() -> DisplayInfo?, + displaySelector: List<DisplayInfo>.() -> DisplayInfo?, effectFactory: (rotation: Int) -> LightRevealEffect, overlayContainerName: String ): FullscreenLightRevealAnimationController diff --git a/packages/SystemUI/src/com/android/systemui/volume/Events.java b/packages/SystemUI/src/com/android/systemui/volume/Events.java index 50d15475434b..e10d1cb833fa 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/Events.java +++ b/packages/SystemUI/src/com/android/systemui/volume/Events.java @@ -60,6 +60,7 @@ public class Events { public static final int EVENT_DISMISS_USB_OVERHEAT_ALARM = 20; // (reason|int) (keyguard|bool) public static final int EVENT_ODI_CAPTIONS_CLICK = 21; public static final int EVENT_ODI_CAPTIONS_TOOLTIP_CLICK = 22; + public static final int EVENT_SLIDER_TOUCH_TRACKING = 23; // (tracking|bool) private static final String[] EVENT_TAGS = { "show_dialog", @@ -84,7 +85,8 @@ public class Events { "show_usb_overheat_alarm", "dismiss_usb_overheat_alarm", "odi_captions_click", - "odi_captions_tooltip_click" + "odi_captions_tooltip_click", + "slider_touch_tracking" }; public static final int DISMISS_REASON_UNKNOWN = 0; @@ -234,6 +236,10 @@ public class Events { VOLUME_DIALOG_SLIDER(150), @UiEvent(doc = "The audio stream was set to silent via slider") VOLUME_DIALOG_SLIDER_TO_ZERO(151), + @UiEvent(doc = "The right-most slider started tracking touch") + VOLUME_DIALOG_SLIDER_STARTED_TRACKING_TOUCH(1620), + @UiEvent(doc = "The right-most slider stopped tracking touch") + VOLUME_DIALOG_SLIDER_STOPPED_TRACKING_TOUCH(1621), @UiEvent(doc = "ODI captions was clicked") VOLUME_DIALOG_ODI_CAPTIONS_CLICKED(1503), @UiEvent(doc = "ODI captions tooltip dismiss was clicked") @@ -491,6 +497,15 @@ public class Events { .append(" keyguard=").append(keyguard); } break; + case EVENT_SLIDER_TOUCH_TRACKING: + final boolean startedTracking = (boolean) list[0]; + final VolumeDialogEvent event; + if (startedTracking) { + event = VolumeDialogEvent.VOLUME_DIALOG_SLIDER_STARTED_TRACKING_TOUCH; + } else { + event = VolumeDialogEvent.VOLUME_DIALOG_SLIDER_STOPPED_TRACKING_TOUCH; + } + sUiEventLogger.log(event); default: sb.append(Arrays.asList(list)); break; diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index 90c5c62718ad..404563087041 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -2518,6 +2518,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, @Override public void onStartTrackingTouch(SeekBar seekBar) { if (D.BUG) Log.d(TAG, "onStartTrackingTouch"+ " " + mRow.stream); + Events.writeEvent(Events.EVENT_SLIDER_TOUCH_TRACKING, /* startedTracking= */true); if (mRow.mHapticPlugin != null) { mRow.mHapticPlugin.onStartTrackingTouch(seekBar); } @@ -2528,6 +2529,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, @Override public void onStopTrackingTouch(SeekBar seekBar) { if (D.BUG) Log.d(TAG, "onStopTrackingTouch"+ " " + mRow.stream); + Events.writeEvent(Events.EVENT_SLIDER_TOUCH_TRACKING, /* startedTracking= */false); if (mRow.mHapticPlugin != null) { mRow.mHapticPlugin.onStopTrackingTouch(seekBar); } diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/MediaDevicesModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/MediaDevicesModule.kt index ab76d450eb0a..9f99e9778ef2 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dagger/MediaDevicesModule.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/MediaDevicesModule.kt @@ -24,6 +24,9 @@ import com.android.settingslib.volume.shared.AudioManagerIntentsReceiver import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.volume.panel.component.mediaoutput.data.repository.LocalMediaRepositoryFactory +import com.android.systemui.volume.panel.component.mediaoutput.data.repository.LocalMediaRepositoryFactoryImpl +import dagger.Binds import dagger.Module import dagger.Provides import kotlin.coroutines.CoroutineContext @@ -32,6 +35,11 @@ import kotlinx.coroutines.CoroutineScope @Module interface MediaDevicesModule { + @Binds + fun bindLocalMediaRepositoryFactory( + impl: LocalMediaRepositoryFactoryImpl + ): LocalMediaRepositoryFactory + companion object { @Provides diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/data/repository/LocalMediaRepositoryFactory.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/data/repository/LocalMediaRepositoryFactory.kt index 0a1ee249d6fb..1f52260bb20d 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/data/repository/LocalMediaRepositoryFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/data/repository/LocalMediaRepositoryFactory.kt @@ -26,7 +26,12 @@ import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope -class LocalMediaRepositoryFactory +interface LocalMediaRepositoryFactory { + + fun create(packageName: String?): LocalMediaRepository +} + +class LocalMediaRepositoryFactoryImpl @Inject constructor( private val intentsReceiver: AudioManagerIntentsReceiver, @@ -34,9 +39,9 @@ constructor( private val localMediaManagerFactory: LocalMediaManagerFactory, @Application private val coroutineScope: CoroutineScope, @Background private val backgroundCoroutineContext: CoroutineContext, -) { +) : LocalMediaRepositoryFactory { - fun create(packageName: String?): LocalMediaRepository = + override fun create(packageName: String?): LocalMediaRepository = LocalMediaRepositoryImpl( intentsReceiver, localMediaManagerFactory.create(packageName), diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteria.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteria.kt new file mode 100644 index 000000000000..020ec64c0491 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteria.kt @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.component.mediaoutput.domain + +import com.android.settingslib.volume.domain.interactor.AudioModeInteractor +import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor +import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope +import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine + +/** Determines if the Media Output Volume Panel component is available. */ +@VolumePanelScope +class MediaOutputAvailabilityCriteria +@Inject +constructor( + private val mediaOutputInteractor: MediaOutputInteractor, + private val audioModeInteractor: AudioModeInteractor, +) : ComponentAvailabilityCriteria { + + override fun isAvailable(): Flow<Boolean> { + return combine(mediaOutputInteractor.mediaDevices, audioModeInteractor.isOngoingCall) { + devices, + isOngoingCall -> + !isOngoingCall && devices.isNotEmpty() + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt new file mode 100644 index 000000000000..170b32c1d0ea --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.component.mediaoutput.domain.interactor + +import android.content.Intent +import android.provider.Settings +import com.android.internal.jank.InteractionJankMonitor +import com.android.systemui.animation.DialogCuj +import com.android.systemui.animation.DialogTransitionAnimator +import com.android.systemui.animation.Expandable +import com.android.systemui.media.dialog.MediaOutputDialogFactory +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaDeviceSession +import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope +import javax.inject.Inject + +/** User actions interactor for Media Output Volume Panel component. */ +@VolumePanelScope +class MediaOutputActionsInteractor +@Inject +constructor( + private val mediaOutputDialogFactory: MediaOutputDialogFactory, + private val activityStarter: ActivityStarter, +) { + + fun onDeviceClick(expandable: Expandable) { + activityStarter.startActivity( + Intent(Settings.ACTION_BLUETOOTH_SETTINGS), + true, + expandable.activityTransitionController(), + ) + } + + fun onBarClick(session: MediaDeviceSession, expandable: Expandable) { + when (session) { + is MediaDeviceSession.Active -> { + mediaOutputDialogFactory.createWithController( + session.packageName, + false, + expandable.dialogController() + ) + } + is MediaDeviceSession.Inactive -> { + mediaOutputDialogFactory.createDialogForSystemRouting(expandable.dialogController()) + } + else -> { + /* do nothing */ + } + } + } + + private fun Expandable.dialogController(): DialogTransitionAnimator.Controller? { + return dialogTransitionController( + cuj = + DialogCuj( + InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, + MediaOutputDialogFactory.INTERACTION_JANK_TAG + ) + ) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractor.kt index 6c456f963f03..24cc29d8e1f9 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractor.kt @@ -17,10 +17,14 @@ package com.android.systemui.volume.panel.component.mediaoutput.domain.interactor import android.content.pm.PackageManager +import android.media.session.MediaController +import android.os.Handler import android.util.Log import com.android.settingslib.media.MediaDevice import com.android.settingslib.volume.data.repository.LocalMediaRepository +import com.android.settingslib.volume.data.repository.MediaControllerChange import com.android.settingslib.volume.data.repository.MediaControllerRepository +import com.android.settingslib.volume.data.repository.stateChanges import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.volume.panel.component.mediaoutput.data.repository.LocalMediaRepositoryFactory import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaDeviceSession @@ -30,14 +34,21 @@ import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.shareIn +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.withContext +/** Provides observable models about the current media session state. */ @OptIn(ExperimentalCoroutinesApi::class) @VolumePanelScope class MediaOutputInteractor @@ -47,32 +58,44 @@ constructor( private val packageManager: PackageManager, @VolumePanelScope private val coroutineScope: CoroutineScope, @Background private val backgroundCoroutineContext: CoroutineContext, + @Background private val backgroundHandler: Handler, mediaControllerRepository: MediaControllerRepository ) { - val mediaDeviceSession: Flow<MediaDeviceSession> = - mediaControllerRepository.activeMediaController.mapNotNull { mediaController -> - if (mediaController == null) { - MediaDeviceSession.Inactive - } else { + /** Current [MediaDeviceSession]. Emits when the session playback changes. */ + val mediaDeviceSession: StateFlow<MediaDeviceSession> = + mediaControllerRepository.activeLocalMediaController + .flatMapLatest { it?.mediaDeviceSession() ?: flowOf(MediaDeviceSession.Inactive) } + .flowOn(backgroundCoroutineContext) + .stateIn(coroutineScope, SharingStarted.Eagerly, MediaDeviceSession.Inactive) + + private fun MediaController.mediaDeviceSession(): Flow<MediaDeviceSession> { + return stateChanges(backgroundHandler) + .onStart { emit(MediaControllerChange.PlaybackStateChanged(playbackState)) } + .filterIsInstance<MediaControllerChange.PlaybackStateChanged>() + .map { MediaDeviceSession.Active( - appLabel = getApplicationLabel(mediaController.packageName) - ?: return@mapNotNull null, - packageName = mediaController.packageName, - sessionToken = mediaController.sessionToken, + appLabel = getApplicationLabel(packageName) + ?: return@map MediaDeviceSession.Inactive, + packageName = packageName, + sessionToken = sessionToken, + playbackState = playbackState, ) } - } - private val localMediaRepository: Flow<LocalMediaRepository> = + } + + private val localMediaRepository: SharedFlow<LocalMediaRepository> = mediaDeviceSession .map { (it as? MediaDeviceSession.Active)?.packageName } .distinctUntilChanged() .map { localMediaRepositoryFactory.create(it) } - .shareIn(coroutineScope, SharingStarted.WhileSubscribed(), replay = 1) + .shareIn(coroutineScope, SharingStarted.Eagerly, replay = 1) + /** Currently connected [MediaDevice]. */ val currentConnectedDevice: Flow<MediaDevice?> = localMediaRepository.flatMapLatest { it.currentConnectedDevice } + /** A list of available [MediaDevice]s. */ val mediaDevices: Flow<Collection<MediaDevice>> = localMediaRepository.flatMapLatest { it.mediaDevices } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/model/MediaDeviceSession.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/model/MediaDeviceSession.kt index f250308802b2..71df8e53b5e2 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/model/MediaDeviceSession.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/model/MediaDeviceSession.kt @@ -17,6 +17,7 @@ package com.android.systemui.volume.panel.component.mediaoutput.domain.model import android.media.session.MediaSession +import android.media.session.PlaybackState /** Represents media playing on the connected device. */ sealed interface MediaDeviceSession { @@ -26,6 +27,7 @@ sealed interface MediaDeviceSession { val appLabel: CharSequence, val packageName: String, val sessionToken: MediaSession.Token, + val playbackState: PlaybackState?, ) : MediaDeviceSession /** Media is not playing. */ diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/ConnectedDeviceViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/ConnectedDeviceViewModel.kt new file mode 100644 index 000000000000..8ba672d2a15e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/ConnectedDeviceViewModel.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.component.mediaoutput.ui.viewmodel + +/** + * Models part of the Media Session Volume Panel component that displays connected device + * information. + */ +data class ConnectedDeviceViewModel( + val label: CharSequence, + val deviceName: CharSequence?, +) diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/DeviceIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/DeviceIconViewModel.kt new file mode 100644 index 000000000000..e0718ace2c30 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/DeviceIconViewModel.kt @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.component.mediaoutput.ui.viewmodel + +import com.android.systemui.common.shared.model.Color +import com.android.systemui.common.shared.model.Icon + +/** Models Media Session Volume Panel component connected device icon. */ +sealed interface DeviceIconViewModel { + + val icon: Icon + val backgroundColor: Color + + class IsPlaying( + override val icon: Icon, + override val backgroundColor: Color, + ) : DeviceIconViewModel + + class IsNotPlaying( + override val icon: Icon, + override val backgroundColor: Color, + ) : DeviceIconViewModel +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt new file mode 100644 index 000000000000..d14899294526 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.component.mediaoutput.ui.viewmodel + +import android.content.Context +import com.android.systemui.animation.Expandable +import com.android.systemui.common.shared.model.Color +import com.android.systemui.common.shared.model.Icon +import com.android.systemui.res.R +import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputActionsInteractor +import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor +import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaDeviceSession +import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope +import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.stateIn + +/** Models the UI of the Media Output Volume Panel component. */ +@VolumePanelScope +class MediaOutputViewModel +@Inject +constructor( + private val context: Context, + @VolumePanelScope private val coroutineScope: CoroutineScope, + private val volumePanelViewModel: VolumePanelViewModel, + private val actionsInteractor: MediaOutputActionsInteractor, + interactor: MediaOutputInteractor, +) { + + private val mediaDeviceSession: StateFlow<MediaDeviceSession> = + interactor.mediaDeviceSession.stateIn( + coroutineScope, + SharingStarted.Eagerly, + MediaDeviceSession.Unknown, + ) + + val connectedDeviceViewModel: StateFlow<ConnectedDeviceViewModel?> = + combine(mediaDeviceSession, interactor.currentConnectedDevice) { + mediaDeviceSession, + currentConnectedDevice -> + ConnectedDeviceViewModel( + if (mediaDeviceSession.isPlaying()) { + context.getString( + R.string.media_output_label_title, + (mediaDeviceSession as MediaDeviceSession.Active).appLabel + ) + } else { + context.getString(R.string.media_output_title_without_playing) + }, + currentConnectedDevice?.name, + ) + } + .stateIn( + coroutineScope, + SharingStarted.Eagerly, + null, + ) + + val deviceIconViewModel: StateFlow<DeviceIconViewModel?> = + combine(mediaDeviceSession, interactor.currentConnectedDevice) { + mediaDeviceSession, + currentConnectedDevice -> + if (mediaDeviceSession.isPlaying()) { + val icon = + currentConnectedDevice?.icon?.let { Icon.Loaded(it, null) } + ?: Icon.Resource( + com.android.internal.R.drawable.ic_bt_headphones_a2dp, + null + ) + DeviceIconViewModel.IsPlaying( + icon, + Color.Attribute(com.android.internal.R.attr.materialColorSecondary), + ) + } else { + DeviceIconViewModel.IsNotPlaying( + Icon.Resource(R.drawable.ic_media_home_devices, null), + Color.Attribute(com.android.internal.R.attr.materialColorSurface), + ) + } + } + .stateIn( + coroutineScope, + SharingStarted.Eagerly, + null, + ) + + private fun MediaDeviceSession.isPlaying(): Boolean = + this is MediaDeviceSession.Active && playbackState?.isActive == true + + fun onDeviceClick(expandable: Expandable) { + actionsInteractor.onDeviceClick(expandable) + volumePanelViewModel.dismissPanel() + } + + fun onBarClick(expandable: Expandable) { + actionsInteractor.onBarClick(mediaDeviceSession.value, expandable) + volumePanelViewModel.dismissPanel() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/shared/model/VolumePanelComponents.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/shared/model/VolumePanelComponents.kt index 842c3234fe26..6c742ba7e5f9 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/shared/model/VolumePanelComponents.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/shared/model/VolumePanelComponents.kt @@ -20,6 +20,7 @@ import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey object VolumePanelComponents { + const val MEDIA_OUTPUT: VolumePanelComponentKey = "media_output" const val BOTTOM_BAR: VolumePanelComponentKey = "bottom_bar" const val CAPTIONING: VolumePanelComponentKey = "captioning" } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/VolumePanelComponent.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/VolumePanelComponent.kt index 841daf85ebcc..afd3f6170d3d 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/VolumePanelComponent.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/VolumePanelComponent.kt @@ -18,6 +18,7 @@ package com.android.systemui.volume.panel.dagger import com.android.systemui.volume.panel.component.bottombar.BottomBarModule import com.android.systemui.volume.panel.component.captioning.CaptioningModule +import com.android.systemui.volume.panel.component.mediaoutput.MediaOutputModule import com.android.systemui.volume.panel.dagger.factory.VolumePanelComponentFactory import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope import com.android.systemui.volume.panel.domain.DomainModule @@ -46,6 +47,7 @@ import kotlinx.coroutines.CoroutineScope // Components modules BottomBarModule::class, CaptioningModule::class, + MediaOutputModule::class, ] ) interface VolumePanelComponent { diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/domain/DomainModule.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/domain/DomainModule.kt index defa92def893..55d8de5aeb95 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/domain/DomainModule.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/domain/DomainModule.kt @@ -51,6 +51,7 @@ interface DomainModule { fun provideEnabledComponents(): Collection<VolumePanelComponentKey> { return setOf( VolumePanelComponents.CAPTIONING, + VolumePanelComponents.MEDIA_OUTPUT, VolumePanelComponents.BOTTOM_BAR, ) } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/UiModule.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/UiModule.kt index a3f052d88b7d..867df4a87dd5 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/UiModule.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/UiModule.kt @@ -37,7 +37,11 @@ interface UiModule { @Provides @VolumePanelScope @HeaderComponents - fun provideHeaderComponents(): Collection<VolumePanelComponentKey> = setOf() + fun provideHeaderComponents(): Collection<VolumePanelComponentKey> { + return setOf( + VolumePanelComponents.MEDIA_OUTPUT, + ) + } @Provides @VolumePanelScope diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/activity/VolumePanelActivity.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/activity/VolumePanelActivity.kt index 1b2265b9891e..53e1b8b5bb70 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/activity/VolumePanelActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/activity/VolumePanelActivity.kt @@ -20,8 +20,8 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels -import androidx.core.view.WindowCompat import com.android.systemui.compose.ComposeFacade +import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel import javax.inject.Inject @@ -32,6 +32,7 @@ class VolumePanelActivity constructor( private val volumePanelViewModelFactory: Provider<VolumePanelViewModel.Factory>, private val volumePanelFlag: VolumePanelFlag, + private val configurationController: ConfigurationController, ) : ComponentActivity() { private val viewModel: VolumePanelViewModel by @@ -43,7 +44,11 @@ constructor( volumePanelFlag.assertNewVolumePanel() - WindowCompat.setDecorFitsSystemWindows(window, false) ComposeFacade.setVolumePanelActivityContent(this, viewModel) { finish() } } + + override fun onContentChanged() { + super.onContentChanged() + configurationController.onConfigurationChanged(resources.configuration) + } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelState.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelState.kt index f67db965e28a..7f33a6bb70f9 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelState.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelState.kt @@ -22,10 +22,13 @@ import android.content.res.Configuration.Orientation /** * State of the Volume Panel itself. * - * @property orientation is current Volume Panel orientation. + * @property orientation is current Volume Panel orientation + * @property isWideScreen is true when Volume Panel should use wide-screen layout and false the + * otherwise */ data class VolumePanelState( @Orientation val orientation: Int, + val isWideScreen: Boolean, val isVisible: Boolean, ) { init { diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModel.kt index d87a79ed90f4..3c5b75cfb349 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModel.kt @@ -21,6 +21,7 @@ import android.content.res.Resources import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.res.R import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.onConfigChanged import com.android.systemui.volume.panel.dagger.VolumePanelComponent @@ -72,7 +73,11 @@ class VolumePanelViewModel( .distinctUntilChanged(), mutablePanelVisibility, ) { configuration, isVisible -> - VolumePanelState(orientation = configuration.orientation, isVisible = isVisible) + VolumePanelState( + orientation = configuration.orientation, + isVisible = isVisible, + isWideScreen = !resources.getBoolean(R.bool.config_edgeToEdgeBottomSheetDialog), + ) } .stateIn( scope, @@ -80,6 +85,7 @@ class VolumePanelViewModel( VolumePanelState( orientation = resources.configuration.orientation, isVisible = mutablePanelVisibility.value, + isWideScreen = !resources.getBoolean(R.bool.config_edgeToEdgeBottomSheetDialog) ), ) val componentsLayout: Flow<ComponentsLayout> = diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt index cd19259091ab..30269664a559 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt @@ -260,7 +260,7 @@ class ClockEventControllerTest : SysuiTestCase() { @Test fun keyguardCallback_visibilityChanged_clockDozeCalled() = runBlocking(IMMEDIATE) { - mSetFlagsRule.disableFlags(AConfigFlags.FLAG_KEYGUARD_SHADE_MIGRATION_NSSL) + mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) val captor = argumentCaptor<KeyguardUpdateMonitorCallback>() verify(keyguardUpdateMonitor).registerCallback(capture(captor)) diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java index e8d86dddcda5..9d81b960336f 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java @@ -35,6 +35,7 @@ import android.view.View; import androidx.test.filters.SmallTest; +import com.android.systemui.Flags; import com.android.systemui.plugins.clocks.ClockFaceConfig; import com.android.systemui.plugins.clocks.ClockTickRate; import com.android.systemui.shared.clocks.ClockRegistry; @@ -50,6 +51,8 @@ import org.mockito.verification.VerificationMode; public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchControllerBaseTest { @Test public void testInit_viewAlreadyAttached() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + mController.init(); verifyAttachment(times(1)); @@ -57,6 +60,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testInit_viewNotYetAttached() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class); @@ -73,12 +78,16 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testInitSubControllers() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + mController.init(); verify(mKeyguardSliceViewController).init(); } @Test public void testInit_viewDetached() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class); mController.init(); @@ -92,6 +101,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testPluginPassesStatusBarState() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + ArgumentCaptor<ClockRegistry.ClockChangeListener> listenerArgumentCaptor = ArgumentCaptor.forClass(ClockRegistry.ClockChangeListener.class); @@ -105,6 +116,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testSmartspaceEnabledRemovesKeyguardStatusArea() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + when(mSmartspaceController.isEnabled()).thenReturn(true); mController.init(); @@ -113,6 +126,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void onLocaleListChangedRebuildsSmartspaceView() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + when(mSmartspaceController.isEnabled()).thenReturn(true); mController.init(); @@ -123,6 +138,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void onLocaleListChanged_rebuildsSmartspaceViews_whenDecouplingEnabled() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + when(mSmartspaceController.isEnabled()).thenReturn(true); when(mSmartspaceController.isDateWeatherDecoupled()).thenReturn(true); mController.init(); @@ -136,6 +153,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testSmartspaceDisabledShowsKeyguardStatusArea() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + when(mSmartspaceController.isEnabled()).thenReturn(false); mController.init(); @@ -144,6 +163,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testRefresh() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + mController.refresh(); verify(mSmartspaceController).requestSmartspaceUpdate(); @@ -151,6 +172,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testChangeToDoubleLineClockSetsSmallClock() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + when(mSecureSettings.getIntForUser(Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, 1, UserHandle.USER_CURRENT)) .thenReturn(0); @@ -174,11 +197,15 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testGetClock_ForwardsToClock() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + assertEquals(mClockController, mController.getClock()); } @Test public void testGetLargeClockBottom_returnsExpectedValue() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + when(mLargeClockFrame.getVisibility()).thenReturn(View.VISIBLE); when(mLargeClockFrame.getHeight()).thenReturn(100); when(mSmallClockFrame.getHeight()).thenReturn(50); @@ -191,6 +218,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testGetSmallLargeClockBottom_returnsExpectedValue() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + when(mLargeClockFrame.getVisibility()).thenReturn(View.GONE); when(mLargeClockFrame.getHeight()).thenReturn(100); when(mSmallClockFrame.getHeight()).thenReturn(50); @@ -203,12 +232,16 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testGetClockBottom_nullClock_returnsZero() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + when(mClockEventController.getClock()).thenReturn(null); assertEquals(0, mController.getClockBottom(10)); } @Test public void testChangeLockscreenWeatherEnabledSetsWeatherViewVisible() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + when(mSmartspaceController.isWeatherEnabled()).thenReturn(true); ArgumentCaptor<ContentObserver> observerCaptor = ArgumentCaptor.forClass(ContentObserver.class); @@ -227,6 +260,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testChangeClockDateWeatherEnabled_SetsDateWeatherViewVisibility() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + ArgumentCaptor<ClockRegistry.ClockChangeListener> listenerArgumentCaptor = ArgumentCaptor.forClass(ClockRegistry.ClockChangeListener.class); when(mSmartspaceController.isEnabled()).thenReturn(true); @@ -249,11 +284,15 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testGetClock_nullClock_returnsNull() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + when(mClockEventController.getClock()).thenReturn(null); assertNull(mController.getClock()); } private void verifyAttachment(VerificationMode times) { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + verify(mClockRegistry, times).registerClockChangeListener( any(ClockRegistry.ClockChangeListener.class)); verify(mClockEventController, times).registerListeners(mView); @@ -261,6 +300,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testSplitShadeEnabledSetToSmartspaceController() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + mController.setSplitShadeEnabled(true); verify(mSmartspaceController, times(1)).setSplitShadeEnabled(true); verify(mSmartspaceController, times(0)).setSplitShadeEnabled(false); @@ -268,6 +309,8 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro @Test public void testSplitShadeDisabledSetToSmartspaceController() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + mController.setSplitShadeEnabled(false); verify(mSmartspaceController, times(1)).setSplitShadeEnabled(false); verify(mSmartspaceController, times(0)).setSplitShadeEnabled(true); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java index 4508aea81176..b4a9d40a6caf 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java @@ -40,6 +40,7 @@ import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.TextView; +import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.clocks.ClockController; import com.android.systemui.plugins.clocks.ClockFaceController; @@ -79,6 +80,8 @@ public class KeyguardClockSwitchTest extends SysuiTestCase { @Before public void setUp() { + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + MockitoAnnotations.initMocks(this); when(mMockKeyguardSliceView.getContext()).thenReturn(mContext); when(mMockKeyguardSliceView.findViewById(R.id.keyguard_status_area)) diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index be06cc5d3d1d..538daee52377 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -1500,7 +1500,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { verify(mHandler).postDelayed(mKeyguardUpdateMonitor.mFpCancelNotReceived, DEFAULT_CANCEL_SIGNAL_TIMEOUT); - mKeyguardUpdateMonitor.onFingerprintAuthenticated(0, true); mTestableLooper.processAllMessages(); @@ -2016,6 +2015,34 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { } @Test + public void authenticateFingerprint_onFaceLockout_detectFingerprint() throws RemoteException { + // GIVEN fingerprintAuthenticate + mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */); + mTestableLooper.processAllMessages(); + verifyFingerprintAuthenticateCall(); + verifyFingerprintDetectNeverCalled(); + clearInvocations(mFingerprintManager); + + // WHEN class 3 face is locked out + when(mFaceAuthInteractor.isFaceAuthStrong()).thenReturn(true); + when(mFaceAuthInteractor.isFaceAuthEnabledAndEnrolled()).thenReturn(true); + setupFingerprintAuth(/* isClass3 */ true); + // GIVEN primary auth is not required by StrongAuthTracker + primaryAuthNotRequiredByStrongAuthTracker(); + + // WHEN face (class 3) is locked out + faceAuthLockOut(); + mTestableLooper.processAllMessages(); + + // THEN unlocking with fingerprint is not allowed + Assert.assertFalse(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed( + BiometricSourceType.FINGERPRINT)); + + // THEN fingerprint detect gets called + verifyFingerprintDetectCall(); + } + + @Test public void testFingerprintSensorProperties() throws RemoteException { mFingerprintAuthenticatorsRegisteredCallback.onAllAuthenticatorsRegistered( new ArrayList<>()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt index 936aa8bb819c..91da88e480d4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt @@ -17,6 +17,7 @@ package com.android.systemui.flags import android.testing.AndroidTestingRunner +import android.util.Log import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import java.io.PrintWriter @@ -41,14 +42,21 @@ class FlagDependenciesTest : SysuiTestCase() { FlagDependencies(TestFeatureFlags(teamfood = teamfood), TestHandler()) private class TestHandler : FlagDependenciesBase.Handler { + override val enableDependencies: Boolean + get() = true override fun warnAboutBadFlagConfiguration( all: List<FlagDependenciesBase.Dependency>, unmet: List<FlagDependenciesBase.Dependency> ) { - val title = "${unmet.size} invalid of ${all.size} flag dependencies" + val title = "Invalid flag dependencies: ${unmet.size}" val details = unmet.joinToString("\n") fail("$title:\n$details") } + + override fun onCollected(all: List<FlagDependenciesBase.Dependency>) { + Log.d("FlagDependencies", "All: ${all.size}") + all.forEach { Log.d("FlagDependencies", " $it") } + } } private class TestFeatureFlags(val teamfood: Boolean) : FeatureFlagsClassic { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index 2732047b4eba..0957748c9938 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -21,6 +21,7 @@ import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_TIMEOUT; import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_USER; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; @@ -650,6 +651,25 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { } @Test + public void testBouncerPrompt_deviceLockedByAdaptiveAuth() { + // GIVEN no trust agents enabled and biometrics aren't enrolled + when(mUpdateMonitor.isTrustUsuallyManaged(anyInt())).thenReturn(false); + when(mUpdateMonitor.isUnlockingWithBiometricsPossible(anyInt())).thenReturn(false); + + // WHEN the strong auth reason is SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST + KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker = + mock(KeyguardUpdateMonitor.StrongAuthTracker.class); + when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(strongAuthTracker); + when(strongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true); + when(strongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn( + SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST); + + // THEN the bouncer prompt reason should return PROMPT_REASON_ADAPTIVE_AUTH_REQUEST + assertEquals(KeyguardSecurityView.PROMPT_REASON_ADAPTIVE_AUTH_REQUEST, + mViewMediator.mViewMediatorCallback.getBouncerPromptReason()); + } + + @Test public void testBouncerPrompt_deviceRestartedDueToMainlineUpdate() { // GIVEN biometrics enrolled when(mUpdateMonitor.isUnlockingWithBiometricsPossible(anyInt())).thenReturn(true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt index ad86ee9f07d2..9c7f254a7b85 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt @@ -38,6 +38,7 @@ import com.android.systemui.keyguard.ui.view.layout.sections.DefaultShortcutsSec import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusBarSection import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusViewSection import com.android.systemui.keyguard.ui.view.layout.sections.DefaultUdfpsAccessibilityOverlaySection +import com.android.systemui.keyguard.ui.view.layout.sections.KeyguardSliceViewSection import com.android.systemui.keyguard.ui.view.layout.sections.SmartspaceSection import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines import com.android.systemui.util.mockito.whenever @@ -71,6 +72,7 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() { @Mock private lateinit var communalTutorialIndicatorSection: CommunalTutorialIndicatorSection @Mock private lateinit var clockSection: ClockSection @Mock private lateinit var smartspaceSection: SmartspaceSection + @Mock private lateinit var keyguardSliceViewSection: KeyguardSliceViewSection @Mock private lateinit var udfpsAccessibilityOverlaySection: DefaultUdfpsAccessibilityOverlaySection @Before @@ -92,6 +94,7 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() { communalTutorialIndicatorSection, clockSection, smartspaceSection, + keyguardSliceViewSection, udfpsAccessibilityOverlaySection, ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSectionTest.kt index deb3a83fcbee..8eccde7d6cb8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSectionTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSectionTest.kt @@ -88,6 +88,8 @@ class SmartspaceSectionTest : SysuiTestCase() { whenever(keyguardClockViewModel.hasCustomWeatherDataDisplay) .thenReturn(hasCustomWeatherDataDisplay) whenever(keyguardClockViewModel.clockShouldBeCentered).thenReturn(clockShouldBeCentered) + whenever(keyguardSmartspaceViewModel.isSmartspaceEnabled).thenReturn(true) + constraintSet = ConstraintSet() } @@ -103,7 +105,6 @@ class SmartspaceSectionTest : SysuiTestCase() { @Test fun testAddViews_smartspaceEnabled_dateWeatherDecoupled() { - whenever(keyguardSmartspaceViewModel.isSmartspaceEnabled).thenReturn(true) whenever(keyguardSmartspaceViewModel.isDateWeatherDecoupled).thenReturn(true) underTest.addViews(constraintLayout) assert(smartspaceView.parent == constraintLayout) @@ -113,7 +114,6 @@ class SmartspaceSectionTest : SysuiTestCase() { @Test fun testAddViews_smartspaceEnabled_notDateWeatherDecoupled() { - whenever(keyguardSmartspaceViewModel.isSmartspaceEnabled).thenReturn(true) whenever(keyguardSmartspaceViewModel.isDateWeatherDecoupled).thenReturn(false) underTest.addViews(constraintLayout) assert(smartspaceView.parent == constraintLayout) @@ -123,7 +123,6 @@ class SmartspaceSectionTest : SysuiTestCase() { @Test fun testConstraintsWhenNotHasCustomWeatherDataDisplay() { - whenever(keyguardSmartspaceViewModel.isSmartspaceEnabled).thenReturn(true) whenever(keyguardSmartspaceViewModel.isDateWeatherDecoupled).thenReturn(true) hasCustomWeatherDataDisplay.value = false underTest.addViews(constraintLayout) diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt index 59965022d7cc..c896486339b9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt @@ -40,6 +40,7 @@ import android.media.MediaMetadata import android.media.session.MediaSession import android.media.session.PlaybackState import android.os.Bundle +import android.platform.test.annotations.EnableFlags import android.provider.Settings import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS import android.testing.AndroidTestingRunner @@ -61,6 +62,7 @@ import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId import com.android.internal.widget.CachingIconView import com.android.systemui.ActivityIntentHelper +import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.bluetooth.BroadcastDialogController import com.android.systemui.broadcast.BroadcastSender @@ -88,6 +90,7 @@ import com.android.systemui.plugins.FalsingManager import com.android.systemui.res.R import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.surfaceeffects.loadingeffect.LoadingEffectView import com.android.systemui.surfaceeffects.ripple.MultiRippleView import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseAnimationConfig import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView @@ -190,6 +193,7 @@ public class MediaControlPanelTest : SysuiTestCase() { private lateinit var dismissText: TextView private lateinit var multiRippleView: MultiRippleView private lateinit var turbulenceNoiseView: TurbulenceNoiseView + private lateinit var loadingEffectView: LoadingEffectView private lateinit var session: MediaSession private lateinit var device: MediaDeviceData @@ -402,6 +406,7 @@ public class MediaControlPanelTest : SysuiTestCase() { multiRippleView = MultiRippleView(context, null) turbulenceNoiseView = TurbulenceNoiseView(context, null) + loadingEffectView = LoadingEffectView(context, null) whenever(viewHolder.player).thenReturn(view) whenever(viewHolder.appIcon).thenReturn(appIcon) @@ -447,6 +452,7 @@ public class MediaControlPanelTest : SysuiTestCase() { whenever(viewHolder.multiRippleView).thenReturn(multiRippleView) whenever(viewHolder.turbulenceNoiseView).thenReturn(turbulenceNoiseView) + whenever(viewHolder.loadingEffectView).thenReturn(loadingEffectView) } /** Initialize elements for the recommendation view holder */ @@ -2429,6 +2435,7 @@ public class MediaControlPanelTest : SysuiTestCase() { mainExecutor.execute { assertThat(turbulenceNoiseView.visibility).isEqualTo(View.VISIBLE) + assertThat(loadingEffectView.visibility).isEqualTo(View.INVISIBLE) clock.advanceTime( MediaControlPanel.TURBULENCE_NOISE_PLAY_DURATION + @@ -2436,6 +2443,40 @@ public class MediaControlPanelTest : SysuiTestCase() { ) assertThat(turbulenceNoiseView.visibility).isEqualTo(View.INVISIBLE) + assertThat(loadingEffectView.visibility).isEqualTo(View.INVISIBLE) + } + } + + @Test + @EnableFlags(Flags.FLAG_SHADERLIB_LOADING_EFFECT_REFACTOR) + fun playTurbulenceNoise_newLoadingEffect_finishesAfterDuration() { + val semanticActions = + MediaButton( + playOrPause = + MediaAction( + icon = null, + action = {}, + contentDescription = "play", + background = null + ) + ) + val data = mediaData.copy(semanticActions = semanticActions) + player.attachPlayer(viewHolder) + player.bindPlayer(data, KEY) + + viewHolder.actionPlayPause.callOnClick() + + mainExecutor.execute { + assertThat(loadingEffectView.visibility).isEqualTo(View.VISIBLE) + assertThat(turbulenceNoiseView.visibility).isEqualTo(View.INVISIBLE) + + clock.advanceTime( + MediaControlPanel.TURBULENCE_NOISE_PLAY_DURATION + + TurbulenceNoiseAnimationConfig.DEFAULT_EASING_DURATION_IN_MILLIS.toLong() + ) + + assertThat(loadingEffectView.visibility).isEqualTo(View.INVISIBLE) + assertThat(turbulenceNoiseView.visibility).isEqualTo(View.INVISIBLE) } } @@ -2458,6 +2499,30 @@ public class MediaControlPanelTest : SysuiTestCase() { viewHolder.action0.callOnClick() assertThat(turbulenceNoiseView.visibility).isEqualTo(View.INVISIBLE) + assertThat(loadingEffectView.visibility).isEqualTo(View.INVISIBLE) + } + + @Test + @EnableFlags(Flags.FLAG_SHADERLIB_LOADING_EFFECT_REFACTOR) + fun playTurbulenceNoise_newLoadingEffect_whenPlaybackStateIsNotPlaying_doesNotPlayTurbulence() { + val semanticActions = + MediaButton( + custom0 = + MediaAction( + icon = null, + action = {}, + contentDescription = "custom0", + background = null + ), + ) + val data = mediaData.copy(semanticActions = semanticActions) + player.attachPlayer(viewHolder) + player.bindPlayer(data, KEY) + + viewHolder.action0.callOnClick() + + assertThat(loadingEffectView.visibility).isEqualTo(View.INVISIBLE) + assertThat(turbulenceNoiseView.visibility).isEqualTo(View.INVISIBLE) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java index bfb18c88bf9b..52859cdeb406 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java @@ -22,6 +22,8 @@ import static android.view.Display.INVALID_DISPLAY; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.wm.shell.Flags.enableTaskbarNavbarUnification; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; @@ -289,32 +291,43 @@ public class NavigationBarControllerImplTest extends SysuiTestCase { verify(mCommandQueue, never()).addCallback(any(TaskbarDelegate.class)); } - @Test public void testConfigurationChange_taskbarNotInitialized() { Configuration configuration = mContext.getResources().getConfiguration(); - when(Utilities.isLargeScreen(any())).thenReturn(true); + mNavigationBarController.mIsLargeScreen = true; mNavigationBarController.onConfigChanged(configuration); verify(mTaskbarDelegate, never()).onConfigurationChanged(configuration); } @Test - public void testConfigurationChangeUnfolding_taskbarInitialized() { + public void testConfigurationChange_taskbarInitialized() { Configuration configuration = mContext.getResources().getConfiguration(); - when(Utilities.isLargeScreen(any())).thenReturn(true); + mNavigationBarController.mIsLargeScreen = true; when(mTaskbarDelegate.isInitialized()).thenReturn(true); mNavigationBarController.onConfigChanged(configuration); verify(mTaskbarDelegate, times(1)).onConfigurationChanged(configuration); } @Test - public void testConfigurationChangeFolding_taskbarInitialized() { + public void testShouldRenderTaskbar_taskbarNotRenderedOnPhone() { + mNavigationBarController.mIsLargeScreen = false; + mNavigationBarController.mIsPhone = true; + assertFalse(mNavigationBarController.supportsTaskbar()); + } + + @Test + public void testShouldRenderTaskbar_taskbarRenderedOnTabletOrUnfolded() { + mNavigationBarController.mIsLargeScreen = true; + mNavigationBarController.mIsPhone = false; + assertTrue(mNavigationBarController.supportsTaskbar()); + } + + @Test + public void testShouldRenderTaskbar_taskbarRenderedInFoldedState() { assumeTrue(enableTaskbarNavbarUnification()); - Configuration configuration = mContext.getResources().getConfiguration(); - when(Utilities.isLargeScreen(any())).thenReturn(false); - when(mTaskbarDelegate.isInitialized()).thenReturn(true); - mNavigationBarController.onConfigChanged(configuration); - verify(mTaskbarDelegate, times(1)).onConfigurationChanged(configuration); + mNavigationBarController.mIsLargeScreen = false; + mNavigationBarController.mIsPhone = false; + assertTrue(mNavigationBarController.supportsTaskbar()); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java index cc27cbd9d809..992658a99df4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java @@ -103,7 +103,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.keyguard.domain.interactor.NaturalScrollingSettingObserver; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; +import com.android.systemui.keyguard.ui.view.KeyguardRootView; import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingLockscreenHostedTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel; @@ -281,6 +281,8 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { @Mock protected UiEventLogger mUiEventLogger; @Mock protected LockIconViewController mLockIconViewController; @Mock protected KeyguardViewConfigurator mKeyguardViewConfigurator; + @Mock protected KeyguardRootView mKeyguardRootView; + @Mock protected View mKeyguardRootViewChild; @Mock protected KeyguardMediaController mKeyguardMediaController; @Mock protected NavigationModeController mNavigationModeController; @Mock protected NavigationBarController mNavigationBarController; @@ -388,9 +390,9 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { mFeatureFlags.set(Flags.LOCKSCREEN_ENABLE_LANDSCAPE, false); mFeatureFlags.set(Flags.QS_USER_DETAIL_SHORTCUT, false); - mSetFlagsRule.disableFlags(KeyguardShadeMigrationNssl.FLAG_NAME); mSetFlagsRule.disableFlags(com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR); mSetFlagsRule.disableFlags(com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); + mSetFlagsRule.disableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR); mMainDispatcher = getMainDispatcher(); KeyguardInteractorFactory.WithDependencies keyguardInteractorDeps = @@ -837,13 +839,13 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { when(mNotificationStackScrollLayoutController.getBottom()).thenReturn(stackBottom); when(mLockIconViewController.getTop()).thenReturn((float) (stackBottom - lockIconPadding)); + when(mKeyguardRootViewChild.getTop()).thenReturn((int) (stackBottom - lockIconPadding)); + when(mKeyguardRootView.findViewById(anyInt())).thenReturn(mKeyguardRootViewChild); + when(mKeyguardViewConfigurator.getKeyguardRootView()).thenReturn(mKeyguardRootView); + when(mResources.getDimensionPixelSize(R.dimen.keyguard_indication_bottom_padding)) .thenReturn(indicationPadding); mNotificationPanelViewController.loadDimens(); - - mNotificationPanelViewController.setAmbientIndicationTop( - /* ambientIndicationTop= */ stackBottom - ambientPadding, - /* ambientTextVisible= */ true); } protected void triggerPositionClockAndNotifications() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java index 2e8d46a83e1c..d24fe1b16ef9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java @@ -57,7 +57,6 @@ import androidx.test.filters.SmallTest; import com.android.systemui.DejankUtils; import com.android.systemui.flags.Flags; -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.domain.interactor.PowerInteractor; import com.android.systemui.res.R; @@ -204,6 +203,10 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo when(mNotificationStackScrollLayoutController.getShelfHeight()).thenReturn(5); assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf()) .isEqualTo(5); + + mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR); + assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf()) + .isEqualTo(5); } @Test @@ -217,6 +220,10 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo when(mNotificationStackScrollLayoutController.getShelfHeight()).thenReturn(5); assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf()) .isEqualTo(0); + + mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR); + assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf()) + .isEqualTo(0); } @Test @@ -230,6 +237,10 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo when(mNotificationStackScrollLayoutController.getShelfHeight()).thenReturn(5); assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf()) .isEqualTo(0); + + mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR); + assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf()) + .isEqualTo(0); } @Test @@ -243,6 +254,10 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo when(mNotificationStackScrollLayoutController.getShelfHeight()).thenReturn(5); assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf()) .isEqualTo(2); + + mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR); + assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf()) + .isEqualTo(2); } @Test @@ -256,6 +271,10 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo when(mNotificationStackScrollLayoutController.getShelfHeight()).thenReturn(5); assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf()) .isEqualTo(0); + + mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR); + assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf()) + .isEqualTo(0); } @Test @@ -363,7 +382,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo @Test public void onInterceptTouchEvent_nsslMigrationOff_userActivity() { - mSetFlagsRule.disableFlags(com.android.systemui.Flags.FLAG_KEYGUARD_SHADE_MIGRATION_NSSL); + mSetFlagsRule.disableFlags(com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); mTouchHandler.onInterceptTouchEvent(MotionEvent.obtain(0L /* downTime */, 0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */, @@ -374,7 +393,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo @Test public void onInterceptTouchEvent_nsslMigrationOn_userActivity_not_called() { - mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_KEYGUARD_SHADE_MIGRATION_NSSL); + mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); mTouchHandler.onInterceptTouchEvent(MotionEvent.obtain(0L /* downTime */, 0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */, @@ -1125,7 +1144,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo @Test public void nsslFlagEnabled_allowOnlyExternalTouches() { - mSetFlagsRule.enableFlags(KeyguardShadeMigrationNssl.FLAG_NAME); + mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); // This sets the dozing state that is read when onMiddleClicked is eventually invoked. mTouchHandler.onTouch(mock(View.class), mDownMotionEvent); diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt index 248ed249c213..c2267903440a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt @@ -44,7 +44,6 @@ import com.android.systemui.flags.Flags.TRACKPAD_GESTURE_FEATURES import com.android.systemui.keyevent.domain.interactor.SysUIKeyEventHandler import com.android.systemui.keyguard.KeyguardUnlockAnimationController import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerDependencies import com.android.systemui.res.R @@ -378,7 +377,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { @Test fun handleDispatchTouchEvent_nsslMigrationOff_userActivity_not_called() { - mSetFlagsRule.disableFlags(Flags.FLAG_KEYGUARD_SHADE_MIGRATION_NSSL) + mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) underTest.setStatusBarViewController(phoneStatusBarViewController) interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT) @@ -388,7 +387,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { @Test fun handleDispatchTouchEvent_nsslMigrationOn_userActivity() { - mSetFlagsRule.enableFlags(Flags.FLAG_KEYGUARD_SHADE_MIGRATION_NSSL) + mSetFlagsRule.enableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) underTest.setStatusBarViewController(phoneStatusBarViewController) interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT) @@ -430,7 +429,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { // AND the lock icon wants the touch whenever(lockIconViewController.willHandleTouchWhileDozing(DOWN_EVENT)).thenReturn(true) - mSetFlagsRule.enableFlags(KeyguardShadeMigrationNssl.FLAG_NAME) + mSetFlagsRule.enableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) // THEN touch should NOT be intercepted by NotificationShade assertThat(interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)).isFalse() @@ -449,7 +448,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { whenever(quickSettingsController.shouldQuickSettingsIntercept(any(), any(), any())) .thenReturn(false) - mSetFlagsRule.enableFlags(KeyguardShadeMigrationNssl.FLAG_NAME) + mSetFlagsRule.enableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) // THEN touch should NOT be intercepted by NotificationShade assertThat(interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)).isTrue() @@ -468,7 +467,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { whenever(quickSettingsController.shouldQuickSettingsIntercept(any(), any(), any())) .thenReturn(true) - mSetFlagsRule.enableFlags(KeyguardShadeMigrationNssl.FLAG_NAME) + mSetFlagsRule.enableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) // THEN touch should NOT be intercepted by NotificationShade assertThat(interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)).isTrue() diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt index c32635020ddc..d7eada82b9a6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt @@ -30,7 +30,6 @@ import com.android.systemui.Flags.FLAG_CENTRALIZED_STATUS_BAR_DIMENS_REFACTOR import com.android.systemui.SysuiTestCase import com.android.systemui.fragments.FragmentHostManager import com.android.systemui.fragments.FragmentService -import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.navigationbar.NavigationModeController import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener import com.android.systemui.plugins.qs.QS @@ -100,7 +99,7 @@ class NotificationsQSContainerControllerTest : SysuiTestCase() { MockitoAnnotations.initMocks(this) fakeSystemClock = FakeSystemClock() delayableExecutor = FakeExecutor(fakeSystemClock) - mSetFlagsRule.enableFlags(KeyguardShadeMigrationNssl.FLAG_NAME) + mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) mContext.ensureTestableResources() whenever(view.context).thenReturn(mContext) whenever(view.resources).thenReturn(mContext.resources) diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt index cc79ca4efaa1..f48993754e63 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt @@ -80,7 +80,7 @@ class ShadeControllerImplTest : SysuiTestCase() { @Mock private lateinit var windowManager: WindowManager @Mock private lateinit var assistManager: AssistManager @Mock private lateinit var gutsManager: NotificationGutsManager - @Mock private lateinit var shadeViewController: ShadeViewController + @Mock private lateinit var npvc: NotificationPanelViewController @Mock private lateinit var nswvc: NotificationShadeWindowViewController @Mock private lateinit var display: Display @Mock private lateinit var touchLog: LogBuffer @@ -120,7 +120,7 @@ class ShadeControllerImplTest : SysuiTestCase() { deviceProvisionedController, notificationShadeWindowController, windowManager, - Lazy { shadeViewController }, + Lazy { npvc }, Lazy { assistManager }, Lazy { gutsManager }, ) @@ -134,9 +134,9 @@ class ShadeControllerImplTest : SysuiTestCase() { // Trying to open it does nothing. shadeController.animateExpandShade() - verify(shadeViewController, never()).expandToNotifications() + verify(npvc, never()).expandToNotifications() shadeController.animateExpandQs() - verify(shadeViewController, never()).expand(ArgumentMatchers.anyBoolean()) + verify(npvc, never()).expand(ArgumentMatchers.anyBoolean()) } @Test @@ -145,15 +145,15 @@ class ShadeControllerImplTest : SysuiTestCase() { // Can now be opened. shadeController.animateExpandShade() - verify(shadeViewController).expandToNotifications() + verify(npvc).expandToNotifications() shadeController.animateExpandQs() - verify(shadeViewController).expandToQs() + verify(npvc).expandToQs() } @Test fun cancelExpansionAndCollapseShade_callsCancelCurrentTouch() { // GIVEN the shade is tracking a touch - whenever(shadeViewController.isTracking).thenReturn(true) + whenever(npvc.isTracking).thenReturn(true) // WHEN cancelExpansionAndCollapseShade is called shadeController.cancelExpansionAndCollapseShade() @@ -165,7 +165,7 @@ class ShadeControllerImplTest : SysuiTestCase() { @Test fun cancelExpansionAndCollapseShade_doesNotCallAnimateCollapseShade_whenCollapsed() { // GIVEN the shade is tracking a touch - whenever(shadeViewController.isTracking).thenReturn(false) + whenever(npvc.isTracking).thenReturn(false) // WHEN cancelExpansionAndCollapseShade is called shadeController.cancelExpansionAndCollapseShade() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt index ffde6015c127..9ec9b69d44c0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt @@ -25,9 +25,9 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.keyguard.domain.interactor.NaturalScrollingSettingObserver import com.android.systemui.plugins.FalsingManager +import com.android.systemui.shade.data.repository.FakeShadeRepository import com.android.systemui.statusbar.notification.row.ExpandableView import com.android.systemui.util.mockito.mock -import com.android.systemui.shade.data.repository.FakeShadeRepository import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -58,12 +58,11 @@ class DragDownHelperTest : SysuiTestCase() { whenever(naturalScrollingSettingObserver.isNaturalScrollingEnabled).thenReturn(true) dragDownHelper = DragDownHelper( - falsingManager, - falsingCollector, - dragDownloadCallback, - naturalScrollingSettingObserver, - FakeShadeRepository(), - mContext, + falsingManager, + dragDownloadCallback, + naturalScrollingSettingObserver, + FakeShadeRepository(), + mContext, ).also { it.expandCallback = expandCallback } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt index 3efcf7b7c26b..0933425d2405 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt @@ -5,10 +5,10 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest -import com.android.systemui.SysUITestModule -import com.android.systemui.TestMocksModule import com.android.systemui.ExpandHelper +import com.android.systemui.SysUITestModule import com.android.systemui.SysuiTestCase +import com.android.systemui.TestMocksModule import com.android.systemui.classifier.FalsingCollectorFake import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.dagger.SysUISingleton @@ -19,7 +19,7 @@ import com.android.systemui.media.controls.ui.MediaHierarchyManager import com.android.systemui.plugins.qs.QS import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.res.R -import com.android.systemui.shade.ShadeViewController +import com.android.systemui.shade.ShadeLockscreenInteractor import com.android.systemui.shade.data.repository.FakeShadeRepository import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel @@ -60,8 +60,8 @@ import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.Mockito.verifyZeroInteractions -import org.mockito.Mockito.`when` as whenever import org.mockito.junit.MockitoJUnit +import org.mockito.Mockito.`when` as whenever private fun <T> anyObject(): T { return Mockito.anyObject<T>() @@ -94,7 +94,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { @Mock lateinit var qS: QS @Mock lateinit var qsTransitionController: LockscreenShadeQsTransitionController @Mock lateinit var scrimController: ScrimController - @Mock lateinit var shadeViewController: ShadeViewController + @Mock lateinit var shadeLockscreenInteractor: ShadeLockscreenInteractor @Mock lateinit var singleShadeOverScroller: SingleShadeLockScreenOverScroller @Mock lateinit var splitShadeOverScroller: SplitShadeLockScreenOverScroller @Mock lateinit var stackscroller: NotificationStackScrollLayout @@ -167,7 +167,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { keyguardTransitionControllerFactory = { notificationPanelController -> LockscreenShadeKeyguardTransitionController( mediaHierarchyManager = mediaHierarchyManager, - notificationPanelController = notificationPanelController, + shadeLockscreenInteractor = notificationPanelController, context = context, configurationController = configurationController, dumpManager = mock(), @@ -186,13 +186,12 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { qsTransitionControllerFactory = { qsTransitionController }, shadeRepository = testComponent.shadeRepository, shadeInteractor = testComponent.shadeInteractor, - powerInteractor = testComponent.powerInteractor, splitShadeStateController = ResourcesSplitShadeStateController(), + shadeLockscreenInteractorLazy = {shadeLockscreenInteractor}, naturalScrollingSettingObserver = naturalScrollingSettingObserver, ) transitionController.addCallback(transitionControllerCallback) - transitionController.shadeViewController = shadeViewController transitionController.centralSurfaces = centralSurfaces transitionController.qS = qS transitionController.setStackScroller(nsslController) @@ -286,7 +285,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { fun testGoToLockedShadeCreatesQSAnimation() { transitionController.goToLockedShade(null) verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED) - verify(shadeViewController).transitionToExpandedShade(anyLong()) + verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong()) assertNotNull(transitionController.dragDownAnimator) } @@ -294,7 +293,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { fun testGoToLockedShadeDoesntCreateQSAnimation() { transitionController.goToLockedShade(null, needsQSAnimation = false) verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED) - verify(shadeViewController).transitionToExpandedShade(anyLong()) + verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong()) assertNull(transitionController.dragDownAnimator) } @@ -302,7 +301,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { fun testGoToLockedShadeAlwaysCreatesQSAnimationInSplitShade() { enableSplitShade() transitionController.goToLockedShade(null, needsQSAnimation = true) - verify(shadeViewController).transitionToExpandedShade(anyLong()) + verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong()) assertNotNull(transitionController.dragDownAnimator) } @@ -358,7 +357,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { fun setDragAmount_setsKeyguardTransitionProgress() { transitionController.dragDownAmount = 10f - verify(shadeViewController).setKeyguardTransitionProgress(anyFloat(), anyInt()) + verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(anyFloat(), anyInt()) } @Test @@ -370,7 +369,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { transitionController.dragDownAmount = 10f val expectedAlpha = 1 - 10f / alphaDistance - verify(shadeViewController).setKeyguardTransitionProgress(eq(expectedAlpha), anyInt()) + verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(eq(expectedAlpha), anyInt()) } @Test @@ -383,7 +382,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { transitionController.dragDownAmount = 10f - verify(shadeViewController).setKeyguardTransitionProgress(anyFloat(), eq(0)) + verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(anyFloat(), eq(0)) } @Test @@ -396,7 +395,8 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { transitionController.dragDownAmount = 10f - verify(shadeViewController).setKeyguardTransitionProgress(anyFloat(), eq(mediaTranslationY)) + verify(shadeLockscreenInteractor) + .setKeyguardTransitionProgress(anyFloat(), eq(mediaTranslationY)) } @Test @@ -416,7 +416,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { R.dimen.lockscreen_shade_keyguard_transition_vertical_offset ) val expectedTranslation = 10f / distance * offset - verify(shadeViewController) + verify(shadeLockscreenInteractor) .setKeyguardTransitionProgress(anyFloat(), eq(expectedTranslation.toInt())) } @@ -555,7 +555,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { transitionController.dragDownAmount = dragDownAmount val expectedAlpha = 1 - dragDownAmount / alphaDistance - verify(shadeViewController).setKeyguardStatusBarAlpha(expectedAlpha) + verify(shadeLockscreenInteractor).setKeyguardStatusBarAlpha(expectedAlpha) } @Test @@ -564,7 +564,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { transitionController.dragDownAmount = 10f - verify(shadeViewController).setKeyguardStatusBarAlpha(-1f) + verify(shadeLockscreenInteractor).setKeyguardStatusBarAlpha(-1f) } private fun enableSplitShade() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java index ccc9dc0d9618..8a48fe10d7fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java @@ -50,8 +50,8 @@ import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; -import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.res.R; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.SbnBuilder; import com.android.systemui.util.time.FakeSystemClock; @@ -280,6 +280,66 @@ public class NotificationEntryTest extends SysuiTestCase { } @Test + public void testIsNotificationVisibilityPrivate_true() { + assertTrue(mEntry.isNotificationVisibilityPrivate()); + } + + @Test + public void testIsNotificationVisibilityPrivate_visibilityPublic_false() { + Notification.Builder notification = new Notification.Builder(mContext, "") + .setVisibility(Notification.VISIBILITY_PUBLIC) + .setSmallIcon(R.drawable.ic_person) + .setContentTitle("Title") + .setContentText("Text"); + + NotificationEntry entry = new NotificationEntryBuilder() + .setPkg(TEST_PACKAGE_NAME) + .setOpPkg(TEST_PACKAGE_NAME) + .setUid(TEST_UID) + .setChannel(mChannel) + .setId(mId++) + .setNotification(notification.build()) + .setUser(new UserHandle(ActivityManager.getCurrentUser())) + .build(); + + assertFalse(entry.isNotificationVisibilityPrivate()); + } + + @Test + public void testIsChannelVisibilityPrivate_true() { + assertTrue(mEntry.isChannelVisibilityPrivate()); + } + + @Test + public void testIsChannelVisibilityPrivate_visibilityPublic_false() { + NotificationChannel channel = + new NotificationChannel("id", "name", NotificationChannel.USER_LOCKED_IMPORTANCE); + channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); + StatusBarNotification sbn = new SbnBuilder().build(); + Ranking ranking = new RankingBuilder() + .setChannel(channel) + .setKey(sbn.getKey()) + .build(); + NotificationEntry entry = + new NotificationEntry(sbn, ranking, mClock.uptimeMillis()); + + assertFalse(entry.isChannelVisibilityPrivate()); + } + + @Test + public void testIsChannelVisibilityPrivate_entryHasNoChannel_false() { + StatusBarNotification sbn = new SbnBuilder().build(); + Ranking ranking = new RankingBuilder() + .setChannel(null) + .setKey(sbn.getKey()) + .build(); + NotificationEntry entry = + new NotificationEntry(sbn, ranking, mClock.uptimeMillis()); + + assertFalse(entry.isChannelVisibilityPrivate()); + } + + @Test public void notificationDataEntry_testIsLastMessageFromReply() { Person.Builder person = new Person.Builder() .setName("name") diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt index 3f3de009fb04..fa669fc222f5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt @@ -105,7 +105,7 @@ class RowAppearanceCoordinatorTest : SysuiTestCase() { @Test fun testSetLastAudiblyAlerted() { afterRenderEntryListener.onAfterRenderEntry(entry1, controller1) - verify(controller1).setLastAudiblyAlertedMs(eq(17.toLong())) + verify(controller1).setLastAudibleMs(eq(17.toLong())) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt index 269b70fe6dfb..5e8b62e799c1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt @@ -207,6 +207,72 @@ class PhoneStatusBarViewTest : SysuiTestCase() { } @Test + fun onConfigurationChanged_noRelevantChange_doesNotUpdateInsets() { + val previousInsets = + Insets.of(/* left = */ 40, /* top = */ 30, /* right = */ 20, /* bottom = */ 10) + whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) + .thenReturn(previousInsets) + context.orCreateTestableResources.overrideConfiguration(Configuration()) + view.onAttachedToWindow() + + val newInsets = Insets.NONE + whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) + .thenReturn(newInsets) + view.onConfigurationChanged(Configuration()) + + assertThat(view.paddingLeft).isEqualTo(previousInsets.left) + assertThat(view.paddingTop).isEqualTo(previousInsets.top) + assertThat(view.paddingRight).isEqualTo(previousInsets.right) + assertThat(view.paddingBottom).isEqualTo(0) + } + + @Test + fun onConfigurationChanged_densityChanged_updatesInsets() { + val previousInsets = + Insets.of(/* left = */ 40, /* top = */ 30, /* right = */ 20, /* bottom = */ 10) + whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) + .thenReturn(previousInsets) + val configuration = Configuration() + configuration.densityDpi = 123 + context.orCreateTestableResources.overrideConfiguration(configuration) + view.onAttachedToWindow() + + val newInsets = Insets.NONE + whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) + .thenReturn(newInsets) + configuration.densityDpi = 456 + view.onConfigurationChanged(configuration) + + assertThat(view.paddingLeft).isEqualTo(newInsets.left) + assertThat(view.paddingTop).isEqualTo(newInsets.top) + assertThat(view.paddingRight).isEqualTo(newInsets.right) + assertThat(view.paddingBottom).isEqualTo(0) + } + + @Test + fun onConfigurationChanged_fontScaleChanged_updatesInsets() { + val previousInsets = + Insets.of(/* left = */ 40, /* top = */ 30, /* right = */ 20, /* bottom = */ 10) + whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) + .thenReturn(previousInsets) + val configuration = Configuration() + configuration.fontScale = 1f + context.orCreateTestableResources.overrideConfiguration(configuration) + view.onAttachedToWindow() + + val newInsets = Insets.NONE + whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) + .thenReturn(newInsets) + configuration.fontScale = 2f + view.onConfigurationChanged(configuration) + + assertThat(view.paddingLeft).isEqualTo(newInsets.left) + assertThat(view.paddingTop).isEqualTo(newInsets.top) + assertThat(view.paddingRight).isEqualTo(newInsets.right) + assertThat(view.paddingBottom).isEqualTo(0) + } + + @Test fun onApplyWindowInsets_updatesLeftTopRightPaddingsBasedOnInsets() { val insets = Insets.of(/* left = */ 90, /* top = */ 10, /* right = */ 45, /* bottom = */ 50) whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index 4015361dc277..bd7406ad004b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -90,8 +90,7 @@ import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.shade.ShadeController; import com.android.systemui.shade.ShadeExpansionChangeEvent; import com.android.systemui.shade.ShadeExpansionStateManager; -import com.android.systemui.shade.ShadeViewController; -import com.android.systemui.statusbar.NotificationMediaManager; +import com.android.systemui.shade.ShadeLockscreenInteractor; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; @@ -125,7 +124,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { @Mock private LockPatternUtils mLockPatternUtils; @Mock private CentralSurfaces mCentralSurfaces; @Mock private ViewGroup mContainer; - @Mock private ShadeViewController mShadeViewController; + @Mock private ShadeLockscreenInteractor mShadeLockscreenInteractor; @Mock private BiometricUnlockController mBiometricUnlockController; @Mock private SysuiStatusBarStateController mStatusBarStateController; @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor; @@ -206,7 +205,6 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { mock(DockManager.class), mNotificationShadeWindowController, mKeyguardStateController, - mock(NotificationMediaManager.class), mKeyguardMessageAreaFactory, Optional.of(mSysUiUnfoldComponent), () -> mShadeController, @@ -234,7 +232,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { .thenReturn(mOnBackInvokedDispatcher); mStatusBarKeyguardViewManager.registerCentralSurfaces( mCentralSurfaces, - mShadeViewController, + mShadeLockscreenInteractor, new ShadeExpansionStateManager(), mBiometricUnlockController, mNotificationContainer, @@ -715,7 +713,6 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { mock(DockManager.class), mock(NotificationShadeWindowController.class), mKeyguardStateController, - mock(NotificationMediaManager.class), mKeyguardMessageAreaFactory, Optional.of(mSysUiUnfoldComponent), () -> mShadeController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt index 1dac642836c6..a2af38f77f41 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt @@ -19,17 +19,24 @@ package com.android.systemui.statusbar.policy import android.app.ActivityOptions import android.app.IActivityManager import android.app.Notification +import android.app.Notification.FLAG_FOREGROUND_SERVICE +import android.app.Notification.VISIBILITY_PRIVATE +import android.app.Notification.VISIBILITY_PUBLIC +import android.app.NotificationChannel +import android.app.NotificationManager.IMPORTANCE_HIGH +import android.app.NotificationManager.VISIBILITY_NO_OVERRIDE import android.media.projection.MediaProjectionInfo import android.media.projection.MediaProjectionManager import android.platform.test.annotations.EnableFlags import android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS -import android.service.notification.StatusBarNotification import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.server.notification.Flags import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.RankingBuilder import com.android.systemui.statusbar.notification.collection.NotificationEntry +import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.concurrency.mockExecutorHandler import com.android.systemui.util.mockito.whenever @@ -316,6 +323,25 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { assertFalse(controller.shouldProtectNotification(notificationEntry)) } + @Test + fun shouldProtectNotification_projectionActive_publicNotification_false() { + mediaProjectionCallback.onStart(mediaProjectionInfo) + + // App marked notification visibility as public + val notificationEntry = setupPublicNotificationEntry(TEST_PROJECTION_PACKAGE_NAME) + + assertFalse(controller.shouldProtectNotification(notificationEntry)) + } + + @Test + fun shouldProtectNotification_projectionActive_publicNotificationUserChannelOverride_true() { + mediaProjectionCallback.onStart(mediaProjectionInfo) + + val notificationEntry = + setupPublicNotificationEntryWithUserOverriddenChannel(TEST_PROJECTION_PACKAGE_NAME) + + assertTrue(controller.shouldProtectNotification(notificationEntry)) + } private fun setDisabledViaDeveloperOption() { globalSettings.putInt(DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS, 1) @@ -336,21 +362,50 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { private fun setupNotificationEntry( packageName: String, - isFgs: Boolean = false + isFgs: Boolean = false, + overrideVisibility: Boolean = false, + overrideChannelVisibility: Boolean = false, ): NotificationEntry { - val notificationEntry = mock(NotificationEntry::class.java) - val sbn = mock(StatusBarNotification::class.java) - val notification = mock(Notification::class.java) - whenever(notificationEntry.sbn).thenReturn(sbn) - whenever(sbn.packageName).thenReturn(packageName) - whenever(sbn.notification).thenReturn(notification) - whenever(notification.isFgsOrUij).thenReturn(isFgs) - + val notification = Notification() + if (isFgs) { + notification.flags = notification.flags or FLAG_FOREGROUND_SERVICE + } + if (overrideVisibility) { + // Developer has marked notification as public + notification.visibility = VISIBILITY_PUBLIC + } + val notificationEntry = + NotificationEntryBuilder().setNotification(notification).setPkg(packageName).build() + val channel = NotificationChannel("1", "1", IMPORTANCE_HIGH) + if (overrideChannelVisibility) { + // User doesn't allow private notifications at the channel level + channel.lockscreenVisibility = VISIBILITY_PRIVATE + } + notificationEntry.setRanking( + RankingBuilder(notificationEntry.ranking) + .setChannel(channel) + .setVisibilityOverride(VISIBILITY_NO_OVERRIDE) + .build() + ) return notificationEntry } private fun setupFgsNotificationEntry(packageName: String): NotificationEntry { - return setupNotificationEntry(packageName, /* isFgs= */ true) + return setupNotificationEntry(packageName, isFgs = true) + } + + private fun setupPublicNotificationEntry(packageName: String): NotificationEntry { + return setupNotificationEntry(packageName, overrideVisibility = true) + } + + private fun setupPublicNotificationEntryWithUserOverriddenChannel( + packageName: String + ): NotificationEntry { + return setupNotificationEntry( + packageName, + overrideVisibility = true, + overrideChannelVisibility = true + ) } companion object { diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java index 25a0bc4fba61..1a3cb87b3422 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java @@ -58,6 +58,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; import android.widget.ImageButton; +import android.widget.SeekBar; import androidx.test.core.view.MotionEventBuilder; import androidx.test.filters.SmallTest; @@ -111,6 +112,7 @@ public class VolumeDialogImplTest extends SysuiTestCase { View mDrawerVibrate; View mDrawerMute; View mDrawerNormal; + ViewGroup mDialogRowsView; CaptionsToggleImageButton mODICaptionsIcon; private TestableLooper mTestableLooper; @@ -222,6 +224,8 @@ public class VolumeDialogImplTest extends SysuiTestCase { } mODICaptionsIcon = mDialog.getDialogView().findViewById(R.id.odi_captions_icon); + mDialogRowsView = mDialog.getDialogView().findViewById(R.id.volume_dialog_rows); + Prefs.putInt(mContext, Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT, VolumePrefs.SHOW_RINGER_TOAST_COUNT + 1); @@ -671,6 +675,45 @@ public class VolumeDialogImplTest extends SysuiTestCase { } @Test + public void volumeSliderTracksTouch_logsStartAndStopTrackingUiEvents() { + UiEventLoggerFake logger = new UiEventLoggerFake(); + Events.sUiEventLogger = logger; + + mDialog.show(SHOW_REASON_UNKNOWN); + mTestableLooper.processAllMessages(); + + MotionEvent down = MotionEventBuilder.newBuilder() + .setAction(MotionEvent.ACTION_DOWN).build(); + MotionEvent up = MotionEventBuilder.newBuilder().setAction(MotionEvent.ACTION_UP).build(); + + SeekBar slider = + mDialogRowsView.getChildAt(0).findViewById(R.id.volume_row_slider); + slider.onTouchEvent(down); + slider.onTouchEvent(up); + mTestableLooper.moveTimeForward(300); + mTestableLooper.processAllMessages(); + + boolean foundStartTrackingTouch = false; + boolean foundStopTrackingTouch = false; + for (UiEventLoggerFake.FakeUiEvent event : logger.getLogs()) { + if (event.eventId + == Events.VolumeDialogEvent.VOLUME_DIALOG_SLIDER_STARTED_TRACKING_TOUCH.getId() + ) { + foundStartTrackingTouch = true; + } + if (event.eventId + == Events.VolumeDialogEvent.VOLUME_DIALOG_SLIDER_STOPPED_TRACKING_TOUCH.getId() + ) { + foundStopTrackingTouch = true; + } + } + Assert.assertTrue("Did not log the event of start tracking touch.", + foundStartTrackingTouch); + Assert.assertTrue("Did not log the event of stop tracking touch.", + foundStopTrackingTouch); + } + + @Test public void turnOnDnD_volumeSliderIconChangesToDnd() { State state = createShellState(); state.zenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS; diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java index b62b3a211e58..353d9709b056 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java @@ -46,6 +46,7 @@ import androidx.core.animation.AndroidXAnimatorIsolationRule; import androidx.test.InstrumentationRegistry; import androidx.test.uiautomator.UiDevice; +import com.android.internal.protolog.common.ProtoLog; import com.android.systemui.broadcast.FakeBroadcastDispatcher; import com.android.systemui.flags.SceneContainerRule; @@ -170,6 +171,7 @@ public abstract class SysuiTestCase { @Before public void SysuiSetup() throws Exception { + ProtoLog.REQUIRE_PROTOLOGTOOL = false; mSysuiDependency = new SysuiTestDependency(mContext, shouldFailOnLeakedReceiver()); mDependency = mSysuiDependency.install(); // TODO(b/292141694): build out Ravenwood support for Instrumentation diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt index fab64e38e1f8..4ed6fe27338a 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt @@ -2,6 +2,7 @@ package com.android.systemui.communal.data.repository import android.appwidget.AppWidgetProviderInfo import android.content.ComponentName +import android.os.UserHandle import com.android.systemui.communal.shared.model.CommunalWidgetContentModel import com.android.systemui.communal.widgets.WidgetConfigurator import kotlinx.coroutines.CoroutineScope @@ -23,6 +24,7 @@ class FakeCommunalWidgetRepository(private val coroutineScope: CoroutineScope) : override fun addWidget( provider: ComponentName, + user: UserHandle, priority: Int, configurator: WidgetConfigurator? ) { diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt index 97f84c67f473..43897c985c2c 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt @@ -18,7 +18,7 @@ package com.android.systemui.flags import android.platform.test.annotations.EnableFlags import com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR -import com.android.systemui.Flags.FLAG_KEYGUARD_SHADE_MIGRATION_NSSL +import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT import com.android.systemui.Flags.FLAG_MEDIA_IN_SCENE_CONTAINER import com.android.systemui.Flags.FLAG_SCENE_CONTAINER @@ -29,7 +29,7 @@ import com.android.systemui.Flags.FLAG_SCENE_CONTAINER @EnableFlags( FLAG_SCENE_CONTAINER, FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR, - FLAG_KEYGUARD_SHADE_MIGRATION_NSSL, + FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT, FLAG_MEDIA_IN_SCENE_CONTAINER, ) @Retention(AnnotationRetention.RUNTIME) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/MediaKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/MediaKosmos.kt new file mode 100644 index 000000000000..e1b1966aed6c --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/MediaKosmos.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.media + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.media.dialog.MediaOutputDialogFactory +import com.android.systemui.util.mockito.mock + +var Kosmos.mediaOutputDialogFactory: MediaOutputDialogFactory by Kosmos.Fixture { mock {} } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt index 82e0b8e83f24..f4acf4d8fb53 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt @@ -73,7 +73,7 @@ val Kosmos.shadeControllerImpl by deviceProvisionedController, mock<NotificationShadeWindowController>(), mock<WindowManager>(), - { mock<ShadeViewController>() }, + { mock<NotificationPanelViewController>() }, { mock<AssistManager>() }, { mock<NotificationGutsManager>() }, ) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorKosmos.kt new file mode 100644 index 000000000000..4221d06e27ed --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorKosmos.kt @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shade.domain.interactor + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testScope +import com.android.systemui.scene.domain.interactor.sceneInteractor +import com.android.systemui.util.mockito.mock + +val Kosmos.shadeLockscreenInteractor by + Kosmos.Fixture { + ShadeLockscreenInteractorImpl( + scope = testScope, + shadeInteractor = shadeInteractorImpl, + sceneInteractor = sceneInteractor, + lockIconViewController = mock(), + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerKosmos.kt index 1c6ce7987cd5..81888c48488a 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerKosmos.kt @@ -26,9 +26,9 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.media.controls.ui.mediaHierarchyManager import com.android.systemui.plugins.activityStarter -import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.domain.interactor.shadeInteractor +import com.android.systemui.shade.domain.interactor.shadeLockscreenInteractor import com.android.systemui.statusbar.notification.stack.ambientState import com.android.systemui.statusbar.phone.keyguardBypassController import com.android.systemui.statusbar.phone.lsShadeTransitionLogger @@ -58,8 +58,8 @@ val Kosmos.lockscreenShadeTransitionController by Fixture { qsTransitionControllerFactory = lockscreenShadeQsTransitionControllerFactory, shadeRepository = shadeRepository, shadeInteractor = shadeInteractor, - powerInteractor = powerInteractor, splitShadeStateController = splitShadeStateController, + shadeLockscreenInteractorLazy = { shadeLockscreenInteractor }, naturalScrollingSettingObserver = naturalScrollingSettingObserver, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt new file mode 100644 index 000000000000..3f20df3376d9 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/MediaOutputKosmos.kt @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume + +import android.content.packageManager +import android.content.pm.ApplicationInfo +import android.media.session.MediaController +import android.os.Handler +import android.testing.TestableLooper +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testCase +import com.android.systemui.kosmos.testScope +import com.android.systemui.media.mediaOutputDialogFactory +import com.android.systemui.plugins.activityStarter +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.mock +import com.android.systemui.util.mockito.whenever +import com.android.systemui.volume.data.repository.FakeLocalMediaRepository +import com.android.systemui.volume.data.repository.FakeMediaControllerRepository +import com.android.systemui.volume.panel.component.mediaoutput.data.repository.FakeLocalMediaRepositoryFactory +import com.android.systemui.volume.panel.component.mediaoutput.data.repository.LocalMediaRepositoryFactory +import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputActionsInteractor +import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor + +var Kosmos.mediaController: MediaController by Kosmos.Fixture { mock {} } + +val Kosmos.localMediaRepository by Kosmos.Fixture { FakeLocalMediaRepository() } +val Kosmos.localMediaRepositoryFactory: LocalMediaRepositoryFactory by + Kosmos.Fixture { FakeLocalMediaRepositoryFactory { localMediaRepository } } + +val Kosmos.mediaOutputActionsInteractor by + Kosmos.Fixture { MediaOutputActionsInteractor(mediaOutputDialogFactory, activityStarter) } +val Kosmos.mediaControllerRepository by Kosmos.Fixture { FakeMediaControllerRepository() } +val Kosmos.mediaOutputInteractor by + Kosmos.Fixture { + MediaOutputInteractor( + localMediaRepositoryFactory, + packageManager.apply { + val appInfo: ApplicationInfo = mock { + whenever(loadLabel(any())).thenReturn("test_label") + } + whenever(getApplicationInfo(any(), any<Int>())).thenReturn(appInfo) + }, + testScope.backgroundScope, + testScope.testScheduler, + Handler(TestableLooper.get(testCase).looper), + mediaControllerRepository, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/VolumeKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/VolumeKosmos.kt new file mode 100644 index 000000000000..5e1f85c70a1b --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/VolumeKosmos.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume + +import com.android.settingslib.volume.domain.interactor.AudioModeInteractor +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.volume.data.repository.FakeAudioRepository + +val Kosmos.audioRepository by Kosmos.Fixture { FakeAudioRepository() } +val Kosmos.audioModeInteractor by Kosmos.Fixture { AudioModeInteractor(audioRepository) } diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt index dddf8e82d5f7..fed3e171862d 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.android.settingslib.volume.data.repository +package com.android.systemui.volume.data.repository import android.media.AudioDeviceInfo +import com.android.settingslib.volume.data.repository.AudioRepository import com.android.settingslib.volume.shared.model.AudioStream import com.android.settingslib.volume.shared.model.AudioStreamModel import com.android.settingslib.volume.shared.model.RingerMode diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeLocalMediaRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeLocalMediaRepository.kt index 642b72c70e55..7835fc89ea52 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeLocalMediaRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeLocalMediaRepository.kt @@ -1,23 +1,24 @@ /* * Copyright (C) 2024 The Android Open Source Project * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 + * 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. + * 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.settingslib.volume.data.repository +package com.android.systemui.volume.data.repository import com.android.settingslib.media.MediaDevice import com.android.settingslib.volume.data.model.RoutingSession +import com.android.settingslib.volume.data.repository.LocalMediaRepository import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeMediaControllerRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeMediaControllerRepository.kt new file mode 100644 index 000000000000..6d52e525d238 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeMediaControllerRepository.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.data.repository + +import android.media.session.MediaController +import com.android.settingslib.volume.data.repository.MediaControllerRepository +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +class FakeMediaControllerRepository : MediaControllerRepository { + + private val mutableActiveLocalMediaController = MutableStateFlow<MediaController?>(null) + override val activeLocalMediaController: StateFlow<MediaController?> = + mutableActiveLocalMediaController.asStateFlow() + + fun setActiveLocalMediaController(controller: MediaController?) { + mutableActiveLocalMediaController.value = controller + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/MediaOutputComponentKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/MediaOutputComponentKosmos.kt new file mode 100644 index 000000000000..ad8ccb00f45f --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/MediaOutputComponentKosmos.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.media.mediaOutputDialogFactory +import com.android.systemui.plugins.activityStarter +import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputActionsInteractor + +val Kosmos.mediaOutputActionsInteractor by + Kosmos.Fixture { MediaOutputActionsInteractor(mediaOutputDialogFactory, activityStarter) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/data/repository/FakeLocalMediaRepositoryFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/data/repository/FakeLocalMediaRepositoryFactory.kt new file mode 100644 index 000000000000..1b3480c423e4 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/data/repository/FakeLocalMediaRepositoryFactory.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.volume.panel.component.mediaoutput.data.repository + +import com.android.settingslib.volume.data.repository.LocalMediaRepository + +class FakeLocalMediaRepositoryFactory( + val provider: (packageName: String?) -> LocalMediaRepository +) : LocalMediaRepositoryFactory { + + override fun create(packageName: String?): LocalMediaRepository = provider(packageName) +} diff --git a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java index c134a4c5b2ad..d8a94d8b8b59 100644 --- a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java +++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java @@ -1204,23 +1204,26 @@ public class CameraExtensionsProxyService extends Service { List<Pair<CameraCharacteristics.Key, Object>> entries = mAdvancedExtender.getAvailableCharacteristicsKeyValues(); - if ((entries != null) && !entries.isEmpty()) { - CameraMetadataNative ret = new CameraMetadataNative(); - long vendorId = mMetadataVendorIdMap.containsKey(cameraId) - ? mMetadataVendorIdMap.get(cameraId) : Long.MAX_VALUE; - ret.setVendorId(vendorId); - int[] characteristicsKeyTags = new int[entries.size()]; - int i = 0; - for (Pair<CameraCharacteristics.Key, Object> entry : entries) { - int tag = CameraMetadataNative.getTag(entry.first.getName(), vendorId); - characteristicsKeyTags[i++] = tag; - ret.set(entry.first, entry.second); - } - ret.set(CameraCharacteristics.REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, - characteristicsKeyTags); + if (entries == null || entries.isEmpty()) { + throw new RuntimeException("A valid set of key/value pairs are required that " + + "are supported by the extension."); + } - return ret; + CameraMetadataNative ret = new CameraMetadataNative(); + long vendorId = mMetadataVendorIdMap.containsKey(cameraId) + ? mMetadataVendorIdMap.get(cameraId) : Long.MAX_VALUE; + ret.setVendorId(vendorId); + int[] characteristicsKeyTags = new int[entries.size()]; + int i = 0; + for (Pair<CameraCharacteristics.Key, Object> entry : entries) { + int tag = CameraMetadataNative.getTag(entry.first.getName(), vendorId); + characteristicsKeyTags[i++] = tag; + ret.set(entry.first, entry.second); } + ret.set(CameraCharacteristics.REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, + characteristicsKeyTags); + + return ret; } return null; diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java index 7b5932b42b84..1d5c79cf10a6 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java @@ -16,6 +16,8 @@ package android.platform.test.ravenwood; +import static org.junit.Assert.assertFalse; + import android.app.ActivityManager; import android.app.Instrumentation; import android.os.Build; @@ -28,12 +30,19 @@ import androidx.test.platform.app.InstrumentationRegistry; import com.android.internal.os.RuntimeInit; +import org.junit.After; import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; import org.junit.runner.Description; import org.junit.runner.RunWith; import org.junit.runners.model.Statement; import java.io.PrintStream; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.Executors; @@ -183,6 +192,7 @@ public class RavenwoodRuleImpl { public static void validate(Statement base, Description description, boolean enableOptionalValidation) { validateTestRunner(base, description, enableOptionalValidation); + validateTestAnnotations(base, description, enableOptionalValidation); } private static void validateTestRunner(Statement base, Description description, @@ -206,4 +216,63 @@ public class RavenwoodRuleImpl { } } } + + private static void validateTestAnnotations(Statement base, Description description, + boolean enableOptionalValidation) { + final var testClass = description.getTestClass(); + + final var message = new StringBuilder(); + + boolean hasErrors = false; + for (Method m : collectMethods(testClass)) { + if (Modifier.isPublic(m.getModifiers()) && m.getName().startsWith("test")) { + if (m.getAnnotation(Test.class) == null) { + message.append("\nMethod " + m.getName() + "() doesn't have @Test"); + hasErrors = true; + } + } + if ("setUp".equals(m.getName())) { + if (m.getAnnotation(Before.class) == null) { + message.append("\nMethod " + m.getName() + "() doesn't have @Before"); + hasErrors = true; + } + if (!Modifier.isPublic(m.getModifiers())) { + message.append("\nMethod " + m.getName() + "() must be public"); + hasErrors = true; + } + } + if ("tearDown".equals(m.getName())) { + if (m.getAnnotation(After.class) == null) { + message.append("\nMethod " + m.getName() + "() doesn't have @After"); + hasErrors = true; + } + if (!Modifier.isPublic(m.getModifiers())) { + message.append("\nMethod " + m.getName() + "() must be public"); + hasErrors = true; + } + } + } + assertFalse("Problem(s) detected in class " + testClass.getCanonicalName() + ":" + + message, hasErrors); + } + + /** + * Collect all (public or private or any) methods in a class, including inherited methods. + */ + private static List<Method> collectMethods(Class<?> clazz) { + var ret = new ArrayList<Method>(); + collectMethods(clazz, ret); + return ret; + } + + private static void collectMethods(Class<?> clazz, List<Method> result) { + // Class.getMethods() only return public methods, so we need to use getDeclaredMethods() + // instead, and recurse. + for (var m : clazz.getDeclaredMethods()) { + result.add(m); + } + if (clazz.getSuperclass() != null) { + collectMethods(clazz.getSuperclass(), result); + } + } } diff --git a/ravenwood/run-ravenwood-tests.sh b/ravenwood/run-ravenwood-tests.sh index 3f4b8a79e864..259aa702452d 100755 --- a/ravenwood/run-ravenwood-tests.sh +++ b/ravenwood/run-ravenwood-tests.sh @@ -13,10 +13,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Run all the ravenwood tests. +# Run all the ravenwood tests + hoststubgen unit tests. + +all_tests="hoststubgentest tiny-framework-dump-test hoststubgen-invoke-test" # "echo" is to remove the newlines -all_tests=$(echo $(${0%/*}/list-ravenwood-tests.sh) ) +all_tests="$all_tests $(echo $(${0%/*}/list-ravenwood-tests.sh) )" echo "Running tests: $all_tests" atest $all_tests diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 5407af7bda44..18e11bab3c54 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -327,10 +327,13 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku synchronized (mLock) { // No need to enforce unlocked state when there is no caller. User can be in the // stopping state or removed by the time the message is processed + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "convert_state_to_bytes"); ensureGroupStateLoadedLocked(userId, false /* enforceUserUnlockingOrUnlocked */); userIdToBytesMapping = saveStateToByteArrayLocked(userId); + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "byte_to_disk_io"); for (int i = 0; i < userIdToBytesMapping.size(); i++) { int currentProfileId = userIdToBytesMapping.keyAt(i); byte[] currentStateByteArray = userIdToBytesMapping.valueAt(i); @@ -351,6 +354,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku currentFile.failWrite(fileStream); } } + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); return true; } @@ -4787,8 +4791,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku synchronized (mLock) { // No need to enforce unlocked state when there is no caller. User can be in the // stopping state or removed by the time the message is processed + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "convert_state_and_io"); ensureGroupStateLoadedLocked(mUserId, false /* enforceUserUnlockingOrUnlocked */ ); saveStateLocked(mUserId); + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 96c65565c96b..d47245eb2272 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -5108,12 +5108,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } } } else if (resultCode == FAILURE_CREDMAN_SELECTOR) { - GetCredentialException exception = resultData.getParcelable( - CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION, - GetCredentialException.class); - Slog.d(TAG, "Credman bottom sheet from pinned " - + "entry failed with: + " + exception.getType() + " , " - + exception.getMessage()); + String[] exception = resultData.getStringArray( + CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION); + if (exception != null && exception.length >= 2) { + Slog.w(TAG, "Credman bottom sheet from pinned " + + "entry failed with: + " + exception[0] + " , " + + exception[1]); + } } else { Slog.d(TAG, "Unknown resultCode from credential " + "manager bottom sheet: " + resultCode); diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index b43f1a93f183..ba1f51baa624 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -40,6 +40,7 @@ import static com.android.internal.util.Preconditions.checkState; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import static com.android.server.companion.AssociationStore.CHANGE_TYPE_UPDATED_ADDRESS_UNCHANGED; import static com.android.server.companion.MetricUtils.logRemoveAssociation; +import static com.android.server.companion.PackageUtils.isRestrictedSettingsAllowed; import static com.android.server.companion.PackageUtils.enforceUsesCompanionDeviceFeature; import static com.android.server.companion.PackageUtils.getPackageInfo; import static com.android.server.companion.PermissionsUtils.checkCallerCanManageCompanionDevice; @@ -871,13 +872,22 @@ public class CompanionDeviceManagerService extends SystemService { @Override public PendingIntent requestNotificationAccess(ComponentName component, int userId) throws RemoteException { - String callingPackage = component.getPackageName(); + int callingUid = getCallingUid(); + final String callingPackage = component.getPackageName(); + checkCanCallNotificationApi(callingPackage, userId); + if (component.flattenToString().length() > MAX_CN_LENGTH) { throw new IllegalArgumentException("Component name is too long."); } + final long identity = Binder.clearCallingIdentity(); try { + if (!isRestrictedSettingsAllowed(getContext(), callingPackage, callingUid)) { + Slog.e(TAG, "Side loaded app must enable restricted " + + "setting before request the notification access"); + return null; + } return PendingIntent.getActivityAsUser(getContext(), 0 /* request code */, NotificationAccessConfirmationActivityContract.launcherIntent( diff --git a/services/companion/java/com/android/server/companion/PackageUtils.java b/services/companion/java/com/android/server/companion/PackageUtils.java index 6c77018de27b..3aae1ec99f55 100644 --- a/services/companion/java/com/android/server/companion/PackageUtils.java +++ b/services/companion/java/com/android/server/companion/PackageUtils.java @@ -28,6 +28,7 @@ import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.app.AppOpsManager; import android.companion.CompanionDeviceService; import android.content.ComponentName; import android.content.Context; @@ -222,4 +223,15 @@ public final class PackageUtils { return requestingPackageSignatureAllowlisted; } + + /** + * Check if restricted settings is enabled for a side-loaded app. + */ + public static boolean isRestrictedSettingsAllowed( + Context context, String packageName, int uid) { + final int mode = context.getSystemService(AppOpsManager.class).noteOpNoThrow( + AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, uid, + packageName, /* attributionTag= */ null, /* message= */ null); + return mode == AppOpsManager.MODE_ALLOWED; + } } diff --git a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java index 6ce471e635cd..fff283dd41bc 100644 --- a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java +++ b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java @@ -16,10 +16,9 @@ package com.android.server; +import static android.permission.flags.Flags.sensitiveNotificationAppProtection; import static android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS; - import static com.android.internal.util.Preconditions.checkNotNull; -import static com.android.server.notification.Flags.sensitiveNotificationAppProtection; import android.annotation.NonNull; import android.annotation.Nullable; diff --git a/services/core/java/com/android/server/adaptiveauth/AdaptiveAuthService.java b/services/core/java/com/android/server/adaptiveauth/AdaptiveAuthService.java new file mode 100644 index 000000000000..3312be231516 --- /dev/null +++ b/services/core/java/com/android/server/adaptiveauth/AdaptiveAuthService.java @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.adaptiveauth; + +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST; + +import android.app.KeyguardManager; +import android.content.Context; +import android.hardware.biometrics.AuthenticationStateListener; +import android.hardware.biometrics.BiometricManager; +import android.hardware.biometrics.BiometricSourceType; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.PowerManager; +import android.os.SystemClock; +import android.util.Log; +import android.util.Slog; +import android.util.SparseIntArray; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.widget.LockPatternUtils; +import com.android.internal.widget.LockSettingsInternal; +import com.android.internal.widget.LockSettingsStateListener; +import com.android.server.LocalServices; +import com.android.server.SystemService; +import com.android.server.pm.UserManagerInternal; +import com.android.server.wm.WindowManagerInternal; + +import java.util.Objects; + +/** + * @hide + */ +public class AdaptiveAuthService extends SystemService { + private static final String TAG = "AdaptiveAuthService"; + private static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.DEBUG); + + @VisibleForTesting + static final int MAX_ALLOWED_FAILED_AUTH_ATTEMPTS = 5; + private static final int MSG_REPORT_PRIMARY_AUTH_ATTEMPT = 1; + private static final int MSG_REPORT_BIOMETRIC_AUTH_ATTEMPT = 2; + private static final int AUTH_SUCCESS = 1; + private static final int AUTH_FAILURE = 0; + + private final LockPatternUtils mLockPatternUtils; + private final LockSettingsInternal mLockSettings; + private final BiometricManager mBiometricManager; + private final KeyguardManager mKeyguardManager; + private final PowerManager mPowerManager; + private final WindowManagerInternal mWindowManager; + private final UserManagerInternal mUserManager; + @VisibleForTesting + final SparseIntArray mFailedAttemptsForUser = new SparseIntArray(); + + public AdaptiveAuthService(Context context) { + this(context, new LockPatternUtils(context)); + } + + @VisibleForTesting + public AdaptiveAuthService(Context context, LockPatternUtils lockPatternUtils) { + super(context); + mLockPatternUtils = lockPatternUtils; + mLockSettings = Objects.requireNonNull( + LocalServices.getService(LockSettingsInternal.class)); + mBiometricManager = Objects.requireNonNull( + context.getSystemService(BiometricManager.class)); + mKeyguardManager = Objects.requireNonNull(context.getSystemService(KeyguardManager.class)); + mPowerManager = Objects.requireNonNull(context.getSystemService(PowerManager.class)); + mWindowManager = Objects.requireNonNull( + LocalServices.getService(WindowManagerInternal.class)); + mUserManager = Objects.requireNonNull(LocalServices.getService(UserManagerInternal.class)); + } + + @Override + public void onStart() {} + + @Override + public void onBootPhase(int phase) { + if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { + init(); + } + } + + @VisibleForTesting + void init() { + mLockSettings.registerLockSettingsStateListener(mLockSettingsStateListener); + mBiometricManager.registerAuthenticationStateListener(mAuthenticationStateListener); + } + + private final LockSettingsStateListener mLockSettingsStateListener = + new LockSettingsStateListener() { + @Override + public void onAuthenticationSucceeded(int userId) { + if (DEBUG) { + Slog.d(TAG, "LockSettingsStateListener#onAuthenticationSucceeded"); + } + mHandler.obtainMessage(MSG_REPORT_PRIMARY_AUTH_ATTEMPT, AUTH_SUCCESS, userId) + .sendToTarget(); + } + + @Override + public void onAuthenticationFailed(int userId) { + Slog.i(TAG, "LockSettingsStateListener#onAuthenticationFailed"); + mHandler.obtainMessage(MSG_REPORT_PRIMARY_AUTH_ATTEMPT, AUTH_FAILURE, userId) + .sendToTarget(); + } + }; + + private final AuthenticationStateListener mAuthenticationStateListener = + new AuthenticationStateListener.Stub() { + @Override + public void onAuthenticationStarted(int requestReason) {} + + @Override + public void onAuthenticationStopped() {} + + @Override + public void onAuthenticationSucceeded(int requestReason, int userId) { + if (DEBUG) { + Slog.d(TAG, "AuthenticationStateListener#onAuthenticationSucceeded"); + } + mHandler.obtainMessage(MSG_REPORT_BIOMETRIC_AUTH_ATTEMPT, AUTH_SUCCESS, userId) + .sendToTarget(); + } + + @Override + public void onAuthenticationFailed(int requestReason, int userId) { + Slog.i(TAG, "AuthenticationStateListener#onAuthenticationFailed"); + mHandler.obtainMessage(MSG_REPORT_BIOMETRIC_AUTH_ATTEMPT, AUTH_FAILURE, userId) + .sendToTarget(); + } + + @Override + public void onAuthenticationAcquired(BiometricSourceType biometricSourceType, + int requestReason, int acquiredInfo) {} + }; + + private final Handler mHandler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_REPORT_PRIMARY_AUTH_ATTEMPT: + handleReportPrimaryAuthAttempt(msg.arg1 != AUTH_FAILURE, msg.arg2); + break; + case MSG_REPORT_BIOMETRIC_AUTH_ATTEMPT: + handleReportBiometricAuthAttempt(msg.arg1 != AUTH_FAILURE, msg.arg2); + break; + } + } + }; + + private void handleReportPrimaryAuthAttempt(boolean success, int userId) { + if (DEBUG) { + Slog.d(TAG, "handleReportPrimaryAuthAttempt: success=" + success + + ", userId=" + userId); + } + reportAuthAttempt(success, userId); + } + + private void handleReportBiometricAuthAttempt(boolean success, int userId) { + if (DEBUG) { + Slog.d(TAG, "handleReportBiometricAuthAttempt: success=" + success + + ", userId=" + userId); + } + reportAuthAttempt(success, userId); + } + + private void reportAuthAttempt(boolean success, int userId) { + if (success) { + // Deleting the entry effectively resets the counter of failed attempts for the user + mFailedAttemptsForUser.delete(userId); + return; + } + + final int numFailedAttempts = mFailedAttemptsForUser.get(userId, 0) + 1; + Slog.i(TAG, "reportAuthAttempt: numFailedAttempts=" + numFailedAttempts + + ", userId=" + userId); + mFailedAttemptsForUser.put(userId, numFailedAttempts); + + // Don't lock again if the device is already locked and if Keyguard is already showing and + // isn't trivially dismissible + if (mKeyguardManager.isDeviceLocked(userId) && mKeyguardManager.isKeyguardLocked()) { + Slog.d(TAG, "Not locking the device because the device is already locked."); + return; + } + + if (numFailedAttempts < MAX_ALLOWED_FAILED_AUTH_ATTEMPTS) { + Slog.d(TAG, "Not locking the device because the number of failed attempts is below" + + " the threshold."); + return; + } + + //TODO: additionally consider the trust signal before locking device + lockDevice(userId); + } + + /** + * Locks the device and requires primary auth or biometric auth for unlocking + */ + private void lockDevice(int userId) { + // Require either primary auth or biometric auth to unlock the device again. Keyguard and + // bouncer will also check the StrongAuthFlag for the user to display correct strings for + // explaining why the device is locked + mLockPatternUtils.requireStrongAuth(SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST, userId); + + // If userId is a profile that has a different parent userId (regardless of its profile + // type, or whether it's a profile with unified challenges or not), its parent userId that + // owns the Keyguard will also be locked + final int parentUserId = mUserManager.getProfileParentId(userId); + Slog.i(TAG, "lockDevice: userId=" + userId + ", parentUserId=" + parentUserId); + if (parentUserId != userId) { + mLockPatternUtils.requireStrongAuth(SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST, + parentUserId); + } + + // Power off the display + mPowerManager.goToSleep(SystemClock.uptimeMillis()); + + // Lock the device + mWindowManager.lockNow(); + } +} diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 7d82f0c2a63e..df46e5dafce8 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -19,6 +19,7 @@ package com.android.server.am; import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL; import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL_IMPLICIT; import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL; +import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; @@ -67,7 +68,10 @@ import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UNBIND_SERVICE; import static android.content.Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION; +import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE; +import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL; +import static android.media.audio.Flags.foregroundAudioControl; import static android.os.Process.SCHED_OTHER; import static android.os.Process.THREAD_GROUP_BACKGROUND; import static android.os.Process.THREAD_GROUP_DEFAULT; @@ -2266,6 +2270,15 @@ public class OomAdjuster { (fgsType & FOREGROUND_SERVICE_TYPE_LOCATION) != 0 ? PROCESS_CAPABILITY_FOREGROUND_LOCATION : 0; + if (foregroundAudioControl()) { // flag check + final int fgsAudioType = FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK + | FOREGROUND_SERVICE_TYPE_CAMERA + | FOREGROUND_SERVICE_TYPE_MICROPHONE + | FOREGROUND_SERVICE_TYPE_PHONE_CALL; + capabilityFromFGS |= (psr.getForegroundServiceTypes() & fgsAudioType) != 0 + ? PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL : 0; + } + final boolean enabled = state.getCachedCompatChange( CACHED_COMPAT_CHANGE_CAMERA_MICROPHONE_CAPABILITY); if (enabled) { diff --git a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java index f85b03e8b4eb..1bf779adcce1 100644 --- a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java +++ b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java @@ -722,14 +722,8 @@ public class OomAdjusterModernImpl extends OomAdjuster { performNewUpdateOomAdjLSP(oomAdjReason, topApp, targetProcesses, activeUids, fullUpdate, now, UNKNOWN_ADJ); - if (fullUpdate) { - assignCachedAdjIfNecessary(mProcessList.getLruProcessesLOSP()); - } else { - activeProcesses.clear(); - activeProcesses.addAll(targetProcesses); - assignCachedAdjIfNecessary(activeProcesses); - activeProcesses.clear(); - } + // TODO: b/319163103 - optimize cache adj assignment to not require the whole lru list. + assignCachedAdjIfNecessary(mProcessList.getLruProcessesLOSP()); postUpdateOomAdjInnerLSP(oomAdjReason, activeUids, now, nowElapsed, oldTime); targetProcesses.clear(); @@ -996,11 +990,11 @@ public class OomAdjusterModernImpl extends OomAdjuster { && service.mState.getMaxAdj() < FOREGROUND_APP_ADJ) || (service.mState.getCurAdj() <= FOREGROUND_APP_ADJ && service.mState.getCurrentSchedulingGroup() > SCHED_GROUP_BACKGROUND - && service.mState.getCurProcState() <= PROCESS_STATE_TOP)) { + && service.mState.getCurProcState() <= PROCESS_STATE_TOP) + || (service.isSdkSandbox && cr.binding.attributedClient != null)) { continue; } - computeServiceHostOomAdjLSP(cr, service, app, now, topApp, fullUpdate, false, false, oomAdjReason, cachedAdj, false, false); } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index d23d9fb16d6c..9883f091deef 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -1678,7 +1678,11 @@ class ProcessRecord implements WindowProcessListener { final ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(j); for (int k = clist.size() - 1; k >= 0; k--) { final ConnectionRecord cr = clist.get(k); - consumer.accept(cr.binding.client); + if (isSdkSandbox && cr.binding.attributedClient != null) { + consumer.accept(cr.binding.attributedClient); + } else { + consumer.accept(cr.binding.client); + } } } } @@ -1689,25 +1693,5 @@ class ProcessRecord implements WindowProcessListener { consumer.accept(conn.client); } } - // If this process is a sandbox itself, also add the app on whose behalf - // its running - if (isSdkSandbox) { - for (int is = mServices.numberOfRunningServices() - 1; is >= 0; is--) { - ServiceRecord s = mServices.getRunningServiceAt(is); - ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = - s.getConnections(); - for (int conni = serviceConnections.size() - 1; conni >= 0; conni--) { - ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni); - for (int i = clist.size() - 1; i >= 0; i--) { - ConnectionRecord cr = clist.get(i); - ProcessRecord attributedApp = cr.binding.attributedClient; - if (attributedApp == null || attributedApp == this) { - continue; - } - consumer.accept(attributedApp); - } - } - } - } } } diff --git a/services/core/java/com/android/server/am/ProcessServiceRecord.java b/services/core/java/com/android/server/am/ProcessServiceRecord.java index 57d233e7c503..562beaf50a7f 100644 --- a/services/core/java/com/android/server/am/ProcessServiceRecord.java +++ b/services/core/java/com/android/server/am/ProcessServiceRecord.java @@ -205,10 +205,10 @@ final class ProcessServiceRecord { } /** - * Returns the FGS typps, but it doesn't tell if the types include "NONE" or not, so - * do not use it outside of this class. + * Returns the FGS types, but it doesn't tell if the types include "NONE" or not, use + * {@link #hasForegroundServices()} */ - private int getForegroundServiceTypes() { + int getForegroundServiceTypes() { return mHasForegroundServices ? mFgServiceTypes : 0; } diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 55ac4cf37283..34ba7f0debb0 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -97,6 +97,7 @@ import android.os.IProgressListener; import android.os.IRemoteCallback; import android.os.IUserManager; import android.os.Message; +import android.os.PowerManagerInternal; import android.os.PowerWhitelistManager; import android.os.Process; import android.os.RemoteCallbackList; @@ -1934,9 +1935,12 @@ class UserController implements Handler.Callback { } /** - * Start user, if its not already running, and bring it to foreground. + * Start user, if it's not already running, and bring it to foreground. */ void startUserInForeground(@UserIdInt int targetUserId) { + if (android.multiuser.Flags.setPowerModeDuringUserSwitch()) { + mInjector.setPerformancePowerMode(true); + } boolean success = startUser(targetUserId, USER_START_MODE_FOREGROUND); if (!success) { mInjector.getWindowManager().setSwitchingUser(false); @@ -2146,6 +2150,9 @@ class UserController implements Handler.Callback { } private void endUserSwitch() { + if (android.multiuser.Flags.setPowerModeDuringUserSwitch()) { + mInjector.setPerformancePowerMode(false); + } final int nextUserId; synchronized (mLock) { nextUserId = ObjectUtils.getOrElse(mPendingTargetUserIds.poll(), UserHandle.USER_NULL); @@ -3535,6 +3542,7 @@ class UserController implements Handler.Callback { private final ActivityManagerService mService; private UserManagerService mUserManager; private UserManagerInternal mUserManagerInternal; + private PowerManagerInternal mPowerManagerInternal; private Handler mHandler; private final Object mUserSwitchingDialogLock = new Object(); @GuardedBy("mUserSwitchingDialogLock") @@ -3636,6 +3644,13 @@ class UserController implements Handler.Callback { return mUserManagerInternal; } + PowerManagerInternal getPowerManagerInternal() { + if (mPowerManagerInternal == null) { + mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); + } + return mPowerManagerInternal; + } + KeyguardManager getKeyguardManager() { return mService.mContext.getSystemService(KeyguardManager.class); } @@ -3829,6 +3844,12 @@ class UserController implements Handler.Callback { getSystemServiceManager().onUserStarting(TimingsTraceAndSlog.newAsyncLog(), userId); } + void setPerformancePowerMode(boolean enabled) { + Slogf.i(TAG, "Setting power mode MODE_FIXED_PERFORMANCE to " + enabled); + getPowerManagerInternal().setPowerMode( + PowerManagerInternal.MODE_FIXED_PERFORMANCE, enabled); + } + void onSystemUserVisibilityChanged(boolean visible) { getUserManagerInternal().onSystemUserVisibilityChanged(visible); } diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 145b213ad2c6..fca119917fd0 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -166,7 +166,6 @@ import com.android.modules.utils.TypedXmlSerializer; import com.android.server.LocalManagerRegistry; import com.android.server.LocalServices; import com.android.server.LockGuard; -import com.android.server.SystemServerInitThreadPool; import com.android.server.SystemServiceManager; import com.android.server.companion.virtual.VirtualDeviceManagerInternal; import com.android.server.pm.PackageList; @@ -659,11 +658,11 @@ public class AppOpsService extends IAppOpsService.Stub { return attributedOp; } - @NonNull OpEntry createEntryLocked() { + @NonNull OpEntry createEntryLocked(String persistentDeviceId) { // TODO(b/308201969): Update this method when we introduce disk persistence of events // for accesses on external devices. final ArrayMap<String, AttributedOp> attributedOps = mDeviceAttributedOps.get( - PERSISTENT_DEVICE_ID_DEFAULT); + persistentDeviceId); final ArrayMap<String, AppOpsManager.AttributedOpEntry> attributionEntries = new ArrayMap<>(attributedOps.size()); for (int i = 0; i < attributedOps.size(); i++) { @@ -1038,7 +1037,7 @@ public class AppOpsService extends IAppOpsService.Stub { new Ops(pkgName, uidState)); } - createSandboxUidStateIfNotExistsForAppLocked(uid); + createSandboxUidStateIfNotExistsForAppLocked(uid, null); } } else if (action.equals(ACTION_PACKAGE_REMOVED) && !intent.hasExtra(EXTRA_REPLACING)) { synchronized (AppOpsService.this) { @@ -1050,69 +1049,8 @@ public class AppOpsService extends IAppOpsService.Stub { return; } - ArrayMap<String, String> dstAttributionTags = new ArrayMap<>(); - ArraySet<String> attributionTags = new ArraySet<>(); - attributionTags.add(null); - if (pkg.getAttributions() != null) { - int numAttributions = pkg.getAttributions().size(); - for (int attributionNum = 0; attributionNum < numAttributions; - attributionNum++) { - ParsedAttribution attribution = pkg.getAttributions().get(attributionNum); - attributionTags.add(attribution.getTag()); - - int numInheritFrom = attribution.getInheritFrom().size(); - for (int inheritFromNum = 0; inheritFromNum < numInheritFrom; - inheritFromNum++) { - dstAttributionTags.put(attribution.getInheritFrom().get(inheritFromNum), - attribution.getTag()); - } - } - } - synchronized (AppOpsService.this) { - UidState uidState = mUidStates.get(uid); - if (uidState == null) { - return; - } - - Ops ops = uidState.pkgOps.get(pkgName); - if (ops == null) { - return; - } - - // Reset cached package properties to re-initialize when needed - ops.bypass = null; - ops.knownAttributionTags.clear(); - - // Merge data collected for removed attributions into their successor - // attributions - int numOps = ops.size(); - for (int opNum = 0; opNum < numOps; opNum++) { - Op op = ops.valueAt(opNum); - for (int deviceIndex = op.mDeviceAttributedOps.size() - 1; deviceIndex >= 0; - deviceIndex--) { - ArrayMap<String, AttributedOp> attributedOps = - op.mDeviceAttributedOps.valueAt(deviceIndex); - for (int tagIndex = attributedOps.size() - 1; tagIndex >= 0; - tagIndex--) { - String tag = attributedOps.keyAt(tagIndex); - if (attributionTags.contains(tag)) { - // attribution still exist after upgrade - continue; - } - - String newAttributionTag = dstAttributionTags.get(tag); - - AttributedOp newAttributedOp = op.getOrCreateAttribution(op, - newAttributionTag, - op.mDeviceAttributedOps.keyAt(deviceIndex)); - newAttributedOp.add(attributedOps.get(tag)); - attributedOps.remove(tag); - - scheduleFastWriteLocked(); - } - } - } + refreshAttributionsLocked(pkg, uid); } } } @@ -1136,41 +1074,6 @@ public class AppOpsService extends IAppOpsService.Stub { mContext.registerReceiverAsUser(mOnPackageUpdatedReceiver, UserHandle.ALL, packageUpdateFilter, null, null); - synchronized (this) { - for (int uidNum = mUidStates.size() - 1; uidNum >= 0; uidNum--) { - int uid = mUidStates.keyAt(uidNum); - UidState uidState = mUidStates.valueAt(uidNum); - - String[] pkgsInUid = getPackagesForUid(uidState.uid); - if (ArrayUtils.isEmpty(pkgsInUid) && uid >= Process.FIRST_APPLICATION_UID) { - uidState.clear(); - mUidStates.removeAt(uidNum); - scheduleFastWriteLocked(); - continue; - } - - ArrayMap<String, Ops> pkgs = uidState.pkgOps; - - int numPkgs = pkgs.size(); - for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) { - String pkg = pkgs.keyAt(pkgNum); - - String action; - if (!ArrayUtils.contains(pkgsInUid, pkg)) { - action = ACTION_PACKAGE_REMOVED; - } else { - action = Intent.ACTION_PACKAGE_REPLACED; - } - - SystemServerInitThreadPool.submit( - () -> mOnPackageUpdatedReceiver.onReceive(mContext, new Intent(action) - .setData(Uri.fromParts("package", pkg, null)) - .putExtra(Intent.EXTRA_UID, uid)), - "Update app-ops uidState in case package " + pkg + " changed"); - } - } - } - prepareInternalCallbacks(); final IntentFilter packageSuspendFilter = new IntentFilter(); @@ -1258,20 +1161,27 @@ public class AppOpsService extends IAppOpsService.Stub { void initializeUidStates() { UserManagerInternal umi = getUserManagerInternal(); synchronized (this) { + SparseBooleanArray knownUids = new SparseBooleanArray(); + + for (int uid : NON_PACKAGE_UIDS) { + if (!mUidStates.contains(uid)) { + mUidStates.put(uid, new UidState(uid)); + } + knownUids.put(uid, true); + } + int[] userIds = umi.getUserIds(); try (PackageManagerLocal.UnfilteredSnapshot snapshot = getPackageManagerLocal().withUnfilteredSnapshot()) { Map<String, PackageState> packageStates = snapshot.getPackageStates(); for (int i = 0; i < userIds.length; i++) { int userId = userIds[i]; - initializeUserUidStatesLocked(userId, packageStates); + initializeUserUidStatesLocked(userId, packageStates, knownUids); } - } - for (int uid : NON_PACKAGE_UIDS) { - mUidStates.put(uid, new UidState(uid)); + trimUidStatesLocked(knownUids, packageStates); + mUidStatesInitialized = true; } - mUidStatesInitialized = true; } } @@ -1279,26 +1189,34 @@ public class AppOpsService extends IAppOpsService.Stub { synchronized (this) { try (PackageManagerLocal.UnfilteredSnapshot snapshot = getPackageManagerLocal().withUnfilteredSnapshot()) { - initializeUserUidStatesLocked(userId, snapshot.getPackageStates()); + initializeUserUidStatesLocked(userId, snapshot.getPackageStates(), null); } } } private void initializeUserUidStatesLocked(int userId, Map<String, - PackageState> packageStates) { + PackageState> packageStates, SparseBooleanArray knownUids) { for (Map.Entry<String, PackageState> entry : packageStates.entrySet()) { - int appId = entry.getValue().getAppId(); + PackageState packageState = entry.getValue(); + if (packageState.isApex()) { + continue; + } + int appId = packageState.getAppId(); String packageName = entry.getKey(); - initializePackageUidStateLocked(userId, appId, packageName); + initializePackageUidStateLocked(userId, appId, packageName, knownUids); } } /* Be careful not to clear any existing data; only want to add objects that don't already exist. */ - private void initializePackageUidStateLocked(int userId, int appId, String packageName) { + private void initializePackageUidStateLocked(int userId, int appId, String packageName, + SparseBooleanArray knownUids) { int uid = UserHandle.getUid(userId, appId); + if (knownUids != null) { + knownUids.put(uid, true); + } UidState uidState = getUidStateLocked(uid, true); Ops ops = uidState.pkgOps.get(packageName); if (ops == null) { @@ -1316,7 +1234,105 @@ public class AppOpsService extends IAppOpsService.Stub { } } - createSandboxUidStateIfNotExistsForAppLocked(uid); + createSandboxUidStateIfNotExistsForAppLocked(uid, knownUids); + } + + private void trimUidStatesLocked(SparseBooleanArray knownUids, + Map<String, PackageState> packageStates) { + synchronized (this) { + // Remove what may have been added during persistence parsing + for (int i = mUidStates.size() - 1; i >= 0; i--) { + int uid = mUidStates.keyAt(i); + if (knownUids.get(uid, false)) { + if (uid >= Process.FIRST_APPLICATION_UID) { + ArrayMap<String, Ops> pkgOps = mUidStates.valueAt(i).pkgOps; + for (int j = 0; j < pkgOps.size(); j++) { + String pkgName = pkgOps.keyAt(j); + if (!packageStates.containsKey(pkgName)) { + pkgOps.removeAt(j); + continue; + } + AndroidPackage pkg = packageStates.get(pkgName).getAndroidPackage(); + if (pkg != null) { + refreshAttributionsLocked(pkg, uid); + } + } + if (pkgOps.isEmpty()) { + mUidStates.remove(i); + } + } + } else { + mUidStates.removeAt(i); + } + } + } + } + + @GuardedBy("this") + private void refreshAttributionsLocked(AndroidPackage pkg, int uid) { + String pkgName = pkg.getPackageName(); + ArrayMap<String, String> dstAttributionTags = new ArrayMap<>(); + ArraySet<String> attributionTags = new ArraySet<>(); + attributionTags.add(null); + if (pkg.getAttributions() != null) { + int numAttributions = pkg.getAttributions().size(); + for (int attributionNum = 0; attributionNum < numAttributions; + attributionNum++) { + ParsedAttribution attribution = pkg.getAttributions().get(attributionNum); + attributionTags.add(attribution.getTag()); + + int numInheritFrom = attribution.getInheritFrom().size(); + for (int inheritFromNum = 0; inheritFromNum < numInheritFrom; + inheritFromNum++) { + dstAttributionTags.put(attribution.getInheritFrom().get(inheritFromNum), + attribution.getTag()); + } + } + } + + UidState uidState = mUidStates.get(uid); + if (uidState == null) { + return; + } + + Ops ops = uidState.pkgOps.get(pkgName); + if (ops == null) { + return; + } + + // Reset cached package properties to re-initialize when needed + ops.bypass = null; + ops.knownAttributionTags.clear(); + + // Merge data collected for removed attributions into their successor + // attributions + int numOps = ops.size(); + for (int opNum = 0; opNum < numOps; opNum++) { + Op op = ops.valueAt(opNum); + for (int deviceIndex = op.mDeviceAttributedOps.size() - 1; deviceIndex >= 0; + deviceIndex--) { + ArrayMap<String, AttributedOp> attributedOps = + op.mDeviceAttributedOps.valueAt(deviceIndex); + for (int tagIndex = attributedOps.size() - 1; tagIndex >= 0; + tagIndex--) { + String tag = attributedOps.keyAt(tagIndex); + if (attributionTags.contains(tag)) { + // attribution still exist after upgrade + continue; + } + + String newAttributionTag = dstAttributionTags.get(tag); + + AttributedOp newAttributedOp = op.getOrCreateAttribution(op, + newAttributionTag, + op.mDeviceAttributedOps.keyAt(deviceIndex)); + newAttributedOp.add(attributedOps.get(tag)); + attributedOps.remove(tag); + + scheduleFastWriteLocked(); + } + } + } } /** @@ -1534,13 +1550,14 @@ public class AppOpsService extends IAppOpsService.Stub { mHistoricalRegistry.shutdown(); } - private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops) { + private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops, + String persistentDeviceId) { ArrayList<AppOpsManager.OpEntry> resOps = null; if (ops == null) { resOps = new ArrayList<>(); for (int j=0; j<pkgOps.size(); j++) { Op curOp = pkgOps.valueAt(j); - resOps.add(getOpEntryForResult(curOp)); + resOps.add(getOpEntryForResult(curOp, persistentDeviceId)); } } else { for (int j=0; j<ops.length; j++) { @@ -1549,7 +1566,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (resOps == null) { resOps = new ArrayList<>(); } - resOps.add(getOpEntryForResult(curOp)); + resOps.add(getOpEntryForResult(curOp, persistentDeviceId)); } } } @@ -1593,16 +1610,23 @@ public class AppOpsService extends IAppOpsService.Stub { return resOps; } - private static @NonNull OpEntry getOpEntryForResult(@NonNull Op op) { - return op.createEntryLocked(); + private static @NonNull OpEntry getOpEntryForResult(@NonNull Op op, String persistentDeviceId) { + return op.createEntryLocked(persistentDeviceId); } @Override public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) { + return getPackagesForOpsForDevice(ops, PERSISTENT_DEVICE_ID_DEFAULT); + } + + @Override + public List<AppOpsManager.PackageOps> getPackagesForOpsForDevice(int[] ops, + @NonNull String persistentDeviceId) { final int callingUid = Binder.getCallingUid(); final boolean hasAllPackageAccess = mContext.checkPermission( Manifest.permission.GET_APP_OPS_STATS, Binder.getCallingPid(), Binder.getCallingUid(), null) == PackageManager.PERMISSION_GRANTED; + ArrayList<AppOpsManager.PackageOps> res = null; synchronized (this) { final int uidStateCount = mUidStates.size(); @@ -1611,21 +1635,24 @@ public class AppOpsService extends IAppOpsService.Stub { if (uidState.pkgOps.isEmpty()) { continue; } + // Caller can always see their packages and with a permission all. + if (!hasAllPackageAccess && callingUid != uidState.uid) { + continue; + } + ArrayMap<String, Ops> packages = uidState.pkgOps; final int packageCount = packages.size(); for (int j = 0; j < packageCount; j++) { Ops pkgOps = packages.valueAt(j); - ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops); + ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops, + persistentDeviceId); if (resOps != null) { if (res == null) { res = new ArrayList<>(); } AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( pkgOps.packageName, pkgOps.uidState.uid, resOps); - // Caller can always see their packages and with a permission all. - if (hasAllPackageAccess || callingUid == pkgOps.uidState.uid) { - res.add(resPackage); - } + res.add(resPackage); } } } @@ -1647,7 +1674,8 @@ public class AppOpsService extends IAppOpsService.Stub { if (pkgOps == null) { return null; } - ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops); + ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops, + PERSISTENT_DEVICE_ID_DEFAULT); if (resOps == null || resOps.size() == 0) { return null; } @@ -4251,8 +4279,15 @@ public class AppOpsService extends IAppOpsService.Stub { return uidState; } - private void createSandboxUidStateIfNotExistsForAppLocked(int uid) { + private void createSandboxUidStateIfNotExistsForAppLocked(int uid, + SparseBooleanArray knownUids) { + if (UserHandle.getAppId(uid) < Process.FIRST_APPLICATION_UID) { + return; + } final int sandboxUid = Process.toSdkSandboxUid(uid); + if (knownUids != null) { + knownUids.put(sandboxUid, true); + } getUidStateLocked(sandboxUid, true); } diff --git a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java index 23a384ff5d3b..bc6ef2005584 100644 --- a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java +++ b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java @@ -16,6 +16,7 @@ package com.android.server.appop; +import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; @@ -30,6 +31,7 @@ import static android.app.AppOpsManager.OP_CAMERA; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO; +import static android.app.AppOpsManager.OP_TAKE_AUDIO_FOCUS; import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE; import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED; import static android.app.AppOpsManager.UID_STATE_TOP; @@ -139,7 +141,6 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { } private int evalModeInternal(int uid, int code, int uidState, int uidCapability) { - if (getUidAppWidgetVisible(uid) || mActivityManagerInternal.isPendingTopUid(uid) || mActivityManagerInternal.isTempAllowlistedForFgsWhileInUse(uid)) { return MODE_ALLOWED; @@ -173,6 +174,8 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { case OP_RECORD_AUDIO: case OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO: return PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; + case OP_TAKE_AUDIO_FOCUS: + return PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; default: return PROCESS_CAPABILITY_NONE; } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index c59f4f7888ce..559a1d647ea4 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -34,6 +34,7 @@ import static android.media.audio.Flags.autoPublicVolumeApiHardening; import static android.media.audio.Flags.automaticBtDeviceType; import static android.media.audio.Flags.featureSpatialAudioHeadtrackingLowLatency; import static android.media.audio.Flags.focusFreezeTestApi; +import static android.media.audio.Flags.foregroundAudioControl; import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration; import static android.os.Process.FIRST_APPLICATION_UID; import static android.os.Process.INVALID_UID; @@ -1356,7 +1357,8 @@ public class AudioService extends IAudioService.Stub mMusicFxHelper = new MusicFxHelper(mContext, mAudioHandler); - mHardeningEnforcer = new HardeningEnforcer(mContext, isPlatformAutomotive()); + mHardeningEnforcer = new HardeningEnforcer(mContext, isPlatformAutomotive(), mAppOps, + context.getPackageManager()); } private void initVolumeStreamStates() { @@ -4517,7 +4519,8 @@ public class AudioService extends IAudioService.Stub } private void dumpFlags(PrintWriter pw) { - pw.println("\nFun with Flags: "); + + pw.println("\nFun with Flags:"); pw.println("\tandroid.media.audio.autoPublicVolumeApiHardening:" + autoPublicVolumeApiHardening()); pw.println("\tandroid.media.audio.Flags.automaticBtDeviceType:" @@ -4528,8 +4531,8 @@ public class AudioService extends IAudioService.Stub + focusFreezeTestApi()); pw.println("\tcom.android.media.audio.disablePrescaleAbsoluteVolume:" + disablePrescaleAbsoluteVolume()); - pw.println("\tandroid.media.audiopolicy.enableFadeManagerConfiguration:" - + enableFadeManagerConfiguration()); + pw.println("\tandroid.media.audio.foregroundAudioControl:" + + foregroundAudioControl()); } private void dumpAudioMode(PrintWriter pw) { @@ -10175,10 +10178,38 @@ public class AudioService extends IAudioService.Stub .record(); return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } + + // does caller have system privileges to bypass HardeningEnforcer + boolean permissionOverridesCheck = false; + if ((mContext.checkCallingOrSelfPermission( + Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) + == PackageManager.PERMISSION_GRANTED) + || (mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_AUDIO_ROUTING) + == PackageManager.PERMISSION_GRANTED)) { + permissionOverridesCheck = true; + } else if (uid < UserHandle.AID_APP_START) { + permissionOverridesCheck = true; + } + + final long token = Binder.clearCallingIdentity(); + try { + if (!permissionOverridesCheck && mHardeningEnforcer.blockFocusMethod(uid, + HardeningEnforcer.METHOD_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS, + clientId, durationHint, callingPackageName)) { + final String reason = "Audio focus request blocked by hardening"; + Log.w(TAG, reason); + mmi.set(MediaMetrics.Property.EARLY_RETURN, reason).record(); + return AudioManager.AUDIOFOCUS_REQUEST_FAILED; + } + } finally { + Binder.restoreCallingIdentity(token); + } + mmi.record(); return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, clientId, callingPackageName, attributionTag, flags, sdk, - forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/); + forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/, + permissionOverridesCheck); } /** see {@link AudioManager#requestAudioFocusForTest(AudioFocusRequest, String, int, int)} */ @@ -10195,7 +10226,7 @@ public class AudioService extends IAudioService.Stub } return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, clientId, callingPackageName, null, flags, - sdk, false /*forceDuck*/, fakeUid); + sdk, false /*forceDuck*/, fakeUid, true /*permissionOverridesCheck*/); } public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, @@ -11639,6 +11670,7 @@ public class AudioService extends IAudioService.Stub pw.println("\nMessage handler is null"); } dumpFlags(pw); + mHardeningEnforcer.dump(pw); mMediaFocusControl.dump(pw); dumpStreamStates(pw); dumpVolumeGroups(pw); diff --git a/services/core/java/com/android/server/audio/HardeningEnforcer.java b/services/core/java/com/android/server/audio/HardeningEnforcer.java index 4ceb83b2e1c9..409ed17001b7 100644 --- a/services/core/java/com/android/server/audio/HardeningEnforcer.java +++ b/services/core/java/com/android/server/audio/HardeningEnforcer.java @@ -18,13 +18,21 @@ package com.android.server.audio; import static android.media.audio.Flags.autoPublicVolumeApiHardening; import android.Manifest; +import android.annotation.NonNull; +import android.app.ActivityManager; +import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; +import android.media.AudioFocusRequest; import android.media.AudioManager; import android.os.Binder; import android.os.UserHandle; import android.text.TextUtils; -import android.util.Log; +import android.util.Slog; + +import com.android.server.utils.EventLogger; + +import java.io.PrintWriter; /** * Class to encapsulate all audio API hardening operations @@ -32,10 +40,19 @@ import android.util.Log; public class HardeningEnforcer { private static final String TAG = "AS.HardeningEnforcer"; + private static final boolean DEBUG = false; + private static final int LOG_NB_EVENTS = 20; final Context mContext; + final AppOpsManager mAppOps; final boolean mIsAutomotive; + final ActivityManager mActivityManager; + final PackageManager mPackageManager; + + final EventLogger mEventLogger = new EventLogger(LOG_NB_EVENTS, + "Hardening enforcement"); + /** * Matches calls from {@link AudioManager#setStreamVolume(int, int, int)} */ @@ -56,10 +73,24 @@ public class HardeningEnforcer { * Matches calls from {@link AudioManager#setRingerMode(int)} */ public static final int METHOD_AUDIO_MANAGER_SET_RINGER_MODE = 200; + /** + * Matches calls from {@link AudioManager#requestAudioFocus(AudioFocusRequest)} + * and legacy variants + */ + public static final int METHOD_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS = 300; - public HardeningEnforcer(Context ctxt, boolean isAutomotive) { + public HardeningEnforcer(Context ctxt, boolean isAutomotive, AppOpsManager appOps, + PackageManager pm) { mContext = ctxt; mIsAutomotive = isAutomotive; + mAppOps = appOps; + mActivityManager = ctxt.getSystemService(ActivityManager.class); + mPackageManager = pm; + } + + protected void dump(PrintWriter pw) { + // log + mEventLogger.dump(pw); } /** @@ -84,7 +115,7 @@ public class HardeningEnforcer { } // TODO metrics? // TODO log for audio dumpsys? - Log.e(TAG, "Preventing volume method " + volumeMethod + " for " + Slog.e(TAG, "Preventing volume method " + volumeMethod + " for " + getPackNameForUid(Binder.getCallingUid())); return true; } @@ -92,10 +123,40 @@ public class HardeningEnforcer { return false; } + /** + * Checks whether the call in the current thread should be allowed or blocked + * @param focusMethod name of the method to check, for logging purposes + * @param clientId id of the requester + * @param durationHint focus type being requested + * @return false if the method call is allowed, true if it should be a no-op + */ + protected boolean blockFocusMethod(int callingUid, int focusMethod, @NonNull String clientId, + int durationHint, @NonNull String packageName) { + if (packageName.isEmpty()) { + packageName = getPackNameForUid(callingUid); + } + + if (checkAppOp(AppOpsManager.OP_TAKE_AUDIO_FOCUS, callingUid, packageName)) { + if (DEBUG) { + Slog.i(TAG, "blockFocusMethod pack:" + packageName + " NOT blocking"); + } + return false; + } + + String errorMssg = "Focus request DENIED for uid:" + callingUid + + " clientId:" + clientId + " req:" + durationHint + + " procState:" + mActivityManager.getUidProcessState(callingUid); + + // TODO metrics + mEventLogger.enqueueAndSlog(errorMssg, EventLogger.Event.ALOGI, TAG); + + return true; + } + private String getPackNameForUid(int uid) { final long token = Binder.clearCallingIdentity(); try { - final String[] names = mContext.getPackageManager().getPackagesForUid(uid); + final String[] names = mPackageManager.getPackagesForUid(uid); if (names == null || names.length == 0 || TextUtils.isEmpty(names[0])) { @@ -106,4 +167,18 @@ public class HardeningEnforcer { Binder.restoreCallingIdentity(token); } } + + /** + * Checks the given op without throwing + * @param op the appOp code + * @param uid the calling uid + * @param packageName the package name of the caller + * @return return false if the operation is not allowed + */ + private boolean checkAppOp(int op, int uid, @NonNull String packageName) { + if (mAppOps.checkOpNoThrow(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) { + return false; + } + return true; + } } diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java index 1376bde2fb71..35d38e2373f5 100644 --- a/services/core/java/com/android/server/audio/MediaFocusControl.java +++ b/services/core/java/com/android/server/audio/MediaFocusControl.java @@ -1090,11 +1090,14 @@ public class MediaFocusControl implements PlayerFocusEnforcer { * accessibility. * @param testUid ignored if flags doesn't contain AudioManager.AUDIOFOCUS_FLAG_TEST * otherwise the UID being injected for testing + * @param permissionOverridesCheck true if permission checks guaranteed that the call should + * go through, false otherwise (e.g. non-privileged caller) * @return */ protected int requestAudioFocus(@NonNull AudioAttributes aa, int focusChangeHint, IBinder cb, IAudioFocusDispatcher fd, @NonNull String clientId, @NonNull String callingPackageName, - String attributionTag, int flags, int sdk, boolean forceDuck, int testUid) { + String attributionTag, int flags, int sdk, boolean forceDuck, int testUid, + boolean permissionOverridesCheck) { new MediaMetrics.Item(mMetricsId) .setUid(Binder.getCallingUid()) .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) @@ -1126,10 +1129,9 @@ public class MediaFocusControl implements PlayerFocusEnforcer { return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } - if ((flags != AudioManager.AUDIOFOCUS_FLAG_TEST) - // note we're using the real uid for appOp evaluation - && (mAppOps.noteOp(AppOpsManager.OP_TAKE_AUDIO_FOCUS, Binder.getCallingUid(), - callingPackageName, attributionTag, null) != AppOpsManager.MODE_ALLOWED)) { + final int res = mAppOps.noteOp(AppOpsManager.OP_TAKE_AUDIO_FOCUS, Binder.getCallingUid(), + callingPackageName, attributionTag, null); + if (!permissionOverridesCheck && res != AppOpsManager.MODE_ALLOWED) { return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java index 3f3540e2868c..48bf9f4967bc 100644 --- a/services/core/java/com/android/server/biometrics/AuthService.java +++ b/services/core/java/com/android/server/biometrics/AuthService.java @@ -216,6 +216,13 @@ public class AuthService extends SystemService { public String[] getFaceAidlInstances() { return ServiceManager.getDeclaredInstances(IFace.DESCRIPTOR); } + + /** + * Allows to test with handlers. + */ + public BiometricHandlerProvider getBiometricHandlerProvider() { + return BiometricHandlerProvider.getInstance(); + } } private final class AuthServiceImpl extends IAuthService.Stub { @@ -772,7 +779,6 @@ public class AuthService extends SystemService { } if (com.android.server.biometrics.Flags.deHidl()) { - Slog.d(TAG, "deHidl flag is on."); registerAuthenticators(); } else { // Registers HIDL and AIDL authenticators, but only HIDL configs need to be provided. @@ -783,10 +789,16 @@ public class AuthService extends SystemService { } private void registerAuthenticators() { - registerFingerprintSensors(mInjector.getFingerprintAidlInstances(), - mInjector.getFingerprintConfiguration(getContext())); - registerFaceSensors(mInjector.getFaceAidlInstances(), - mInjector.getFaceConfiguration(getContext())); + BiometricHandlerProvider handlerProvider = mInjector.getBiometricHandlerProvider(); + + handlerProvider.getFingerprintHandler().post(() -> + registerFingerprintSensors(mInjector.getFingerprintAidlInstances(), + mInjector.getFingerprintConfiguration(getContext()), getContext(), + mInjector.getFingerprintService())); + handlerProvider.getFaceHandler().post(() -> + registerFaceSensors(mInjector.getFaceAidlInstances(), + mInjector.getFaceConfiguration(getContext()), getContext(), + mInjector.getFaceService())); registerIrisSensors(mInjector.getIrisConfiguration(getContext())); } @@ -837,15 +849,18 @@ public class AuthService extends SystemService { } } - private void registerFaceSensors(final String[] faceAidlInstances, - final String[] hidlConfigStrings) { + /** + * This method is invoked on {@link BiometricHandlerProvider.mFaceHandler}. + */ + private static void registerFaceSensors(final String[] faceAidlInstances, + final String[] hidlConfigStrings, final Context context, + final IFaceService faceService) { final FaceSensorConfigurations mFaceSensorConfigurations = new FaceSensorConfigurations(hidlConfigStrings != null && hidlConfigStrings.length > 0); if (hidlConfigStrings != null && hidlConfigStrings.length > 0) { - mFaceSensorConfigurations.addHidlConfigs( - hidlConfigStrings, getContext()); + mFaceSensorConfigurations.addHidlConfigs(hidlConfigStrings, context); } if (faceAidlInstances != null && faceAidlInstances.length > 0) { @@ -854,7 +869,6 @@ public class AuthService extends SystemService { ServiceManager.waitForDeclaredService(name)))); } - final IFaceService faceService = mInjector.getFaceService(); if (faceService != null) { try { faceService.registerAuthenticatorsLegacy(mFaceSensorConfigurations); @@ -866,14 +880,18 @@ public class AuthService extends SystemService { } } - private void registerFingerprintSensors(final String[] fingerprintAidlInstances, - final String[] hidlConfigStrings) { + /** + * This method is invoked on {@link BiometricHandlerProvider.mFingerprintHandler}. + */ + private static void registerFingerprintSensors(final String[] fingerprintAidlInstances, + final String[] hidlConfigStrings, final Context context, + final IFingerprintService fingerprintService) { final FingerprintSensorConfigurations mFingerprintSensorConfigurations = new FingerprintSensorConfigurations(!(hidlConfigStrings != null && hidlConfigStrings.length > 0)); if (hidlConfigStrings != null && hidlConfigStrings.length > 0) { - mFingerprintSensorConfigurations.addHidlSensors(hidlConfigStrings, getContext()); + mFingerprintSensorConfigurations.addHidlSensors(hidlConfigStrings, context); } if (fingerprintAidlInstances != null && fingerprintAidlInstances.length > 0) { @@ -882,7 +900,6 @@ public class AuthService extends SystemService { ServiceManager.waitForDeclaredService(name)))); } - final IFingerprintService fingerprintService = mInjector.getFingerprintService(); if (fingerprintService != null) { try { fingerprintService.registerAuthenticatorsLegacy(mFingerprintSensorConfigurations); diff --git a/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java index b0649b90c466..0f01510bd908 100644 --- a/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java +++ b/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java @@ -22,7 +22,6 @@ import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.os.IBinder; -import com.android.server.biometrics.Flags; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; import com.android.server.biometrics.log.OperationContextExt; @@ -94,9 +93,6 @@ public abstract class HalClientMonitor<T> extends BaseClientMonitor { } protected OperationContextExt getOperationContext() { - if (Flags.deHidl()) { - return mOperationContext; - } return getBiometricContext().updateContext(mOperationContext, isCryptoOperation()); } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 1ca3923b325c..d5863a73a0c3 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -1638,21 +1638,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // SDR brightness is unchanged, so animate quickly as this is only impacting // a likely minority amount of display content // ie, the highlights of an HDR video or UltraHDR image + // Ideally we'd do this as fast as possible (ie, skip the animation entirely), + // but this requires display support and would need an entry in the + // display configuration. For now just do the fast animation slowChange = false; - - // Going from HDR to no HDR; visually this should be a "no-op" anyway - // as the remaining SDR content's brightness should be holding steady - // due to the sdr brightness not shifting - if (BrightnessSynchronizer.floatEquals(sdrAnimateValue, animateValue)) { - skipAnimation = true; - } - - // Going from no HDR to HDR; visually this is a significant scene change - // and the animation just prevents advanced clients from doing their own - // handling of enter/exit animations if they would like to do such a thing - if (BrightnessSynchronizer.floatEquals(sdrAnimateValue, currentBrightness)) { - skipAnimation = true; - } } if (skipAnimation) { animateScreenBrightness(animateValue, sdrAnimateValue, diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 4bb8e1913199..bc169ca40117 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -2901,16 +2901,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") void clearClientSessionsLocked() { if (getCurMethodLocked() != null) { - // TODO(b/322816970): Replace this with lambda. - mClientController.forAllClients(new Consumer<ClientState>() { - - @GuardedBy("ImfLock.class") - @Override - public void accept(ClientState c) { - clearClientSessionLocked(c); - clearClientSessionForAccessibilityLocked(c); - } - }); + // TODO(b/324907325): Remove the suppress warnings once b/324907325 is fixed. + @SuppressWarnings("GuardedBy") Consumer<ClientState> clearClientSession = c -> { + clearClientSessionLocked(c); + clearClientSessionForAccessibilityLocked(c); + }; + mClientController.forAllClients(clearClientSession); finishSessionLocked(mEnabledSession); for (int i = 0; i < mEnabledAccessibilitySessions.size(); i++) { @@ -4653,15 +4649,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub super.startImeTrace_enforcePermission(); ImeTracing.getInstance().startTrace(null /* printwriter */); synchronized (ImfLock.class) { - // TODO(b/322816970): Replace this with lambda. - mClientController.forAllClients(new Consumer<ClientState>() { - - @GuardedBy("ImfLock.class") - @Override - public void accept(ClientState c) { - c.mClient.setImeTraceEnabled(true /* enabled */); - } - }); + mClientController.forAllClients(c -> c.mClient.setImeTraceEnabled(true /* enabled */)); } } @@ -4673,15 +4661,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub ImeTracing.getInstance().stopTrace(null /* printwriter */); synchronized (ImfLock.class) { - // TODO(b/322816970): Replace this with lambda. - mClientController.forAllClients(new Consumer<ClientState>() { - - @GuardedBy("ImfLock.class") - @Override - public void accept(ClientState c) { - c.mClient.setImeTraceEnabled(false /* enabled */); - } - }); + mClientController.forAllClients(c -> c.mClient.setImeTraceEnabled(false /* enabled */)); } } @@ -5916,15 +5896,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // We only have sessions when we bound to an input method. Remove this session // from all clients. if (getCurMethodLocked() != null) { - // TODO(b/322816970): Replace this with lambda. - mClientController.forAllClients(new Consumer<ClientState>() { + // TODO(b/324907325): Remove the suppress warnings once b/324907325 is fixed. + @SuppressWarnings("GuardedBy") Consumer<ClientState> clearClientSession = + c -> clearClientSessionForAccessibilityLocked(c, + accessibilityConnectionId); + mClientController.forAllClients(clearClientSession); - @GuardedBy("ImfLock.class") - @Override - public void accept(ClientState c) { - clearClientSessionForAccessibilityLocked(c, accessibilityConnectionId); - } - }); AccessibilitySessionState session = mEnabledAccessibilitySessions.get( accessibilityConnectionId); if (session != null) { @@ -6126,24 +6103,21 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } // Dump ClientController#mClients p.println(" ClientStates:"); - // TODO(b/322816970): Replace this with lambda. - mClientController.forAllClients(new Consumer<ClientState>() { + // TODO(b/324907325): Remove the suppress warnings once b/324907325 is fixed. + @SuppressWarnings("GuardedBy") Consumer<ClientState> clientControllerDump = c -> { + p.println(" " + c + ":"); + p.println(" client=" + c.mClient); + p.println(" fallbackInputConnection=" + + c.mFallbackInputConnection); + p.println(" sessionRequested=" + + c.mSessionRequested); + p.println( + " sessionRequestedForAccessibility=" + + c.mSessionRequestedForAccessibility); + p.println(" curSession=" + c.mCurSession); + }; + mClientController.forAllClients(clientControllerDump); - @GuardedBy("ImfLock.class") - @Override - public void accept(ClientState c) { - p.println(" " + c + ":"); - p.println(" client=" + c.mClient); - p.println(" fallbackInputConnection=" - + c.mFallbackInputConnection); - p.println(" sessionRequested=" - + c.mSessionRequested); - p.println( - " sessionRequestedForAccessibility=" - + c.mSessionRequestedForAccessibility); - p.println(" curSession=" + c.mCurSession); - } - }); p.println(" mCurMethodId=" + getSelectedMethodIdLocked()); client = mCurClient; p.println(" mCurClient=" + client + " mCurSeq=" + getSequenceNumberLocked()); diff --git a/services/core/java/com/android/server/location/GeocoderProxy.java b/services/core/java/com/android/server/location/GeocoderProxy.java deleted file mode 100644 index ac42646499a3..000000000000 --- a/services/core/java/com/android/server/location/GeocoderProxy.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.location; - -import android.annotation.Nullable; -import android.content.Context; -import android.location.GeocoderParams; -import android.location.IGeocodeListener; -import android.location.IGeocodeProvider; -import android.os.IBinder; -import android.os.RemoteException; - -import com.android.server.servicewatcher.CurrentUserServiceSupplier; -import com.android.server.servicewatcher.ServiceWatcher; - -import java.util.Collections; - -/** - * Proxy for IGeocodeProvider implementations. - * - * @hide - */ -public class GeocoderProxy { - - private static final String SERVICE_ACTION = "com.android.location.service.GeocodeProvider"; - - /** - * Creates and registers this proxy. If no suitable service is available for the proxy, returns - * null. - */ - @Nullable - public static GeocoderProxy createAndRegister(Context context) { - GeocoderProxy proxy = new GeocoderProxy(context); - if (proxy.register()) { - return proxy; - } else { - return null; - } - } - - private final ServiceWatcher mServiceWatcher; - - private GeocoderProxy(Context context) { - mServiceWatcher = ServiceWatcher.create(context, "GeocoderProxy", - CurrentUserServiceSupplier.createFromConfig(context, SERVICE_ACTION, - com.android.internal.R.bool.config_enableGeocoderOverlay, - com.android.internal.R.string.config_geocoderProviderPackageName), - null); - } - - private boolean register() { - boolean resolves = mServiceWatcher.checkServiceResolves(); - if (resolves) { - mServiceWatcher.register(); - } - return resolves; - } - - /** - * Geocodes stuff. - */ - public void getFromLocation(double latitude, double longitude, int maxResults, - GeocoderParams params, IGeocodeListener listener) { - mServiceWatcher.runOnBinder(new ServiceWatcher.BinderOperation() { - @Override - public void run(IBinder binder) throws RemoteException { - IGeocodeProvider provider = IGeocodeProvider.Stub.asInterface(binder); - provider.getFromLocation(latitude, longitude, maxResults, params, listener); - } - - @Override - public void onError(Throwable t) { - try { - listener.onResults(t.toString(), Collections.emptyList()); - } catch (RemoteException e) { - // ignore - } - } - }); - } - - /** - * Geocodes stuff. - */ - public void getFromLocationName(String locationName, - double lowerLeftLatitude, double lowerLeftLongitude, - double upperRightLatitude, double upperRightLongitude, int maxResults, - GeocoderParams params, IGeocodeListener listener) { - mServiceWatcher.runOnBinder(new ServiceWatcher.BinderOperation() { - @Override - public void run(IBinder binder) throws RemoteException { - IGeocodeProvider provider = IGeocodeProvider.Stub.asInterface(binder); - provider.getFromLocationName(locationName, lowerLeftLatitude, - lowerLeftLongitude, upperRightLatitude, upperRightLongitude, - maxResults, params, listener); - } - - @Override - public void onError(Throwable t) { - try { - listener.onResults(t.toString(), Collections.emptyList()); - } catch (RemoteException e) { - // ignore - } - } - }); - } -} diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index 323cdc54edae..c5f38553ed81 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -52,13 +52,11 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.location.Criteria; -import android.location.GeocoderParams; import android.location.Geofence; import android.location.GnssAntennaInfo; import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.GnssMeasurementRequest; -import android.location.IGeocodeListener; import android.location.IGnssAntennaInfoListener; import android.location.IGnssMeasurementsListener; import android.location.IGnssNavigationMessageListener; @@ -75,8 +73,11 @@ import android.location.LocationManagerInternal.LocationPackageTagsListener; import android.location.LocationProvider; import android.location.LocationRequest; import android.location.LocationTime; +import android.location.provider.ForwardGeocodeRequest; +import android.location.provider.IGeocodeCallback; import android.location.provider.IProviderRequestListener; import android.location.provider.ProviderProperties; +import android.location.provider.ReverseGeocodeRequest; import android.location.util.identity.CallerIdentity; import android.os.Binder; import android.os.Build; @@ -141,6 +142,7 @@ import com.android.server.location.provider.MockLocationProvider; import com.android.server.location.provider.PassiveLocationProvider; import com.android.server.location.provider.PassiveLocationProviderManager; import com.android.server.location.provider.StationaryThrottlingLocationProvider; +import com.android.server.location.provider.proxy.ProxyGeocodeProvider; import com.android.server.location.provider.proxy.ProxyLocationProvider; import com.android.server.location.settings.LocationSettings; import com.android.server.location.settings.LocationUserSettings; @@ -253,7 +255,7 @@ public class LocationManagerService extends ILocationManager.Stub implements private final GeofenceManager mGeofenceManager; private volatile @Nullable GnssManagerService mGnssManagerService = null; - private GeocoderProxy mGeocodeProvider; + private ProxyGeocodeProvider mGeocodeProvider; private final Object mDeprecatedGnssBatchingLock = new Object(); @GuardedBy("mDeprecatedGnssBatchingLock") @@ -493,7 +495,7 @@ public class LocationManagerService extends ILocationManager.Stub implements } // bind to geocoder provider - mGeocodeProvider = GeocoderProxy.createAndRegister(mContext); + mGeocodeProvider = ProxyGeocodeProvider.createAndRegister(mContext); if (mGeocodeProvider == null) { Log.e(TAG, "no geocoder provider found"); } @@ -1363,23 +1365,22 @@ public class LocationManagerService extends ILocationManager.Stub implements } @Override - public boolean geocoderIsPresent() { + public boolean isGeocodeAvailable() { return mGeocodeProvider != null; } @Override - public void getFromLocation(double latitude, double longitude, int maxResults, - GeocoderParams params, IGeocodeListener listener) { - // validate identity - CallerIdentity identity = CallerIdentity.fromBinder(mContext, params.getClientPackage(), - params.getClientAttributionTag()); - Preconditions.checkArgument(identity.getUid() == params.getClientUid()); + public void reverseGeocode(ReverseGeocodeRequest request, IGeocodeCallback callback) { + CallerIdentity identity = + CallerIdentity.fromBinder( + mContext, request.getCallingPackage(), request.getCallingAttributionTag()); + Preconditions.checkArgument(identity.getUid() == request.getCallingUid()); if (mGeocodeProvider != null) { - mGeocodeProvider.getFromLocation(latitude, longitude, maxResults, params, listener); + mGeocodeProvider.reverseGeocode(request, callback); } else { try { - listener.onResults(null, Collections.emptyList()); + callback.onError(null); } catch (RemoteException e) { // ignore } @@ -1387,22 +1388,17 @@ public class LocationManagerService extends ILocationManager.Stub implements } @Override - public void getFromLocationName(String locationName, - double lowerLeftLatitude, double lowerLeftLongitude, - double upperRightLatitude, double upperRightLongitude, int maxResults, - GeocoderParams params, IGeocodeListener listener) { - // validate identity - CallerIdentity identity = CallerIdentity.fromBinder(mContext, params.getClientPackage(), - params.getClientAttributionTag()); - Preconditions.checkArgument(identity.getUid() == params.getClientUid()); + public void forwardGeocode(ForwardGeocodeRequest request, IGeocodeCallback callback) { + CallerIdentity identity = + CallerIdentity.fromBinder( + mContext, request.getCallingPackage(), request.getCallingAttributionTag()); + Preconditions.checkArgument(identity.getUid() == request.getCallingUid()); if (mGeocodeProvider != null) { - mGeocodeProvider.getFromLocationName(locationName, lowerLeftLatitude, - lowerLeftLongitude, upperRightLatitude, upperRightLongitude, - maxResults, params, listener); + mGeocodeProvider.forwardGeocode(request, callback); } else { try { - listener.onResults(null, Collections.emptyList()); + callback.onError(null); } catch (RemoteException e) { // ignore } diff --git a/services/core/java/com/android/server/location/provider/proxy/ProxyGeocodeProvider.java b/services/core/java/com/android/server/location/provider/proxy/ProxyGeocodeProvider.java new file mode 100644 index 000000000000..ac945f1d2921 --- /dev/null +++ b/services/core/java/com/android/server/location/provider/proxy/ProxyGeocodeProvider.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.location.provider.proxy; + +import android.annotation.Nullable; +import android.content.Context; +import android.location.provider.ForwardGeocodeRequest; +import android.location.provider.GeocodeProviderBase; +import android.location.provider.IGeocodeCallback; +import android.location.provider.IGeocodeProvider; +import android.location.provider.ReverseGeocodeRequest; +import android.os.IBinder; +import android.os.RemoteException; + +import com.android.server.servicewatcher.CurrentUserServiceSupplier; +import com.android.server.servicewatcher.ServiceWatcher; + +/** Proxy for IGeocodeProvider implementations. */ +public class ProxyGeocodeProvider { + + /** + * Creates and registers this proxy. If no suitable service is available for the proxy, returns + * null. + */ + @Nullable + public static ProxyGeocodeProvider createAndRegister(Context context) { + ProxyGeocodeProvider proxy = new ProxyGeocodeProvider(context); + if (proxy.register()) { + return proxy; + } else { + return null; + } + } + + private final ServiceWatcher mServiceWatcher; + + private ProxyGeocodeProvider(Context context) { + mServiceWatcher = + ServiceWatcher.create( + context, + "GeocoderProxy", + CurrentUserServiceSupplier.createFromConfig( + context, + GeocodeProviderBase.ACTION_GEOCODE_PROVIDER, + com.android.internal.R.bool.config_enableGeocoderOverlay, + com.android.internal.R.string.config_geocoderProviderPackageName), + null); + } + + private boolean register() { + boolean resolves = mServiceWatcher.checkServiceResolves(); + if (resolves) { + mServiceWatcher.register(); + } + return resolves; + } + + /** Reverse geocodes. */ + public void reverseGeocode(ReverseGeocodeRequest request, IGeocodeCallback callback) { + mServiceWatcher.runOnBinder( + new ServiceWatcher.BinderOperation() { + @Override + public void run(IBinder binder) throws RemoteException { + IGeocodeProvider.Stub.asInterface(binder).reverseGeocode(request, callback); + } + + @Override + public void onError(Throwable t) { + try { + callback.onError(t.toString()); + } catch (RemoteException e) { + // ignore + } + } + }); + } + + /** Forward geocodes. */ + public void forwardGeocode(ForwardGeocodeRequest request, IGeocodeCallback callback) { + mServiceWatcher.runOnBinder( + new ServiceWatcher.BinderOperation() { + @Override + public void run(IBinder binder) throws RemoteException { + IGeocodeProvider.Stub.asInterface(binder).forwardGeocode(request, callback); + } + + @Override + public void onError(Throwable t) { + try { + callback.onError(t.toString()); + } catch (RemoteException e) { + // ignore + } + } + }); + } +} diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 7fb3e001c4c3..9a76ebd148aa 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -18,6 +18,7 @@ package com.android.server.locksettings; import static android.security.Flags.reportPrimaryAuthAttempts; import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE; +import static android.Manifest.permission.CONFIGURE_FACTORY_RESET_PROTECTION; import static android.Manifest.permission.MANAGE_BIOMETRIC; import static android.Manifest.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS; import static android.Manifest.permission.SET_INITIAL_LOCK; @@ -27,6 +28,7 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.PROFILE_ENCRY import static android.app.admin.DevicePolicyResources.Strings.Core.PROFILE_ENCRYPTED_MESSAGE; import static android.app.admin.DevicePolicyResources.Strings.Core.PROFILE_ENCRYPTED_TITLE; import static android.content.Context.KEYGUARD_SERVICE; +import static android.content.Intent.ACTION_MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.UserHandle.USER_ALL; import static android.os.UserHandle.USER_SYSTEM; @@ -1201,8 +1203,9 @@ public class LockSettingsService extends ILockSettings.Stub { final boolean inSetupWizard = Settings.Secure.getIntForUser(cr, Settings.Secure.USER_SETUP_COMPLETE, 0, mainUserId) == 0; - final boolean secureFrp = Settings.Global.getInt(cr, - Settings.Global.SECURE_FRP_MODE, 0) == 1; + final boolean secureFrp = android.security.Flags.frpEnforcement() + ? mStorage.isFactoryResetProtectionActive() + : (Settings.Global.getInt(cr, Settings.Global.SECURE_FRP_MODE, 0) == 1); if (inSetupWizard && secureFrp) { throw new SecurityException("Cannot change credential in SUW while factory reset" @@ -2332,8 +2335,13 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mSpManager) { if (isSpecialUserId(userId)) { - return mSpManager.verifySpecialUserCredential(userId, getGateKeeperService(), + response = mSpManager.verifySpecialUserCredential(userId, getGateKeeperService(), credential, progressCallback); + if (android.security.Flags.frpEnforcement() && response.isMatched() + && userId == USER_FRP) { + mStorage.deactivateFactoryResetProtectionWithoutSecret(); + } + return response; } long protectorId = getCurrentLskfBasedProtectorId(userId); @@ -3054,6 +3062,7 @@ public class LockSettingsService extends ILockSettings.Stub { setCurrentLskfBasedProtectorId(newProtectorId, userId); LockPatternUtils.invalidateCredentialTypeCache(); synchronizeUnifiedChallengeForProfiles(userId, profilePasswords); + sendMainUserCredentialChangedNotificationIfNeeded(userId); setUserPasswordMetrics(credential, userId); mUnifiedProfilePasswordCache.removePassword(userId); @@ -3071,6 +3080,24 @@ public class LockSettingsService extends ILockSettings.Stub { return newProtectorId; } + private void sendMainUserCredentialChangedNotificationIfNeeded(int userId) { + if (!android.security.Flags.frpEnforcement()) { + return; + } + + if (userId != mInjector.getUserManagerInternal().getMainUserId()) { + return; + } + + sendBroadcast(new Intent(ACTION_MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED), + UserHandle.of(userId), CONFIGURE_FACTORY_RESET_PROTECTION); + } + + @VisibleForTesting + void sendBroadcast(Intent intent, UserHandle userHandle, String permission) { + mContext.sendBroadcastAsUser(intent, userHandle, permission, /* options */ null); + } + private void removeBiometricsForUser(int userId) { removeAllFingerprintForUser(userId); removeAllFaceForUser(userId); diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java index 6d123ccebc7c..158d444bcff2 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java @@ -34,6 +34,7 @@ import android.os.Environment; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import android.service.persistentdata.PersistentDataBlockManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.AtomicFile; @@ -587,6 +588,10 @@ class LockSettingsStorage { return mPersistentDataBlockManagerInternal; } + /** + * Writes main user credential handle to the persistent data block, to enable factory reset + * protection to be deactivated with the credential. + */ public void writePersistentDataBlock(int persistentType, int userId, int qualityForUi, byte[] payload) { PersistentDataBlockManagerInternal persistentDataBlock = getPersistentDataBlockManager(); @@ -610,6 +615,31 @@ class LockSettingsStorage { } } + public void deactivateFactoryResetProtectionWithoutSecret() { + PersistentDataBlockManagerInternal persistentDataBlock = getPersistentDataBlockManager(); + if (persistentDataBlock != null) { + persistentDataBlock.deactivateFactoryResetProtectionWithoutSecret(); + } else { + Slog.wtf(TAG, "Failed to get PersistentDataBlockManagerInternal"); + } + } + + public boolean isFactoryResetProtectionActive() { + PersistentDataBlockManager persistentDataBlockManager = + mContext.getSystemService(PersistentDataBlockManager.class); + if (persistentDataBlockManager != null) { + return persistentDataBlockManager.isFactoryResetProtectionActive(); + } else { + Slog.wtf(TAG, "Failed to get PersistentDataBlockManager"); + // This should never happen, but in the event it does, let's not block the user. This + // may be the wrong call, since if an attacker can find a way to prevent us from + // getting the PersistentDataBlockManager they can defeat FRP, but if they can block + // access to PersistentDataBlockManager they must have compromised the system and we've + // probably already lost this battle. + return false; + } + } + /** * Provides a concrete data structure to represent the minimal information from * a user's LSKF-based SP protector that is needed to verify the user's LSKF, diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 8cb5cef38ec6..f97f6d2350bc 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -105,6 +105,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -151,7 +152,9 @@ public class MediaSessionService extends SystemService implements Monitor { private boolean mHasFeatureLeanback; private ActivityManagerInternal mActivityManagerInternal; private UsageStatsManagerInternal mUsageStatsManagerInternal; - private final Set<Integer> mUserEngagingSessions = new HashSet<>(); + + /* Maps uid with all user engaging session tokens associated to it */ + private final Map<Integer, Set<MediaSession.Token>> mUserEngagingSessions = new HashMap<>(); // The FullUserRecord of the current users. (i.e. The foreground user that isn't a profile) // It's always not null after the MediaSessionService is started. @@ -615,32 +618,36 @@ public class MediaSessionService extends SystemService implements Monitor { } private void reportMediaInteractionEvent(MediaSessionRecordImpl record, boolean userEngaged) { - if (!android.app.usage.Flags.userInteractionTypeApi()) { - return; - } + if (!android.app.usage.Flags.userInteractionTypeApi() + || !(record instanceof MediaSessionRecord)) { + return; + } - String packageName = record.getPackageName(); - int sessionUid = record.getUid(); - String actionToLog = null; - if (userEngaged) { - if (!mUserEngagingSessions.contains(sessionUid)) { - actionToLog = "start"; - } - mUserEngagingSessions.add(sessionUid); - } else { - if (mUserEngagingSessions.contains(sessionUid)) { - actionToLog = "stop"; - } + String packageName = record.getPackageName(); + int sessionUid = record.getUid(); + String actionToLog = null; + MediaSession.Token token = ((MediaSessionRecord) record).getSessionToken(); + if (userEngaged) { + if (!mUserEngagingSessions.containsKey(sessionUid)) { + mUserEngagingSessions.put(sessionUid, new HashSet<>()); + actionToLog = "start"; + } + mUserEngagingSessions.get(sessionUid).add(token); + } else if (mUserEngagingSessions.containsKey(sessionUid)) { + mUserEngagingSessions.get(sessionUid).remove(token); + if (mUserEngagingSessions.get(sessionUid).isEmpty()) { + actionToLog = "stop"; mUserEngagingSessions.remove(sessionUid); } + } - if (actionToLog != null) { - PersistableBundle extras = new PersistableBundle(); - extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, "android.media"); - extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, actionToLog); - mUsageStatsManagerInternal.reportUserInteractionEvent( - packageName, record.getUserId(), extras); - } + if (actionToLog != null) { + PersistableBundle extras = new PersistableBundle(); + extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, "android.media"); + extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, actionToLog); + mUsageStatsManagerInternal.reportUserInteractionEvent( + packageName, record.getUserId(), extras); + } } void tempAllowlistTargetPkgIfPossible(int targetUid, String targetPackage, diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java index 1546895e8df9..bbb19e351b5d 100644 --- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java +++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java @@ -550,8 +550,8 @@ public final class MediaProjectionManagerService extends SystemService break; case RECORD_CONTENT_TASK: IBinder taskWindowContainerToken = - mProjectionGrant.getLaunchCookieInternal() == null ? null - : mProjectionGrant.getLaunchCookieInternal().binder; + mProjectionGrant.getLaunchCookie() == null ? null + : mProjectionGrant.getLaunchCookie().binder; setReviewedConsentSessionLocked( ContentRecordingSession.createTaskSession(taskWindowContainerToken)); break; @@ -603,17 +603,6 @@ public final class MediaProjectionManagerService extends SystemService return projection; } - /** - * Test API mirroring the types in the aidl interface for access outside the projection - * package. - */ - @VisibleForTesting - public IMediaProjection createProjectionInternal(int processUid, String packageName, int type, - boolean isPermanentGrant) { - return createProjectionInternal(processUid, packageName, type, isPermanentGrant, - Binder.getCallingUserHandle()); - } - // TODO(b/261563516): Remove internal method and test aidl directly, here and elsewhere. @VisibleForTesting MediaProjection getProjectionInternal(int uid, String packageName) { @@ -1203,10 +1192,6 @@ public final class MediaProjectionManagerService extends SystemService @Override // Binder call public void setLaunchCookie(LaunchCookie launchCookie) { setLaunchCookie_enforcePermission(); - setLaunchCookieInternal(launchCookie); - } - - @VisibleForTesting void setLaunchCookieInternal(LaunchCookie launchCookie) { mLaunchCookie = launchCookie; } @@ -1214,10 +1199,6 @@ public final class MediaProjectionManagerService extends SystemService @Override // Binder call public LaunchCookie getLaunchCookie() { getLaunchCookie_enforcePermission(); - return getLaunchCookieInternal(); - } - - @VisibleForTesting LaunchCookie getLaunchCookieInternal() { return mLaunchCookie; } @@ -1225,11 +1206,6 @@ public final class MediaProjectionManagerService extends SystemService @Override public boolean isValid() { isValid_enforcePermission(); - return isValidInternal(); - } - - @VisibleForTesting - boolean isValidInternal() { synchronized (mLock) { final long curMs = mClock.uptimeMillis(); final boolean hasTimedOut = curMs - mCreateTimeMs > mTimeoutMs; @@ -1260,11 +1236,6 @@ public final class MediaProjectionManagerService extends SystemService @Override public void notifyVirtualDisplayCreated(int displayId) { notifyVirtualDisplayCreated_enforcePermission(); - notifyVirtualDisplayCreatedInternal(displayId); - } - - @VisibleForTesting - void notifyVirtualDisplayCreatedInternal(int displayId) { synchronized (mLock) { mVirtualDisplayId = displayId; diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index f9ffb1cebac4..b5c51af47009 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -26,6 +26,8 @@ import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.OBSERVE_NETWORK_POLICY; import static android.Manifest.permission.READ_PHONE_STATE; import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; +import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK; +import static android.app.ActivityManager.PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK; import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; import static android.app.ActivityManager.isProcStateConsideredInteraction; import static android.app.ActivityManager.printCapabilitiesSummary; @@ -85,8 +87,10 @@ import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_ import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS; import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM; import static android.net.NetworkPolicyManager.ALLOWED_REASON_TOP; +import static android.net.NetworkPolicyManager.BACKGROUND_THRESHOLD_STATE; import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; +import static android.net.NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE; import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.POLICY_NONE; import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; @@ -97,6 +101,7 @@ import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; import static android.net.NetworkPolicyManager.RULE_REJECT_RESTRICTED_MODE; import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED; import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED; +import static android.net.NetworkPolicyManager.TOP_THRESHOLD_STATE; import static android.net.NetworkPolicyManager.allowedReasonsToString; import static android.net.NetworkPolicyManager.blockedReasonsToString; import static android.net.NetworkPolicyManager.isProcStateAllowedNetworkWhileBackground; @@ -469,7 +474,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { */ private static final int MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS = 24; - private static final int UID_MSG_STATE_CHANGED = 100; + @VisibleForTesting + static final int UID_MSG_STATE_CHANGED = 100; private static final int UID_MSG_GONE = 101; private static final String PROP_SUB_PLAN_OWNER = "persist.sys.sub_plan_owner"; @@ -1075,8 +1081,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final int cutpoint = mBackgroundNetworkRestricted ? PROCESS_STATE_UNKNOWN : NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE; - // TODO (b/319728914): Filter out the unnecessary changes when using no cutpoint. - mActivityManagerInternal.registerNetworkPolicyUidObserver(mUidObserver, changes, cutpoint, "android"); mNetworkManager.registerObserver(mAlertObserver); @@ -1185,6 +1189,51 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } final private IUidObserver mUidObserver = new UidObserver() { + + /** + * Returns whether the uid state change information is relevant for the service. If the + * state information does not lead to any change in the network rules, it can safely be + * ignored. + */ + @GuardedBy("mUidStateCallbackInfos") + private boolean isUidStateChangeRelevant(UidStateCallbackInfo previousInfo, + int newProcState, long newProcStateSeq, int newCapability) { + if (previousInfo.procStateSeq == -1) { + // No previous record. Always process the first state change callback. + return true; + } + if (newProcStateSeq <= previousInfo.procStateSeq) { + // Stale callback. Ignore. + return false; + } + final int previousProcState = previousInfo.procState; + if (mBackgroundNetworkRestricted && (previousProcState >= BACKGROUND_THRESHOLD_STATE) + != (newProcState >= BACKGROUND_THRESHOLD_STATE)) { + // Proc-state change crossed BACKGROUND_THRESHOLD_STATE: Network rules for the + // BACKGROUND chain may change. + return true; + } + if ((previousProcState <= TOP_THRESHOLD_STATE) + != (newProcState <= TOP_THRESHOLD_STATE)) { + // Proc-state change crossed TOP_THRESHOLD_STATE: Network rules for the + // LOW_POWER_STANDBY chain may change. + return true; + } + if ((previousProcState <= FOREGROUND_THRESHOLD_STATE) + != (newProcState <= FOREGROUND_THRESHOLD_STATE)) { + // Proc-state change crossed FOREGROUND_THRESHOLD_STATE: Network rules for many + // different chains may change. + return true; + } + final int networkCapabilities = PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK + | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK; + if ((previousInfo.capability & networkCapabilities) + != (newCapability & networkCapabilities)) { + return true; + } + return false; + } + @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, @ProcessCapability int capability) { synchronized (mUidStateCallbackInfos) { @@ -1193,13 +1242,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { callbackInfo = new UidStateCallbackInfo(); mUidStateCallbackInfos.put(uid, callbackInfo); } - if (callbackInfo.procStateSeq == -1 || procStateSeq > callbackInfo.procStateSeq) { + if (isUidStateChangeRelevant(callbackInfo, procState, procStateSeq, capability)) { callbackInfo.update(uid, procState, procStateSeq, capability); - } - if (!callbackInfo.isPending) { - mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, callbackInfo) - .sendToTarget(); - callbackInfo.isPending = true; + if (!callbackInfo.isPending) { + mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, callbackInfo) + .sendToTarget(); + callbackInfo.isPending = true; + } } } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index d751186b2869..53ae60b0cc76 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1879,11 +1879,11 @@ public class NotificationManagerService extends SystemService { true, record.getUserId(), REASON_TIMEOUT, null); // If cancellation will be prevented due to lifetime extension, we send an // update to system UI. + final int packageImportance = getPackageImportanceWithIdentity( + record.getSbn().getPackageName()); synchronized (mNotificationLock) { maybeNotifySystemUiListenerLifetimeExtendedLocked(record, - record.getSbn().getPackageName(), - mActivityManager.getPackageImportance( - record.getSbn().getPackageName())); + record.getSbn().getPackageName(), packageImportance); } } else { cancelNotification(record.getSbn().getUid(), @@ -3852,7 +3852,7 @@ public class NotificationManagerService extends SystemService { // If cancellation will be prevented due to lifetime extension, we send an update to // system UI. NotificationRecord record = null; - final int packageImportance = mActivityManager.getPackageImportance(pkg); + final int packageImportance = getPackageImportanceWithIdentity(pkg); synchronized (mNotificationLock) { record = findNotificationLocked(pkg, tag, id, userId); maybeNotifySystemUiListenerLifetimeExtendedLocked(record, pkg, @@ -3877,10 +3877,9 @@ public class NotificationManagerService extends SystemService { pkg, null, 0, FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB | FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY, userId, REASON_APP_CANCEL_ALL); + final int packageImportance = getPackageImportanceWithIdentity(pkg); // If cancellation will be prevented due to lifetime extension, we send updates // to system UI. - // In this case, we need to hold the lock to access these lists. - final int packageImportance = mActivityManager.getPackageImportance(pkg); synchronized (mNotificationLock) { notifySystemUiListenerLifetimeExtendedListLocked(mNotificationList, packageImportance); @@ -5029,7 +5028,7 @@ public class NotificationManagerService extends SystemService { pkg = info.component.getPackageName(); } if (lifetimeExtensionRefactor()) { - packageImportance = mActivityManager.getPackageImportance(pkg); + packageImportance = getPackageImportanceWithIdentity(pkg); } else { packageImportance = IMPORTANCE_NONE; } @@ -5348,7 +5347,7 @@ public class NotificationManagerService extends SystemService { final int packageImportance; try { if (lifetimeExtensionRefactor()) { - packageImportance = mActivityManager.getPackageImportance(pkg); + packageImportance = getPackageImportanceWithIdentity(pkg); } else { packageImportance = IMPORTANCE_NONE; } @@ -7609,14 +7608,9 @@ public class NotificationManagerService extends SystemService { } } - // Need escalated privileges to get package importance - final long token = Binder.clearCallingIdentity(); - boolean isAppForeground; - try { - isAppForeground = mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND; - } finally { - Binder.restoreCallingIdentity(token); - } + // Need escalated privileges to get package importance. + final int packageImportance = getPackageImportanceWithIdentity(pkg); + boolean isAppForeground = packageImportance == IMPORTANCE_FOREGROUND; mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground, tracker)); return true; } @@ -7944,9 +7938,9 @@ public class NotificationManagerService extends SystemService { NotificationRecord r = mNotificationsByKey.get(key); packageName = r != null ? r.getSbn().getPackageName() : null; } + final int packageImportance = getPackageImportanceWithIdentity(packageName); boolean isAppForeground = packageName != null - && mActivityManager.getPackageImportance(packageName) - == IMPORTANCE_FOREGROUND; + && packageImportance == IMPORTANCE_FOREGROUND; synchronized (mNotificationLock) { NotificationRecord r = mNotificationsByKey.get(key); if (r != null) { @@ -11867,6 +11861,18 @@ public class NotificationManagerService extends SystemService { } } + @FlaggedApi(FLAG_LIFETIME_EXTENSION_REFACTOR) + private int getPackageImportanceWithIdentity(String pkg) { + final long token = Binder.clearCallingIdentity(); + final int packageImportance; + try { + packageImportance = mActivityManager.getPackageImportance(pkg); + } finally { + Binder.restoreCallingIdentity(token); + } + return packageImportance; + } + public class NotificationListeners extends ManagedServices { static final String TAG_ENABLED_NOTIFICATION_LISTENERS = "enabled_listeners"; static final String TAG_REQUESTED_LISTENERS = "request_listeners"; diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig index 722654a9102c..53244f9e5ecf 100644 --- a/services/core/java/com/android/server/notification/flags.aconfig +++ b/services/core/java/com/android/server/notification/flags.aconfig @@ -50,15 +50,6 @@ flag { } flag { - name: "sensitive_notification_app_protection" - namespace: "systemui" - description: "This flag controls the sensitive notification app protections while screen sharing" - bug: "312784351" - # Referenced in WM where WM starts before DeviceConfig - is_fixed_read_only: true -} - -flag { name: "notification_reduce_messagequeue_usage" namespace: "systemui" description: "When this flag is on, NMS will no longer call removeMessage() and hasCallbacks() on Handler" diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index d987622676b5..872952299055 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -1143,10 +1143,9 @@ public final class OverlayManagerService extends SystemService { }; private static final class PackageManagerHelperImpl implements PackageManagerHelper { - private static final class PackageStateUsers { + private static class PackageStateUsers { private PackageState mPackageState; - private Boolean mDefinesOverlayable = null; - private final ArraySet<Integer> mInstalledUsers = new ArraySet<>(); + private final Set<Integer> mInstalledUsers = new ArraySet<>(); private PackageStateUsers(@NonNull PackageState packageState) { this.mPackageState = packageState; } @@ -1196,11 +1195,13 @@ public final class OverlayManagerService extends SystemService { return userPackages; } - private PackageStateUsers getRawPackageStateForUser(@NonNull final String packageName, + @Override + @Nullable + public PackageState getPackageStateForUser(@NonNull final String packageName, final int userId) { final PackageStateUsers pkg = mCache.get(packageName); if (pkg != null && pkg.mInstalledUsers.contains(userId)) { - return pkg; + return pkg.mPackageState; } try { if (!mPackageManager.isPackageAvailable(packageName, userId)) { @@ -1214,14 +1215,8 @@ public final class OverlayManagerService extends SystemService { return addPackageUser(packageName, userId); } - @Override - public PackageState getPackageStateForUser(@NonNull final String packageName, - final int userId) { - final PackageStateUsers pkg = getRawPackageStateForUser(packageName, userId); - return pkg != null ? pkg.mPackageState : null; - } - - private PackageStateUsers addPackageUser(@NonNull final String packageName, + @NonNull + private PackageState addPackageUser(@NonNull final String packageName, final int user) { final PackageState pkg = mPackageManagerInternal.getPackageStateInternal(packageName); if (pkg == null) { @@ -1233,20 +1228,20 @@ public final class OverlayManagerService extends SystemService { } @NonNull - private PackageStateUsers addPackageUser(@NonNull final PackageState pkg, + private PackageState addPackageUser(@NonNull final PackageState pkg, final int user) { PackageStateUsers pkgUsers = mCache.get(pkg.getPackageName()); if (pkgUsers == null) { pkgUsers = new PackageStateUsers(pkg); mCache.put(pkg.getPackageName(), pkgUsers); - } else if (pkgUsers.mPackageState != pkg) { + } else { pkgUsers.mPackageState = pkg; - pkgUsers.mDefinesOverlayable = null; } pkgUsers.mInstalledUsers.add(user); - return pkgUsers; + return pkgUsers.mPackageState; } + @NonNull private void removePackageUser(@NonNull final String packageName, final int user) { final PackageStateUsers pkgUsers = mCache.get(packageName); @@ -1264,15 +1259,15 @@ public final class OverlayManagerService extends SystemService { } } + @Nullable public PackageState onPackageAdded(@NonNull final String packageName, final int userId) { - final var pu = addPackageUser(packageName, userId); - return pu != null ? pu.mPackageState : null; + return addPackageUser(packageName, userId); } + @Nullable public PackageState onPackageUpdated(@NonNull final String packageName, final int userId) { - final var pu = addPackageUser(packageName, userId); - return pu != null ? pu.mPackageState : null; + return addPackageUser(packageName, userId); } public void onPackageRemoved(@NonNull final String packageName, final int userId) { @@ -1312,30 +1307,22 @@ public final class OverlayManagerService extends SystemService { return (pkgs.length == 0) ? null : pkgs[0]; } + @Nullable @Override public OverlayableInfo getOverlayableForTarget(@NonNull String packageName, @NonNull String targetOverlayableName, int userId) throws IOException { - final var psu = getRawPackageStateForUser(packageName, userId); - final var pkg = (psu == null || psu.mPackageState == null) - ? null : psu.mPackageState.getAndroidPackage(); + var packageState = getPackageStateForUser(packageName, userId); + var pkg = packageState == null ? null : packageState.getAndroidPackage(); if (pkg == null) { throw new IOException("Unable to get target package"); } - if (Boolean.FALSE.equals(psu.mDefinesOverlayable)) { - return null; - } - ApkAssets apkAssets = null; try { apkAssets = ApkAssets.loadFromPath(pkg.getSplits().get(0).getPath(), ApkAssets.PROPERTY_ONLY_OVERLAYABLES); - if (psu.mDefinesOverlayable == null) { - psu.mDefinesOverlayable = apkAssets.definesOverlayable(); - } - return Boolean.FALSE.equals(psu.mDefinesOverlayable) - ? null : apkAssets.getOverlayableInfo(targetOverlayableName); + return apkAssets.getOverlayableInfo(targetOverlayableName); } finally { if (apkAssets != null) { try { @@ -1349,29 +1336,24 @@ public final class OverlayManagerService extends SystemService { @Override public boolean doesTargetDefineOverlayable(String targetPackageName, int userId) throws IOException { - final var psu = getRawPackageStateForUser(targetPackageName, userId); - var pkg = (psu == null || psu.mPackageState == null) - ? null : psu.mPackageState.getAndroidPackage(); + var packageState = getPackageStateForUser(targetPackageName, userId); + var pkg = packageState == null ? null : packageState.getAndroidPackage(); if (pkg == null) { throw new IOException("Unable to get target package"); } - if (psu.mDefinesOverlayable == null) { - ApkAssets apkAssets = null; - try { - apkAssets = ApkAssets.loadFromPath(pkg.getSplits().get(0).getPath(), - ApkAssets.PROPERTY_ONLY_OVERLAYABLES); - psu.mDefinesOverlayable = apkAssets.definesOverlayable(); - } finally { - if (apkAssets != null) { - try { - apkAssets.close(); - } catch (Throwable ignored) { - } + ApkAssets apkAssets = null; + try { + apkAssets = ApkAssets.loadFromPath(pkg.getSplits().get(0).getPath()); + return apkAssets.definesOverlayable(); + } finally { + if (apkAssets != null) { + try { + apkAssets.close(); + } catch (Throwable ignored) { } } } - return psu.mDefinesOverlayable; } @Override diff --git a/services/core/java/com/android/server/ondeviceintelligence/OWNERS b/services/core/java/com/android/server/ondeviceintelligence/OWNERS new file mode 100644 index 000000000000..09774f78d712 --- /dev/null +++ b/services/core/java/com/android/server/ondeviceintelligence/OWNERS @@ -0,0 +1 @@ +file:/core/java/android/app/ondeviceintelligence/OWNERS diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java index 85d2df320fc9..bbce26c85549 100644 --- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java +++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java @@ -27,11 +27,14 @@ import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; +import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.Flags; import android.content.pm.PackageManager; import android.os.Build; import android.os.Environment; import android.os.FileUtils; +import android.os.SystemProperties; import android.os.Trace; import android.text.TextUtils; import android.util.ArraySet; @@ -50,9 +53,15 @@ import libcore.io.IoUtils; import java.io.File; import java.io.IOException; +import java.util.Set; final class PackageAbiHelperImpl implements PackageAbiHelper { + @Nullable + private static String[] sNativelySupported32BitAbis = null; + @Nullable + private static String[] sNativelySupported64BitAbis = null; + private static String calculateBundledApkRoot(final String codePathString) { final File codePath = new File(codePathString); final File codeRoot; @@ -122,13 +131,20 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { } } - private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws - PackageManagerException { + private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet, + boolean forceMatch) throws PackageManagerException { if (copyRet < 0) { if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { throw new PackageManagerException(copyRet, message); } + + if (forceMatch && copyRet == PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { + throw new PackageManagerException( + PackageManager.INSTALL_FAILED_MULTI_ARCH_NOT_MATCH_ALL_NATIVE_ABIS, + "The multiArch app's native libs don't support all the natively" + + " supported ABIs of the device."); + } } } @@ -296,7 +312,40 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { return new Abis(primaryCpuAbi, secondaryCpuAbi); } + @NonNull + private static String[] getNativelySupportedAbis(@NonNull String[] supportedAbis) { + Set<String> nativelySupportedAbis = new ArraySet<>(); + for (int i = 0; i < supportedAbis.length; i++) { + final String currentAbi = supportedAbis[i]; + // In presence of a native bridge this means the Abi is emulated. + final String currentIsa = VMRuntime.getInstructionSet(currentAbi); + if (TextUtils.isEmpty(SystemProperties.get("ro.dalvik.vm.isa." + currentIsa))) { + nativelySupportedAbis.add(currentAbi); + } + } + return nativelySupportedAbis.toArray(new String[0]); + } + + private static String[] getNativelySupported32BitAbis() { + if (sNativelySupported32BitAbis != null) { + return sNativelySupported32BitAbis; + } + + sNativelySupported32BitAbis = getNativelySupportedAbis(Build.SUPPORTED_32_BIT_ABIS); + return sNativelySupported32BitAbis; + } + + private static String[] getNativelySupported64BitAbis() { + if (sNativelySupported64BitAbis != null) { + return sNativelySupported64BitAbis; + } + + sNativelySupported64BitAbis = getNativelySupportedAbis(Build.SUPPORTED_64_BIT_ABIS); + return sNativelySupported64BitAbis; + } + @Override + @SuppressWarnings("AndroidFrameworkCompatChange") // the check is before the apk is installed public Pair<Abis, NativeLibraryPaths> derivePackageAbi(AndroidPackage pkg, boolean isSystemApp, boolean isUpdatedSystemApp, String cpuAbiOverride, File appLib32InstallDir) throws PackageManagerException { @@ -334,18 +383,33 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { primaryCpuAbi = null; secondaryCpuAbi = null; if (pkg.isMultiArch()) { + // Force the match for these cases + // 1. pkg.getTargetSdkVersion >= Build.VERSION_CODES.VANILLA_ICE_CREAM + // 2. cpuAbiOverride is null. If it is non-null, it is set via shell for testing + final boolean forceMatch = Flags.forceMultiArchNativeLibsMatch() + && pkg.getTargetSdkVersion() >= Build.VERSION_CODES.VANILLA_ICE_CREAM + && cpuAbiOverride == null; + + String[] supported32BitAbis = forceMatch ? getNativelySupported32BitAbis() + : Build.SUPPORTED_32_BIT_ABIS; + String[] supported64BitAbis = forceMatch ? getNativelySupported64BitAbis() + : Build.SUPPORTED_64_BIT_ABIS; + + final boolean systemSupports32BitAbi = supported32BitAbis.length > 0; + final boolean systemSupports64BitAbi = supported64BitAbis.length > 0; + int abi32 = PackageManager.NO_NATIVE_LIBRARIES; int abi64 = PackageManager.NO_NATIVE_LIBRARIES; - if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { + if (systemSupports32BitAbi) { if (extractLibs) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, - nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, + nativeLibraryRoot, supported32BitAbis, useIsaSpecificSubdirs, onIncremental); } else { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); abi32 = NativeLibraryHelper.findSupportedAbi( - handle, Build.SUPPORTED_32_BIT_ABIS); + handle, supported32BitAbis); } Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } @@ -357,24 +421,26 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { } maybeThrowExceptionForMultiArchCopy( - "Error unpackaging 32 bit native libs for multiarch app.", abi32); + "Error unpackaging 32 bit native libs for multiarch app.", abi32, + forceMatch && systemSupports32BitAbi); - if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { + if (systemSupports64BitAbi) { if (extractLibs) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, - nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, + nativeLibraryRoot, supported64BitAbis, useIsaSpecificSubdirs, onIncremental); } else { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); abi64 = NativeLibraryHelper.findSupportedAbi( - handle, Build.SUPPORTED_64_BIT_ABIS); + handle, supported64BitAbis); } Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } maybeThrowExceptionForMultiArchCopy( - "Error unpackaging 64 bit native libs for multiarch app.", abi64); + "Error unpackaging 64 bit native libs for multiarch app.", abi64, + forceMatch && systemSupports64BitAbi); if (abi64 >= 0) { // Shared library native libs should be in the APK zip aligned @@ -382,11 +448,11 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Shared library native lib extraction not supported"); } - primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; + primaryCpuAbi = supported64BitAbis[abi64]; } if (abi32 >= 0) { - final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; + final String abi = supported32BitAbis[abi32]; if (abi64 >= 0) { if (pkg.is32BitAbiPreferred()) { secondaryCpuAbi = primaryCpuAbi; diff --git a/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java b/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java index 4b98e3408cd3..ea37d8e5d3c9 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java @@ -78,6 +78,7 @@ public final class PackageInstallerHistoricalSession { private final int mSessionErrorCode; private final String mSessionErrorMessage; private final String mPreVerifiedDomains; + private final String mPackageName; PackageInstallerHistoricalSession(int sessionId, int userId, int originalInstallerUid, String originalInstallerPackageName, InstallSource installSource, int installerUid, @@ -88,7 +89,8 @@ public final class PackageInstallerHistoricalSession { String finalMessage, SessionParams params, int parentSessionId, int[] childSessionIds, boolean sessionApplied, boolean sessionFailed, boolean sessionReady, int sessionErrorCode, String sessionErrorMessage, - PreapprovalDetails preapprovalDetails, DomainSet preVerifiedDomains) { + PreapprovalDetails preapprovalDetails, DomainSet preVerifiedDomains, + String packageNameFromApk) { this.sessionId = sessionId; this.userId = userId; this.mOriginalInstallerUid = originalInstallerUid; @@ -135,6 +137,9 @@ public final class PackageInstallerHistoricalSession { } else { this.mPreVerifiedDomains = null; } + + this.mPackageName = preapprovalDetails != null ? preapprovalDetails.getPackageName() + : packageNameFromApk != null ? packageNameFromApk : params.appPackageName; } void dump(IndentingPrintWriter pw) { @@ -178,6 +183,7 @@ public final class PackageInstallerHistoricalSession { pw.printPair("mSessionErrorMessage", mSessionErrorMessage); pw.printPair("mPreapprovalDetails", mPreapprovalDetails); pw.printPair("mPreVerifiedDomains", mPreVerifiedDomains); + pw.printPair("mAppPackageName", mPackageName); pw.println(); pw.decreaseIndent(); @@ -206,6 +212,7 @@ public final class PackageInstallerHistoricalSession { info.createdMillis = mCreatedMillis; info.updatedMillis = mUpdatedMillis; info.installerUid = mInstallerUid; + info.appPackageName = mPackageName; return info; } } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index c860b5ae79f6..5792d864a8ab 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -1242,7 +1242,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mStageDirInUse, mDestroyed, mFds.size(), mBridges.size(), mFinalStatus, mFinalMessage, params, mParentSessionId, getChildSessionIdsLocked(), mSessionApplied, mSessionFailed, mSessionReady, mSessionErrorCode, - mSessionErrorMessage, mPreapprovalDetails, mPreVerifiedDomains); + mSessionErrorMessage, mPreapprovalDetails, mPreVerifiedDomains, mPackageName); } } diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index f44fcf002a62..21e2bf2e76e5 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -42,6 +42,7 @@ import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.AppOpsManager.AttributionFlags; import android.app.IActivityManager; +import android.companion.virtual.VirtualDeviceManager; import android.content.AttributionSource; import android.content.AttributionSourceState; import android.content.Context; @@ -78,6 +79,7 @@ import com.android.internal.util.Preconditions; import com.android.internal.util.function.QuadFunction; import com.android.internal.util.function.TriFunction; import com.android.server.LocalServices; +import com.android.server.companion.virtual.VirtualDeviceManagerInternal; import com.android.server.pm.UserManagerService; import com.android.server.pm.permission.PermissionManagerServiceInternal.HotwordDetectionServiceProvider; import com.android.server.pm.pkg.AndroidPackage; @@ -135,6 +137,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { @Nullable private HotwordDetectionServiceProvider mHotwordDetectionServiceProvider; + @Nullable + private VirtualDeviceManagerInternal mVirtualDeviceManagerInternal; + PermissionManagerService(@NonNull Context context, @NonNull ArrayMap<String, FeatureInfo> availableFeatures) { // The package info cache is the cache for package and permission information. @@ -146,6 +151,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { mContext = context; mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class); mAppOpsManager = context.getSystemService(AppOpsManager.class); + mVirtualDeviceManagerInternal = + LocalServices.getService(VirtualDeviceManagerInternal.class); mAttributionSourceRegistry = new AttributionSourceRegistry(context); @@ -246,16 +253,30 @@ public class PermissionManagerService extends IPermissionManager.Stub { return PackageManager.PERMISSION_DENIED; } + String persistentDeviceId = getPersistentDeviceId(deviceId); + final CheckPermissionDelegate checkPermissionDelegate; synchronized (mLock) { checkPermissionDelegate = mCheckPermissionDelegate; } - - if (checkPermissionDelegate == null) { - return mPermissionManagerServiceImpl.checkUidPermission(uid, permissionName, deviceId); + if (checkPermissionDelegate == null) { + return mPermissionManagerServiceImpl.checkUidPermission(uid, permissionName, + persistentDeviceId); } return checkPermissionDelegate.checkUidPermission(uid, permissionName, - deviceId, mPermissionManagerServiceImpl::checkUidPermission); + persistentDeviceId, mPermissionManagerServiceImpl::checkUidPermission); + } + + private String getPersistentDeviceId(int deviceId) { + if (deviceId == Context.DEVICE_ID_DEFAULT) { + return VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT; + } + + if (mVirtualDeviceManagerInternal == null) { + mVirtualDeviceManagerInternal = + LocalServices.getService(VirtualDeviceManagerInternal.class); + } + return mVirtualDeviceManagerInternal.getPersistentIdForDevice(deviceId); } @Override @@ -608,15 +629,17 @@ public class PermissionManagerService extends IPermissionManager.Stub { @Override public boolean shouldShowRequestPermissionRationale(String packageName, String permissionName, int deviceId, int userId) { + String persistentDeviceId = getPersistentDeviceId(deviceId); return mPermissionManagerServiceImpl.shouldShowRequestPermissionRationale(packageName, - permissionName, deviceId, userId); + permissionName, persistentDeviceId, userId); } @Override public boolean isPermissionRevokedByPolicy(String packageName, String permissionName, int deviceId, int userId) { + String persistentDeviceId = getPersistentDeviceId(deviceId); return mPermissionManagerServiceImpl.isPermissionRevokedByPolicy(packageName, - permissionName, deviceId, userId); + permissionName, persistentDeviceId, userId); } @Override @@ -914,13 +937,13 @@ public class PermissionManagerService extends IPermissionManager.Stub { * * @param uid the UID to be checked * @param permissionName the name of the permission to be checked - * @param deviceId The device ID + * @param persistentDeviceId The persistent device ID * @param superImpl the original implementation that can be delegated to * @return {@link android.content.pm.PackageManager#PERMISSION_GRANTED} if the package has * the permission, or {@link android.content.pm.PackageManager#PERMISSION_DENIED} otherwise */ - int checkUidPermission(int uid, @NonNull String permissionName, int deviceId, - TriFunction<Integer, String, Integer, Integer> superImpl); + int checkUidPermission(int uid, @NonNull String permissionName, String persistentDeviceId, + TriFunction<Integer, String, String, Integer> superImpl); /** * @return list of delegated permissions @@ -965,17 +988,18 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @Override - public int checkUidPermission(int uid, @NonNull String permissionName, int deviceId, - @NonNull TriFunction<Integer, String, Integer, Integer> superImpl) { + public int checkUidPermission(int uid, @NonNull String permissionName, + String persistentDeviceId, + @NonNull TriFunction<Integer, String, String, Integer> superImpl) { if (uid == mDelegatedUid && isDelegatedPermission(permissionName)) { final long identity = Binder.clearCallingIdentity(); try { - return superImpl.apply(Process.SHELL_UID, permissionName, deviceId); + return superImpl.apply(Process.SHELL_UID, permissionName, persistentDeviceId); } finally { Binder.restoreCallingIdentity(identity); } } - return superImpl.apply(uid, permissionName, deviceId); + return superImpl.apply(uid, permissionName, persistentDeviceId); } @Override diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java index c5b637d8b48b..70913c351eeb 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java @@ -682,7 +682,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt } @Override - public int getPermissionFlags(String packageName, String permName, String persistentDeviceId, + public int getPermissionFlags(String packageName, String permName, String deviceId, int userId) { final int callingUid = Binder.getCallingUid(); return getPermissionFlagsInternal(packageName, permName, callingUid, userId); @@ -726,8 +726,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt @Override public void updatePermissionFlags(String packageName, String permName, int flagMask, - int flagValues, boolean checkAdjustPolicyFlagPermission, String persistentDeviceId, - int userId) { + int flagValues, boolean checkAdjustPolicyFlagPermission, String deviceId, int userId) { final int callingUid = Binder.getCallingUid(); boolean overridePolicy = false; @@ -917,8 +916,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt } @Override - public int checkPermission(String pkgName, String permName, String persistentDeviceId, - int userId) { + public int checkPermission(String pkgName, String permName, String deviceId, int userId) { if (!mUserManagerInt.exists(userId)) { return PackageManager.PERMISSION_DENIED; } @@ -985,11 +983,11 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt } private int checkUidPermission(int uid, String permName) { - return checkUidPermission(uid, permName, Context.DEVICE_ID_DEFAULT); + return checkUidPermission(uid, permName, VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); } @Override - public int checkUidPermission(int uid, String permName, int deviceId) { + public int checkUidPermission(int uid, String permName, String deviceId) { final int userId = UserHandle.getUserId(uid); if (!mUserManagerInt.exists(userId)) { return PackageManager.PERMISSION_DENIED; @@ -1001,7 +999,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt @Override public Map<String, PermissionManager.PermissionState> getAllPermissionStates( - @NonNull String packageName, @NonNull String persistentDeviceId, int userId) { + @NonNull String packageName, @NonNull String deviceId, int userId) { throw new UnsupportedOperationException( "This method is supported in newer implementation only"); } @@ -1315,8 +1313,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt } @Override - public void grantRuntimePermission(String packageName, String permName, - String persistentDeviceId, int userId) { + public void grantRuntimePermission(String packageName, String permName, String deviceId, + int userId) { final int callingUid = Binder.getCallingUid(); final boolean overridePolicy = checkUidPermission(callingUid, ADJUST_RUNTIME_PERMISSIONS_POLICY) @@ -1489,12 +1487,13 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt } @Override - public void revokeRuntimePermission(String packageName, String permName, - String persistentDeviceId, int userId, String reason) { + public void revokeRuntimePermission(String packageName, String permName, String deviceId, + int userId, String reason) { final int callingUid = Binder.getCallingUid(); final boolean overridePolicy = checkUidPermission(callingUid, ADJUST_RUNTIME_PERMISSIONS_POLICY, - Context.DEVICE_ID_DEFAULT) == PackageManager.PERMISSION_GRANTED; + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT) + == PackageManager.PERMISSION_GRANTED; revokeRuntimePermissionInternal(packageName, permName, overridePolicy, callingUid, userId, reason, mDefaultPermissionCallback); @@ -1880,7 +1879,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt @Override public boolean shouldShowRequestPermissionRationale(String packageName, String permName, - int deviceId, @UserIdInt int userId) { + String deviceId, @UserIdInt int userId) { final int callingUid = Binder.getCallingUid(); if (UserHandle.getCallingUserId() != userId) { mContext.enforceCallingPermission( @@ -1943,7 +1942,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt } @Override - public boolean isPermissionRevokedByPolicy(String packageName, String permName, int deviceId, + public boolean isPermissionRevokedByPolicy(String packageName, String permName, String deviceId, int userId) { if (UserHandle.getCallingUserId() != userId) { mContext.enforceCallingPermission( diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java index 7c1042535973..47032ea2d6af 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java @@ -141,11 +141,11 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte * * @param packageName the package name for which to get the flags * @param permName the permission for which to get the flags - * @param persistentDeviceId The device for which to get the flags + * @param deviceId The device for which to get the flags * @param userId the user for which to get permission flags * @return the permission flags */ - int getPermissionFlags(String packageName, String permName, String persistentDeviceId, + int getPermissionFlags(String packageName, String permName, String deviceId, @UserIdInt int userId); /** @@ -156,11 +156,11 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte * @param permName The permission for which to update the flags * @param flagMask The flags which to replace * @param flagValues The flags with which to replace - * @param persistentDeviceId The device for which to update the permission flags + * @param deviceId The device for which to update the permission flags * @param userId The user for which to update the permission flags */ void updatePermissionFlags(String packageName, String permName, int flagMask, int flagValues, - boolean checkAdjustPolicyFlagPermission, String persistentDeviceId, + boolean checkAdjustPolicyFlagPermission, String deviceId, @UserIdInt int userId); /** @@ -295,12 +295,12 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte * * @param packageName the package to which to grant the permission * @param permName the permission name to grant - * @param persistentDeviceId the device for which to grant the permission + * @param deviceId the device for which to grant the permission * @param userId the user for which to grant the permission * * @see #revokeRuntimePermission(String, String, String, int, String) */ - void grantRuntimePermission(String packageName, String permName, String persistentDeviceId, + void grantRuntimePermission(String packageName, String permName, String deviceId, @UserIdInt int userId); /** @@ -316,13 +316,13 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte * * @param packageName the package from which to revoke the permission * @param permName the permission name to revoke - * @param persistentDeviceId the device for which to revoke the permission + * @param deviceId the device for which to revoke the permission * @param userId the user for which to revoke the permission * @param reason the reason for the revoke, or {@code null} for unspecified * * @see #grantRuntimePermission(String, String, String, int) */ - void revokeRuntimePermission(String packageName, String permName, String persistentDeviceId, + void revokeRuntimePermission(String packageName, String permName, String deviceId, @UserIdInt int userId, String reason); /** @@ -347,7 +347,7 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte * @return whether you can show permission rationale UI */ boolean shouldShowRequestPermissionRationale(String packageName, String permName, - int deviceId, @UserIdInt int userId); + String deviceId, @UserIdInt int userId); /** * Checks whether a particular permission has been revoked for a package by policy. Typically, @@ -361,8 +361,8 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte * @param userId the device for which you are checking the permission * @return whether the permission is restricted by policy */ - boolean isPermissionRevokedByPolicy(String packageName, String permName, int deviceId, - @UserIdInt int userId); + boolean isPermissionRevokedByPolicy(String packageName, String permName, + String deviceId, @UserIdInt int userId); /** * Get set of permissions that have been split into more granular or dependent permissions. @@ -389,11 +389,11 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte * * @param pkgName package name * @param permName permission name - * @param persistentDeviceId persistent device ID + * @param deviceId persistent device ID * @param userId user ID * @return permission result {@link PackageManager.PermissionResult} */ - int checkPermission(String pkgName, String permName, String persistentDeviceId, + int checkPermission(String pkgName, String permName, String deviceId, @UserIdInt int userId); /** @@ -401,23 +401,23 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte * * @param uid UID * @param permName permission name - * @param deviceId device ID + * @param deviceId persistent device ID * @return permission result {@link PackageManager.PermissionResult} */ - int checkUidPermission(int uid, String permName, int deviceId); + int checkUidPermission(int uid, String permName, String deviceId); /** * Gets the permission states for requested package, persistent device and user. * * @param packageName name of the package you are checking against - * @param persistentDeviceId id of the persistent device you are checking against + * @param deviceId id of the persistent device you are checking against * @param userId id of the user for which to get permission flags * @return mapping of all permission states keyed by their permission names * * @hide */ Map<String, PermissionState> getAllPermissionStates(@NonNull String packageName, - @NonNull String persistentDeviceId, @UserIdInt int userId); + @NonNull String deviceId, @UserIdInt int userId); /** * Get all the package names requesting app op permissions. diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java index 91a778d49d61..c18f856594ed 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java @@ -121,24 +121,22 @@ public class PermissionManagerServiceLoggingDecorator implements PermissionManag } @Override - public int getPermissionFlags(String packageName, String permName, String persistentDeviceId, + public int getPermissionFlags(String packageName, String permName, String deviceId, int userId) { Log.i(LOG_TAG, "getPermissionFlags(packageName = " + packageName + ", permName = " - + permName + ", persistentDeviceId = " + persistentDeviceId + ", userId = " + userId - + ")"); - return mService.getPermissionFlags(packageName, permName, persistentDeviceId, userId); + + permName + ", deviceId = " + deviceId + ", userId = " + userId + ")"); + return mService.getPermissionFlags(packageName, permName, deviceId, userId); } @Override public void updatePermissionFlags(String packageName, String permName, int flagMask, - int flagValues, boolean checkAdjustPolicyFlagPermission, String persistentDeviceId, - int userId) { + int flagValues, boolean checkAdjustPolicyFlagPermission, String deviceId, int userId) { Log.i(LOG_TAG, "updatePermissionFlags(packageName = " + packageName + ", permName = " + permName + ", flagMask = " + flagMask + ", flagValues = " + flagValues + ", checkAdjustPolicyFlagPermission = " + checkAdjustPolicyFlagPermission - + ", persistentDeviceId = " + persistentDeviceId + ", userId = " + userId + ")"); + + ", deviceId = " + deviceId + ", userId = " + userId + ")"); mService.updatePermissionFlags(packageName, permName, flagMask, flagValues, - checkAdjustPolicyFlagPermission, persistentDeviceId, userId); + checkAdjustPolicyFlagPermission, deviceId, userId); } @Override @@ -186,21 +184,20 @@ public class PermissionManagerServiceLoggingDecorator implements PermissionManag } @Override - public void grantRuntimePermission(String packageName, String permName, - String persistentDeviceId, int userId) { + public void grantRuntimePermission(String packageName, String permName, String deviceId, + int userId) { Log.i(LOG_TAG, "grantRuntimePermission(packageName = " + packageName + ", permName = " - + permName + ", persistentDeviceId = " + persistentDeviceId + ", userId = " + userId - + ")"); - mService.grantRuntimePermission(packageName, permName, persistentDeviceId, userId); + + permName + ", deviceId = " + deviceId + ", userId = " + userId + ")"); + mService.grantRuntimePermission(packageName, permName, deviceId, userId); } @Override - public void revokeRuntimePermission(String packageName, String permName, - String persistentDeviceId, int userId, String reason) { + public void revokeRuntimePermission(String packageName, String permName, String deviceId, + int userId, String reason) { Log.i(LOG_TAG, "revokeRuntimePermission(packageName = " + packageName + ", permName = " - + permName + ", persistentDeviceId = " + persistentDeviceId + ", userId = " + userId - + ", reason = " + reason + ")"); - mService.revokeRuntimePermission(packageName, permName, persistentDeviceId, userId, reason); + + permName + ", deviceId = " + deviceId + ", userId = " + userId + ", reason = " + + reason + ")"); + mService.revokeRuntimePermission(packageName, permName, deviceId, userId, reason); } @Override @@ -212,16 +209,16 @@ public class PermissionManagerServiceLoggingDecorator implements PermissionManag @Override public boolean shouldShowRequestPermissionRationale(String packageName, String permName, - int deviceId, int userId) { + String deviceId, int userId) { Log.i(LOG_TAG, "shouldShowRequestPermissionRationale(packageName = " + packageName - + ", permName = " + permName + ", deviceId = " + deviceId - + ", userId = " + userId + ")"); + + ", permName = " + permName + ", deviceId = " + deviceId + ", userId = " + + userId + ")"); return mService.shouldShowRequestPermissionRationale(packageName, permName, deviceId, userId); } @Override - public boolean isPermissionRevokedByPolicy(String packageName, String permName, int deviceId, + public boolean isPermissionRevokedByPolicy(String packageName, String permName, String deviceId, int userId) { Log.i(LOG_TAG, "isPermissionRevokedByPolicy(packageName = " + packageName + ", permName = " + permName + ", deviceId = " + deviceId + ", userId = " + userId + ")"); @@ -235,26 +232,27 @@ public class PermissionManagerServiceLoggingDecorator implements PermissionManag } @Override - public int checkPermission(String pkgName, String permName, String persistentDeviceId, + public int checkPermission(String pkgName, String permName, String deviceId, int userId) { Log.i(LOG_TAG, "checkPermission(pkgName = " + pkgName + ", permName = " + permName - + ", persistentDeviceId = " + persistentDeviceId + ", userId = " + userId + ")"); - return mService.checkPermission(pkgName, permName, persistentDeviceId, userId); + + ", deviceId = " + deviceId + ", userId = " + userId + ")"); + return mService.checkPermission(pkgName, permName, deviceId, userId); } @Override - public int checkUidPermission(int uid, String permName, int deviceId) { - Log.i(LOG_TAG, "checkUidPermission(uid = " + uid + ", permName = " - + permName + ", deviceId = " + deviceId + ")"); + public int checkUidPermission(int uid, String permName, String deviceId) { + Log.i(LOG_TAG, "checkUidPermission(uid = " + uid + ", permName = " + permName + + ", deviceId = " + deviceId + ")"); return mService.checkUidPermission(uid, permName, deviceId); } @Override public Map<String, PermissionState> getAllPermissionStates(@NonNull String packageName, - @NonNull String persistentDeviceId, int userId) { - Log.i(LOG_TAG, "getAllPermissionStates(packageName = " + packageName - + ", persistentDeviceId = " + persistentDeviceId + ", userId = " + userId + ")"); - return mService.getAllPermissionStates(packageName, persistentDeviceId, userId); + @NonNull String deviceId, int userId) { + Log.i(LOG_TAG, + "getAllPermissionStates(packageName = " + packageName + ", deviceId = " + deviceId + + ", userId = " + userId + ")"); + return mService.getAllPermissionStates(packageName, deviceId, userId); } @Override diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java index 0a4ff0797c97..40139baf0e98 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java @@ -154,12 +154,10 @@ public class PermissionManagerServiceTestingShim implements PermissionManagerSer } @Override - public int getPermissionFlags(String packageName, String permName, String persistentDeviceId, + public int getPermissionFlags(String packageName, String permName, String deviceId, @UserIdInt int userId) { - int oldVal = mOldImplementation.getPermissionFlags(packageName, permName, - persistentDeviceId, userId); - int newVal = mNewImplementation.getPermissionFlags(packageName, permName, - persistentDeviceId, userId); + int oldVal = mOldImplementation.getPermissionFlags(packageName, permName, deviceId, userId); + int newVal = mNewImplementation.getPermissionFlags(packageName, permName, deviceId, userId); if (!Objects.equals(oldVal, newVal)) { signalImplDifference("getPermissionFlags"); @@ -169,12 +167,12 @@ public class PermissionManagerServiceTestingShim implements PermissionManagerSer @Override public void updatePermissionFlags(String packageName, String permName, int flagMask, - int flagValues, boolean checkAdjustPolicyFlagPermission, String persistentDeviceId, + int flagValues, boolean checkAdjustPolicyFlagPermission, String deviceId, @UserIdInt int userId) { mOldImplementation.updatePermissionFlags(packageName, permName, flagMask, flagValues, - checkAdjustPolicyFlagPermission, persistentDeviceId, userId); + checkAdjustPolicyFlagPermission, deviceId, userId); mNewImplementation.updatePermissionFlags(packageName, permName, flagMask, flagValues, - checkAdjustPolicyFlagPermission, persistentDeviceId, userId); + checkAdjustPolicyFlagPermission, deviceId, userId); } @Override @@ -239,21 +237,17 @@ public class PermissionManagerServiceTestingShim implements PermissionManagerSer } @Override - public void grantRuntimePermission(String packageName, String permName, - String persistentDeviceId, @UserIdInt int userId) { - mOldImplementation.grantRuntimePermission(packageName, permName, persistentDeviceId, - userId); - mNewImplementation.grantRuntimePermission(packageName, permName, persistentDeviceId, - userId); + public void grantRuntimePermission(String packageName, String permName, String deviceId, + @UserIdInt int userId) { + mOldImplementation.grantRuntimePermission(packageName, permName, deviceId, userId); + mNewImplementation.grantRuntimePermission(packageName, permName, deviceId, userId); } @Override - public void revokeRuntimePermission(String packageName, String permName, - String persistentDeviceId, @UserIdInt int userId, String reason) { - mOldImplementation.revokeRuntimePermission(packageName, permName, persistentDeviceId, - userId, reason); - mNewImplementation.revokeRuntimePermission(packageName, permName, persistentDeviceId, - userId, reason); + public void revokeRuntimePermission(String packageName, String permName, String deviceId, + @UserIdInt int userId, String reason) { + mOldImplementation.revokeRuntimePermission(packageName, permName, deviceId, userId, reason); + mNewImplementation.revokeRuntimePermission(packageName, permName, deviceId, userId, reason); } @Override @@ -265,7 +259,7 @@ public class PermissionManagerServiceTestingShim implements PermissionManagerSer @Override public boolean shouldShowRequestPermissionRationale(String packageName, String permName, - int deviceId, @UserIdInt int userId) { + String deviceId, @UserIdInt int userId) { boolean oldVal = mOldImplementation.shouldShowRequestPermissionRationale(packageName, permName, deviceId, userId); boolean newVal = mNewImplementation.shouldShowRequestPermissionRationale(packageName, @@ -278,7 +272,7 @@ public class PermissionManagerServiceTestingShim implements PermissionManagerSer } @Override - public boolean isPermissionRevokedByPolicy(String packageName, String permName, int deviceId, + public boolean isPermissionRevokedByPolicy(String packageName, String permName, String deviceId, @UserIdInt int userId) { boolean oldVal = mOldImplementation.isPermissionRevokedByPolicy(packageName, permName, deviceId, userId); @@ -303,12 +297,9 @@ public class PermissionManagerServiceTestingShim implements PermissionManagerSer } @Override - public int checkPermission(String pkgName, String permName, String persistentDeviceId, - int userId) { - int oldVal = mOldImplementation.checkPermission(pkgName, permName, persistentDeviceId, - userId); - int newVal = mNewImplementation.checkPermission(pkgName, permName, persistentDeviceId, - userId); + public int checkPermission(String pkgName, String permName, String deviceId, int userId) { + int oldVal = mOldImplementation.checkPermission(pkgName, permName, deviceId, userId); + int newVal = mNewImplementation.checkPermission(pkgName, permName, deviceId, userId); if (!Objects.equals(oldVal, newVal)) { signalImplDifference("checkPermission"); @@ -317,7 +308,7 @@ public class PermissionManagerServiceTestingShim implements PermissionManagerSer } @Override - public int checkUidPermission(int uid, String permName, int deviceId) { + public int checkUidPermission(int uid, String permName, String deviceId) { int oldVal = mOldImplementation.checkUidPermission(uid, permName, deviceId); int newVal = mNewImplementation.checkUidPermission(uid, permName, deviceId); @@ -329,8 +320,8 @@ public class PermissionManagerServiceTestingShim implements PermissionManagerSer @Override public Map<String, PermissionState> getAllPermissionStates(@NonNull String packageName, - @NonNull String persistentDeviceId, int userId) { - return mNewImplementation.getAllPermissionStates(packageName, persistentDeviceId, userId); + @NonNull String deviceId, int userId) { + return mNewImplementation.getAllPermissionStates(packageName, deviceId, userId); } @Override diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java index bc29e6773bca..981d3d92b15a 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java @@ -159,11 +159,11 @@ public class PermissionManagerServiceTracingDecorator implements PermissionManag } @Override - public int getPermissionFlags(String packageName, String permName, String persistentDeviceId, + public int getPermissionFlags(String packageName, String permName, String deviceId, int userId) { Trace.traceBegin(TRACE_TAG, "TaggedTracingPermissionManagerServiceImpl#getPermissionFlags"); try { - return mService.getPermissionFlags(packageName, permName, persistentDeviceId, userId); + return mService.getPermissionFlags(packageName, permName, deviceId, userId); } finally { Trace.traceEnd(TRACE_TAG); } @@ -171,13 +171,12 @@ public class PermissionManagerServiceTracingDecorator implements PermissionManag @Override public void updatePermissionFlags(String packageName, String permName, int flagMask, - int flagValues, boolean checkAdjustPolicyFlagPermission, String persistentDeviceId, - int userId) { + int flagValues, boolean checkAdjustPolicyFlagPermission, String deviceId, int userId) { Trace.traceBegin(TRACE_TAG, "TaggedTracingPermissionManagerServiceImpl#updatePermissionFlags"); try { mService.updatePermissionFlags(packageName, permName, flagMask, flagValues, - checkAdjustPolicyFlagPermission, persistentDeviceId, userId); + checkAdjustPolicyFlagPermission, deviceId, userId); } finally { Trace.traceEnd(TRACE_TAG); } @@ -256,25 +255,24 @@ public class PermissionManagerServiceTracingDecorator implements PermissionManag } @Override - public void grantRuntimePermission(String packageName, String permName, - String persistentDeviceId, int userId) { + public void grantRuntimePermission(String packageName, String permName, String deviceId, + int userId) { Trace.traceBegin(TRACE_TAG, "TaggedTracingPermissionManagerServiceImpl#grantRuntimePermission"); try { - mService.grantRuntimePermission(packageName, permName, persistentDeviceId, userId); + mService.grantRuntimePermission(packageName, permName, deviceId, userId); } finally { Trace.traceEnd(TRACE_TAG); } } @Override - public void revokeRuntimePermission(String packageName, String permName, - String persistentDeviceId, int userId, String reason) { + public void revokeRuntimePermission(String packageName, String permName, String deviceId, + int userId, String reason) { Trace.traceBegin(TRACE_TAG, "TaggedTracingPermissionManagerServiceImpl#revokeRuntimePermission"); try { - mService.revokeRuntimePermission(packageName, permName, persistentDeviceId, userId, - reason); + mService.revokeRuntimePermission(packageName, permName, deviceId, userId, reason); } finally { Trace.traceEnd(TRACE_TAG); } @@ -293,19 +291,19 @@ public class PermissionManagerServiceTracingDecorator implements PermissionManag @Override public boolean shouldShowRequestPermissionRationale(String packageName, String permName, - int deviceId, int userId) { + String deviceId, int userId) { Trace.traceBegin(TRACE_TAG, "TaggedTracingPermissionManagerServiceImpl#shouldShowRequestPermissionRationale"); try { - return mService.shouldShowRequestPermissionRationale( - packageName, permName, deviceId, userId); + return mService.shouldShowRequestPermissionRationale(packageName, permName, deviceId, + userId); } finally { Trace.traceEnd(TRACE_TAG); } } @Override - public boolean isPermissionRevokedByPolicy(String packageName, String permName, int deviceId, + public boolean isPermissionRevokedByPolicy(String packageName, String permName, String deviceId, int userId) { Trace.traceBegin(TRACE_TAG, "TaggedTracingPermissionManagerServiceImpl#isPermissionRevokedByPolicy"); @@ -328,18 +326,17 @@ public class PermissionManagerServiceTracingDecorator implements PermissionManag } @Override - public int checkPermission(String pkgName, String permName, String persistentDeviceId, - int userId) { + public int checkPermission(String pkgName, String permName, String deviceId, int userId) { Trace.traceBegin(TRACE_TAG, "TaggedTracingPermissionManagerServiceImpl#checkPermission"); try { - return mService.checkPermission(pkgName, permName, persistentDeviceId, userId); + return mService.checkPermission(pkgName, permName, deviceId, userId); } finally { Trace.traceEnd(TRACE_TAG); } } @Override - public int checkUidPermission(int uid, String permName, int deviceId) { + public int checkUidPermission(int uid, String permName, String deviceId) { Trace.traceBegin(TRACE_TAG, "TaggedTracingPermissionManagerServiceImpl#checkUidPermission"); try { return mService.checkUidPermission(uid, permName, deviceId); @@ -350,11 +347,11 @@ public class PermissionManagerServiceTracingDecorator implements PermissionManag @Override public Map<String, PermissionState> getAllPermissionStates(@NonNull String packageName, - @NonNull String persistentDeviceId, int userId) { + @NonNull String deviceId, int userId) { Trace.traceBegin(TRACE_TAG, "TaggedTracingPermissionManagerServiceImpl" + "#getAllPermissionStates"); try { - return mService.getAllPermissionStates(packageName, persistentDeviceId, userId); + return mService.getAllPermissionStates(packageName, deviceId, userId); } finally { Trace.traceEnd(TRACE_TAG); } diff --git a/services/core/java/com/android/server/selinux/OWNERS b/services/core/java/com/android/server/selinux/OWNERS index 6ca4da2fd740..4cf2066018b5 100644 --- a/services/core/java/com/android/server/selinux/OWNERS +++ b/services/core/java/com/android/server/selinux/OWNERS @@ -1,3 +1,4 @@ # Bug component: 1117393 sandrom@google.com +melisacz@google.com diff --git a/services/core/java/com/android/server/selinux/SelinuxAuditLogsCollector.java b/services/core/java/com/android/server/selinux/SelinuxAuditLogsCollector.java index 0219645bee38..03822aaf76b2 100644 --- a/services/core/java/com/android/server/selinux/SelinuxAuditLogsCollector.java +++ b/services/core/java/com/android/server/selinux/SelinuxAuditLogsCollector.java @@ -88,7 +88,7 @@ class SelinuxAuditLogsCollector { if (eventTime.isAfter(latestTimestamp)) { latestTimestamp = eventTime; } - if (eventTime.isBefore(mLastWrite)) { + if (eventTime.compareTo(mLastWrite) <= 0) { continue; } Object eventData = event.getData(); diff --git a/services/core/java/com/android/server/utils/EventLogger.java b/services/core/java/com/android/server/utils/EventLogger.java index 4772bbfe97dd..2e1049b9ea32 100644 --- a/services/core/java/com/android/server/utils/EventLogger.java +++ b/services/core/java/com/android/server/utils/EventLogger.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.util.Log; +import android.util.Slog; import java.io.PrintWriter; import java.lang.annotation.Retention; @@ -84,6 +85,17 @@ public class EventLogger { enqueue(event.printLog(logType, tag)); } + /** + * Add a string-based event to the system log, and print it to the log with a specific severity. + * @param msg the message to appear in the log + * @param logType the log severity (verbose/info/warning/error) + * @param tag the tag under which the log entry will appear + */ + public synchronized void enqueueAndSlog(String msg, @Event.LogType int logType, String tag) { + final Event event = new StringEvent(msg); + enqueue(event.printSlog(logType, tag)); + } + /** Dumps events into the given {@link DumpSink}. */ public synchronized void dump(DumpSink dumpSink) { dumpSink.sink(mTag, new ArrayList<>(mEvents)); @@ -138,7 +150,7 @@ public class EventLogger { /** * Causes the string message for the event to appear in the logcat. * Here is an example of how to create a new event (a StringEvent), adding it to the logger - * (an instance of AudioEventLogger) while also making it show in the logcat: + * (an instance of EventLogger) while also making it show in the logcat: * <pre> * myLogger.log( * (new StringEvent("something for logcat and logger")).printLog(MyClass.TAG) ); @@ -167,9 +179,9 @@ public class EventLogger { /** * Same as {@link #printLog(String)} with a log type - * @param type one of {@link #ALOGI}, {@link #ALOGE}, {@link #ALOGV} - * @param tag - * @return + * @param type one of {@link #ALOGI}, {@link #ALOGE}, {@link #ALOGV}, {@link #ALOGW} + * @param tag the tag the log entry will be printed under + * @return the event itself */ public Event printLog(@LogType int type, String tag) { switch (type) { @@ -191,6 +203,32 @@ public class EventLogger { } /** + * Causes the string message for the event to appear in the system log. + * @param type one of {@link #ALOGI}, {@link #ALOGE}, {@link #ALOGV}, {@link #ALOGW} + * @param tag the tag the log entry will be printed under + * @return the event itself + * @see #printLog(int, String) + */ + public Event printSlog(@LogType int type, String tag) { + switch (type) { + case ALOGI: + Slog.i(tag, eventToString()); + break; + case ALOGE: + Slog.e(tag, eventToString()); + break; + case ALOGW: + Slog.w(tag, eventToString()); + break; + case ALOGV: + default: + Slog.v(tag, eventToString()); + break; + } + return this; + } + + /** * Convert event to String. * This method is only called when the logger history is about to the dumped, * so this method is where expensive String conversions should be made, not when the Event diff --git a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java b/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java index 5f4852f77727..a25d67ab66af 100644 --- a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java +++ b/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java @@ -252,7 +252,7 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor { } getInboundTransformInternal() - .getIpSecTransformState( + .requestIpSecTransformState( new HandlerExecutor(mHandler), new IpSecTransformStateReceiver()); // Schedule for next poll @@ -302,7 +302,8 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor { "packetLossRate: " + packetLossRate + "% in the past " - + (state.getTimestamp() - mLastIpSecTransformState.getTimestamp()) + + (state.getTimestampMillis() + - mLastIpSecTransformState.getTimestampMillis()) + "ms"; mLastIpSecTransformState = state; diff --git a/services/core/java/com/android/server/vcn/routeselection/NetworkMetricMonitor.java b/services/core/java/com/android/server/vcn/routeselection/NetworkMetricMonitor.java index a79f188713e1..1704aa117a2b 100644 --- a/services/core/java/com/android/server/vcn/routeselection/NetworkMetricMonitor.java +++ b/services/core/java/com/android/server/vcn/routeselection/NetworkMetricMonitor.java @@ -138,10 +138,10 @@ public abstract class NetworkMetricMonitor implements AutoCloseable { } /** Poll an IpSecTransformState */ - public void getIpSecTransformState( + public void requestIpSecTransformState( @NonNull Executor executor, @NonNull OutcomeReceiver<IpSecTransformState, RuntimeException> callback) { - ipSecTransform.getIpSecTransformState(executor, callback); + ipSecTransform.requestIpSecTransformState(executor, callback); } /** Close this instance and release the underlying resources */ diff --git a/services/core/java/com/android/server/vibrator/TEST_MAPPING b/services/core/java/com/android/server/vibrator/TEST_MAPPING index 92b327d9abff..c64941bebbf4 100644 --- a/services/core/java/com/android/server/vibrator/TEST_MAPPING +++ b/services/core/java/com/android/server/vibrator/TEST_MAPPING @@ -5,6 +5,9 @@ }, { "path": "cts/tests/vibrator" + }, + { + "path": "frameworks/hardware/interfaces/vibrator/aidl" } ] } diff --git a/services/core/java/com/android/server/wm/ActivityCallerState.java b/services/core/java/com/android/server/wm/ActivityCallerState.java index 4416605d9f04..e7972904adaa 100644 --- a/services/core/java/com/android/server/wm/ActivityCallerState.java +++ b/services/core/java/com/android/server/wm/ActivityCallerState.java @@ -16,6 +16,8 @@ package com.android.server.wm; +import static android.os.Process.INVALID_UID; + import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -51,6 +53,9 @@ final class ActivityCallerState { private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityCallerState" : TAG_ATM; // XML tags for CallerInfo + private static final String ATTR_CALLER_UID = "caller_uid"; + private static final String ATTR_CALLER_PACKAGE = "caller_package"; + private static final String ATTR_CALLER_IS_SHARE_ENABLED = "caller_is_share_enabled"; private static final String TAG_READABLE_CONTENT_URI = "readable_content_uri"; private static final String TAG_WRITABLE_CONTENT_URI = "writable_content_uri"; private static final String TAG_INACCESSIBLE_CONTENT_URI = "inaccessible_content_uri"; @@ -71,12 +76,33 @@ final class ActivityCallerState { return mCallerTokenInfoMap.getOrDefault(callerToken, null); } + boolean hasCaller(IBinder callerToken) { + return getCallerInfoOrNull(callerToken) != null; + } + + int getUid(IBinder callerToken) { + CallerInfo callerInfo = getCallerInfoOrNull(callerToken); + return callerInfo != null ? callerInfo.mUid : INVALID_UID; + } + + String getPackage(IBinder callerToken) { + CallerInfo callerInfo = getCallerInfoOrNull(callerToken); + return callerInfo != null ? callerInfo.mPackageName : null; + } + + boolean isShareIdentityEnabled(IBinder callerToken) { + CallerInfo callerInfo = getCallerInfoOrNull(callerToken); + return callerInfo != null ? callerInfo.mIsShareIdentityEnabled : false; + } + void add(IBinder callerToken, CallerInfo callerInfo) { mCallerTokenInfoMap.put(callerToken, callerInfo); } - void computeCallerInfo(IBinder callerToken, Intent intent, int callerUid) { - final CallerInfo callerInfo = new CallerInfo(); + void computeCallerInfo(IBinder callerToken, Intent intent, int callerUid, + String callerPackageName, boolean isCallerShareIdentityEnabled) { + final CallerInfo callerInfo = new CallerInfo(callerUid, callerPackageName, + isCallerShareIdentityEnabled); mCallerTokenInfoMap.put(callerToken, callerInfo); final ArraySet<Uri> contentUris = getContentUrisFromIntent(intent); @@ -180,12 +206,26 @@ final class ActivityCallerState { } public static final class CallerInfo { + final int mUid; + final String mPackageName; + final boolean mIsShareIdentityEnabled; final ArraySet<GrantUri> mReadableContentUris = new ArraySet<>(); final ArraySet<GrantUri> mWritableContentUris = new ArraySet<>(); final ArraySet<GrantUri> mInaccessibleContentUris = new ArraySet<>(); + CallerInfo(int uid, String packageName, boolean isShareIdentityEnabled) { + mUid = uid; + mPackageName = packageName; + mIsShareIdentityEnabled = isShareIdentityEnabled; + } + public void saveToXml(TypedXmlSerializer out) throws IOException, XmlPullParserException { + out.attributeInt(null, ATTR_CALLER_UID, mUid); + if (mPackageName != null) { + out.attribute(null, ATTR_CALLER_PACKAGE, mPackageName); + } + out.attributeBoolean(null, ATTR_CALLER_IS_SHARE_ENABLED, mIsShareIdentityEnabled); for (int i = mReadableContentUris.size() - 1; i >= 0; i--) { saveGrantUriToXml(out, mReadableContentUris.valueAt(i), TAG_READABLE_CONTENT_URI); } @@ -202,7 +242,12 @@ final class ActivityCallerState { public static CallerInfo restoreFromXml(TypedXmlPullParser in) throws IOException, XmlPullParserException { - CallerInfo callerInfo = new CallerInfo(); + int uid = in.getAttributeInt(null, ATTR_CALLER_UID, 0); + String packageName = in.getAttributeValue(null, ATTR_CALLER_PACKAGE); + boolean isShareIdentityEnabled = in.getAttributeBoolean(null, + ATTR_CALLER_IS_SHARE_ENABLED, false); + + CallerInfo callerInfo = new CallerInfo(uid, packageName, isShareIdentityEnabled); final int outerDepth = in.getDepth(); int event; while (((event = in.next()) != END_DOCUMENT) diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index efaa467e43e4..ed5df5fab017 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -695,30 +695,57 @@ class ActivityClientController extends IActivityClientController.Stub { @Override public int getLaunchedFromUid(IBinder token) { + return getUid(token, /* callerToken */ null, /* isActivityCallerCall */ false); + } + + @Override + public String getLaunchedFromPackage(IBinder token) { + return getPackage(token, /* callerToken */ null, /* isActivityCallerCall */ false); + } + + @Override + public int getActivityCallerUid(IBinder activityToken, IBinder callerToken) { + return getUid(activityToken, callerToken, /* isActivityCallerCall */ true); + } + + @Override + public String getActivityCallerPackage(IBinder activityToken, IBinder callerToken) { + return getPackage(activityToken, callerToken, /* isActivityCallerCall */ true); + } + + private int getUid(IBinder activityToken, IBinder callerToken, boolean isActivityCallerCall) { final int uid = Binder.getCallingUid(); final boolean isInternalCaller = isInternalCallerGetLaunchedFrom(uid); synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r != null && (isInternalCaller || canGetLaunchedFromLocked(uid, r))) { - return r.launchedFromUid; + final ActivityRecord r = ActivityRecord.forTokenLocked(activityToken); + if (r != null && (isInternalCaller || canGetLaunchedFromLocked(uid, r, callerToken, + isActivityCallerCall)) && isValidCaller(r, callerToken, isActivityCallerCall)) { + return isActivityCallerCall ? r.getCallerUid(callerToken) : r.launchedFromUid; } } return INVALID_UID; } - @Override - public String getLaunchedFromPackage(IBinder token) { + private String getPackage(IBinder activityToken, IBinder callerToken, + boolean isActivityCallerCall) { final int uid = Binder.getCallingUid(); final boolean isInternalCaller = isInternalCallerGetLaunchedFrom(uid); synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r != null && (isInternalCaller || canGetLaunchedFromLocked(uid, r))) { - return r.launchedFromPackage; + final ActivityRecord r = ActivityRecord.forTokenLocked(activityToken); + if (r != null && (isInternalCaller || canGetLaunchedFromLocked(uid, r, callerToken, + isActivityCallerCall)) && isValidCaller(r, callerToken, isActivityCallerCall)) { + return isActivityCallerCall + ? r.getCallerPackage(callerToken) : r.launchedFromPackage; } } return null; } + private boolean isValidCaller(ActivityRecord r, IBinder callerToken, + boolean isActivityCallerCall) { + return isActivityCallerCall ? r.hasCaller(callerToken) : callerToken == null; + } + /** * @param uri This uri must NOT contain an embedded userId. * @param userId The userId in which the uri is to be resolved. @@ -768,9 +795,13 @@ class ActivityClientController extends IActivityClientController.Stub { * verifying whether the provided {@code ActivityRecord r} has opted in to sharing its * identity or if the uid of the activity matches that of the launching app. */ - private static boolean canGetLaunchedFromLocked(int uid, ActivityRecord r) { + private static boolean canGetLaunchedFromLocked(int uid, ActivityRecord r, + IBinder callerToken, boolean isActivityCallerCall) { if (CompatChanges.isChangeEnabled(ACCESS_SHARED_IDENTITY, uid)) { - return r.mShareIdentity || r.launchedFromUid == uid; + boolean isShareIdentityEnabled = isActivityCallerCall + ? r.isCallerShareIdentityEnabled(callerToken) : r.mShareIdentity; + int callerUid = isActivityCallerCall ? r.getCallerUid(callerToken) : r.launchedFromUid; + return isShareIdentityEnabled || callerUid == uid; } return false; } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 09c329be7d09..c36df8da77ae 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2024,12 +2024,31 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } + boolean hasCaller(IBinder callerToken) { + return mCallerState.hasCaller(callerToken); + } + + int getCallerUid(IBinder callerToken) { + return mCallerState.getUid(callerToken); + } + + String getCallerPackage(IBinder callerToken) { + return mCallerState.getPackage(callerToken); + } + + boolean isCallerShareIdentityEnabled(IBinder callerToken) { + return mCallerState.isShareIdentityEnabled(callerToken); + } + void computeInitialCallerInfo() { - computeCallerInfo(initialCallerInfoAccessToken, intent, launchedFromUid); + computeCallerInfo(initialCallerInfoAccessToken, intent, launchedFromUid, + launchedFromPackage, mShareIdentity); } - void computeCallerInfo(IBinder callerToken, Intent intent, int callerUid) { - mCallerState.computeCallerInfo(callerToken, intent, callerUid); + void computeCallerInfo(IBinder callerToken, Intent intent, int callerUid, + String callerPackageName, boolean isCallerShareIdentityEnabled) { + mCallerState.computeCallerInfo(callerToken, intent, callerUid, callerPackageName, + isCallerShareIdentityEnabled); } boolean checkContentUriPermission(IBinder callerToken, GrantUri grantUri, int modeFlags) { @@ -3526,6 +3545,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(resultGrants, resultTo.getUriPermissionsLocked()); } + IBinder callerToken = new Binder(); + if (android.security.Flags.contentUriPermissionApis()) { + try { + resultTo.computeCallerInfo(callerToken, intent, this.getUid(), + mAtmService.getPackageManager().getNameForUid(this.getUid()), + /* isShareIdentityEnabled */ false); + // Result callers cannot share their identity via + // {@link ActivityOptions#setShareIdentityEnabled(boolean)} since + // {@link android.app.Activity#setResult} doesn't have a + // {@link android.os.Bundle}. + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } if (mForceSendResultForMediaProjection || resultTo.isState(RESUMED)) { // Sending the result to the resultTo activity asynchronously to prevent the // resultTo activity getting results before this Activity paused. @@ -3533,12 +3566,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mAtmService.mH.post(() -> { synchronized (mAtmService.mGlobalLock) { resultToActivity.sendResult(this.getUid(), resultWho, requestCode, - resultCode, resultData, resultGrants, + resultCode, resultData, callerToken, resultGrants, mForceSendResultForMediaProjection); } }); } else { - resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData); + resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData, + callerToken); } resultTo = null; } else if (DEBUG_RESULTS) { @@ -4822,9 +4856,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A void addResultLocked(ActivityRecord from, String resultWho, int requestCode, int resultCode, - Intent resultData) { + Intent resultData, IBinder callerToken) { ActivityResult r = new ActivityResult(from, resultWho, - requestCode, resultCode, resultData); + requestCode, resultCode, resultData, callerToken); if (results == null) { results = new ArrayList<ResultInfo>(); } @@ -4850,13 +4884,27 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } void sendResult(int callingUid, String resultWho, int requestCode, int resultCode, - Intent data, NeededUriGrants dataGrants) { - sendResult(callingUid, resultWho, requestCode, resultCode, data, dataGrants, + Intent data, IBinder callerToken, NeededUriGrants dataGrants) { + sendResult(callingUid, resultWho, requestCode, resultCode, data, callerToken, dataGrants, false /* forceSendForMediaProjection */); } void sendResult(int callingUid, String resultWho, int requestCode, int resultCode, - Intent data, NeededUriGrants dataGrants, boolean forceSendForMediaProjection) { + Intent data, IBinder callerToken, NeededUriGrants dataGrants, + boolean forceSendForMediaProjection) { + if (android.security.Flags.contentUriPermissionApis() + && !mCallerState.hasCaller(callerToken)) { + try { + computeCallerInfo(callerToken, data, callingUid, + mAtmService.getPackageManager().getNameForUid(callingUid), + false /* isShareIdentityEnabled */); + // Result callers cannot share their identity via + // {@link ActivityOptions#setShareIdentityEnabled(boolean)} since + // {@link android.app.Activity#setResult} doesn't have a {@link android.os.Bundle}. + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } if (callingUid > 0) { mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(dataGrants, getUriPermissionsLocked()); @@ -4872,7 +4920,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (isState(RESUMED) && attachedToProcess()) { try { final ArrayList<ResultInfo> list = new ArrayList<>(); - list.add(new ResultInfo(resultWho, requestCode, resultCode, data)); + list.add(new ResultInfo(resultWho, requestCode, resultCode, data, callerToken)); mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), ActivityResultItem.obtain(token, list)); return; @@ -4886,7 +4934,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A STOPPING, STOPPED)) { // Build result to be returned immediately. final ActivityResultItem activityResultItem = ActivityResultItem.obtain( - token, List.of(new ResultInfo(resultWho, requestCode, resultCode, data))); + token, List.of(new ResultInfo(resultWho, requestCode, resultCode, data, + callerToken))); // When the activity result is delivered, the activity will transition to RESUMED. // Since the activity is only resumed so the result can be immediately delivered, // return it to its original lifecycle state. @@ -4910,7 +4959,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return; } - addResultLocked(null /* from */, resultWho, requestCode, resultCode, data); + addResultLocked(null /* from */, resultWho, requestCode, resultCode, data, callerToken); } /** @@ -4960,11 +5009,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * method will be called at the proper time. */ final void deliverNewIntentLocked(int callingUid, Intent intent, NeededUriGrants intentGrants, - String referrer) { + String referrer, boolean isShareIdentityEnabled) { + IBinder callerToken = new Binder(); + if (android.security.Flags.contentUriPermissionApis()) { + computeCallerInfo(callerToken, intent, callingUid, referrer, isShareIdentityEnabled); + } // The activity now gets access to the data associated with this Intent. mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants, getUriPermissionsLocked()); - final ReferrerIntent rintent = new ReferrerIntent(intent, getFilteredReferrer(referrer)); + final ReferrerIntent rintent = new ReferrerIntent(intent, getFilteredReferrer(referrer), + callerToken); boolean unsent = true; final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping(); diff --git a/services/core/java/com/android/server/wm/ActivityResult.java b/services/core/java/com/android/server/wm/ActivityResult.java index f2510de6dfb2..c5c51b50961c 100644 --- a/services/core/java/com/android/server/wm/ActivityResult.java +++ b/services/core/java/com/android/server/wm/ActivityResult.java @@ -18,16 +18,17 @@ package com.android.server.wm; import android.app.ResultInfo; import android.content.Intent; +import android.os.IBinder; /** * Pending result information to send back to an activity. */ final class ActivityResult extends ResultInfo { final ActivityRecord mFrom; - + public ActivityResult(ActivityRecord from, String resultWho, - int requestCode, int resultCode, Intent data) { - super(resultWho, requestCode, resultCode, data); + int requestCode, int resultCode, Intent data, IBinder callerToken) { + super(resultWho, requestCode, resultCode, data, callerToken); mFrom = from; } } diff --git a/services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java b/services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java index db27f607c867..01d077a5bc55 100644 --- a/services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java +++ b/services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java @@ -22,12 +22,10 @@ import static com.android.server.wm.ActivityStarter.ASM_RESTRICTIONS; import android.annotation.NonNull; import android.app.compat.CompatChanges; -import android.content.pm.PackageManager; import android.provider.DeviceConfig; import com.android.internal.annotations.GuardedBy; -import java.util.HashSet; import java.util.concurrent.Executor; /** @@ -50,74 +48,49 @@ class ActivitySecurityModelFeatureFlags { private static final String KEY_ASM_RESTRICTIONS_ENABLED = KEY_ASM_PREFIX + "asm_restrictions_enabled"; private static final String KEY_ASM_TOASTS_ENABLED = KEY_ASM_PREFIX + "asm_toasts_enabled"; - private static final String KEY_ASM_EXEMPTED_PACKAGES = KEY_ASM_PREFIX - + "asm_exempted_packages"; + private static final int VALUE_DISABLE = 0; private static final int VALUE_ENABLE_FOR_V = 1; private static final int VALUE_ENABLE_FOR_ALL = 2; private static final int DEFAULT_VALUE = VALUE_DISABLE; - private static final String DEFAULT_EXCEPTION_LIST = ""; private static int sAsmToastsEnabled; private static int sAsmRestrictionsEnabled; - private static final HashSet<String> sExcludedPackageNames = new HashSet<>(); - private static PackageManager sPm; @GuardedBy("ActivityTaskManagerService.mGlobalLock") - static void initialize(@NonNull Executor executor, @NonNull PackageManager pm) { + static void initialize(@NonNull Executor executor) { updateFromDeviceConfig(); DeviceConfig.addOnPropertiesChangedListener(NAMESPACE, executor, properties -> updateFromDeviceConfig()); - sPm = pm; } @GuardedBy("ActivityTaskManagerService.mGlobalLock") static boolean shouldShowToast(int uid) { - return flagEnabledForUid(sAsmToastsEnabled, uid); + return sAsmToastsEnabled == VALUE_ENABLE_FOR_ALL + || (sAsmToastsEnabled == VALUE_ENABLE_FOR_V + && CompatChanges.isChangeEnabled(ASM_RESTRICTIONS, uid)); } @GuardedBy("ActivityTaskManagerService.mGlobalLock") static boolean shouldRestrictActivitySwitch(int uid) { - return flagEnabledForUid(sAsmRestrictionsEnabled, uid); - } - - private static boolean flagEnabledForUid(int flag, int uid) { - boolean flagEnabled = flag == VALUE_ENABLE_FOR_ALL - || (flag == VALUE_ENABLE_FOR_V - && CompatChanges.isChangeEnabled(ASM_RESTRICTIONS, uid)); - - if (flagEnabled) { - String[] packageNames = sPm.getPackagesForUid(uid); - if (packageNames == null) { - return true; - } - for (int i = 0; i < packageNames.length; i++) { - if (sExcludedPackageNames.contains(packageNames[i])) { - return false; - } - } - return true; + if (android.security.Flags.asmRestrictionsEnabled()) { + return CompatChanges.isChangeEnabled(ASM_RESTRICTIONS, uid) + || asmRestrictionsEnabledForAll(); } return false; } + @GuardedBy("ActivityTaskManagerService.mGlobalLock") + static boolean asmRestrictionsEnabledForAll() { + return sAsmRestrictionsEnabled == VALUE_ENABLE_FOR_ALL; + } + private static void updateFromDeviceConfig() { sAsmToastsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_TOASTS_ENABLED, DEFAULT_VALUE); sAsmRestrictionsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_RESTRICTIONS_ENABLED, DEFAULT_VALUE); - - String rawExceptionList = DeviceConfig.getString(NAMESPACE, - KEY_ASM_EXEMPTED_PACKAGES, DEFAULT_EXCEPTION_LIST); - sExcludedPackageNames.clear(); - String[] packages = rawExceptionList.split(","); - for (String packageName : packages) { - String packageNameTrimmed = packageName.trim(); - if (!packageNameTrimmed.isEmpty()) { - sExcludedPackageNames.add(packageNameTrimmed); - } - } } } diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 07afa5fc21be..cfd049508e65 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1103,7 +1103,7 @@ class ActivityStarter { if (err != START_SUCCESS) { if (resultRecord != null) { resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED, - null /* data */, null /* dataGrants */); + null /* data */, null /* callerToken */, null /* dataGrants */); } SafeActivityOptions.abort(options); return err; @@ -1128,7 +1128,8 @@ class ActivityStarter { .filterAppAccess(targetPackageName, callingUid, userId)) { if (resultRecord != null) { resultRecord.sendResult(INVALID_UID, resultWho, requestCode, - RESULT_CANCELED, null /* data */, null /* dataGrants */); + RESULT_CANCELED, null /* data */, null /* callerToken */, + null /* dataGrants */); } SafeActivityOptions.abort(options); return ActivityManager.START_CLASS_NOT_FOUND; @@ -1216,7 +1217,7 @@ class ActivityStarter { if (abort) { if (resultRecord != null) { resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED, - null /* data */, null /* dataGrants */); + null /* data */, null /* callerToken */, null /* dataGrants */); } // We pretend to the caller that it was really started, but they will just get a // cancel result. @@ -1380,7 +1381,7 @@ class ActivityStarter { int requestCode = r.requestCode; if (resultRecord != null) { resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED, - null /* data */, null /* dataGrants */); + null /* data */, null /* callerToken */, null /* dataGrants */); } // We pretend to the caller that it was really started to make it backward compatible, but // they will just get a cancel result. @@ -1727,7 +1728,7 @@ class ActivityStarter { if (startResult != START_SUCCESS) { if (r.resultTo != null) { r.resultTo.sendResult(INVALID_UID, r.resultWho, r.requestCode, RESULT_CANCELED, - null /* data */, null /* dataGrants */); + null /* data */, null /* callerToken */, null /* dataGrants */); } return startResult; } @@ -2226,7 +2227,7 @@ class ActivityStarter { if (mStartActivity.resultTo != null) { mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED, - null /* data */, null /* dataGrants */); + null /* data */, null /* callerToken */, null /* dataGrants */); mStartActivity.resultTo = null; } @@ -2607,7 +2608,7 @@ class ActivityStarter { Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED, - null /* data */, null /* dataGrants */); + null /* data */, null /* callerToken */, null /* dataGrants */); mStartActivity.resultTo = null; } } @@ -2909,7 +2910,7 @@ class ActivityStarter { activity.logStartActivity(EventLogTags.WM_NEW_INTENT, activity.getTask()); activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, intentGrants, - mStartActivity.launchedFromPackage); + mStartActivity.launchedFromPackage, mStartActivity.mShareIdentity); mIntentDelivered = true; } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 0e6c06dad486..52fdfda7acfe 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -881,7 +881,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mTaskSupervisor.onSystemReady(); mActivityClientController.onSystemReady(); // TODO(b/258792202) Cleanup once ASM is ready to launch - ActivitySecurityModelFeatureFlags.initialize(mContext.getMainExecutor(), pm); + ActivitySecurityModelFeatureFlags.initialize(mContext.getMainExecutor()); mGrammaticalManagerInternal = LocalServices.getService( GrammaticalInflectionManagerInternal.class); } @@ -6334,7 +6334,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final NeededUriGrants dataGrants = collectGrants(data, r); synchronized (mGlobalLock) { - r.sendResult(callingUid, resultWho, requestCode, resultCode, data, dataGrants); + r.sendResult(callingUid, resultWho, requestCode, resultCode, data, new Binder(), + dataGrants); } } diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 49df39664b1c..09f5eda5b571 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -1118,7 +1118,8 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { if (resultRecord != null) { resultRecord.sendResult(INVALID_UID, resultWho, requestCode, - Activity.RESULT_CANCELED, null /* data */, null /* dataGrants */); + Activity.RESULT_CANCELED, null /* data */, null /* callerToken */, + null /* dataGrants */); } final String msg; if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java index 2d6f03a6c9ad..86ca1eac8a50 100644 --- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java +++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java @@ -56,6 +56,7 @@ import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.content.ComponentName; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Process; import android.os.SystemClock; @@ -529,6 +530,9 @@ public class BackgroundActivityStartController { static final BalVerdict BLOCK = new BalVerdict(BAL_BLOCK, false, "Blocked"); static final BalVerdict ALLOW_BY_DEFAULT = new BalVerdict(BAL_ALLOW_DEFAULT, false, "Default"); + // Careful using this - it will bypass all ASM checks. + static final BalVerdict ALLOW_PRIVILEGED = + new BalVerdict(BAL_ALLOW_ALLOWLISTED_UID, false, "PRIVILEGED"); private final @BalCode int mCode; private final boolean mBackground; private final String mMessage; @@ -722,9 +726,8 @@ public class BackgroundActivityStartController { // Allowed before V by creator if (state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts()) { Slog.wtf(TAG, "With Android 15 BAL hardening this activity start may be blocked" - + " if the PI creator upgrades target_sdk to 35+! " - + " (missing opt in by PI creator)! " - + state.dump()); + + " if the PI creator upgrades target_sdk to 35+! " + + " (missing opt in by PI creator)!" + state.dump()); showBalRiskToast(); return allowBasedOnCaller(state); } @@ -733,17 +736,15 @@ public class BackgroundActivityStartController { // Allowed before U by sender if (state.mBalAllowedByPiSender.allowsBackgroundActivityStarts()) { Slog.wtf(TAG, "With Android 14 BAL hardening this activity start will be blocked" - + " if the PI sender upgrades target_sdk to 34+! " - + " (missing opt in by PI sender)! " - + state.dump()); + + " if the PI sender upgrades target_sdk to 34+! " + + " (missing opt in by PI sender)!" + state.dump()); showBalRiskToast(); return allowBasedOnRealCaller(state); } } // caller or real caller could start the activity, but would need to explicitly opt in if (callerCanAllow || realCallerCanAllow) { - Slog.wtf(TAG, "Without BAL hardening this activity start would be allowed " - + state.dump()); + Slog.w(TAG, "Without BAL hardening this activity start would be allowed"); } // neither the caller not the realCaller can allow or have explicitly opted out return abortLaunch(state); @@ -766,7 +767,7 @@ public class BackgroundActivityStartController { } private BalVerdict abortLaunch(BalState state) { - Slog.w(TAG, "Background activity launch blocked! " + Slog.wtf(TAG, "Background activity launch blocked! " + state.dump()); showBalBlockedToast(); return statsLog(BalVerdict.BLOCK, state); @@ -1234,7 +1235,8 @@ public class BackgroundActivityStartController { boolean shouldBlockActivityStart = ActivitySecurityModelFeatureFlags .shouldRestrictActivitySwitch(callingUid); int[] finishCount = new int[0]; - if (shouldBlockActivityStart) { + if (shouldBlockActivityStart + && blockCrossUidActivitySwitchFromBelowForActivity(targetTaskTop)) { ActivityRecord activity = targetTask.getActivity(isLaunchingOrLaunched); if (activity == null) { // mStartActivity is not in task, so clear everything @@ -1319,7 +1321,7 @@ public class BackgroundActivityStartController { boolean restrictActivitySwitch = ActivitySecurityModelFeatureFlags .shouldRestrictActivitySwitch(callingUid) - && bas.mBlockActivityStartIfFlagEnabled; + && bas.mBlockActivityStartIfFlagEnabled; PackageManager pm = mService.mContext.getPackageManager(); String callingPackage = pm.getNameForUid(callingUid); @@ -1373,19 +1375,19 @@ public class BackgroundActivityStartController { int uid, @Nullable ActivityRecord sourceRecord) { // If the source is visible, consider it 'top'. if (sourceRecord != null && sourceRecord.isVisibleRequested()) { - return new BlockActivityStart(false, false); + return BlockActivityStart.ACTIVITY_START_ALLOWED; } // Always allow actual top activity to clear task ActivityRecord topActivity = task.getTopMostActivity(); if (topActivity != null && topActivity.isUid(uid)) { - return new BlockActivityStart(false, false); + return BlockActivityStart.ACTIVITY_START_ALLOWED; } // If UID is visible in target task, allow launch if (task.forAllActivities((Predicate<ActivityRecord>) ar -> ar.isUid(uid) && ar.isVisibleRequested())) { - return new BlockActivityStart(false, false); + return BlockActivityStart.ACTIVITY_START_ALLOWED; } // Consider the source activity, whether or not it is finishing. Do not consider any other @@ -1452,12 +1454,11 @@ public class BackgroundActivityStartController { private BlockActivityStart blockCrossUidActivitySwitchFromBelow(ActivityRecord ar, int sourceUid) { if (ar.isUid(sourceUid)) { - return new BlockActivityStart(false, false); + return BlockActivityStart.ACTIVITY_START_ALLOWED; } - // If mAllowCrossUidActivitySwitchFromBelow is set, honor it. - if (ar.mAllowCrossUidActivitySwitchFromBelow) { - return new BlockActivityStart(false, false); + if (!blockCrossUidActivitySwitchFromBelowForActivity(ar)) { + return BlockActivityStart.ACTIVITY_START_ALLOWED; } // At this point, we would block if the feature is launched and both apps were V+ @@ -1468,8 +1469,11 @@ public class BackgroundActivityStartController { ActivitySecurityModelFeatureFlags.shouldRestrictActivitySwitch(ar.getUid()) && ActivitySecurityModelFeatureFlags .shouldRestrictActivitySwitch(sourceUid); - return new BackgroundActivityStartController - .BlockActivityStart(restrictActivitySwitch, true); + if (restrictActivitySwitch) { + return BlockActivityStart.BLOCK; + } else { + return BlockActivityStart.LOG_ONLY; + } } /** @@ -1675,14 +1679,52 @@ public class BackgroundActivityStartController { } } - static class BlockActivityStart { + /** + * Activity level allowCrossUidActivitySwitchFromBelow defaults to false. + * Package level defaults to true. + * We block the launch if dev has explicitly set package level to false, and activity level has + * not opted out + */ + private boolean blockCrossUidActivitySwitchFromBelowForActivity(@NonNull ActivityRecord ar) { + // We don't need to check package level if activity has opted out. + if (ar.mAllowCrossUidActivitySwitchFromBelow) { + return false; + } + + if (ActivitySecurityModelFeatureFlags.asmRestrictionsEnabledForAll()) { + return true; + } + + String packageName = ar.packageName; + if (packageName == null) { + return false; + } + + PackageManager pm = mService.mContext.getPackageManager(); + ApplicationInfo applicationInfo; + + try { + applicationInfo = pm.getApplicationInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + Slog.wtf(TAG, "Package name: " + packageName + " not found."); + return false; + } + + return !applicationInfo.allowCrossUidActivitySwitchFromBelow; + } + + private static class BlockActivityStart { + private static final BlockActivityStart ACTIVITY_START_ALLOWED = + new BlockActivityStart(false, false); + private static final BlockActivityStart LOG_ONLY = new BlockActivityStart(false, true); + private static final BlockActivityStart BLOCK = new BlockActivityStart(true, true); // We should block if feature flag is enabled private final boolean mBlockActivityStartIfFlagEnabled; // Used for logging/toasts. Would we block if target sdk was V and feature was // enabled? private final boolean mWouldBlockActivityStartIgnoringFlag; - BlockActivityStart(boolean shouldBlockActivityStart, + private BlockActivityStart(boolean shouldBlockActivityStart, boolean wouldBlockActivityStartIgnoringFlags) { this.mBlockActivityStartIfFlagEnabled = shouldBlockActivityStart; this.mWouldBlockActivityStartIgnoringFlag = wouldBlockActivityStartIgnoringFlags; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 25a5fca1432c..e7431723789d 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -6783,14 +6783,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return mSandboxDisplayApis; } - /** - * For testing only; inject a ContentRecorder instance. - */ - @VisibleForTesting - void setContentRecorder(ContentRecorder contentRecorder) { - mContentRecorder = contentRecorder; - } - private ContentRecorder getContentRecorder() { if (mContentRecorder == null) { mContentRecorder = new ContentRecorder(this); diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java index e6ef90bd33d2..fac62fc8b3db 100644 --- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java +++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java @@ -17,6 +17,7 @@ package com.android.server.wm; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_EMBEDDED_WINDOWS; import static com.android.server.wm.IdentifierProto.HASH_CODE; import static com.android.server.wm.IdentifierProto.TITLE; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -34,6 +35,9 @@ import android.view.InputApplicationHandle; import android.view.InputChannel; import android.window.InputTransferToken; +import com.android.internal.protolog.common.ProtoLog; +import com.android.server.input.InputManagerService; + /** * Keeps track of embedded windows. * @@ -52,9 +56,13 @@ class EmbeddedWindowController { private final Object mGlobalLock; private final ActivityTaskManagerService mAtmService; - EmbeddedWindowController(ActivityTaskManagerService atmService) { + private final InputManagerService mInputManagerService; + + EmbeddedWindowController(ActivityTaskManagerService atmService, + InputManagerService inputManagerService) { mAtmService = atmService; mGlobalLock = atmService.getGlobalLock(); + mInputManagerService = inputManagerService; } /** @@ -135,6 +143,61 @@ class EmbeddedWindowController { return mWindowsByWindowToken.get(windowToken); } + private boolean isValidTouchGestureParams(WindowState hostWindowState, + EmbeddedWindow embeddedWindow) { + if (embeddedWindow == null) { + ProtoLog.w(WM_DEBUG_EMBEDDED_WINDOWS, + "Attempt to transfer touch gesture with non-existent embedded window"); + return false; + } + final WindowState wsAssociatedWithEmbedded = embeddedWindow.getWindowState(); + if (wsAssociatedWithEmbedded == null) { + ProtoLog.w(WM_DEBUG_EMBEDDED_WINDOWS, + "Attempt to transfer touch gesture using embedded window with no associated " + + "host"); + return false; + } + if (wsAssociatedWithEmbedded.mClient.asBinder() != hostWindowState.mClient.asBinder()) { + ProtoLog.w(WM_DEBUG_EMBEDDED_WINDOWS, + "Attempt to transfer touch gesture with host window not associated with " + + "embedded window"); + return false; + } + + if (embeddedWindow.getInputChannelToken() == null) { + ProtoLog.w(WM_DEBUG_EMBEDDED_WINDOWS, + "Attempt to transfer touch gesture using embedded window that has no input " + + "channel"); + return false; + } + if (hostWindowState.mInputChannelToken == null) { + ProtoLog.w(WM_DEBUG_EMBEDDED_WINDOWS, + "Attempt to transfer touch gesture using a host window with no input channel"); + return false; + } + return true; + } + + boolean transferToHost(@NonNull InputTransferToken embeddedWindowToken, + @NonNull WindowState transferToHostWindowState) { + EmbeddedWindow ew = getByInputTransferToken(embeddedWindowToken); + if (!isValidTouchGestureParams(transferToHostWindowState, ew)) { + return false; + } + return mInputManagerService.transferTouchFocus(ew.getInputChannelToken(), + transferToHostWindowState.mInputChannelToken); + } + + boolean transferToEmbedded(WindowState hostWindowState, + @NonNull InputTransferToken transferToToken) { + final EmbeddedWindowController.EmbeddedWindow ew = getByInputTransferToken(transferToToken); + if (!isValidTouchGestureParams(hostWindowState, ew)) { + return false; + } + return mInputManagerService.transferTouchFocus(hostWindowState.mInputChannelToken, + ew.getInputChannelToken()); + } + static class EmbeddedWindow implements InputTarget { final IBinder mClient; @Nullable final WindowState mHostWindowState; diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 609ad1e76370..bf45804192a9 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -612,10 +612,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } void refreshSecureSurfaceState() { - forAllWindows((w) -> { - if (w.mHasSurface) { - w.setSecureLocked(w.isSecureLocked()); - } + forAllWindows(w -> { + w.setSecureLocked(w.isSecureLocked()); }, true /* traverseTopToBottom */); } diff --git a/services/core/java/com/android/server/wm/SensitiveContentPackages.java b/services/core/java/com/android/server/wm/SensitiveContentPackages.java index a7d6903bbe30..5fe48d12d498 100644 --- a/services/core/java/com/android/server/wm/SensitiveContentPackages.java +++ b/services/core/java/com/android/server/wm/SensitiveContentPackages.java @@ -56,6 +56,17 @@ public class SensitiveContentPackages { } /** + * Clears apps added to collection of apps in which screen capture should be disabled. + * + * @param packageInfos set of {@link PackageInfo} whose windows should be unblocked + * from capture. + * @return {@code true} if packages set is modified, {@code false} otherwise. + */ + public boolean removeBlockScreenCaptureForApps(@NonNull ArraySet<PackageInfo> packageInfos) { + return mProtectedPackages.removeAll(packageInfos); + } + + /** * Clears the set of package/uid pairs that should be blocked from screen capture * * @return {@code true} if packages set is modified, {@code false} otherwise. diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 3c8c55e278e3..975208fb4b4c 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -970,40 +970,6 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override - public boolean transferEmbeddedTouchFocusToHost(IWindow embeddedWindow) { - if (embeddedWindow == null) { - return false; - } - - final long identity = Binder.clearCallingIdentity(); - boolean didTransfer = false; - try { - didTransfer = mService.transferEmbeddedTouchFocusToHost(embeddedWindow); - } finally { - Binder.restoreCallingIdentity(identity); - } - return didTransfer; - } - - @Override - public boolean transferHostTouchGestureToEmbedded(IWindow hostWindow, - InputTransferToken inputTransferToken) { - if (hostWindow == null) { - return false; - } - - final long identity = Binder.clearCallingIdentity(); - boolean didTransfer; - try { - didTransfer = mService.transferHostTouchGestureToEmbedded(this, hostWindow, - inputTransferToken); - } finally { - Binder.restoreCallingIdentity(identity); - } - return didTransfer; - } - - @Override public boolean moveFocusToAdjacentWindow(IWindow fromWindow, @FocusDirection int direction) { final long identity = Binder.clearCallingIdentity(); try { diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index ae4c3b9a510a..669c61c4b40c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -1043,6 +1043,15 @@ public abstract class WindowManagerInternal { /** * Clears apps added to collection of apps in which screen capture should be disabled. * + * @param packageInfos set of {@link PackageInfo} whose windows should be unblocked + * from capture. + */ + public abstract void removeBlockScreenCaptureForApps( + @NonNull ArraySet<PackageInfo> packageInfos); + + /** + * Clears all apps added to collection of apps in which screen capture should be disabled. + * * <p> This clears and resets any existing set or added applications from * * {@link #addBlockScreenCaptureForApps(ArraySet)} */ diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 631ebcd2b6e9..e538f5d5cf41 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1344,7 +1344,7 @@ public class WindowManagerService extends IWindowManager.Stub LocalServices.addService(WindowManagerInternal.class, new LocalService()); LocalServices.addService( ImeTargetVisibilityPolicy.class, new ImeTargetVisibilityPolicyImpl()); - mEmbeddedWindowController = new EmbeddedWindowController(mAtmService); + mEmbeddedWindowController = new EmbeddedWindowController(mAtmService, inputManager); mDisplayAreaPolicyProvider = DisplayAreaPolicy.Provider.fromResources( mContext.getResources()); @@ -8632,6 +8632,17 @@ public class WindowManagerService extends IWindowManager.Stub } @Override + public void removeBlockScreenCaptureForApps(ArraySet<PackageInfo> packageInfos) { + synchronized (mGlobalLock) { + boolean modified = + mSensitiveContentPackages.removeBlockScreenCaptureForApps(packageInfos); + if (modified) { + WindowManagerService.this.refreshScreenCaptureDisabled(); + } + } + } + + @Override public void clearBlockedApps() { synchronized (mGlobalLock) { boolean modified = mSensitiveContentPackages.clearBlockedApps(); @@ -9044,73 +9055,33 @@ public class WindowManagerService extends IWindowManager.Stub null /* region */, clientToken); } - boolean transferEmbeddedTouchFocusToHost(IWindow embeddedWindow) { - final IBinder windowBinder = embeddedWindow.asBinder(); - final IBinder hostInputChannel, embeddedInputChannel; - synchronized (mGlobalLock) { - final EmbeddedWindowController.EmbeddedWindow ew = - mEmbeddedWindowController.getByWindowToken(windowBinder); - if (ew == null) { - Slog.w(TAG, "Attempt to transfer touch focus from non-existent embedded window"); - return false; - } - final WindowState hostWindowState = ew.getWindowState(); - if (hostWindowState == null) { - Slog.w(TAG, "Attempt to transfer touch focus from embedded window with no" + - " associated host"); - return false; - } - embeddedInputChannel = ew.getInputChannelToken(); - if (embeddedInputChannel == null) { - Slog.w(TAG, "Attempt to transfer touch focus from embedded window with no input" + - " channel"); - return false; - } - hostInputChannel = hostWindowState.mInputChannelToken; - if (hostInputChannel == null) { - Slog.w(TAG, "Attempt to transfer touch focus to a host window with no" + - " input channel"); - return false; - } - return mInputManager.transferTouchFocus(embeddedInputChannel, hostInputChannel); - } - } - - boolean transferHostTouchGestureToEmbedded(Session session, IWindow hostWindow, - InputTransferToken inputTransferToken) { - final IBinder hostInputChannel, embeddedInputChannel; - synchronized (mGlobalLock) { - final WindowState hostWindowState = windowForClientLocked(session, hostWindow, false); - if (hostWindowState == null) { - Slog.w(TAG, "Attempt to transfer touch gesture with invalid host window"); - return false; - } + @Override + public boolean transferTouchGesture(@NonNull InputTransferToken transferFromToken, + @NonNull InputTransferToken transferToToken) { + Objects.requireNonNull(transferFromToken); + Objects.requireNonNull(transferToToken); - final EmbeddedWindowController.EmbeddedWindow ew = - mEmbeddedWindowController.getByInputTransferToken(inputTransferToken); - if (ew == null || ew.mHostWindowState == null) { - Slog.w(TAG, "Attempt to transfer touch gesture to non-existent embedded window"); - return false; - } - if (ew.mHostWindowState.mClient.asBinder() != hostWindow.asBinder()) { - Slog.w(TAG, "Attempt to transfer touch gesture to embedded window not associated" - + " with host window"); - return false; - } - embeddedInputChannel = ew.getInputChannelToken(); - if (embeddedInputChannel == null) { - Slog.w(TAG, "Attempt to transfer touch focus from embedded window with no input" - + " channel"); - return false; - } - hostInputChannel = hostWindowState.mInputChannelToken; - if (hostInputChannel == null) { - Slog.w(TAG, - "Attempt to transfer touch focus to a host window with no input channel"); - return false; + final long identity = Binder.clearCallingIdentity(); + boolean didTransfer; + try { + synchronized (mGlobalLock) { + // If the transferToToken exists in the input to window map, it means the request + // is to transfer from embedded to host. Otherwise, the transferToToken + // represents an embedded window so transfer from host to embedded. + WindowState windowStateTo = mInputToWindowMap.get(transferToToken.mToken); + if (windowStateTo != null) { + didTransfer = mEmbeddedWindowController.transferToHost(transferFromToken, + windowStateTo); + } else { + WindowState windowStateFrom = mInputToWindowMap.get(transferFromToken.mToken); + didTransfer = mEmbeddedWindowController.transferToEmbedded(windowStateFrom, + transferToToken); + } } - return mInputManager.transferTouchFocus(hostInputChannel, embeddedInputChannel); + } finally { + Binder.restoreCallingIdentity(identity); } + return didTransfer; } private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid, diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index f56e50e2e9fd..6e993b340352 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1897,7 +1897,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return true; } - if (com.android.server.notification.Flags.sensitiveNotificationAppProtection()) { + if (android.permission.flags.Flags.sensitiveNotificationAppProtection()) { if (mWmService.mSensitiveContentPackages .shouldBlockScreenCaptureForApp(getOwningPackage(), getOwningUid())) { return true; diff --git a/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java b/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java index adb1b72cf3ee..d06d4d869192 100644 --- a/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java +++ b/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java @@ -168,6 +168,9 @@ public class GetCandidateRequestSession extends RequestSession<GetCredentialRequ mRequestSessionMetric.collectFrameworkException(exception); if (finalResponseReceiver != null) { Bundle resultData = new Bundle(); + resultData.putStringArray( + CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION, + new String[] {exception, message}); finalResponseReceiver.send(Constants.FAILURE_CREDMAN_SELECTOR, resultData); } else { respondToClientWithErrorAndFinish(exception, message); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index e619440b580b..58e198e532cd 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -28,10 +28,13 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_AIRPLANE_MODE; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_APPS_CONTROL; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_APP_RESTRICTIONS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_AUDIO_OUTPUT; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_AUTOFILL; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_BLOCK_UNINSTALL; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_BLUETOOTH; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CALLS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CAMERA; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CAMERA_TOGGLE; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CERTIFICATES; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CONTENT_PROTECTION; @@ -50,6 +53,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_TASK; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MANAGED_SUBSCRIPTIONS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MICROPHONE; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MICROPHONE_TOGGLE; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MOBILE_NETWORK; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MODIFY_USERS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MTE; @@ -74,6 +78,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_STATUS_BAR; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SUPPORT_MESSAGE; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_THEFT_DETECTION; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_THREAD_NETWORK; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_TIME; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING; @@ -328,6 +333,7 @@ import android.app.admin.DevicePolicyStringResource; import android.app.admin.DeviceStateCache; import android.app.admin.FactoryResetProtectionPolicy; import android.app.admin.FullyManagedDeviceProvisioningParams; +import android.app.admin.IAuditLogEventsCallback; import android.app.admin.IDevicePolicyManager; import android.app.admin.IntegerPolicyValue; import android.app.admin.IntentFilterPolicyKey; @@ -2060,7 +2066,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mLockPatternUtils = injector.newLockPatternUtils(); mLockSettingsInternal = injector.getLockSettingsInternal(); // TODO: why does SecurityLogMonitor need to be created even when mHasFeature == false? - mSecurityLogMonitor = new SecurityLogMonitor(this); + mSecurityLogMonitor = new SecurityLogMonitor(this, mHandler); mHasFeature = mInjector.hasFeature(); mIsWatch = mInjector.getPackageManager() @@ -2718,8 +2724,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private void maybeStartSecurityLogMonitorOnActivityManagerReady() { - synchronized (getLockObject()) { - if (mInjector.securityLogIsLoggingEnabled()) { + if (!mInjector.securityLogIsLoggingEnabled()) { + return; + } + + if (securityLogV2Enabled()) { + boolean auditLoggingEnabled = Boolean.TRUE.equals( + mDevicePolicyEngine.getResolvedPolicy( + PolicyDefinition.AUDIT_LOGGING, UserHandle.USER_ALL)); + boolean securityLoggingEnabled = Boolean.TRUE.equals( + mDevicePolicyEngine.getResolvedPolicy( + PolicyDefinition.SECURITY_LOGGING, UserHandle.USER_ALL)); + setLoggingConfiguration(securityLoggingEnabled, auditLoggingEnabled); + } else { + synchronized (getLockObject()) { mSecurityLogMonitor.start(getSecurityLoggingEnabledUser()); mInjector.runCryptoSelfTest(); maybePauseDeviceWideLoggingLocked(); @@ -15780,7 +15798,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void enforceSecurityLoggingPolicy(boolean enabled) { - enforceLoggingPolicy(enabled); + if (!securityLogV2Enabled()) { + return; + } + Boolean auditLoggingEnabled = mDevicePolicyEngine.getResolvedPolicy( + PolicyDefinition.AUDIT_LOGGING, UserHandle.USER_ALL); + enforceLoggingPolicy(enabled, Boolean.TRUE.equals(auditLoggingEnabled)); + } + + @Override + public void enforceAuditLoggingPolicy(boolean enabled) { + if (!securityLogV2Enabled()) { + return; + } + Boolean securityLoggingEnabled = mDevicePolicyEngine.getResolvedPolicy( + PolicyDefinition.SECURITY_LOGGING, UserHandle.USER_ALL); + enforceLoggingPolicy(Boolean.TRUE.equals(securityLoggingEnabled), enabled); } private List<EnforcingUser> getEnforcingUsers(Set<EnforcingAdmin> admins) { @@ -15800,17 +15833,23 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - private void enforceLoggingPolicy(boolean securityLoggingEnabled) { - Slogf.i(LOG_TAG, "Enforcing security logging, securityLoggingEnabled: %b", - securityLoggingEnabled); - SecurityLog.setLoggingEnabledProperty(securityLoggingEnabled); - if (securityLoggingEnabled) { - mSecurityLogMonitor.start(getSecurityLoggingEnabledUser()); + private void enforceLoggingPolicy( + boolean securityLoggingEnabled, boolean auditLoggingEnabled) { + Slogf.i(LOG_TAG, "Enforcing logging policy, security: %b audit: %b", + securityLoggingEnabled, auditLoggingEnabled); + SecurityLog.setLoggingEnabledProperty(securityLoggingEnabled || auditLoggingEnabled); + setLoggingConfiguration(securityLoggingEnabled, auditLoggingEnabled); + } + + private void setLoggingConfiguration( + boolean securityLoggingEnabled, boolean auditLoggingEnabled) { + final int loggingEnabledUser = getSecurityLoggingEnabledUser(); + mSecurityLogMonitor.setLoggingParams( + loggingEnabledUser, securityLoggingEnabled, auditLoggingEnabled); + if (securityLoggingEnabled || auditLoggingEnabled) { synchronized (getLockObject()) { maybePauseDeviceWideLoggingLocked(); } - } else { - mSecurityLogMonitor.stop(); } } @@ -17891,6 +17930,82 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override + public void setAuditLogEnabled(String callingPackage, boolean enabled) { + if (!mHasFeature) { + return; + } + final CallerIdentity caller = getCallerIdentity(callingPackage); + + if (!securityLogV2Enabled()) { + throw new UnsupportedOperationException("Audit log not enabled"); + } + + EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin( + null /* admin */, + MANAGE_DEVICE_POLICY_AUDIT_LOGGING, + caller.getPackageName(), + caller.getUserId()); + if (enabled) { + mDevicePolicyEngine.setGlobalPolicy( + PolicyDefinition.AUDIT_LOGGING, + admin, + new BooleanPolicyValue(true)); + } else { + mDevicePolicyEngine.removeGlobalPolicy( + PolicyDefinition.AUDIT_LOGGING, + admin); + mSecurityLogMonitor.setAuditLogEventsCallback(caller.getUid(), null /* callback */); + } + } + + @Override + public boolean isAuditLogEnabled(String callingPackage) { + if (!mHasFeature) { + return false; + } + + if (!securityLogV2Enabled()) { + throw new UnsupportedOperationException("Audit log not enabled"); + } + + final CallerIdentity caller = getCallerIdentity(callingPackage); + EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin( + null /* admin */, + MANAGE_DEVICE_POLICY_AUDIT_LOGGING, + caller.getPackageName(), + caller.getUserId()); + + Boolean policy = mDevicePolicyEngine.getGlobalPolicySetByAdmin( + PolicyDefinition.AUDIT_LOGGING, admin); + + return Boolean.TRUE.equals(policy); + } + + @Override + public void setAuditLogEventsCallback(String callingPackage, IAuditLogEventsCallback callback) { + if (!mHasFeature) { + return; + } + + final CallerIdentity caller = getCallerIdentity(callingPackage); + EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin( + null /* admin */, + MANAGE_DEVICE_POLICY_AUDIT_LOGGING, + caller.getPackageName(), + caller.getUserId()); + + Boolean policy = mDevicePolicyEngine.getGlobalPolicySetByAdmin( + PolicyDefinition.AUDIT_LOGGING, admin); + + if (!Boolean.TRUE.equals(policy)) { + throw new IllegalStateException( + "Managing app has to enable audit log before setting events callback"); + } + + mSecurityLogMonitor.setAuditLogEventsCallback(caller.getUid(), callback); + } + + @Override public long forceSecurityLogs() { Preconditions.checkCallAuthorization(isAdb(getCallerIdentity()) || hasCallingOrSelfPermission(permission.FORCE_DEVICE_POLICY_MANAGER_LOGS), @@ -21984,6 +22099,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override + public boolean isTheftDetectionTriggered(String callerPackageName) { + final CallerIdentity caller = getCallerIdentity(callerPackageName); + if (!android.app.admin.flags.Flags.deviceTheftImplEnabled()) { + return false; + } + enforcePermission(MANAGE_DEVICE_POLICY_THEFT_DETECTION, caller.getPackageName(), + caller.getUserId()); + + //STOPSHIP: replace 1<<9 with + // LockPatternUtils.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST once ag/26042068 lands + return 0 != (mLockPatternUtils.getStrongAuthForUser(caller.getUserId()) & (1 << 9)); + } + + @Override public void setWifiSsidPolicy(String callerPackageName, WifiSsidPolicy policy) { CallerIdentity caller; @@ -22424,14 +22553,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { }); } - // Permission that will need to be created in V. - private static final String MANAGE_DEVICE_POLICY_BLOCK_UNINSTALL = - "manage_device_policy_block_uninstall"; - private static final String MANAGE_DEVICE_POLICY_CAMERA_TOGGLE = - "manage_device_policy_camera_toggle"; - private static final String MANAGE_DEVICE_POLICY_MICROPHONE_TOGGLE = - "manage_device_policy_microphone_toggle"; - // DPC types private static final int NOT_A_DPC = -1; private static final int DEFAULT_DEVICE_OWNER = 0; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java index 3474db3c7c1f..1247f900260a 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java @@ -141,6 +141,13 @@ final class PolicyDefinition<V> { PolicyEnforcerCallbacks::enforceSecurityLogging, new BooleanPolicySerializer()); + static PolicyDefinition<Boolean> AUDIT_LOGGING = new PolicyDefinition<>( + new NoArgsPolicyKey(DevicePolicyIdentifiers.AUDIT_LOGGING_POLICY), + TRUE_MORE_RESTRICTIVE, + POLICY_FLAG_GLOBAL_ONLY_POLICY, + PolicyEnforcerCallbacks::enforceAuditLogging, + new BooleanPolicySerializer()); + static PolicyDefinition<LockTaskPolicy> LOCK_TASK = new PolicyDefinition<>( new NoArgsPolicyKey(DevicePolicyIdentifiers.LOCK_TASK_POLICY), new TopPriority<>(List.of( @@ -365,6 +372,8 @@ final class PolicyDefinition<V> { GENERIC_PERMISSION_GRANT); POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.SECURITY_LOGGING_POLICY, SECURITY_LOGGING); + POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.AUDIT_LOGGING_POLICY, + AUDIT_LOGGING); POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.LOCK_TASK_POLICY, LOCK_TASK); POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.USER_CONTROL_DISABLED_PACKAGES_POLICY, USER_CONTROLLED_DISABLED_PACKAGES); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java index 4aaefa670ea2..54242ab279b0 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java @@ -136,6 +136,14 @@ final class PolicyEnforcerCallbacks { return true; } + static boolean enforceAuditLogging( + @Nullable Boolean value, @NonNull Context context, int userId, + @NonNull PolicyKey policyKey) { + final var dpmi = LocalServices.getService(DevicePolicyManagerInternal.class); + dpmi.enforceAuditLoggingPolicy(Boolean.TRUE.equals(value)); + return true; + } + static boolean setLockTask( @Nullable LockTaskPolicy policy, @NonNull Context context, int userId) { List<String> packages = Collections.emptyList(); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java index 7a4454b11fce..02f39189ae72 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java @@ -16,22 +16,32 @@ package com.android.server.devicepolicy; +import static android.app.admin.flags.Flags.securityLogV2Enabled; + import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; import android.app.admin.DeviceAdminReceiver; +import android.app.admin.IAuditLogEventsCallback; import android.app.admin.SecurityLog; import android.app.admin.SecurityLog.SecurityEvent; +import android.os.Handler; +import android.os.IBinder; import android.os.Process; +import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; import android.util.Slog; +import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.utils.Slogf; import java.io.IOException; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -53,15 +63,11 @@ class SecurityLogMonitor implements Runnable { private int mEnabledUser; - SecurityLogMonitor(DevicePolicyManagerService service) { - this(service, 0 /* id */); - } - - @VisibleForTesting - SecurityLogMonitor(DevicePolicyManagerService service, long id) { + SecurityLogMonitor(DevicePolicyManagerService service, Handler handler) { mService = service; - mId = id; + mId = 0; mLastForceNanos = System.nanoTime(); + mHandler = handler; } private static final boolean DEBUG = false; // STOPSHIP if true. @@ -118,6 +124,9 @@ class SecurityLogMonitor implements Runnable { @GuardedBy("mLock") private boolean mCriticalLevelLogged = false; + private boolean mLegacyLogEnabled; + private boolean mAuditLogEnabled; + /** * Last events fetched from log to check for overlap between batches. We can leave it empty if * we are sure there will be no overlap anymore, e.g. when we get empty batch. @@ -143,6 +152,40 @@ class SecurityLogMonitor implements Runnable { private long mLastForceNanos = 0; /** + * Handler shared with DPMS. + */ + private final Handler mHandler; + + /** + * Oldest events get purged from audit log buffer if total number exceeds this value. + */ + private static final int MAX_AUDIT_LOG_EVENTS = 10000; + /** + * Events older than this get purged from audit log buffer. + */ + private static final long MAX_AUDIT_LOG_EVENT_AGE_NS = TimeUnit.HOURS.toNanos(8); + + /** + * Audit log callbacks keyed by UID. The code should maintain the following invariant: all + * callbacks in this map have received (or are scheduled to receive) all events in + * mAuditLogEventsBuffer. To ensure this, before a callback is put into this map, it must be + * scheduled to receive all the events in the buffer, and conversely, before a new chunk of + * events is added to the buffer, it must be scheduled to be sent to all callbacks already in + * this list. All scheduling should happen on mHandler, so that they aren't reordered, and + * while holding the lock. This ensures that no callback misses an event or receives a duplicate + * or out of order events. + */ + @GuardedBy("mLock") + private final SparseArray<IAuditLogEventsCallback> mAuditLogCallbacks = new SparseArray<>(); + + /** + * Audit log event buffer. It is shrunk automatically whenever either there are too many events + * or the oldest one is too old. + */ + @GuardedBy("mLock") + private final ArrayDeque<SecurityEvent> mAuditLogEventBuffer = new ArrayDeque<>(); + + /** * Start security logging. * * @param enabledUser which user logging is enabled on, or USER_ALL to enable logging for all @@ -154,18 +197,8 @@ class SecurityLogMonitor implements Runnable { mLock.lock(); try { if (mMonitorThread == null) { - mPendingLogs = new ArrayList<>(); - mCriticalLevelLogged = false; - mId = 0; - mAllowedToRetrieve = false; - mNextAllowedRetrievalTimeMillis = -1; - mPaused = false; - - mMonitorThread = new Thread(this); - mMonitorThread.start(); - - SecurityLog.writeEvent(SecurityLog.TAG_LOGGING_STARTED); - Slog.i(TAG, "Security log monitor thread started"); + resetLegacyBufferLocked(); + startMonitorThreadLocked(); } else { Slog.i(TAG, "Security log monitor thread is already running"); } @@ -176,29 +209,82 @@ class SecurityLogMonitor implements Runnable { void stop() { Slog.i(TAG, "Stopping security logging."); - SecurityLog.writeEvent(SecurityLog.TAG_LOGGING_STOPPED); mLock.lock(); try { if (mMonitorThread != null) { - mMonitorThread.interrupt(); - try { - mMonitorThread.join(TimeUnit.SECONDS.toMillis(5)); - } catch (InterruptedException e) { - Log.e(TAG, "Interrupted while waiting for thread to stop", e); - } - // Reset state and clear buffer - mPendingLogs = new ArrayList<>(); - mId = 0; - mAllowedToRetrieve = false; - mNextAllowedRetrievalTimeMillis = -1; - mPaused = false; - mMonitorThread = null; + stopMonitorThreadLocked(); + resetLegacyBufferLocked(); } } finally { mLock.unlock(); } } + void setLoggingParams(int enabledUser, boolean legacyLogEnabled, boolean auditLogEnabled) { + Slogf.i(TAG, "Setting logging params, user = %d -> %d, legacy: %b -> %b, audit %b -> %b", + mEnabledUser, enabledUser, mLegacyLogEnabled, legacyLogEnabled, mAuditLogEnabled, + auditLogEnabled); + mLock.lock(); + try { + mEnabledUser = enabledUser; + if (mMonitorThread == null && (legacyLogEnabled || auditLogEnabled)) { + startMonitorThreadLocked(); + } else if (mMonitorThread != null && !legacyLogEnabled && !auditLogEnabled) { + stopMonitorThreadLocked(); + } + + if (mLegacyLogEnabled != legacyLogEnabled) { + resetLegacyBufferLocked(); + mLegacyLogEnabled = legacyLogEnabled; + } + + if (mAuditLogEnabled != auditLogEnabled) { + resetAuditBufferLocked(); + mAuditLogEnabled = auditLogEnabled; + } + } finally { + mLock.unlock(); + } + + } + + @GuardedBy("mLock") + private void startMonitorThreadLocked() { + mId = 0; + mPaused = false; + mMonitorThread = new Thread(this); + mMonitorThread.start(); + SecurityLog.writeEvent(SecurityLog.TAG_LOGGING_STARTED); + Slog.i(TAG, "Security log monitor thread started"); + } + + @GuardedBy("mLock") + private void stopMonitorThreadLocked() { + mMonitorThread.interrupt(); + try { + mMonitorThread.join(TimeUnit.SECONDS.toMillis(5)); + } catch (InterruptedException e) { + Log.e(TAG, "Interrupted while waiting for thread to stop", e); + } + mMonitorThread = null; + SecurityLog.writeEvent(SecurityLog.TAG_LOGGING_STOPPED); + } + + @GuardedBy("mLock") + private void resetLegacyBufferLocked() { + mPendingLogs = new ArrayList<>(); + mCriticalLevelLogged = false; + mAllowedToRetrieve = false; + mNextAllowedRetrievalTimeMillis = -1; + Slog.i(TAG, "Legacy buffer reset."); + } + + @GuardedBy("mLock") + private void resetAuditBufferLocked() { + mAuditLogEventBuffer.clear(); + mAuditLogCallbacks.clear(); + } + /** * If logs are being collected, keep collecting them but stop notifying the device owner that * new logs are available (since they cannot be retrieved). @@ -338,8 +424,7 @@ class SecurityLogMonitor implements Runnable { */ @GuardedBy("mLock") private void mergeBatchLocked(final ArrayList<SecurityEvent> newLogs) { - // Reserve capacity so that copying doesn't occur. - mPendingLogs.ensureCapacity(mPendingLogs.size() + newLogs.size()); + List<SecurityEvent> dedupedLogs = new ArrayList<>(); // Run through the first events of the batch to check if there is an overlap with previous // batch and if so, skip overlapping events. Events are sorted by timestamp, so we can // compare it in linear time by advancing two pointers, one for each batch. @@ -358,8 +443,7 @@ class SecurityLogMonitor implements Runnable { if (lastNanos > currentNanos) { // New event older than the last we've seen so far, must be due to reordering. if (DEBUG) Slog.d(TAG, "New event in the overlap: " + currentNanos); - assignLogId(curEvent); - mPendingLogs.add(curEvent); + dedupedLogs.add(curEvent); curPos++; } else if (lastNanos < currentNanos) { if (DEBUG) Slog.d(TAG, "Event disappeared from the overlap: " + lastNanos); @@ -371,8 +455,7 @@ class SecurityLogMonitor implements Runnable { if (DEBUG) Slog.d(TAG, "Skipped dup event with timestamp: " + lastNanos); } else { // Wow, what a coincidence, or probably the clock is too coarse. - assignLogId(curEvent); - mPendingLogs.add(curEvent); + dedupedLogs.add(curEvent); if (DEBUG) Slog.d(TAG, "Event timestamp collision: " + lastNanos); } lastPos++; @@ -380,12 +463,23 @@ class SecurityLogMonitor implements Runnable { } } // Assign an id to the new logs, after the overlap with mLastEvents. - List<SecurityEvent> idLogs = newLogs.subList(curPos, newLogs.size()); - for (SecurityEvent event : idLogs) { + dedupedLogs.addAll(newLogs.subList(curPos, newLogs.size())); + for (SecurityEvent event : dedupedLogs) { assignLogId(event); } + + if (!securityLogV2Enabled() || mLegacyLogEnabled) { + addToLegacyBuffer(dedupedLogs); + } + + if (securityLogV2Enabled() && mAuditLogEnabled) { + addAuditLogEvents(dedupedLogs); + } + } + + private void addToLegacyBuffer(List<SecurityEvent> dedupedLogs) { // Save the rest of the new batch. - mPendingLogs.addAll(idLogs); + mPendingLogs.addAll(dedupedLogs); checkCriticalLevel(); @@ -453,7 +547,10 @@ class SecurityLogMonitor implements Runnable { saveLastEvents(newLogs); newLogs.clear(); - notifyDeviceOwnerOrProfileOwnerIfNeeded(force); + + if (!securityLogV2Enabled() || mLegacyLogEnabled) { + notifyDeviceOwnerOrProfileOwnerIfNeeded(force); + } } catch (IOException e) { Log.e(TAG, "Failed to read security log", e); } catch (InterruptedException e) { @@ -532,4 +629,121 @@ class SecurityLogMonitor implements Runnable { return 0; } } + + public void setAuditLogEventsCallback(int uid, IAuditLogEventsCallback callback) { + mLock.lock(); + try { + if (callback == null) { + mAuditLogCallbacks.remove(uid); + Slogf.i(TAG, "Cleared audit log callback for UID %d", uid); + return; + } + // Create a copy while holding the lock, so that that new events are not added + // resulting in duplicates. + final List<SecurityEvent> events = new ArrayList<>(mAuditLogEventBuffer); + scheduleSendAuditLogs(uid, callback, events); + mAuditLogCallbacks.append(uid, callback); + } finally { + mLock.unlock(); + } + Slogf.i(TAG, "Set audit log callback for UID %d", uid); + } + + private void addAuditLogEvents(List<SecurityEvent> events) { + mLock.lock(); + try { + if (mPaused) { + // TODO: maybe we need to stash the logs in some temp buffer wile paused so that + // they can be accessed after affiliation is fixed. + return; + } + if (!events.isEmpty()) { + for (int i = 0; i < mAuditLogCallbacks.size(); i++) { + final int uid = mAuditLogCallbacks.keyAt(i); + scheduleSendAuditLogs(uid, mAuditLogCallbacks.valueAt(i), events); + } + } + if (DEBUG) { + Slogf.d(TAG, "Adding audit %d events to % already present in the buffer", + events.size(), mAuditLogEventBuffer.size()); + } + mAuditLogEventBuffer.addAll(events); + trimAuditLogBufferLocked(); + if (DEBUG) { + Slogf.d(TAG, "Audit event buffer size after trimming: %d", + mAuditLogEventBuffer.size()); + } + } finally { + mLock.unlock(); + } + } + + @GuardedBy("mLock") + private void trimAuditLogBufferLocked() { + long nowNanos = TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()); + + final Iterator<SecurityEvent> iterator = mAuditLogEventBuffer.iterator(); + while (iterator.hasNext()) { + final SecurityEvent event = iterator.next(); + if (mAuditLogEventBuffer.size() <= MAX_AUDIT_LOG_EVENTS + && nowNanos - event.getTimeNanos() <= MAX_AUDIT_LOG_EVENT_AGE_NS) { + break; + } + + iterator.remove(); + } + } + + private void scheduleSendAuditLogs( + int uid, IAuditLogEventsCallback callback, List<SecurityEvent> events) { + if (DEBUG) { + Slogf.d(TAG, "Scheduling to send %d audit log events to UID %d", events.size(), uid); + } + mHandler.post(() -> sendAuditLogs(uid, callback, events)); + } + + private void sendAuditLogs( + int uid, IAuditLogEventsCallback callback, List<SecurityEvent> events) { + try { + final int size = events.size(); + if (DEBUG) { + Slogf.d(TAG, "Sending %d audit log events to UID %d", size, uid); + } + callback.onNewAuditLogEvents(events); + if (DEBUG) { + Slogf.d(TAG, "Sent %d audit log events to UID %d", size, uid); + } + } catch (RemoteException e) { + Slogf.e(TAG, e, "Failed to invoke audit log callback for UID %d", uid); + removeAuditLogEventsCallbackIfDead(uid, callback); + } + } + + private void removeAuditLogEventsCallbackIfDead(int uid, IAuditLogEventsCallback callback) { + final IBinder binder = callback.asBinder(); + if (binder.isBinderAlive()) { + Slog.i(TAG, "Callback binder is still alive, not removing."); + return; + } + + mLock.lock(); + try { + int index = mAuditLogCallbacks.indexOfKey(uid); + if (index < 0) { + Slogf.i(TAG, "Callback not registered for UID %d, nothing to remove", uid); + return; + } + + final IBinder storedBinder = mAuditLogCallbacks.valueAt(index).asBinder(); + if (!storedBinder.equals(binder)) { + Slogf.i(TAG, "Callback is already replaced for UID %d, not removing", uid); + return; + } + + Slogf.i(TAG, "Removing callback for UID %d", uid); + mAuditLogCallbacks.removeAt(index); + } finally { + mLock.unlock(); + } + } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 1d89d1722f74..ee758dbd0516 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -107,6 +107,7 @@ import com.android.internal.util.EmergencyAffordanceManager; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.widget.ILockSettings; import com.android.internal.widget.LockSettingsInternal; +import com.android.server.adaptiveauth.AdaptiveAuthService; import com.android.server.am.ActivityManagerService; import com.android.server.appbinding.AppBindingService; import com.android.server.appop.AppOpMigrationHelper; @@ -2615,6 +2616,12 @@ public final class SystemServer implements Dumpable { mSystemServiceManager.startService(AuthService.class); t.traceEnd(); + if (android.adaptiveauth.Flags.enableAdaptiveAuth()) { + t.traceBegin("StartAdaptiveAuthService"); + mSystemServiceManager.startService(AdaptiveAuthService.class); + t.traceEnd(); + } + if (!isWatch) { // We don't run this on watches as there are no plans to use the data logged // on watch devices. @@ -3014,7 +3021,7 @@ public final class SystemServer implements Dumpable { t.traceEnd(); } - if (com.android.server.notification.Flags.sensitiveNotificationAppProtection() + if (android.permission.flags.Flags.sensitiveNotificationAppProtection() || android.view.flags.Flags.sensitiveContentAppProtection()) { t.traceBegin("StartSensitiveContentProtectionManager"); mSystemServiceManager.startService(SensitiveContentProtectionManagerService.class); diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt index 558827631dfe..4b086b3aca17 100644 --- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt +++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt @@ -46,6 +46,7 @@ import com.android.server.pm.KnownPackages import com.android.server.pm.parsing.PackageInfoUtils import com.android.server.pm.pkg.AndroidPackage import com.android.server.pm.pkg.PackageState +import libcore.util.EmptyArray class AppIdPermissionPolicy : SchemePolicy() { private val persistence = AppIdPermissionPersistence() @@ -73,40 +74,42 @@ class AppIdPermissionPolicy : SchemePolicy() { } override fun MutateStateScope.onInitialized() { - newState.externalState.configPermissions.forEach { (permissionName, permissionEntry) -> - val oldPermission = newState.systemState.permissions[permissionName] - val newPermission = - if (oldPermission != null) { - if (permissionEntry.gids != null) { - oldPermission.copy( - gids = permissionEntry.gids, - areGidsPerUser = permissionEntry.perUser - ) - } else { - return@forEach - } - } else { - @Suppress("DEPRECATION") - val permissionInfo = - PermissionInfo().apply { - name = permissionName - packageName = PLATFORM_PACKAGE_NAME - protectionLevel = PermissionInfo.PROTECTION_SIGNATURE + if (!Flags.newPermissionGidEnabled()) { + newState.externalState.configPermissions.forEach { (permissionName, permissionEntry) -> + val oldPermission = newState.systemState.permissions[permissionName] + val newPermission = + if (oldPermission != null) { + if (permissionEntry.gids != null) { + oldPermission.copy( + gids = permissionEntry.gids, + areGidsPerUser = permissionEntry.perUser + ) + } else { + return@forEach } - if (permissionEntry.gids != null) { - Permission( - permissionInfo, - false, - Permission.TYPE_CONFIG, - 0, - permissionEntry.gids, - permissionEntry.perUser - ) } else { - Permission(permissionInfo, false, Permission.TYPE_CONFIG, 0) + @Suppress("DEPRECATION") + val permissionInfo = + PermissionInfo().apply { + name = permissionName + packageName = PLATFORM_PACKAGE_NAME + protectionLevel = PermissionInfo.PROTECTION_SIGNATURE + } + if (permissionEntry.gids != null) { + Permission( + permissionInfo, + false, + Permission.TYPE_CONFIG, + 0, + permissionEntry.gids, + permissionEntry.perUser + ) + } else { + Permission(permissionInfo, false, Permission.TYPE_CONFIG, 0) + } } - } - newState.mutateSystemState().mutatePermissions()[permissionName] = newPermission + newState.mutateSystemState().mutatePermissions()[permissionName] = newPermission + } } } @@ -459,7 +462,7 @@ class AppIdPermissionPolicy : SchemePolicy() { ) return@forEachIndexed } - val newPermission = + var newPermission = if (oldPermission != null && newPackageName != oldPermission.packageName) { val oldPackageName = oldPermission.packageName // Only allow system apps to redefine non-system permissions. @@ -582,6 +585,29 @@ class AppIdPermissionPolicy : SchemePolicy() { ) } } + if (Flags.newPermissionGidEnabled()) { + var gids = EmptyArray.INT + var areGidsPerUser = false + if (!parsedPermission.isTree && packageState.isSystem) { + newState.externalState.configPermissions[permissionName]?.let { + // PermissionEntry.gids may return null when parsing legacy config trying + // to work around an issue about upgrading from L platfrm. We can just + // ignore such entries now. + if (it.gids != null) { + gids = it.gids + areGidsPerUser = it.perUser + } + } + } + newPermission = Permission( + newPermissionInfo, + true, + Permission.TYPE_MANIFEST, + packageState.appId, + gids, + areGidsPerUser + ) + } if (parsedPermission.isTree) { newState.mutateSystemState().mutatePermissionTrees()[permissionName] = newPermission diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt index 67f66de71d39..0704c8ffca25 100644 --- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt +++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt @@ -466,7 +466,7 @@ class PermissionService(private val service: AccessCheckingService) : return size } - override fun checkUidPermission(uid: Int, permissionName: String, deviceId: Int): Int { + override fun checkUidPermission(uid: Int, permissionName: String, deviceId: String): Int { val userId = UserHandle.getUserId(uid) if (!userManagerInternal.exists(userId)) { return PackageManager.PERMISSION_DENIED @@ -489,15 +489,9 @@ class PermissionService(private val service: AccessCheckingService) : return PackageManager.PERMISSION_DENIED } - val persistentDeviceId = getPersistentDeviceId(deviceId) - if (persistentDeviceId == null) { - Slog.e(LOG_TAG, "Cannot find persistent device id for $deviceId.") - return PackageManager.PERMISSION_DENIED - } - val isPermissionGranted = service.getState { - isPermissionGranted(packageState, userId, permissionName, persistentDeviceId) + isPermissionGranted(packageState, userId, permissionName, deviceId) } return if (isPermissionGranted) { PackageManager.PERMISSION_GRANTED @@ -531,7 +525,7 @@ class PermissionService(private val service: AccessCheckingService) : override fun checkPermission( packageName: String, permissionName: String, - persistentDeviceId: String, + deviceId: String, userId: Int ): Int { if (!userManagerInternal.exists(userId)) { @@ -545,9 +539,7 @@ class PermissionService(private val service: AccessCheckingService) : ?: return PackageManager.PERMISSION_DENIED val isPermissionGranted = - service.getState { - isPermissionGranted(packageState, userId, permissionName, persistentDeviceId) - } + service.getState { isPermissionGranted(packageState, userId, permissionName, deviceId) } return if (isPermissionGranted) { PackageManager.PERMISSION_GRANTED } else { @@ -565,21 +557,13 @@ class PermissionService(private val service: AccessCheckingService) : packageState: PackageState, userId: Int, permissionName: String, - persistentDeviceId: String + deviceId: String ): Boolean { val appId = packageState.appId // Note that instant apps can't have shared UIDs, so we only need to check the current // package state. val isInstantApp = packageState.getUserStateOrDefault(userId).isInstantApp - if ( - isSinglePermissionGranted( - appId, - userId, - isInstantApp, - permissionName, - persistentDeviceId - ) - ) { + if (isSinglePermissionGranted(appId, userId, isInstantApp, permissionName, deviceId)) { return true } @@ -591,7 +575,7 @@ class PermissionService(private val service: AccessCheckingService) : userId, isInstantApp, fullerPermissionName, - persistentDeviceId + deviceId ) ) { return true @@ -606,9 +590,9 @@ class PermissionService(private val service: AccessCheckingService) : userId: Int, isInstantApp: Boolean, permissionName: String, - persistentDeviceId: String, + deviceId: String, ): Boolean { - val flags = getPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId) + val flags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId) if (!PermissionFlags.isPermissionGranted(flags)) { return false } @@ -689,22 +673,16 @@ class PermissionService(private val service: AccessCheckingService) : override fun grantRuntimePermission( packageName: String, permissionName: String, - persistentDeviceId: String, + deviceId: String, userId: Int ) { - setRuntimePermissionGranted( - packageName, - userId, - permissionName, - persistentDeviceId, - isGranted = true - ) + setRuntimePermissionGranted(packageName, userId, permissionName, deviceId, isGranted = true) } override fun revokeRuntimePermission( packageName: String, permissionName: String, - persistentDeviceId: String, + deviceId: String, userId: Int, reason: String? ) { @@ -712,7 +690,7 @@ class PermissionService(private val service: AccessCheckingService) : packageName, userId, permissionName, - persistentDeviceId, + deviceId, isGranted = false, revokeReason = reason ) @@ -740,7 +718,7 @@ class PermissionService(private val service: AccessCheckingService) : packageName: String, userId: Int, permissionName: String, - persistentDeviceId: String, + deviceId: String, isGranted: Boolean, skipKillUid: Boolean = false, revokeReason: String? = null @@ -765,7 +743,7 @@ class PermissionService(private val service: AccessCheckingService) : (if (isGranted) "" else "skipKillUid = $skipKillUid, reason = $revokeReason") + ", userId = $userId," + " callingUid = $callingUidName ($callingUid))," + - " persistentDeviceId = $persistentDeviceId", + " deviceId = $deviceId", RuntimeException() ) } @@ -835,7 +813,7 @@ class PermissionService(private val service: AccessCheckingService) : packageState, userId, permissionName, - persistentDeviceId, + deviceId, isGranted, canManageRolePermission, overridePolicyFixed, @@ -923,7 +901,7 @@ class PermissionService(private val service: AccessCheckingService) : packageState: PackageState, userId: Int, permissionName: String, - persistentDeviceId: String, + deviceId: String, isGranted: Boolean, canManageRolePermission: Boolean, overridePolicyFixed: Boolean, @@ -982,8 +960,7 @@ class PermissionService(private val service: AccessCheckingService) : } val appId = packageState.appId - val oldFlags = - getPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId) + val oldFlags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId) if (permissionName !in androidPackage.requestedPermissions && oldFlags == 0) { if (reportError) { @@ -1055,7 +1032,7 @@ class PermissionService(private val service: AccessCheckingService) : return } - setPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId, newFlags) + setPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId, newFlags) if (permission.isRuntime) { val action = @@ -1089,7 +1066,7 @@ class PermissionService(private val service: AccessCheckingService) : override fun getPermissionFlags( packageName: String, permissionName: String, - persistentDeviceId: String, + deviceId: String, userId: Int, ): Int { if (!userManagerInternal.exists(userId)) { @@ -1125,12 +1102,7 @@ class PermissionService(private val service: AccessCheckingService) : } val flags = - getPermissionFlagsWithPolicy( - packageState.appId, - userId, - permissionName, - persistentDeviceId - ) + getPermissionFlagsWithPolicy(packageState.appId, userId, permissionName, deviceId) return PermissionFlags.toApiFlags(flags) } @@ -1138,7 +1110,7 @@ class PermissionService(private val service: AccessCheckingService) : override fun getAllPermissionStates( packageName: String, - persistentDeviceId: String, + deviceId: String, userId: Int ): Map<String, PermissionState> { if (!userManagerInternal.exists(userId)) { @@ -1165,14 +1137,15 @@ class PermissionService(private val service: AccessCheckingService) : val permissionFlagsMap = service.getState { - if (persistentDeviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT) { + if (deviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT) { with(policy) { getAllPermissionFlags(packageState.appId, userId) } } else { with(devicePolicy) { - getAllPermissionFlags(packageState.appId, persistentDeviceId, userId) + getAllPermissionFlags(packageState.appId, deviceId, userId) } } - } ?: return emptyMap() + } + ?: return emptyMap() val permissionStates = ArrayMap<String, PermissionState>() permissionFlagsMap.forEachIndexed { _, permissionName, flags -> @@ -1186,7 +1159,7 @@ class PermissionService(private val service: AccessCheckingService) : override fun isPermissionRevokedByPolicy( packageName: String, permissionName: String, - deviceId: Int, + deviceId: String, userId: Int ): Boolean { if (!userManagerInternal.exists(userId)) { @@ -1207,24 +1180,13 @@ class PermissionService(private val service: AccessCheckingService) : } ?: return false - val persistentDeviceId = getPersistentDeviceId(deviceId) - if (persistentDeviceId == null) { - Slog.w(LOG_TAG, "Cannot find persistent device Id for $deviceId") - return false - } - service.getState { - if (isPermissionGranted(packageState, userId, permissionName, persistentDeviceId)) { + if (isPermissionGranted(packageState, userId, permissionName, deviceId)) { return false } val flags = - getPermissionFlagsWithPolicy( - packageState.appId, - userId, - permissionName, - persistentDeviceId - ) + getPermissionFlagsWithPolicy(packageState.appId, userId, permissionName, deviceId) return flags.hasBits(PermissionFlags.POLICY_FIXED) } @@ -1248,7 +1210,7 @@ class PermissionService(private val service: AccessCheckingService) : override fun shouldShowRequestPermissionRationale( packageName: String, permissionName: String, - deviceId: Int, + deviceId: String, userId: Int, ): Boolean { if (!userManagerInternal.exists(userId)) { @@ -1274,19 +1236,13 @@ class PermissionService(private val service: AccessCheckingService) : return false } - val persistentDeviceId = getPersistentDeviceId(deviceId) - if (persistentDeviceId == null) { - Slog.w(LOG_TAG, "Cannot find persistent device Id for $deviceId") - return false - } - val flags: Int service.getState { - if (isPermissionGranted(packageState, userId, permissionName, persistentDeviceId)) { + if (isPermissionGranted(packageState, userId, permissionName, deviceId)) { return false } - flags = getPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId) + flags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId) } if (flags.hasAnyBit(UNREQUESTABLE_MASK)) { return false @@ -1325,7 +1281,7 @@ class PermissionService(private val service: AccessCheckingService) : flagMask: Int, flagValues: Int, enforceAdjustPolicyPermission: Boolean, - persistentDeviceId: String, + deviceId: String, userId: Int ) { val callingUid = Binder.getCallingUid() @@ -1351,7 +1307,7 @@ class PermissionService(private val service: AccessCheckingService) : "updatePermissionFlags(packageName = $packageName," + " permissionName = $permissionName, flagMask = $flagMaskString," + " flagValues = $flagValuesString, userId = $userId," + - " persistentDeviceId = $persistentDeviceId," + + " deviceId = $deviceId," + " callingUid = $callingUidName ($callingUid))", RuntimeException() ) @@ -1441,7 +1397,7 @@ class PermissionService(private val service: AccessCheckingService) : appId, userId, permissionName, - persistentDeviceId, + deviceId, flagMask, flagValues, canUpdateSystemFlags, @@ -1527,7 +1483,7 @@ class PermissionService(private val service: AccessCheckingService) : appId: Int, userId: Int, permissionName: String, - persistentDeviceId: String, + deviceId: String, flagMask: Int, flagValues: Int, canUpdateSystemFlags: Boolean, @@ -1561,8 +1517,7 @@ class PermissionService(private val service: AccessCheckingService) : return } - val oldFlags = - getPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId) + val oldFlags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId) if (!isPermissionRequested && oldFlags == 0) { Slog.w( LOG_TAG, @@ -1573,7 +1528,7 @@ class PermissionService(private val service: AccessCheckingService) : } val newFlags = PermissionFlags.updateFlags(permission, oldFlags, flagMask, flagValues) - setPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId, newFlags) + setPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId, newFlags) } override fun getAllowlistedRestrictedPermissions( @@ -1648,11 +1603,11 @@ class PermissionService(private val service: AccessCheckingService) : appId: Int, userId: Int, permissionName: String, - persistentDeviceId: String, + deviceId: String, ): Int { return if ( !Flags.deviceAwarePermissionApisEnabled() || - persistentDeviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT + deviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT ) { with(policy) { getPermissionFlags(appId, userId, permissionName) } } else { @@ -1664,9 +1619,7 @@ class PermissionService(private val service: AccessCheckingService) : ) return with(policy) { getPermissionFlags(appId, userId, permissionName) } } - with(devicePolicy) { - getPermissionFlags(appId, persistentDeviceId, userId, permissionName) - } + with(devicePolicy) { getPermissionFlags(appId, deviceId, userId, permissionName) } } } @@ -1674,12 +1627,12 @@ class PermissionService(private val service: AccessCheckingService) : appId: Int, userId: Int, permissionName: String, - persistentDeviceId: String, + deviceId: String, flags: Int ): Boolean { return if ( !Flags.deviceAwarePermissionApisEnabled() || - persistentDeviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT + deviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT ) { with(policy) { setPermissionFlags(appId, userId, permissionName, flags) } } else { @@ -1693,23 +1646,11 @@ class PermissionService(private val service: AccessCheckingService) : } with(devicePolicy) { - setPermissionFlags(appId, persistentDeviceId, userId, permissionName, flags) + setPermissionFlags(appId, deviceId, userId, permissionName, flags) } } } - private fun getPersistentDeviceId(deviceId: Int): String? { - if (deviceId == Context.DEVICE_ID_DEFAULT) { - return VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT - } - - if (virtualDeviceManagerInternal == null) { - virtualDeviceManagerInternal = - LocalServices.getService(VirtualDeviceManagerInternal::class.java) - } - return virtualDeviceManagerInternal?.getPersistentIdForDevice(deviceId) - } - /** * This method does not enforce checks on the caller, should only be called after required * checks. @@ -2270,9 +2211,9 @@ class PermissionService(private val service: AccessCheckingService) : userState.appIdDevicePermissionFlags[appId]?.forEachIndexed { _, - persistentDeviceId, + deviceId, devicePermissionFlags -> - println("Permissions (Device $persistentDeviceId):") + println("Permissions (Device $deviceId):") withIndent { devicePermissionFlags.forEachIndexed { _, permissionName, flags -> val isGranted = PermissionFlags.isPermissionGranted(flags) @@ -2415,9 +2356,8 @@ class PermissionService(private val service: AccessCheckingService) : with(devicePolicy) { trimDevicePermissionStates(persistentDeviceIds) } } } - virtualDeviceManagerInternal?.registerPersistentDeviceIdRemovedListener { persistentDeviceId - -> - service.mutateState { with(devicePolicy) { onDeviceIdRemoved(persistentDeviceId) } } + virtualDeviceManagerInternal?.registerPersistentDeviceIdRemovedListener { deviceId -> + service.mutateState { with(devicePolicy) { onDeviceIdRemoved(deviceId) } } } permissionControllerManager = @@ -2764,7 +2704,7 @@ class PermissionService(private val service: AccessCheckingService) : override fun onDevicePermissionFlagsChanged( appId: Int, userId: Int, - persistentDeviceId: String, + deviceId: String, permissionName: String, oldFlags: Int, newFlags: Int @@ -2787,8 +2727,7 @@ class PermissionService(private val service: AccessCheckingService) : permissionName in NOTIFICATIONS_PERMISSIONS && runtimePermissionRevokedUids.get(uid, true) } - runtimePermissionChangedUidDevices.getOrPut(uid) { mutableSetOf() } += - persistentDeviceId + runtimePermissionChangedUidDevices.getOrPut(uid) { mutableSetOf() } += deviceId } if (permission.hasGids && !wasPermissionGranted && isPermissionGranted) { @@ -2803,8 +2742,8 @@ class PermissionService(private val service: AccessCheckingService) : } runtimePermissionChangedUidDevices.forEachIndexed { _, uid, persistentDeviceIds -> - persistentDeviceIds.forEach { persistentDeviceId -> - onPermissionsChangeListeners.onPermissionsChanged(uid, persistentDeviceId) + persistentDeviceIds.forEach { deviceId -> + onPermissionsChangeListeners.onPermissionsChanged(uid, deviceId) } } runtimePermissionChangedUidDevices.clear() @@ -2844,8 +2783,11 @@ class PermissionService(private val service: AccessCheckingService) : private fun isAppBackupAndRestoreRunning(uid: Int): Boolean { if ( - checkUidPermission(uid, Manifest.permission.BACKUP, Context.DEVICE_ID_DEFAULT) != - PackageManager.PERMISSION_GRANTED + checkUidPermission( + uid, + Manifest.permission.BACKUP, + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT + ) != PackageManager.PERMISSION_GRANTED ) { return false } @@ -2879,16 +2821,16 @@ class PermissionService(private val service: AccessCheckingService) : when (msg.what) { MSG_ON_PERMISSIONS_CHANGED -> { val uid = msg.arg1 - val persistentDeviceId = msg.obj as String - handleOnPermissionsChanged(uid, persistentDeviceId) + val deviceId = msg.obj as String + handleOnPermissionsChanged(uid, deviceId) } } } - private fun handleOnPermissionsChanged(uid: Int, persistentDeviceId: String) { + private fun handleOnPermissionsChanged(uid: Int, deviceId: String) { listeners.broadcast { listener -> try { - listener.onPermissionsChanged(uid, persistentDeviceId) + listener.onPermissionsChanged(uid, deviceId) } catch (e: RemoteException) { Slog.e(LOG_TAG, "Error when calling OnPermissionsChangeListener", e) } @@ -2903,9 +2845,9 @@ class PermissionService(private val service: AccessCheckingService) : listeners.unregister(listener) } - fun onPermissionsChanged(uid: Int, persistentDeviceId: String) { + fun onPermissionsChanged(uid: Int, deviceId: String) { if (listeners.registeredCallbackCount > 0) { - obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0, persistentDeviceId).sendToTarget() + obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0, deviceId).sendToTarget() } } diff --git a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp index bd86fe22f8d0..f15e533fee2b 100644 --- a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp +++ b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp @@ -32,8 +32,6 @@ android_test { "androidx.test.runner", "truth", "Harrier", - "frameworks-base-testutils", - "services.core", ], platform_apis: true, certificate: "platform", diff --git a/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/AppEnumerationInternalTests.java b/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/AppEnumerationInternalTests.java index c615823f25aa..4012d8e4af96 100644 --- a/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/AppEnumerationInternalTests.java +++ b/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/AppEnumerationInternalTests.java @@ -16,36 +16,32 @@ package com.android.server.pm.test.appenumeration; +import static android.content.Context.MEDIA_PROJECTION_SERVICE; + import static com.android.compatibility.common.util.ShellUtils.runShellCommand; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; - -import android.app.ActivityManagerInternal; import android.app.AppGlobals; import android.app.PendingIntent; import android.content.Context; import android.content.IntentSender; import android.content.pm.IPackageManager; import android.content.pm.ProviderInfo; +import android.media.projection.IMediaProjectionManager; import android.media.projection.MediaProjectionManager; import android.os.Process; +import android.os.ServiceManager; import android.os.UserHandle; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.util.test.LocalServiceKeeperRule; -import com.android.server.media.projection.MediaProjectionManagerService; - import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; import java.util.ArrayList; import java.util.List; @@ -77,17 +73,9 @@ public class AppEnumerationInternalTests { private IPackageManager mIPackageManager; - @Rule - public LocalServiceKeeperRule mLocalServiceKeeperRule = new LocalServiceKeeperRule(); - - @Mock private ActivityManagerInternal mActivityManagerInternal; - @Before public void setup() { - initMocks(this); mIPackageManager = AppGlobals.getPackageManager(); - mLocalServiceKeeperRule.overrideLocalService(ActivityManagerInternal.class, - mActivityManagerInternal); } @After @@ -181,11 +169,11 @@ public class AppEnumerationInternalTests { public void mediaProjectionManager_createProjection_canSeeForceQueryable() throws Exception { installPackage(SHARED_USER_APK_PATH, true /* forceQueryable */); - final Context context = InstrumentationRegistry.getInstrumentation().getContext(); - final MediaProjectionManagerService mediaProjectionManager = - new MediaProjectionManagerService(context); + final IMediaProjectionManager mediaProjectionManager = + IMediaProjectionManager.Stub.asInterface( + ServiceManager.getService(MEDIA_PROJECTION_SERVICE)); - assertThat(mediaProjectionManager.createProjectionInternal(0 /* uid */, TARGET_SHARED_USER, + assertThat(mediaProjectionManager.createProjection(0 /* uid */, TARGET_SHARED_USER, MediaProjectionManager.TYPE_SCREEN_CAPTURE, false /* permanentGrant */)) .isNotNull(); } @@ -193,13 +181,12 @@ public class AppEnumerationInternalTests { @Test public void mediaProjectionManager_createProjection_cannotSeeTarget() { installPackage(SHARED_USER_APK_PATH, false /* forceQueryable */); - final Context context = InstrumentationRegistry.getInstrumentation().getContext(); - final MediaProjectionManagerService mediaProjectionManager = - new MediaProjectionManagerService(context); + final IMediaProjectionManager mediaProjectionManager = + IMediaProjectionManager.Stub.asInterface( + ServiceManager.getService(MEDIA_PROJECTION_SERVICE)); Assert.assertThrows(IllegalArgumentException.class, - () -> mediaProjectionManager.createProjectionInternal(0 /* uid */, - TARGET_SHARED_USER, + () -> mediaProjectionManager.createProjection(0 /* uid */, TARGET_SHARED_USER, MediaProjectionManager.TYPE_SCREEN_CAPTURE, false /* permanentGrant */)); } diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt index cfe701f42065..d4b57f191ecd 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt @@ -273,7 +273,8 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag AndroidPackage::hasRequestForegroundServiceExemption, AndroidPackage::hasRequestRawExternalStorageAccess, AndroidPackage::isUpdatableSystem, - AndroidPackage::getEmergencyInstaller + AndroidPackage::getEmergencyInstaller, + AndroidPackage::isAllowCrossUidActivitySwitchFromBelow, ) override fun extraParams() = listOf( diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java index 57b86324e171..807774f90655 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java @@ -725,8 +725,8 @@ public final class DisplayPowerControllerTest { } @Test - @RequiresFlagsEnabled(Flags.FLAG_FAST_HDR_TRANSITIONS) public void testDisplayBrightnessHdr_SkipAnimationOnHdrAppearance() { + when(mDisplayManagerFlagsMock.isFastHdrTransitionsEnabled()).thenReturn(true); Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); @@ -757,12 +757,12 @@ public final class DisplayPowerControllerTest { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness), - eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); } @Test - @RequiresFlagsEnabled(Flags.FLAG_FAST_HDR_TRANSITIONS) public void testDisplayBrightnessHdr_SkipAnimationOnHdrRemoval() { + when(mDisplayManagerFlagsMock.isFastHdrTransitionsEnabled()).thenReturn(true); Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); @@ -797,7 +797,7 @@ public final class DisplayPowerControllerTest { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness), - eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false)); + eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false)); } @Test diff --git a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceTest.java index 9473e572259f..c298d516c89e 100644 --- a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceTest.java @@ -18,7 +18,7 @@ package com.android.server; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static com.android.server.notification.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION; +import static android.permission.flags.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index d876dae29798..47928bcffb9a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -72,6 +72,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.mockito.AdditionalAnswers.answer; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; @@ -157,9 +159,11 @@ public class MockingOomAdjusterTests { private static final int MOCKAPP2_UID_OTHER = MOCKAPP2_UID + UserHandle.PER_USER_RANGE; private static final int MOCKAPP_ISOLATED_UID = Process.FIRST_ISOLATED_UID + 321; private static final String MOCKAPP_ISOLATED_PROCESSNAME = "isolated test #1"; + private static final int MOCKAPP_SDK_SANDBOX_UID = Process.FIRST_SDK_SANDBOX_UID + 654; + private static final String MOCKAPP_SDK_SANDBOX_PROCESSNAME = "sandbox test #1"; private static int sFirstCachedAdj = ProcessList.CACHED_APP_MIN_ADJ - + ProcessList.CACHED_APP_IMPORTANCE_LEVELS; + + ProcessList.CACHED_APP_IMPORTANCE_LEVELS; private static Context sContext; private static PackageManagerInternal sPackageManagerInternal; private static ActivityManagerService sService; @@ -271,7 +275,6 @@ public class MockingOomAdjusterTests { /** * Replace the process LRU with the given processes. - * @param apps */ @SuppressWarnings("GuardedBy") private void setProcessesToLru(ProcessRecord... apps) { @@ -660,7 +663,7 @@ public class MockingOomAdjusterTests { app.mState.setLastTopTime(nowUptime); // Simulate the system starting and binding to a service in the app. ServiceRecord s = bindService(app, system, - null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); + null, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); s.lastTopAlmostPerceptibleBindRequestUptimeMs = nowUptime; s.getConnections().clear(); app.mServices.updateHasTopStartedAlmostPerceptibleServices(); @@ -682,7 +685,7 @@ public class MockingOomAdjusterTests { app.mState.setLastTopTime(nowUptime); // Simulate the system starting and binding to a service in the app. ServiceRecord s = bindService(app, system, - null, Context.BIND_ALMOST_PERCEPTIBLE + 2, mock(IBinder.class)); + null, null, Context.BIND_ALMOST_PERCEPTIBLE + 2, mock(IBinder.class)); s.lastTopAlmostPerceptibleBindRequestUptimeMs = nowUptime - 2 * sService.mConstants.mServiceBindAlmostPerceptibleTimeoutMs; app.mServices.updateHasTopStartedAlmostPerceptibleServices(); @@ -704,7 +707,7 @@ public class MockingOomAdjusterTests { app.mState.setLastTopTime(nowUptime); // Simulate the system starting and binding to a service in the app. ServiceRecord s = bindService(app, system, - null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); + null, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); s.lastTopAlmostPerceptibleBindRequestUptimeMs = nowUptime - 2 * sService.mConstants.mServiceBindAlmostPerceptibleTimeoutMs; s.getConnections().clear(); @@ -729,7 +732,7 @@ public class MockingOomAdjusterTests { system.mState.setHasTopUi(true); // Simulate the system starting and binding to a service in the app. ServiceRecord s = bindService(app, system, - null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); + null, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(system, app); @@ -901,7 +904,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - ServiceRecord s = bindService(app, client, null, Context.BIND_WAIVE_PRIORITY, + ServiceRecord s = bindService(app, client, null, null, Context.BIND_WAIVE_PRIORITY, mock(IBinder.class)); s.startRequested = true; sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); @@ -921,7 +924,7 @@ public class MockingOomAdjusterTests { ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); client.mServices.setTreatLikeActivity(true); - bindService(app, client, null, Context.BIND_WAIVE_PRIORITY + bindService(app, client, null, null, Context.BIND_WAIVE_PRIORITY | Context.BIND_TREAT_LIKE_ACTIVITY, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -937,7 +940,7 @@ public class MockingOomAdjusterTests { ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); IBinder binder = mock(IBinder.class); - ServiceRecord s = bindService(app, client, null, Context.BIND_WAIVE_PRIORITY + ServiceRecord s = bindService(app, client, null, null, Context.BIND_WAIVE_PRIORITY | Context.BIND_ADJUST_WITH_ACTIVITY | Context.BIND_IMPORTANT, binder); ConnectionRecord cr = s.getConnections().get(binder).get(0); setFieldValue(ConnectionRecord.class, cr, "activity", @@ -955,7 +958,7 @@ public class MockingOomAdjusterTests { public void testUpdateOomAdj_DoOne_Service_Self() { ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); - bindService(app, app, null, 0, mock(IBinder.class)); + bindService(app, app, null, null, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app); @@ -970,7 +973,7 @@ public class MockingOomAdjusterTests { ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); client.mServices.setTreatLikeActivity(true); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -988,7 +991,8 @@ public class MockingOomAdjusterTests { doReturn(true).when(wpc).hasActivities(); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, Context.BIND_ALLOW_OOM_MANAGEMENT, mock(IBinder.class)); + bindService(app, client, null, null, Context.BIND_ALLOW_OOM_MANAGEMENT, + mock(IBinder.class)); doReturn(PROCESS_STATE_TOP).when(sService.mAtmInternal).getTopProcessState(); doReturn(client).when(sService).getTopApp(); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); @@ -1005,7 +1009,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, Context.BIND_FOREGROUND_SERVICE, mock(IBinder.class)); + bindService(app, client, null, null, Context.BIND_FOREGROUND_SERVICE, mock(IBinder.class)); client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); client.mState.setHasTopUi(true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); @@ -1023,7 +1027,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, Context.BIND_IMPORTANT, mock(IBinder.class)); + bindService(app, client, null, null, Context.BIND_IMPORTANT, mock(IBinder.class)); client.mServices.startExecutingService(mock(ServiceRecord.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -1039,7 +1043,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); doReturn(PROCESS_STATE_TOP).when(sService.mAtmInternal).getTopProcessState(); doReturn(client).when(sService).getTopApp(); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); @@ -1056,7 +1060,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, Context.BIND_FOREGROUND_SERVICE, mock(IBinder.class)); + bindService(app, client, null, null, Context.BIND_FOREGROUND_SERVICE, mock(IBinder.class)); client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -1074,7 +1078,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, Context.BIND_NOT_FOREGROUND, mock(IBinder.class)); + bindService(app, client, null, null, Context.BIND_NOT_FOREGROUND, mock(IBinder.class)); client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -1090,7 +1094,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -1109,7 +1113,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); // In order to trick OomAdjuster to think it has a short-service, we need this logic. ServiceRecord s = ServiceRecord.newEmptyInstanceForTest(sService); @@ -1172,8 +1176,8 @@ public class MockingOomAdjusterTests { ProcessRecord app1 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app1, pers, null, Context.BIND_FOREGROUND_SERVICE, mock(IBinder.class)); - bindService(app2, app1, null, 0, mock(IBinder.class)); + bindService(app1, pers, null, null, Context.BIND_FOREGROUND_SERVICE, mock(IBinder.class)); + bindService(app2, app1, null, null, 0, mock(IBinder.class)); updateOomAdj(pers, app1, app2); @@ -1192,7 +1196,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, Context.BIND_ABOVE_CLIENT, mock(IBinder.class)); + bindService(app, client, null, null, Context.BIND_ABOVE_CLIENT, mock(IBinder.class)); BackupRecord backupTarget = new BackupRecord(null, 0, 0, 0); backupTarget.app = client; doReturn(backupTarget).when(sService.mBackupTargets).get(anyInt()); @@ -1218,7 +1222,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, Context.BIND_NOT_PERCEPTIBLE, mock(IBinder.class)); + bindService(app, client, null, null, Context.BIND_NOT_PERCEPTIBLE, mock(IBinder.class)); client.mState.setRunningRemoteAnimation(true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -1233,7 +1237,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, Context.BIND_NOT_VISIBLE, mock(IBinder.class)); + bindService(app, client, null, null, Context.BIND_NOT_VISIBLE, mock(IBinder.class)); client.mState.setRunningRemoteAnimation(true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -1248,7 +1252,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); client.mState.setHasOverlayUi(true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -1264,7 +1268,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, + bindService(app, client, null, null, Context.BIND_ALMOST_PERCEPTIBLE | Context.BIND_NOT_FOREGROUND, mock(IBinder.class)); client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); @@ -1283,7 +1287,7 @@ public class MockingOomAdjusterTests { MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); WindowProcessController wpc = client.getWindowProcessController(); doReturn(true).when(wpc).isHeavyWeightProcess(); - bindService(app, client, null, + bindService(app, client, null, null, Context.BIND_ALMOST_PERCEPTIBLE | Context.BIND_NOT_FOREGROUND, mock(IBinder.class)); client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); @@ -1301,7 +1305,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, + bindService(app, client, null, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); @@ -1320,7 +1324,7 @@ public class MockingOomAdjusterTests { MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); WindowProcessController wpc = client.getWindowProcessController(); doReturn(true).when(wpc).isHeavyWeightProcess(); - bindService(app, client, null, + bindService(app, client, null, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); @@ -1341,7 +1345,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); client.mState.setRunningRemoteAnimation(true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -1356,7 +1360,8 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, Context.BIND_IMPORTANT_BACKGROUND, mock(IBinder.class)); + bindService(app, client, null, null, Context.BIND_IMPORTANT_BACKGROUND, + mock(IBinder.class)); client.mState.setHasOverlayUi(true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -1496,10 +1501,10 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(client, client2, null, 0, mock(IBinder.class)); + bindService(client, client2, null, null, 0, mock(IBinder.class)); doReturn(PROCESS_STATE_TOP).when(sService.mAtmInternal).getTopProcessState(); doReturn(client2).when(sService).getTopApp(); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); @@ -1517,10 +1522,10 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(app, client2, null, 0, mock(IBinder.class)); + bindService(app, client2, null, null, 0, mock(IBinder.class)); client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, client2, app); @@ -1537,10 +1542,10 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(client, client2, null, 0, mock(IBinder.class)); + bindService(client, client2, null, null, 0, mock(IBinder.class)); client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, client2, app); @@ -1557,12 +1562,12 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(client, client2, null, 0, mock(IBinder.class)); + bindService(client, client2, null, null, 0, mock(IBinder.class)); client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); - bindService(client2, app, null, 0, mock(IBinder.class)); + bindService(client2, app, null, null, 0, mock(IBinder.class)); // Note: We add processes to LRU but still call updateOomAdjLocked() with a specific // processes. @@ -1599,11 +1604,11 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); - bindService(client, app, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); + bindService(client, app, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(client2, client, null, 0, mock(IBinder.class)); + bindService(client2, client, null, null, 0, mock(IBinder.class)); client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, client, client2); @@ -1626,11 +1631,11 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(client, client2, null, 0, mock(IBinder.class)); - bindService(client2, client, null, 0, mock(IBinder.class)); + bindService(client, client2, null, null, 0, mock(IBinder.class)); + bindService(client2, client, null, null, 0, mock(IBinder.class)); client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, client, client2); @@ -1653,18 +1658,18 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(client, client2, null, 0, mock(IBinder.class)); - bindService(client2, client, null, 0, mock(IBinder.class)); + bindService(client, client2, null, null, 0, mock(IBinder.class)); + bindService(client2, client, null, null, 0, mock(IBinder.class)); ProcessRecord client3 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false)); - bindService(client3, client, null, 0, mock(IBinder.class)); + bindService(client3, client, null, null, 0, mock(IBinder.class)); ProcessRecord client4 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID, MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false)); - bindService(client3, client4, null, 0, mock(IBinder.class)); - bindService(client4, client3, null, 0, mock(IBinder.class)); + bindService(client3, client4, null, null, 0, mock(IBinder.class)); + bindService(client4, client3, null, null, 0, mock(IBinder.class)); client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, client, client2, client3, client4); @@ -1693,16 +1698,16 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(client, client2, null, 0, mock(IBinder.class)); + bindService(client, client2, null, null, 0, mock(IBinder.class)); client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); - bindService(client2, app, null, 0, mock(IBinder.class)); + bindService(client2, app, null, null, 0, mock(IBinder.class)); ProcessRecord client3 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false)); client3.mState.setForcingToImportant(new Object()); - bindService(app, client3, null, 0, mock(IBinder.class)); + bindService(app, client3, null, null, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, client, client2, client3); @@ -1718,17 +1723,17 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(client, client2, null, 0, mock(IBinder.class)); - bindService(client2, app, null, 0, mock(IBinder.class)); + bindService(client, client2, null, null, 0, mock(IBinder.class)); + bindService(client2, app, null, null, 0, mock(IBinder.class)); WindowProcessController wpc = client2.getWindowProcessController(); doReturn(true).when(wpc).isHomeProcess(); ProcessRecord client3 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false)); client3.mState.setForcingToImportant(new Object()); - bindService(app, client3, null, 0, mock(IBinder.class)); + bindService(app, client3, null, null, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, client, client2, client3); @@ -1743,11 +1748,11 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(client, client2, null, 0, mock(IBinder.class)); - bindService(client2, app, null, 0, mock(IBinder.class)); + bindService(client, client2, null, null, 0, mock(IBinder.class)); + bindService(client2, app, null, null, 0, mock(IBinder.class)); WindowProcessController wpc = client2.getWindowProcessController(); doReturn(true).when(wpc).isHomeProcess(); ProcessRecord client3 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, @@ -1755,7 +1760,7 @@ public class MockingOomAdjusterTests { ProcessRecord client4 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID, MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false)); client4.mState.setForcingToImportant(new Object()); - bindService(app, client4, null, 0, mock(IBinder.class)); + bindService(app, client4, null, null, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, client, client2, client3, client4); @@ -1770,21 +1775,21 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(client, client2, null, 0, mock(IBinder.class)); - bindService(client2, app, null, 0, mock(IBinder.class)); + bindService(client, client2, null, null, 0, mock(IBinder.class)); + bindService(client2, app, null, null, 0, mock(IBinder.class)); WindowProcessController wpc = client2.getWindowProcessController(); doReturn(true).when(wpc).isHomeProcess(); ProcessRecord client3 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false)); client3.mState.setForcingToImportant(new Object()); - bindService(app, client3, null, 0, mock(IBinder.class)); + bindService(app, client3, null, null, 0, mock(IBinder.class)); ProcessRecord client4 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID, MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false)); client4.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); - bindService(app, client4, null, 0, mock(IBinder.class)); + bindService(app, client4, null, null, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, client, client2, client3, client4); @@ -1802,15 +1807,15 @@ public class MockingOomAdjusterTests { MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); WindowProcessController wpc = client.getWindowProcessController(); doReturn(true).when(wpc).isHomeProcess(); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(app, client2, null, 0, mock(IBinder.class)); + bindService(app, client2, null, null, 0, mock(IBinder.class)); client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); ProcessRecord client3 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false)); client3.mState.setForcingToImportant(new Object()); - bindService(app, client3, null, 0, mock(IBinder.class)); + bindService(app, client3, null, null, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, client2, client3, app); @@ -1826,7 +1831,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); bindProvider(client, client2, null, null, false); @@ -1846,12 +1851,12 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, 0, mock(IBinder.class)); + bindService(app, client, null, null, 0, mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); bindProvider(client, client2, null, null, false); client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); - bindService(client2, app, null, 0, mock(IBinder.class)); + bindService(client2, app, null, null, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, client, client2); @@ -1912,9 +1917,9 @@ public class MockingOomAdjusterTests { MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); final ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false)); - bindService(app1, client1, null, Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, + bindService(app1, client1, null, null, Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, mock(IBinder.class)); - bindService(app2, client2, null, Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, + bindService(app2, client2, null, null, Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, mock(IBinder.class)); client1.mState.setMaxAdj(PERSISTENT_PROC_ADJ); client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); @@ -1929,8 +1934,10 @@ public class MockingOomAdjusterTests { assertBfsl(app1); assertBfsl(app2); - bindService(app1, client1, null, Context.BIND_SCHEDULE_LIKE_TOP_APP, mock(IBinder.class)); - bindService(app2, client2, null, Context.BIND_SCHEDULE_LIKE_TOP_APP, mock(IBinder.class)); + bindService(app1, client1, null, null, Context.BIND_SCHEDULE_LIKE_TOP_APP, + mock(IBinder.class)); + bindService(app2, client2, null, null, Context.BIND_SCHEDULE_LIKE_TOP_APP, + mock(IBinder.class)); updateOomAdj(client1, client2, app1, app2); assertProcStates(app1, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, VISIBLE_APP_ADJ, @@ -1946,8 +1953,8 @@ public class MockingOomAdjusterTests { SCHED_GROUP_DEFAULT); assertBfsl(app2); - bindService(client2, app1, null, 0, mock(IBinder.class)); - bindService(app1, client2, null, 0, mock(IBinder.class)); + bindService(client2, app1, null, null, 0, mock(IBinder.class)); + bindService(app1, client2, null, null, 0, mock(IBinder.class)); client2.mServices.setHasForegroundServices(false, 0, /* hasNoneType=*/false); updateOomAdj(app1, client1, client2); assertProcStates(app1, PROCESS_STATE_IMPORTANT_FOREGROUND, VISIBLE_APP_ADJ, @@ -1968,9 +1975,9 @@ public class MockingOomAdjusterTests { client1.mState.setMaxAdj(PERSISTENT_PROC_ADJ); client2.mState.setMaxAdj(PERSISTENT_PROC_ADJ); - final ServiceRecord s1 = bindService(app1, client1, null, + final ServiceRecord s1 = bindService(app1, client1, null, null, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE, mock(IBinder.class)); - final ServiceRecord s2 = bindService(app2, client2, null, + final ServiceRecord s2 = bindService(app2, client2, null, null, Context.BIND_IMPORTANT, mock(IBinder.class)); updateOomAdj(client1, client2, app1, app2); @@ -1980,7 +1987,7 @@ public class MockingOomAdjusterTests { assertProcStates(app2, PROCESS_STATE_PERSISTENT, PERSISTENT_SERVICE_ADJ, SCHED_GROUP_DEFAULT); - bindService(app2, client1, s2, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE, + bindService(app2, client1, null, s2, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE, mock(IBinder.class)); updateOomAdj(app2); assertProcStates(app2, PROCESS_STATE_PERSISTENT, PERSISTENT_SERVICE_ADJ, @@ -1995,9 +2002,9 @@ public class MockingOomAdjusterTests { client1.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); client2.mState.setHasOverlayUi(true); - bindService(app1, client1, s1, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE, + bindService(app1, client1, null, s1, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE, mock(IBinder.class)); - bindService(app2, client2, s2, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE, + bindService(app2, client2, null, s2, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE, mock(IBinder.class)); updateOomAdj(client1, client2, app1, app2); @@ -2030,7 +2037,7 @@ public class MockingOomAdjusterTests { app1.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); - bindService(app1, client1, null, Context.BIND_NOT_PERCEPTIBLE, mock(IBinder.class)); + bindService(app1, client1, null, null, Context.BIND_NOT_PERCEPTIBLE, mock(IBinder.class)); updateOomAdj(client1, app1); @@ -2051,7 +2058,8 @@ public class MockingOomAdjusterTests { app1.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); - bindService(app1, client1, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); + bindService(app1, client1, null, null, Context.BIND_ALMOST_PERCEPTIBLE, + mock(IBinder.class)); updateOomAdj(client1, app1); @@ -2121,19 +2129,19 @@ public class MockingOomAdjusterTests { final ComponentName cn1 = ComponentName.unflattenFromString( MOCKAPP_PACKAGENAME + "/.TestService"); - final ServiceRecord s1 = bindService(app1, client1, null, 0, mock(IBinder.class)); + final ServiceRecord s1 = bindService(app1, client1, null, null, 0, mock(IBinder.class)); setFieldValue(ServiceRecord.class, s1, "name", cn1); s1.startRequested = true; final ComponentName cn2 = ComponentName.unflattenFromString( MOCKAPP2_PACKAGENAME + "/.TestService"); - final ServiceRecord s2 = bindService(app2, client2, null, 0, mock(IBinder.class)); + final ServiceRecord s2 = bindService(app2, client2, null, null, 0, mock(IBinder.class)); setFieldValue(ServiceRecord.class, s2, "name", cn2); s2.startRequested = true; final ComponentName cn3 = ComponentName.unflattenFromString( MOCKAPP5_PACKAGENAME + "/.TestService"); - final ServiceRecord s3 = bindService(app3, client1, null, 0, mock(IBinder.class)); + final ServiceRecord s3 = bindService(app3, client1, null, null, 0, mock(IBinder.class)); setFieldValue(ServiceRecord.class, s3, "name", cn3); s3.startRequested = true; @@ -2177,7 +2185,7 @@ public class MockingOomAdjusterTests { clientUidRecord.setIdle(true); doReturn(ActivityManager.APP_START_MODE_DELAYED).when(sService) .getAppStartModeLOSP(anyInt(), any(String.class), anyInt(), - anyInt(), anyBoolean(), anyBoolean(), anyBoolean()); + anyInt(), anyBoolean(), anyBoolean(), anyBoolean()); doNothing().when(sService.mServices) .scheduleServiceTimeoutLocked(any(ProcessRecord.class)); updateOomAdj(client1, client2, app1, app2, app3); @@ -2188,7 +2196,7 @@ public class MockingOomAdjusterTests { } finally { doCallRealMethod().when(sService) .getAppStartModeLOSP(anyInt(), any(String.class), anyInt(), - anyInt(), anyBoolean(), anyBoolean(), anyBoolean()); + anyInt(), anyBoolean(), anyBoolean(), anyBoolean()); sService.mServices.mServiceMap.clear(); sService.mOomAdjuster.mActiveUids.clear(); } @@ -2223,7 +2231,7 @@ public class MockingOomAdjusterTests { ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); app2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); - bindService(app, app2, null, 0, mock(IBinder.class)); + bindService(app, app2, null, null, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, app2); @@ -2242,12 +2250,12 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, app2, null, 0, mock(IBinder.class)); + bindService(app, app2, null, null, 0, mock(IBinder.class)); ProcessRecord app3 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(app2, app3, null, 0, mock(IBinder.class)); + bindService(app2, app3, null, null, 0, mock(IBinder.class)); app3.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); - bindService(app3, app, null, 0, mock(IBinder.class)); + bindService(app3, app, null, null, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, app2, app3); @@ -2278,21 +2286,21 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - ServiceRecord s = bindService(app, app2, null, 0, mock(IBinder.class)); + ServiceRecord s = bindService(app, app2, null, null, 0, mock(IBinder.class)); ProcessRecord app3 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(app2, app3, null, 0, mock(IBinder.class)); - bindService(app3, app, null, 0, mock(IBinder.class)); + bindService(app2, app3, null, null, 0, mock(IBinder.class)); + bindService(app3, app, null, null, 0, mock(IBinder.class)); WindowProcessController wpc = app3.getWindowProcessController(); doReturn(true).when(wpc).isHomeProcess(); ProcessRecord app4 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false)); app4.mState.setHasOverlayUi(true); - bindService(app, app4, s, 0, mock(IBinder.class)); + bindService(app, app4, null, s, 0, mock(IBinder.class)); ProcessRecord app5 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID, MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false)); app5.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); - bindService(app, app5, s, 0, mock(IBinder.class)); + bindService(app, app5, null, s, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, app2, app3, app4, app5); @@ -2320,21 +2328,21 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - ServiceRecord s = bindService(app, app2, null, 0, mock(IBinder.class)); + ServiceRecord s = bindService(app, app2, null, null, 0, mock(IBinder.class)); ProcessRecord app3 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(app2, app3, null, 0, mock(IBinder.class)); - bindService(app3, app, null, 0, mock(IBinder.class)); + bindService(app2, app3, null, null, 0, mock(IBinder.class)); + bindService(app3, app, null, null, 0, mock(IBinder.class)); WindowProcessController wpc = app3.getWindowProcessController(); doReturn(true).when(wpc).isHomeProcess(); ProcessRecord app4 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false)); app4.mState.setHasOverlayUi(true); - bindService(app, app4, s, 0, mock(IBinder.class)); + bindService(app, app4, null, s, 0, mock(IBinder.class)); ProcessRecord app5 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID, MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false)); app5.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); - bindService(app, app5, s, 0, mock(IBinder.class)); + bindService(app, app5, null, s, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app5, app4, app3, app2, app); @@ -2362,21 +2370,21 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - ServiceRecord s = bindService(app, app2, null, 0, mock(IBinder.class)); + ServiceRecord s = bindService(app, app2, null, null, 0, mock(IBinder.class)); ProcessRecord app3 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(app2, app3, null, 0, mock(IBinder.class)); - bindService(app3, app, null, 0, mock(IBinder.class)); + bindService(app2, app3, null, null, 0, mock(IBinder.class)); + bindService(app3, app, null, null, 0, mock(IBinder.class)); WindowProcessController wpc = app3.getWindowProcessController(); doReturn(true).when(wpc).isHomeProcess(); ProcessRecord app4 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false)); app4.mState.setHasOverlayUi(true); - bindService(app, app4, s, 0, mock(IBinder.class)); + bindService(app, app4, null, s, 0, mock(IBinder.class)); ProcessRecord app5 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID, MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false)); app5.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true); - bindService(app, app5, s, 0, mock(IBinder.class)); + bindService(app, app5, null, s, 0, mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app3, app4, app2, app, app5); @@ -2404,15 +2412,19 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, Context.BIND_INCLUDE_CAPABILITIES, mock(IBinder.class)); + bindService(app, client, null, null, Context.BIND_INCLUDE_CAPABILITIES, + mock(IBinder.class)); ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); - bindService(client, client2, null, Context.BIND_INCLUDE_CAPABILITIES, mock(IBinder.class)); - bindService(client2, app, null, Context.BIND_INCLUDE_CAPABILITIES, mock(IBinder.class)); + bindService(client, client2, null, null, Context.BIND_INCLUDE_CAPABILITIES, + mock(IBinder.class)); + bindService(client2, app, null, null, Context.BIND_INCLUDE_CAPABILITIES, + mock(IBinder.class)); ProcessRecord client3 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false)); client3.mState.setMaxAdj(PERSISTENT_PROC_ADJ); - bindService(app, client3, null, Context.BIND_INCLUDE_CAPABILITIES, mock(IBinder.class)); + bindService(app, client3, null, null, Context.BIND_INCLUDE_CAPABILITIES, + mock(IBinder.class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app, client, client2, client3); @@ -2472,10 +2484,10 @@ public class MockingOomAdjusterTests { ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); long now = SystemClock.uptimeMillis(); - ServiceRecord s = bindService(app, app2, null, 0, mock(IBinder.class)); + ServiceRecord s = bindService(app, app2, null, null, 0, mock(IBinder.class)); s.startRequested = true; s.lastActivity = now; - s = bindService(app2, app, null, 0, mock(IBinder.class)); + s = bindService(app2, app, null, null, 0, mock(IBinder.class)); s.startRequested = true; s.lastActivity = now; ProcessRecord app3 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, @@ -2507,11 +2519,11 @@ public class MockingOomAdjusterTests { final int userOwner = 0; final int userOther = 1; final int cachedAdj1 = sService.mConstants.USE_TIERED_CACHED_ADJ - ? CACHED_APP_MIN_ADJ + 10 - : CACHED_APP_MIN_ADJ + ProcessList.CACHED_APP_IMPORTANCE_LEVELS; + ? CACHED_APP_MIN_ADJ + 10 + : CACHED_APP_MIN_ADJ + ProcessList.CACHED_APP_IMPORTANCE_LEVELS; final int cachedAdj2 = sService.mConstants.USE_TIERED_CACHED_ADJ - ? CACHED_APP_MIN_ADJ + 10 - : cachedAdj1 + ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2; + ? CACHED_APP_MIN_ADJ + 10 + : cachedAdj1 + ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2; doReturn(userOwner).when(sService.mUserController).getCurrentUserId(); final ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP(); @@ -2626,7 +2638,7 @@ public class MockingOomAdjusterTests { // Simulate binding to a service in the same process using BIND_ABOVE_CLIENT and // verify that its OOM adjustment level is unaffected. - bindService(app, app, null, Context.BIND_ABOVE_CLIENT, mock(IBinder.class)); + bindService(app, app, null, null, Context.BIND_ABOVE_CLIENT, mock(IBinder.class)); app.mServices.updateHasAboveClientLocked(); assertFalse(app.mServices.hasAboveClient()); @@ -2644,12 +2656,12 @@ public class MockingOomAdjusterTests { final ProcessRecord app3 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); long now = SystemClock.uptimeMillis(); - ServiceRecord s = bindService(app, app2, null, 0, mock(IBinder.class)); + ServiceRecord s = bindService(app, app2, null, null, 0, mock(IBinder.class)); s.startRequested = true; s.lastActivity = now; - s = bindService(app2, app3, null, 0, mock(IBinder.class)); + s = bindService(app2, app3, null, null, 0, mock(IBinder.class)); s.lastActivity = now; - s = bindService(app3, app2, null, 0, mock(IBinder.class)); + s = bindService(app3, app2, null, null, 0, mock(IBinder.class)); s.lastActivity = now; sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); @@ -2678,7 +2690,7 @@ public class MockingOomAdjusterTests { // Start binding to a service that isn't running yet. ServiceRecord sr = makeServiceRecord(app); sr.app = null; - bindService(null, app, sr, Context.BIND_ABOVE_CLIENT, mock(IBinder.class)); + bindService(null, app, null, sr, Context.BIND_ABOVE_CLIENT, mock(IBinder.class)); // Since sr.app is null, this service cannot be in the same process as the // client so we expect the BIND_ABOVE_CLIENT adjustment to take effect. @@ -2772,91 +2784,37 @@ public class MockingOomAdjusterTests { ApplicationExitInfo.SUBREASON_ISOLATED_NOT_NEEDED, true); } + @SuppressWarnings("GuardedBy") + @Test + public void testUpdateOomAdj_DoAll_SdkSandbox_attributedClient() { + ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, + MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); + ProcessRecord attributedClient = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, + MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, true)); + ProcessRecord sandboxService = spy(new ProcessRecordBuilder(MOCKAPP_PID, + MOCKAPP_SDK_SANDBOX_UID, MOCKAPP_SDK_SANDBOX_PROCESSNAME, MOCKAPP_PACKAGENAME) + .setSdkSandboxClientAppPackage(MOCKAPP3_PACKAGENAME) + .build()); + + setProcessesToLru(sandboxService, client, attributedClient); + + client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); + attributedClient.mServices.setHasForegroundServices(true, 0, true); + bindService(sandboxService, client, attributedClient, null, 0, mock(IBinder.class)); + sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); + updateOomAdj(); + assertProcStates(client, PROCESS_STATE_PERSISTENT, PERSISTENT_PROC_ADJ, + SCHED_GROUP_DEFAULT); + assertProcStates(attributedClient, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ, + SCHED_GROUP_DEFAULT); + assertProcStates(sandboxService, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ, + SCHED_GROUP_DEFAULT); + } + private ProcessRecord makeDefaultProcessRecord(int pid, int uid, String processName, String packageName, boolean hasShownUi) { - long now = SystemClock.uptimeMillis(); - return makeProcessRecord(sService, pid, uid, processName, - packageName, 12345, Build.VERSION_CODES.CUR_DEVELOPMENT, - now, now, now, 12345, UNKNOWN_ADJ, UNKNOWN_ADJ, - UNKNOWN_ADJ, CACHED_APP_MAX_ADJ, - SCHED_GROUP_DEFAULT, SCHED_GROUP_DEFAULT, - PROCESS_STATE_NONEXISTENT, PROCESS_STATE_NONEXISTENT, - PROCESS_STATE_NONEXISTENT, PROCESS_STATE_NONEXISTENT, - 0, 0, false, false, false, ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE, - false, false, false, hasShownUi, false, false, false, false, false, false, null, - 0, Long.MIN_VALUE, Long.MIN_VALUE, true, 0, null, false); - } - - private ProcessRecord makeProcessRecord(ActivityManagerService service, int pid, int uid, - String processName, String packageName, long versionCode, int targetSdkVersion, - long lastActivityTime, long lastPssTime, long nextPssTime, long lastPss, int maxAdj, - int setRawAdj, int curAdj, int setAdj, int curSchedGroup, int setSchedGroup, - int curProcState, int repProcState, int curRawProcState, int setProcState, - int connectionGroup, int connectionImportance, boolean serviceb, - boolean hasClientActivities, boolean hasForegroundServices, int fgServiceTypes, - boolean hasForegroundActivities, boolean repForegroundActivities, boolean systemNoUi, - boolean hasShownUi, boolean hasTopUi, boolean hasOverlayUi, - boolean runningRemoteAnimation, boolean hasAboveClient, boolean treatLikeActivity, - boolean killedByAm, Object forcingToImportant, int numOfCurReceivers, - long lastProviderTime, long lastTopTime, boolean cached, int numOfExecutingServices, - String isolatedEntryPoint, boolean execServicesFg) { - ApplicationInfo ai = spy(new ApplicationInfo()); - ai.uid = uid; - ai.packageName = packageName; - ai.longVersionCode = versionCode; - ai.targetSdkVersion = targetSdkVersion; - ProcessRecord app = new ProcessRecord(service, ai, processName, uid); - final ProcessStateRecord state = app.mState; - final ProcessServiceRecord services = app.mServices; - final ProcessReceiverRecord receivers = app.mReceivers; - final ProcessProfileRecord profile = app.mProfile; - final ProcessProviderRecord providers = app.mProviders; - app.makeActive(mock(IApplicationThread.class), sService.mProcessStats); - app.setLastActivityTime(lastActivityTime); - app.setKilledByAm(killedByAm); - app.setIsolatedEntryPoint(isolatedEntryPoint); - setFieldValue(ProcessRecord.class, app, "mWindowProcessController", - mock(WindowProcessController.class)); - profile.setLastPssTime(lastPssTime); - profile.setNextPssTime(nextPssTime); - profile.setLastPss(lastPss); - state.setMaxAdj(maxAdj); - state.setSetRawAdj(setRawAdj); - state.setCurAdj(curAdj); - state.setSetAdj(setAdj); - state.setCurrentSchedulingGroup(curSchedGroup); - state.setSetSchedGroup(setSchedGroup); - state.setCurProcState(curProcState); - state.setReportedProcState(repProcState); - state.setCurRawProcState(curRawProcState); - state.setSetProcState(setProcState); - state.setServiceB(serviceb); - state.setRepForegroundActivities(repForegroundActivities); - state.setHasForegroundActivities(hasForegroundActivities); - state.setSystemNoUi(systemNoUi); - state.setHasShownUi(hasShownUi); - state.setHasTopUi(hasTopUi); - state.setRunningRemoteAnimation(runningRemoteAnimation); - state.setHasOverlayUi(hasOverlayUi); - state.setCached(cached); - state.setLastTopTime(lastTopTime); - state.setForcingToImportant(forcingToImportant); - services.setConnectionGroup(connectionGroup); - services.setConnectionImportance(connectionImportance); - services.setHasClientActivities(hasClientActivities); - services.setHasForegroundServices(hasForegroundServices, fgServiceTypes, - /* hasNoneType=*/false); - services.setHasAboveClient(hasAboveClient); - services.setTreatLikeActivity(treatLikeActivity); - services.setExecServicesFg(execServicesFg); - for (int i = 0; i < numOfExecutingServices; i++) { - services.startExecutingService(mock(ServiceRecord.class)); - } - for (int i = 0; i < numOfCurReceivers; i++) { - receivers.addCurReceiver(mock(BroadcastRecord.class)); - } - providers.setLastProviderTime(lastProviderTime); - return app; + return new ProcessRecordBuilder(pid, uid, processName, packageName).setHasShownUi( + hasShownUi).build(); } private ServiceRecord makeServiceRecord(ProcessRecord app) { @@ -2870,6 +2828,7 @@ public class MockingOomAdjusterTests { record.appInfo = app.info; setFieldValue(ServiceRecord.class, record, "bindings", new ArrayMap<>()); setFieldValue(ServiceRecord.class, record, "pendingStarts", new ArrayList<>()); + setFieldValue(ServiceRecord.class, record, "isSdkSandbox", app.isSdkSandbox); return record; } @@ -2892,11 +2851,11 @@ public class MockingOomAdjusterTests { } private ServiceRecord bindService(ProcessRecord service, ProcessRecord client, - ServiceRecord record, long bindFlags, IBinder binder) { + ProcessRecord attributedClient, ServiceRecord record, long bindFlags, IBinder binder) { if (record == null) { record = makeServiceRecord(service); } - AppBindRecord binding = new AppBindRecord(record, null, client, null); + AppBindRecord binding = new AppBindRecord(record, null, client, attributedClient); ConnectionRecord cr = spy(new ConnectionRecord(binding, mock(ActivityServiceConnectionsHolder.class), mock(IServiceConnection.class), bindFlags, @@ -2961,4 +2920,140 @@ public class MockingOomAdjusterTests { assertBfsl(app); } } + + private static class ProcessRecordBuilder { + @SuppressWarnings("UnusedVariable") + int mPid; + int mUid; + String mProcessName; + String mPackageName; + long mVersionCode = 12345; + int mTargetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; + long mLastActivityTime; + long mLastPssTime; + long mNextPssTime; + long mLastPss = 12345; + int mMaxAdj = UNKNOWN_ADJ; + int mSetRawAdj = UNKNOWN_ADJ; + int mCurAdj = UNKNOWN_ADJ; + int mSetAdj = CACHED_APP_MAX_ADJ; + int mCurSchedGroup = SCHED_GROUP_DEFAULT; + int mSetSchedGroup = SCHED_GROUP_DEFAULT; + int mCurProcState = PROCESS_STATE_NONEXISTENT; + int mRepProcState = PROCESS_STATE_NONEXISTENT; + int mCurRawProcState = PROCESS_STATE_NONEXISTENT; + int mSetProcState = PROCESS_STATE_NONEXISTENT; + int mConnectionGroup = 0; + int mConnectionImportance = 0; + boolean mServiceb = false; + boolean mHasClientActivities = false; + boolean mHasForegroundServices = false; + int mFgServiceTypes = ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE; + boolean mHasForegroundActivities = false; + boolean mRepForegroundActivities = false; + boolean mSystemNoUi = false; + boolean mHasShownUi = false; + boolean mHasTopUi = false; + boolean mHasOverlayUi = false; + boolean mRunningRemoteAnimation = false; + boolean mHasAboveClient = false; + boolean mTreatLikeActivity = false; + boolean mKilledByAm = false; + Object mForcingToImportant; + int mNumOfCurReceivers = 0; + long mLastProviderTime = Long.MIN_VALUE; + long mLastTopTime = Long.MIN_VALUE; + boolean mCached = true; + int mNumOfExecutingServices = 0; + String mIsolatedEntryPoint = null; + boolean mExecServicesFg = false; + String mSdkSandboxClientAppPackage = null; + + ProcessRecordBuilder(int pid, int uid, String processName, String packageName) { + mPid = pid; + mUid = uid; + mProcessName = processName; + mPackageName = packageName; + + long now = SystemClock.uptimeMillis(); + mLastActivityTime = now; + mLastPssTime = now; + mNextPssTime = now; + } + + ProcessRecordBuilder setHasShownUi(boolean hasShownUi) { + mHasShownUi = hasShownUi; + return this; + } + + ProcessRecordBuilder setSdkSandboxClientAppPackage(String sdkSandboxClientAppPackage) { + mSdkSandboxClientAppPackage = sdkSandboxClientAppPackage; + return this; + } + + @SuppressWarnings("GuardedBy") + public ProcessRecord build() { + ApplicationInfo ai = spy(new ApplicationInfo()); + ai.uid = mUid; + ai.packageName = mPackageName; + ai.longVersionCode = mVersionCode; + ai.targetSdkVersion = mTargetSdkVersion; + doCallRealMethod().when(sService).getPackageManagerInternal(); + doReturn(null).when(sPackageManagerInternal).getApplicationInfo( + eq(mSdkSandboxClientAppPackage), anyLong(), anyInt(), anyInt()); + ProcessRecord app = new ProcessRecord(sService, ai, mProcessName, mUid, + mSdkSandboxClientAppPackage, -1, null); + final ProcessStateRecord state = app.mState; + final ProcessServiceRecord services = app.mServices; + final ProcessReceiverRecord receivers = app.mReceivers; + final ProcessProfileRecord profile = app.mProfile; + final ProcessProviderRecord providers = app.mProviders; + app.makeActive(mock(IApplicationThread.class), sService.mProcessStats); + app.setLastActivityTime(mLastActivityTime); + app.setKilledByAm(mKilledByAm); + app.setIsolatedEntryPoint(mIsolatedEntryPoint); + setFieldValue(ProcessRecord.class, app, "mWindowProcessController", + mock(WindowProcessController.class)); + profile.setLastPssTime(mLastPssTime); + profile.setNextPssTime(mNextPssTime); + profile.setLastPss(mLastPss); + state.setMaxAdj(mMaxAdj); + state.setSetRawAdj(mSetRawAdj); + state.setCurAdj(mCurAdj); + state.setSetAdj(mSetAdj); + state.setCurrentSchedulingGroup(mCurSchedGroup); + state.setSetSchedGroup(mSetSchedGroup); + state.setCurProcState(mCurProcState); + state.setReportedProcState(mRepProcState); + state.setCurRawProcState(mCurRawProcState); + state.setSetProcState(mSetProcState); + state.setServiceB(mServiceb); + state.setRepForegroundActivities(mRepForegroundActivities); + state.setHasForegroundActivities(mHasForegroundActivities); + state.setSystemNoUi(mSystemNoUi); + state.setHasShownUi(mHasShownUi); + state.setHasTopUi(mHasTopUi); + state.setRunningRemoteAnimation(mRunningRemoteAnimation); + state.setHasOverlayUi(mHasOverlayUi); + state.setCached(mCached); + state.setLastTopTime(mLastTopTime); + state.setForcingToImportant(mForcingToImportant); + services.setConnectionGroup(mConnectionGroup); + services.setConnectionImportance(mConnectionImportance); + services.setHasClientActivities(mHasClientActivities); + services.setHasForegroundServices(mHasForegroundServices, mFgServiceTypes, + /* hasNoneType=*/false); + services.setHasAboveClient(mHasAboveClient); + services.setTreatLikeActivity(mTreatLikeActivity); + services.setExecServicesFg(mExecServicesFg); + for (int i = 0; i < mNumOfExecutingServices; i++) { + services.startExecutingService(mock(ServiceRecord.class)); + } + for (int i = 0; i < mNumOfCurReceivers; i++) { + receivers.addCurReceiver(mock(BroadcastRecord.class)); + } + providers.setLastProviderTime(mLastProviderTime); + return app; + } + } } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java index cd904eb562de..a0c4b5e26c3f 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java @@ -150,6 +150,9 @@ public class MagnificationControllerTest { @Mock private DisplayManagerInternal mDisplayManagerInternal; + @Mock + private Scroller mMockScroller; + // To mock package-private class @Rule public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule = @@ -208,7 +211,7 @@ public class MagnificationControllerTest { mScaleProvider, () -> null, ConcurrentUtils.DIRECT_EXECUTOR, - () -> new Scroller(mContext), + () -> mMockScroller, () -> mTimeAnimator)); mScreenMagnificationController.register(TEST_DISPLAY); diff --git a/services/tests/servicestests/src/com/android/server/adaptiveauth/AdaptiveAuthServiceTest.java b/services/tests/servicestests/src/com/android/server/adaptiveauth/AdaptiveAuthServiceTest.java new file mode 100644 index 000000000000..08a65292cf20 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/adaptiveauth/AdaptiveAuthServiceTest.java @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.adaptiveauth; + +import static android.adaptiveauth.Flags.FLAG_ENABLE_ADAPTIVE_AUTH; +import static android.adaptiveauth.Flags.FLAG_REPORT_BIOMETRIC_AUTH_ATTEMPTS; +import static android.security.Flags.FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS; + +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST; +import static com.android.server.adaptiveauth.AdaptiveAuthService.MAX_ALLOWED_FAILED_AUTH_ATTEMPTS; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.KeyguardManager; +import android.content.Context; +import android.hardware.biometrics.AuthenticationStateListener; +import android.hardware.biometrics.BiometricManager; +import android.os.RemoteException; +import android.platform.test.flag.junit.SetFlagsRule; + +import androidx.test.InstrumentationRegistry; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.internal.widget.LockPatternUtils; +import com.android.internal.widget.LockSettingsInternal; +import com.android.internal.widget.LockSettingsStateListener; +import com.android.server.LocalServices; +import com.android.server.pm.UserManagerInternal; +import com.android.server.wm.WindowManagerInternal; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * atest FrameworksServicesTests:AdaptiveAuthServiceTest + */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class AdaptiveAuthServiceTest { + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + private static final int PRIMARY_USER_ID = 0; + private static final int MANAGED_PROFILE_USER_ID = 12; + private static final int DEFAULT_COUNT_FAILED_AUTH_ATTEMPTS = 0; + private static final int REASON_UNKNOWN = 0; // BiometricRequestConstants.RequestReason + + private Context mContext; + private AdaptiveAuthService mAdaptiveAuthService; + + @Mock + LockPatternUtils mLockPatternUtils; + @Mock + private LockSettingsInternal mLockSettings; + @Mock + private BiometricManager mBiometricManager; + @Mock + private KeyguardManager mKeyguardManager; + @Mock + private WindowManagerInternal mWindowManager; + @Mock + private UserManagerInternal mUserManager; + + @Captor + ArgumentCaptor<LockSettingsStateListener> mLockSettingsStateListenerCaptor; + @Captor + ArgumentCaptor<AuthenticationStateListener> mAuthenticationStateListenerCaptor; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mSetFlagsRule.enableFlags(FLAG_ENABLE_ADAPTIVE_AUTH); + mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS); + mSetFlagsRule.enableFlags(FLAG_REPORT_BIOMETRIC_AUTH_ATTEMPTS); + + mContext = spy(ApplicationProvider.getApplicationContext()); + when(mContext.getSystemService(BiometricManager.class)).thenReturn(mBiometricManager); + when(mContext.getSystemService(KeyguardManager.class)).thenReturn(mKeyguardManager); + + LocalServices.removeServiceForTest(LockSettingsInternal.class); + LocalServices.addService(LockSettingsInternal.class, mLockSettings); + LocalServices.removeServiceForTest(WindowManagerInternal.class); + LocalServices.addService(WindowManagerInternal.class, mWindowManager); + LocalServices.removeServiceForTest(UserManagerInternal.class); + LocalServices.addService(UserManagerInternal.class, mUserManager); + + mAdaptiveAuthService = new AdaptiveAuthService(mContext, mLockPatternUtils); + mAdaptiveAuthService.init(); + + verify(mLockSettings).registerLockSettingsStateListener( + mLockSettingsStateListenerCaptor.capture()); + verify(mBiometricManager).registerAuthenticationStateListener( + mAuthenticationStateListenerCaptor.capture()); + + // Set PRIMARY_USER_ID as the parent of MANAGED_PROFILE_USER_ID + when(mUserManager.getProfileParentId(eq(MANAGED_PROFILE_USER_ID))) + .thenReturn(PRIMARY_USER_ID); + } + + @After + public void tearDown() throws Exception { + LocalServices.removeServiceForTest(LockSettingsInternal.class); + LocalServices.removeServiceForTest(WindowManagerInternal.class); + LocalServices.removeServiceForTest(UserManagerInternal.class); + } + + @Test + public void testReportAuthAttempt_primaryAuthSucceeded() + throws RemoteException { + mLockSettingsStateListenerCaptor.getValue().onAuthenticationSucceeded(PRIMARY_USER_ID); + waitForAuthCompletion(); + + verifyNotLockDevice(DEFAULT_COUNT_FAILED_AUTH_ATTEMPTS /* expectedCntFailedAttempts */, + PRIMARY_USER_ID); + } + + @Test + public void testReportAuthAttempt_primaryAuthFailed_once() + throws RemoteException { + mLockSettingsStateListenerCaptor.getValue().onAuthenticationFailed(PRIMARY_USER_ID); + waitForAuthCompletion(); + + verifyNotLockDevice(1 /* expectedCntFailedAttempts */, PRIMARY_USER_ID); + } + + @Test + public void testReportAuthAttempt_primaryAuthFailed_multiple_deviceCurrentlyLocked() + throws RemoteException { + // Device is currently locked and Keyguard is showing + when(mKeyguardManager.isDeviceLocked(PRIMARY_USER_ID)).thenReturn(true); + when(mKeyguardManager.isKeyguardLocked()).thenReturn(true); + + for (int i = 0; i < MAX_ALLOWED_FAILED_AUTH_ATTEMPTS; i++) { + mLockSettingsStateListenerCaptor.getValue().onAuthenticationFailed(PRIMARY_USER_ID); + } + waitForAuthCompletion(); + + verifyNotLockDevice(MAX_ALLOWED_FAILED_AUTH_ATTEMPTS /* expectedCntFailedAttempts */, + PRIMARY_USER_ID); + } + + @Test + public void testReportAuthAttempt_primaryAuthFailed_multiple_deviceCurrentlyNotLocked() + throws RemoteException { + // Device is currently not locked and Keyguard is not showing + when(mKeyguardManager.isDeviceLocked(PRIMARY_USER_ID)).thenReturn(false); + when(mKeyguardManager.isKeyguardLocked()).thenReturn(false); + + for (int i = 0; i < MAX_ALLOWED_FAILED_AUTH_ATTEMPTS; i++) { + mLockSettingsStateListenerCaptor.getValue().onAuthenticationFailed(PRIMARY_USER_ID); + } + waitForAuthCompletion(); + + verifyLockDevice(PRIMARY_USER_ID); + } + + @Test + public void testReportAuthAttempt_biometricAuthSucceeded() + throws RemoteException { + mAuthenticationStateListenerCaptor.getValue() + .onAuthenticationSucceeded(REASON_UNKNOWN, PRIMARY_USER_ID); + waitForAuthCompletion(); + + verifyNotLockDevice(DEFAULT_COUNT_FAILED_AUTH_ATTEMPTS /* expectedCntFailedAttempts */, + PRIMARY_USER_ID); + } + + @Test + public void testReportAuthAttempt_biometricAuthFailed_once() + throws RemoteException { + mAuthenticationStateListenerCaptor.getValue() + .onAuthenticationFailed(REASON_UNKNOWN, PRIMARY_USER_ID); + waitForAuthCompletion(); + + verifyNotLockDevice(1 /* expectedCntFailedAttempts */, PRIMARY_USER_ID); + } + + @Test + public void testReportAuthAttempt_biometricAuthFailed_multiple_deviceCurrentlyLocked() + throws RemoteException { + // Device is currently locked and Keyguard is showing + when(mKeyguardManager.isDeviceLocked(PRIMARY_USER_ID)).thenReturn(true); + when(mKeyguardManager.isKeyguardLocked()).thenReturn(true); + + for (int i = 0; i < MAX_ALLOWED_FAILED_AUTH_ATTEMPTS; i++) { + mAuthenticationStateListenerCaptor.getValue() + .onAuthenticationFailed(REASON_UNKNOWN, PRIMARY_USER_ID); + } + waitForAuthCompletion(); + + verifyNotLockDevice(MAX_ALLOWED_FAILED_AUTH_ATTEMPTS /* expectedCntFailedAttempts */, + PRIMARY_USER_ID); + } + + @Test + public void testReportAuthAttempt_biometricAuthFailed_multiple_deviceCurrentlyNotLocked() + throws RemoteException { + // Device is currently not locked and Keyguard is not showing + when(mKeyguardManager.isDeviceLocked(PRIMARY_USER_ID)).thenReturn(false); + when(mKeyguardManager.isKeyguardLocked()).thenReturn(false); + + for (int i = 0; i < MAX_ALLOWED_FAILED_AUTH_ATTEMPTS; i++) { + mAuthenticationStateListenerCaptor.getValue() + .onAuthenticationFailed(REASON_UNKNOWN, PRIMARY_USER_ID); + } + waitForAuthCompletion(); + + verifyLockDevice(PRIMARY_USER_ID); + } + + @Test + public void testReportAuthAttempt_biometricAuthFailedThenPrimaryAuthSucceeded() + throws RemoteException { + // Three failed biometric auth attempts + for (int i = 0; i < 3; i++) { + mAuthenticationStateListenerCaptor.getValue() + .onAuthenticationFailed(REASON_UNKNOWN, PRIMARY_USER_ID); + } + // One successful primary auth attempt + mLockSettingsStateListenerCaptor.getValue().onAuthenticationSucceeded(PRIMARY_USER_ID); + waitForAuthCompletion(); + + verifyNotLockDevice(DEFAULT_COUNT_FAILED_AUTH_ATTEMPTS /* expectedCntFailedAttempts */, + PRIMARY_USER_ID); + } + + @Test + public void testReportAuthAttempt_primaryAuthFailedThenBiometricAuthSucceeded() + throws RemoteException { + // Three failed primary auth attempts + for (int i = 0; i < 3; i++) { + mLockSettingsStateListenerCaptor.getValue().onAuthenticationFailed(PRIMARY_USER_ID); + } + // One successful biometric auth attempt + mAuthenticationStateListenerCaptor.getValue() + .onAuthenticationSucceeded(REASON_UNKNOWN, PRIMARY_USER_ID); + waitForAuthCompletion(); + + verifyNotLockDevice(DEFAULT_COUNT_FAILED_AUTH_ATTEMPTS /* expectedCntFailedAttempts */, + PRIMARY_USER_ID); + } + + @Test + public void testReportAuthAttempt_primaryAuthAndBiometricAuthFailed_primaryUser() + throws RemoteException { + // Three failed primary auth attempts + for (int i = 0; i < 3; i++) { + mLockSettingsStateListenerCaptor.getValue().onAuthenticationFailed(PRIMARY_USER_ID); + } + // Two failed biometric auth attempts + for (int i = 0; i < 2; i++) { + mAuthenticationStateListenerCaptor.getValue() + .onAuthenticationFailed(REASON_UNKNOWN, PRIMARY_USER_ID); + } + waitForAuthCompletion(); + + verifyLockDevice(PRIMARY_USER_ID); + } + + @Test + public void testReportAuthAttempt_primaryAuthAndBiometricAuthFailed_profileOfPrimaryUser() + throws RemoteException { + // Three failed primary auth attempts + for (int i = 0; i < 3; i++) { + mLockSettingsStateListenerCaptor.getValue() + .onAuthenticationFailed(MANAGED_PROFILE_USER_ID); + } + // Two failed biometric auth attempts + for (int i = 0; i < 2; i++) { + mAuthenticationStateListenerCaptor.getValue() + .onAuthenticationFailed(REASON_UNKNOWN, MANAGED_PROFILE_USER_ID); + } + waitForAuthCompletion(); + + verifyLockDevice(MANAGED_PROFILE_USER_ID); + } + + private void verifyNotLockDevice(int expectedCntFailedAttempts, int userId) { + assertEquals(expectedCntFailedAttempts, + mAdaptiveAuthService.mFailedAttemptsForUser.get(userId)); + verify(mWindowManager, never()).lockNow(); + } + + private void verifyLockDevice(int userId) { + assertEquals(MAX_ALLOWED_FAILED_AUTH_ATTEMPTS, + mAdaptiveAuthService.mFailedAttemptsForUser.get(userId)); + verify(mLockPatternUtils).requireStrongAuth( + eq(SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST), eq(userId)); + // If userId is MANAGED_PROFILE_USER_ID, the StrongAuthFlag of its parent (PRIMARY_USER_ID) + // should also be verified + if (userId == MANAGED_PROFILE_USER_ID) { + verify(mLockPatternUtils).requireStrongAuth( + eq(SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST), eq(PRIMARY_USER_ID)); + } + verify(mWindowManager).lockNow(); + } + + /** + * Wait for all auth events to complete before verification + */ + private static void waitForAuthCompletion() { + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + } +} diff --git a/services/tests/servicestests/src/com/android/server/adaptiveauth/OWNERS b/services/tests/servicestests/src/com/android/server/adaptiveauth/OWNERS new file mode 100644 index 000000000000..0218a7835586 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/adaptiveauth/OWNERS @@ -0,0 +1 @@ +include /services/core/java/com/android/server/adaptiveauth/OWNERS
\ No newline at end of file diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java index 071db68704af..f0dc5f0606f3 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java @@ -60,8 +60,10 @@ import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.IFingerprintService; import android.hardware.iris.IIrisService; import android.os.Binder; +import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; +import android.os.test.TestLooper; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; @@ -127,6 +129,8 @@ public class AuthServiceTest { AppOpsManager mAppOpsManager; @Mock private VirtualDeviceManagerInternal mVdmInternal; + @Mock + private BiometricHandlerProvider mBiometricHandlerProvider; @Captor private ArgumentCaptor<List<FingerprintSensorPropertiesInternal>> mFingerprintPropsCaptor; @Captor @@ -136,6 +140,9 @@ public class AuthServiceTest { @Captor private ArgumentCaptor<List<FaceSensorPropertiesInternal>> mFacePropsCaptor; + private final TestLooper mFingerprintLooper = new TestLooper(); + private final TestLooper mFaceLooper = new TestLooper(); + @Before public void setUp() { // Placeholder test config @@ -167,6 +174,11 @@ public class AuthServiceTest { when(mInjector.getIrisService()).thenReturn(mIrisService); when(mInjector.getAppOps(any())).thenReturn(mAppOpsManager); when(mInjector.isHidlDisabled(any())).thenReturn(false); + when(mInjector.getBiometricHandlerProvider()).thenReturn(mBiometricHandlerProvider); + when(mBiometricHandlerProvider.getFingerprintHandler()).thenReturn( + new Handler(mFingerprintLooper.getLooper())); + when(mBiometricHandlerProvider.getFaceHandler()).thenReturn( + new Handler(mFaceLooper.getLooper())); setInternalAndTestBiometricPermissions(mContext, false /* hasPermission */); } @@ -250,6 +262,9 @@ public class AuthServiceTest { mAuthService = new AuthService(mContext, mInjector); mAuthService.onStart(); + mFingerprintLooper.dispatchAll(); + mFaceLooper.dispatchAll(); + verify(mFingerprintService).registerAuthenticatorsLegacy( mFingerprintSensorConfigurationsCaptor.capture()); diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java index 6986cab72f56..e59b5ea027ed 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java @@ -270,6 +270,9 @@ public abstract class BaseLockSettingsServiceTests { } protected void setSecureFrpMode(boolean secure) { + if (android.security.Flags.frpEnforcement()) { + mStorage.setTestFactoryResetProtectionState(secure); + } Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.SECURE_FRP_MODE, secure ? 1 : 0, UserHandle.USER_SYSTEM); } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java index ee076c6bcf4b..296d2cba83dd 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java @@ -21,12 +21,14 @@ import static org.mockito.Mockito.mock; import android.app.IActivityManager; import android.app.admin.DeviceStateCache; import android.content.Context; +import android.content.Intent; import android.content.pm.UserInfo; import android.hardware.authsecret.IAuthSecret; import android.os.Handler; import android.os.Parcel; import android.os.Process; import android.os.RemoteException; +import android.os.UserHandle; import android.os.storage.IStorageManager; import android.security.KeyStore; import android.security.keystore.KeyPermanentlyInvalidatedException; @@ -41,6 +43,9 @@ import com.android.server.pm.UserManagerInternal; import java.io.FileNotFoundException; public class LockSettingsServiceTestable extends LockSettingsService { + private Intent mSavedFrpNotificationIntent = null; + private UserHandle mSavedFrpNotificationUserHandle = null; + private String mSavedFrpNotificationPermission = null; public static class MockInjector extends LockSettingsService.Injector { @@ -218,4 +223,29 @@ public class LockSettingsServiceTestable extends LockSettingsService { mAuthSecret = null; } } + + @Override + void sendBroadcast(Intent intent, UserHandle userHandle, String permission) { + mSavedFrpNotificationIntent = intent; + mSavedFrpNotificationUserHandle = userHandle; + mSavedFrpNotificationPermission = permission; + } + + String getSavedFrpNotificationPermission() { + return mSavedFrpNotificationPermission; + } + + UserHandle getSavedFrpNotificationUserHandle() { + return mSavedFrpNotificationUserHandle; + } + + Intent getSavedFrpNotificationIntent() { + return mSavedFrpNotificationIntent; + } + + void clearRecordedFrpNotificationData() { + mSavedFrpNotificationIntent = null; + mSavedFrpNotificationPermission = null; + mSavedFrpNotificationUserHandle = null; + } } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java index 705359708bc7..4b22652a3f21 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java @@ -16,6 +16,7 @@ package com.android.server.locksettings; +import static android.Manifest.permission.CONFIGURE_FACTORY_RESET_PROTECTION; import static android.security.Flags.FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; @@ -39,7 +40,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.PropertyInvalidatedCache; +import android.content.Intent; import android.os.RemoteException; +import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.service.gatekeeper.GateKeeperResponse; @@ -239,6 +242,12 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { } @Test + public void testSetLockCredential_forPrimaryUser_sendsFrpNotification() throws Exception { + setCredential(PRIMARY_USER_ID, newPassword("password")); + checkRecordedFrpNotificationIntent(); + } + + @Test public void testSetLockCredential_forPrimaryUser_sendsCredentials() throws Exception { setCredential(PRIMARY_USER_ID, newPassword("password")); verify(mRecoverableKeyStoreManager) @@ -323,6 +332,15 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { } @Test + public void testClearLockCredential_sendsFrpNotification() throws Exception { + setCredential(PRIMARY_USER_ID, newPassword("password")); + checkRecordedFrpNotificationIntent(); + mService.clearRecordedFrpNotificationData(); + clearCredential(PRIMARY_USER_ID, newPassword("password")); + checkRecordedFrpNotificationIntent(); + } + + @Test public void testSetLockCredential_forUnifiedToSeparateChallengeProfile_sendsNewCredentials() throws Exception { final LockscreenCredential parentPassword = newPassword("parentPassword"); @@ -519,6 +537,23 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { mService.setString(null, "value", 0); } + private void checkRecordedFrpNotificationIntent() { + if (android.security.Flags.frpEnforcement()) { + Intent savedNotificationIntent = mService.getSavedFrpNotificationIntent(); + assertNotNull(savedNotificationIntent); + UserHandle userHandle = mService.getSavedFrpNotificationUserHandle(); + assertEquals(userHandle, + UserHandle.of(mInjector.getUserManagerInternal().getMainUserId())); + + String permission = mService.getSavedFrpNotificationPermission(); + assertEquals(CONFIGURE_FACTORY_RESET_PROTECTION, permission); + } else { + assertNull(mService.getSavedFrpNotificationIntent()); + assertNull(mService.getSavedFrpNotificationUserHandle()); + assertNull(mService.getSavedFrpNotificationPermission()); + } + } + private void checkPasswordHistoryLength(int userId, int expectedLen) { String history = mService.getString(LockPatternUtils.PASSWORD_HISTORY_KEY, "", userId); String[] hashes = TextUtils.split(history, LockPatternUtils.PASSWORD_HISTORY_DELIMITER); diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java index fa3c7a4c4769..c01d0f644983 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java @@ -35,6 +35,7 @@ public class LockSettingsStorageTestable extends LockSettingsStorage { public final File mStorageDir; public PersistentDataBlockManagerInternal mPersistentDataBlockManager; private byte[] mPersistentData; + private boolean mIsFactoryResetProtectionActive = false; public LockSettingsStorageTestable(Context context, File storageDir) { super(context); @@ -63,6 +64,10 @@ public class LockSettingsStorageTestable extends LockSettingsStorage { }).when(mPersistentDataBlockManager).getFrpCredentialHandle(); } + void setTestFactoryResetProtectionState(boolean active) { + mIsFactoryResetProtectionActive = active; + } + @Override File getChildProfileLockFile(int userId) { return remapToStorageDir(super.getChildProfileLockFile(userId)); @@ -101,4 +106,9 @@ public class LockSettingsStorageTestable extends LockSettingsStorage { mappedPath.getParentFile().mkdirs(); return mappedPath; } + + @Override + public boolean isFactoryResetProtectionActive() { + return mIsFactoryResetProtectionActive; + } } diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java index aefa6de9184a..abd3abee82fb 100644 --- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java @@ -75,12 +75,12 @@ import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; -import com.android.internal.util.test.LocalServiceKeeperRule; +import com.android.server.LocalServices; import com.android.server.testutils.OffsettableClock; import com.android.server.wm.WindowManagerInternal; +import org.junit.After; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -164,17 +164,15 @@ public class MediaProjectionManagerServiceTest { @Captor private ArgumentCaptor<ContentRecordingSession> mSessionCaptor; - @Rule - public LocalServiceKeeperRule mLocalServiceKeeperRule = new LocalServiceKeeperRule(); - @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); when(mWatcherCallback.asBinder()).thenReturn(new Binder()); - mLocalServiceKeeperRule.overrideLocalService(ActivityManagerInternal.class, mAmInternal); - mLocalServiceKeeperRule.overrideLocalService(WindowManagerInternal.class, - mWindowManagerInternal); + LocalServices.removeServiceForTest(ActivityManagerInternal.class); + LocalServices.addService(ActivityManagerInternal.class, mAmInternal); + LocalServices.removeServiceForTest(WindowManagerInternal.class); + LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal); mContext = spy(new ContextWrapper( InstrumentationRegistry.getInstrumentation().getTargetContext())); @@ -189,6 +187,12 @@ public class MediaProjectionManagerServiceTest { mService = new MediaProjectionManagerService(mContext); } + @After + public void tearDown() { + LocalServices.removeServiceForTest(ActivityManagerInternal.class); + LocalServices.removeServiceForTest(WindowManagerInternal.class); + } + @Test public void testGetActiveProjectionInfoInternal() throws NameNotFoundException { assertThat(mService.getActiveProjectionInfo()).isNull(); @@ -384,16 +388,16 @@ public class MediaProjectionManagerServiceTest { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions( service); // No starts yet, and not timed out yet - so still valid. - assertThat(projection.isValidInternal()).isTrue(); + assertThat(projection.isValid()).isTrue(); // Only one start - so still valid. projection.start(mIMediaProjectionCallback); - assertThat(projection.isValidInternal()).isTrue(); + assertThat(projection.isValid()).isTrue(); // Second start - technically allowed to start again, without stopping in between. // Token should no longer be valid. projection.start(mIMediaProjectionCallback); - assertThat(projection.isValidInternal()).isFalse(); + assertThat(projection.isValid()).isFalse(); } @Test @@ -403,17 +407,17 @@ public class MediaProjectionManagerServiceTest { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions( service); // No starts yet, and not timed out yet - so still valid. - assertThat(projection.isValidInternal()).isTrue(); + assertThat(projection.isValid()).isTrue(); // Only one start - so still valid. projection.start(mIMediaProjectionCallback); - assertThat(projection.isValidInternal()).isTrue(); + assertThat(projection.isValid()).isTrue(); projection.stop(); // Second start - so not valid. projection.start(mIMediaProjectionCallback); - assertThat(projection.isValidInternal()).isFalse(); + assertThat(projection.isValid()).isFalse(); } @Test @@ -438,7 +442,7 @@ public class MediaProjectionManagerServiceTest { mClock.fastForward(projection.mDefaultTimeoutMs + 10); // Immediate timeout - so no longer valid. - assertThat(projection.isValidInternal()).isFalse(); + assertThat(projection.isValid()).isFalse(); } @Test @@ -448,10 +452,10 @@ public class MediaProjectionManagerServiceTest { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions( service); // Simulate MediaProjection#createVirtualDisplay being invoked previously. - projection.notifyVirtualDisplayCreatedInternal(10); + projection.notifyVirtualDisplayCreated(10); // Trying to re-use token on another MediaProjection#createVirtualDisplay - no longer valid. - assertThat(projection.isValidInternal()).isFalse(); + assertThat(projection.isValid()).isFalse(); } // TODO(269273190): Test flag using compat annotations instead. @@ -467,7 +471,7 @@ public class MediaProjectionManagerServiceTest { // Second start - so not valid. projection.start(mIMediaProjectionCallback); - assertThrows(SecurityException.class, projection::isValidInternal); + assertThrows(SecurityException.class, projection::isValid); } // TODO(269273190): Test flag using compat annotations instead. @@ -484,7 +488,7 @@ public class MediaProjectionManagerServiceTest { // Second start - so not valid. projection.start(mIMediaProjectionCallback); - assertThat(projection.isValidInternal()).isFalse(); + assertThat(projection.isValid()).isFalse(); } @Test @@ -623,7 +627,7 @@ public class MediaProjectionManagerServiceTest { mService.setUserReviewGrantedConsentResult(RECORD_CONTENT_DISPLAY, projection); // Virtual Display is finally created. - projection.notifyVirtualDisplayCreatedInternal(10); + projection.notifyVirtualDisplayCreated(10); verifySetSessionWithContent(ContentRecordingSession.RECORD_CONTENT_DISPLAY); } @@ -726,7 +730,7 @@ public class MediaProjectionManagerServiceTest { throws Exception { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(); projection.start(mIMediaProjectionCallback); - projection.notifyVirtualDisplayCreatedInternal(10); + projection.notifyVirtualDisplayCreated(10); // Waiting for user to review consent. assertThat(mService.isCurrentProjection(projection)).isTrue(); doReturn(true).when(mWindowManagerInternal).setContentRecordingSession( @@ -781,9 +785,9 @@ public class MediaProjectionManagerServiceTest { @RecordContent int recordedContent) throws NameNotFoundException { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(); - projection.setLaunchCookieInternal(new LaunchCookie()); + projection.setLaunchCookie(new LaunchCookie()); projection.start(mIMediaProjectionCallback); - projection.notifyVirtualDisplayCreatedInternal(10); + projection.notifyVirtualDisplayCreated(10); // Waiting for user to review consent. doReturn(true).when(mWindowManagerInternal).setContentRecordingSession( any(ContentRecordingSession.class)); @@ -804,7 +808,7 @@ public class MediaProjectionManagerServiceTest { throws NameNotFoundException { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(); projection.start(mIMediaProjectionCallback); - projection.notifyVirtualDisplayCreatedInternal(10); + projection.notifyVirtualDisplayCreated(10); // Waiting for user to review consent. doReturn(true).when(mWindowManagerInternal).setContentRecordingSession( eq(mWaitingDisplaySession)); @@ -822,7 +826,7 @@ public class MediaProjectionManagerServiceTest { public void testSetUserReviewGrantedConsentResult_displayMirroring_noPriorSession() throws NameNotFoundException { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(); - projection.setLaunchCookieInternal(new LaunchCookie()); + projection.setLaunchCookie(new LaunchCookie()); projection.start(mIMediaProjectionCallback); // Skip setting the prior session details. @@ -841,7 +845,7 @@ public class MediaProjectionManagerServiceTest { public void testSetUserReviewGrantedConsentResult_displayMirroring_sessionNotWaiting() throws NameNotFoundException { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(); - projection.setLaunchCookieInternal(new LaunchCookie()); + projection.setLaunchCookie(new LaunchCookie()); projection.start(mIMediaProjectionCallback); // Session is not waiting for user's consent. doReturn(true).when(mWindowManagerInternal).setContentRecordingSession( diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index 4451cae8db42..5f2abc3285c9 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -18,6 +18,7 @@ package com.android.server.net; import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.Manifest.permission.NETWORK_STACK; +import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL; import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE; import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK; import static android.app.ActivityManager.PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK; @@ -58,9 +59,11 @@ import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM; import static android.net.NetworkPolicyManager.ALLOWED_REASON_TOP; import static android.net.NetworkPolicyManager.BACKGROUND_THRESHOLD_STATE; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; +import static android.net.NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE; import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.POLICY_NONE; import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; +import static android.net.NetworkPolicyManager.TOP_THRESHOLD_STATE; import static android.net.NetworkPolicyManager.allowedReasonsToString; import static android.net.NetworkPolicyManager.blockedReasonsToString; import static android.net.NetworkPolicyManager.uidPoliciesToString; @@ -88,6 +91,7 @@ import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT; import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED; import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID; import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING; +import static com.android.server.net.NetworkPolicyManagerService.UID_MSG_STATE_CHANGED; import static com.android.server.net.NetworkPolicyManagerService.UidBlockedState.getEffectiveBlockedReasons; import static com.android.server.net.NetworkPolicyManagerService.normalizeTemplate; @@ -196,8 +200,6 @@ import com.android.server.LocalServices; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.usage.AppStandbyInternal; -import com.google.common.util.concurrent.AbstractFuture; - import libcore.io.Streams; import org.junit.After; @@ -241,10 +243,8 @@ import java.util.Map; import java.util.Set; import java.util.TimeZone; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -2247,6 +2247,123 @@ public class NetworkPolicyManagerServiceTest { } @Test + @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE) + public void testUidObserverFiltersProcStateChanges() throws Exception { + int testProcStateSeq = 0; + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // First callback for uid. + callOnUidStatechanged(UID_A, BACKGROUND_THRESHOLD_STATE + 1, testProcStateSeq++, + PROCESS_CAPABILITY_NONE); + assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // Doesn't cross the background threshold. + callOnUidStatechanged(UID_A, BACKGROUND_THRESHOLD_STATE, testProcStateSeq++, + PROCESS_CAPABILITY_NONE); + assertFalse(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // Crosses the background threshold. + callOnUidStatechanged(UID_A, BACKGROUND_THRESHOLD_STATE - 1, testProcStateSeq++, + PROCESS_CAPABILITY_NONE); + assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // Doesn't cross the foreground threshold. + callOnUidStatechanged(UID_A, FOREGROUND_THRESHOLD_STATE + 1, testProcStateSeq++, + PROCESS_CAPABILITY_NONE); + assertFalse(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // Crosses the foreground threshold. + callOnUidStatechanged(UID_A, FOREGROUND_THRESHOLD_STATE, testProcStateSeq++, + PROCESS_CAPABILITY_NONE); + assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // Doesn't cross the top threshold. + callOnUidStatechanged(UID_A, TOP_THRESHOLD_STATE + 1, testProcStateSeq++, + PROCESS_CAPABILITY_NONE); + assertFalse(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // Crosses the top threshold. + callOnUidStatechanged(UID_A, TOP_THRESHOLD_STATE, testProcStateSeq++, + PROCESS_CAPABILITY_NONE); + assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // Doesn't cross any other threshold. + callOnUidStatechanged(UID_A, TOP_THRESHOLD_STATE - 1, testProcStateSeq++, + PROCESS_CAPABILITY_NONE); + assertFalse(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE) + public void testUidObserverFiltersStaleChanges() throws Exception { + final int testProcStateSeq = 51; + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // First callback for uid. + callOnUidStatechanged(UID_B, BACKGROUND_THRESHOLD_STATE + 100, testProcStateSeq, + PROCESS_CAPABILITY_NONE); + assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // Stale callback because the procStateSeq is smaller. + callOnUidStatechanged(UID_B, BACKGROUND_THRESHOLD_STATE - 100, testProcStateSeq - 10, + PROCESS_CAPABILITY_NONE); + assertFalse(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE) + public void testUidObserverFiltersCapabilityChanges() throws Exception { + int testProcStateSeq = 0; + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // First callback for uid. + callOnUidStatechanged(UID_A, TOP_THRESHOLD_STATE, testProcStateSeq++, + PROCESS_CAPABILITY_NONE); + assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // The same process-state with one network capability added. + callOnUidStatechanged(UID_A, TOP_THRESHOLD_STATE, testProcStateSeq++, + PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK); + assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // The same process-state with another network capability added. + callOnUidStatechanged(UID_A, TOP_THRESHOLD_STATE, testProcStateSeq++, + PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK + | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK); + assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // The same process-state with all capabilities, but no change in network capabilities. + callOnUidStatechanged(UID_A, TOP_THRESHOLD_STATE, testProcStateSeq++, + PROCESS_CAPABILITY_ALL); + assertFalse(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + } + + @Test public void testLowPowerStandbyAllowlist() throws Exception { // Chain background is also enabled but these procstates are important enough to be exempt. callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, 0); @@ -2559,17 +2676,6 @@ public class NetworkPolicyManagerServiceTest { verify(mStatsManager).setDefaultGlobalAlert(anyLong()); } - private static class TestAbstractFuture<T> extends AbstractFuture<T> { - @Override - public T get() throws InterruptedException, ExecutionException { - try { - return get(5, TimeUnit.SECONDS); - } catch (TimeoutException e) { - throw new RuntimeException(e); - } - } - } - private static void assertTimeEquals(long expected, long actual) { if (expected != actual) { fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual)); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 31d6fa3e91f8..67c528cf40ae 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -769,7 +769,8 @@ public class ActivityRecordTests extends WindowTestsBase { activity.setState(STOPPED, "Testing"); ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(task).build(); - activity.addResultLocked(topActivity, "resultWho", 0, 0, new Intent()); + activity.addResultLocked(topActivity, "resultWho", 0, 0, new Intent(), + /* callerToken */ null); topActivity.finishing = true; doReturn(TASK_FRAGMENT_VISIBILITY_VISIBLE).when(task).getVisibility(null); @@ -1298,8 +1299,8 @@ public class ActivityRecordTests extends WindowTestsBase { targetActivity.finishIfPossible(0, new Intent(), null, "test", false /* oomAdj */); waitUntilHandlersIdle(); - verify(resultToActivity).sendResult(anyInt(), eq(null), anyInt(), anyInt(), any(), eq(null), - anyBoolean()); + verify(resultToActivity).sendResult(anyInt(), eq(null), anyInt(), anyInt(), any(), any(), + eq(null), anyBoolean()); } /** diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index 847c9d09b73a..6132ee3c89c4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -1561,7 +1561,7 @@ public class ActivityStarterTests extends WindowTestsBase { .build(); final int result = starter.recycleTask(task, null, null, null, - BalVerdict.ALLOW_BY_DEFAULT); + BalVerdict.ALLOW_PRIVILEGED); assertThat(result == START_SUCCESS).isTrue(); assertThat(starter.mAddingToTask).isTrue(); } @@ -1857,7 +1857,7 @@ public class ActivityStarterTests extends WindowTestsBase { startActivityInner(starter, targetRecord, sourceRecord, null /* options */, null /* inTask */, null /* inTaskFragment */); verify(sourceRecord).sendResult(anyInt(), any(), anyInt(), eq(RESULT_CANCELED), any(), - any()); + any(), any()); } @Test @@ -2075,7 +2075,7 @@ public class ActivityStarterTests extends WindowTestsBase { starter.startActivityInner(target, source, null /* voiceSession */, null /* voiceInteractor */, 0 /* startFlags */, options, inTask, inTaskFragment, - BalVerdict.ALLOW_BY_DEFAULT, + BalVerdict.ALLOW_PRIVILEGED, null /* intentGrants */, -1 /* realCallingUid */); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java index 203475156491..0b466b2b8a2c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java @@ -242,7 +242,8 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase { verify(activity).getFilteredReferrer(eq(activity.launchedFromPackage)); activity.deliverNewIntentLocked(ActivityBuilder.DEFAULT_FAKE_UID, - new Intent(), null /* intentGrants */, "other.package2"); + new Intent(), null /* intentGrants */, "other.package2", + /* isShareIdentityEnabled */ false); verify(activity).getFilteredReferrer(eq("other.package2")); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java index 60dfe6f01817..887e5ee0c58a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java @@ -811,7 +811,7 @@ public class ContentRecorderTests extends WindowTestsBase { @Test public void testDisplayContentUpdatesRecording_withSurface() { - createContentRecorder(createDefaultDisplayInfo()); + defaultInit(); // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // mirror. setUpDefaultTaskDisplayAreaWindowToken(); @@ -820,7 +820,6 @@ public class ContentRecorderTests extends WindowTestsBase { // getDisplaySurfaceDefaultSize (done by surfaceControlMirrors in setUp). final DisplayContent virtualDisplay = mRootWindowContainer.getDisplayContent(mDisplaySession.getVirtualDisplayId()); - virtualDisplay.setContentRecorder(mContentRecorder); mWm.mContentRecordingController.setContentRecordingSessionLocked(mDisplaySession, mWm); virtualDisplay.updateRecording(); @@ -845,7 +844,6 @@ public class ContentRecorderTests extends WindowTestsBase { // WHEN getting the DisplayContent for the new virtual display. final DisplayContent virtualDisplay = mRootWindowContainer.getDisplayContent(mDisplaySession.getVirtualDisplayId()); - virtualDisplay.setContentRecorder(mContentRecorder); // Return the default display as the value to mirror to ensure the VD with flag mirroring // creates a ContentRecordingSession automatically. doReturn(DEFAULT_DISPLAY).when(mWm.mDisplayManagerInternal).getDisplayIdToMirror(anyInt()); diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java index 42004c365ba5..c84fe0871d3f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java @@ -24,7 +24,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import android.platform.test.annotations.Presubmit; @@ -32,8 +31,6 @@ import android.view.ContentRecordingSession; import androidx.test.filters.SmallTest; -import com.android.server.wm.ContentRecorder.MediaProjectionManagerWrapper; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -71,11 +68,6 @@ public class ContentRecordingControllerTests extends WindowTestsBase { mVirtualDisplayId = mVirtualDisplayContent.getDisplayId(); mWm.mRoot.onDisplayAdded(mVirtualDisplayId); spyOn(mVirtualDisplayContent); - final MediaProjectionManagerWrapper - mediaProjectionManagerWrapper = mock(MediaProjectionManagerWrapper.class); - final ContentRecorder contentRecorder = new ContentRecorder(mVirtualDisplayContent, - mediaProjectionManagerWrapper, /* correctForAnisotropicPixels= */ false); - mVirtualDisplayContent.setContentRecorder(contentRecorder); mDefaultSession.setVirtualDisplayId(mVirtualDisplayId); mWaitingDisplaySession.setVirtualDisplayId(mVirtualDisplayId); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java index c404c77c8550..bb5887d12f4b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java @@ -187,7 +187,7 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { /* options */null, /* inTask */null, /* inTaskFragment */ null, - BalVerdict.ALLOW_BY_DEFAULT, + BalVerdict.ALLOW_PRIVILEGED, /* intentGrants */null, /* realCaiingUid */ -1); @@ -217,7 +217,7 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { /* options= */null, /* inTask= */null, /* inTaskFragment= */ null, - BalVerdict.ALLOW_BY_DEFAULT, + BalVerdict.ALLOW_PRIVILEGED, /* intentGrants= */null, /* realCaiingUid */ -1); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index f02dd3f70feb..cd3ce9192509 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.permission.flags.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.InsetsSource.ID_IME; import static android.view.Surface.ROTATION_0; @@ -55,7 +56,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; -import static com.android.server.notification.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION; import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL; import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; import static com.android.server.wm.WindowContainer.SYNC_STATE_WAITING_FOR_DRAW; @@ -1424,6 +1424,25 @@ public class WindowStateTests extends WindowTestsBase { assertFalse(window2.isSecureLocked()); } + @Test + @RequiresFlagsEnabled(FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION) + public void testIsSecureLocked_sensitiveContentBlockOrClearScreenCaptureForApp() { + String testPackage = "test"; + int ownerId = 20; + final WindowState window = createWindow(null, TYPE_APPLICATION, "window", ownerId); + window.mAttrs.packageName = testPackage; + assertFalse(window.isSecureLocked()); + + PackageInfo blockedPackage = new PackageInfo(testPackage, ownerId); + ArraySet<PackageInfo> blockedPackages = new ArraySet(); + blockedPackages.add(blockedPackage); + mWm.mSensitiveContentPackages.addBlockScreenCaptureForApps(blockedPackages); + assertTrue(window.isSecureLocked()); + + mWm.mSensitiveContentPackages.removeBlockScreenCaptureForApps(blockedPackages); + assertFalse(window.isSecureLocked()); + } + private static class TestImeTargetChangeListener implements ImeTargetChangeListener { private IBinder mImeTargetToken; private boolean mIsRemoved; diff --git a/telecomm/java/android/telecom/CallAttributes.java b/telecomm/java/android/telecom/CallAttributes.java index 8c6e101f2c03..afd34fc74e43 100644 --- a/telecomm/java/android/telecom/CallAttributes.java +++ b/telecomm/java/android/telecom/CallAttributes.java @@ -16,6 +16,7 @@ package android.telecom; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -24,6 +25,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import com.android.server.telecom.flags.Flags; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; @@ -113,7 +116,8 @@ public final class CallAttributes implements Parcelable { public static final int VIDEO_CALL = 2; /** @hide */ - @IntDef(value = {SUPPORTS_SET_INACTIVE, SUPPORTS_STREAM, SUPPORTS_TRANSFER}, flag = true) + @IntDef(value = {SUPPORTS_SET_INACTIVE, SUPPORTS_STREAM, SUPPORTS_TRANSFER, + SUPPORTS_VIDEO_CALLING}, flag = true) @Retention(RetentionPolicy.SOURCE) public @interface CallCapability { } @@ -133,6 +137,12 @@ public final class CallAttributes implements Parcelable { * The call can be completely transferred from one endpoint to another. */ public static final int SUPPORTS_TRANSFER = 1 << 3; + /** + * The call supports video calling. This allows clients to gate video calling on a per call + * basis as opposed to re-registering the phone account. + */ + @FlaggedApi(Flags.FLAG_TRANSACTIONAL_VIDEO_STATE) + public static final int SUPPORTS_VIDEO_CALLING = 1 << 4; /** * Build an instance of {@link CallAttributes}. In order to build a valid instance, a diff --git a/telecomm/java/android/telecom/CallControl.java b/telecomm/java/android/telecom/CallControl.java index a14078697c71..808a57589b47 100644 --- a/telecomm/java/android/telecom/CallControl.java +++ b/telecomm/java/android/telecom/CallControl.java @@ -293,12 +293,50 @@ public final class CallControl { try { mServerInterface.setMuteState(isMuted, new CallControlResultReceiver("requestMuteState", executor, callback)); - } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } } + /** + * Request a new video state for the ongoing call. This can only be changed if the application + * has registered a {@link PhoneAccount} with the + * {@link PhoneAccount#CAPABILITY_SUPPORTS_VIDEO_CALLING} and set the + * {@link CallAttributes#SUPPORTS_VIDEO_CALLING} when adding the call via + * {@link TelecomManager#addCall(CallAttributes, Executor, OutcomeReceiver, + * CallControlCallback, CallEventCallback)} + * + * @param videoState to report to Telecom. To see the valid argument to pass, + * see {@link CallAttributes.CallType}. + * @param executor The {@link Executor} on which the {@link OutcomeReceiver} callback + * will be called on. + * @param callback that will be completed on the Telecom side that details success or failure + * of the requested operation. + * + * {@link OutcomeReceiver#onResult} will be called if Telecom has successfully + * switched the video state. + * + * {@link OutcomeReceiver#onError} will be called if Telecom has failed to set + * the new video state. A {@link CallException} will be passed + * that details why the operation failed. + * @throws IllegalArgumentException if the argument passed for videoState is invalid. To see a + * list of valid states, see {@link CallAttributes.CallType}. + */ + @FlaggedApi(Flags.FLAG_TRANSACTIONAL_VIDEO_STATE) + public void requestVideoState(@CallAttributes.CallType int videoState, + @CallbackExecutor @NonNull Executor executor, + @NonNull OutcomeReceiver<Void, CallException> callback) { + validateVideoState(videoState); + Objects.requireNonNull(executor); + Objects.requireNonNull(callback); + try { + mServerInterface.requestVideoState(videoState, mCallId, + new CallControlResultReceiver("requestVideoState", executor, callback)); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + /** * Raises an event to the {@link android.telecom.InCallService} implementations tracking this * call via {@link android.telecom.Call.Callback#onConnectionEvent(Call, String, Bundle)}. diff --git a/telecomm/java/android/telecom/CallEventCallback.java b/telecomm/java/android/telecom/CallEventCallback.java index a41c0113e933..b0438bfa0289 100644 --- a/telecomm/java/android/telecom/CallEventCallback.java +++ b/telecomm/java/android/telecom/CallEventCallback.java @@ -16,9 +16,12 @@ package android.telecom; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.os.Bundle; +import com.android.server.telecom.flags.Flags; + import java.util.List; /** @@ -51,6 +54,14 @@ public interface CallEventCallback { void onMuteStateChanged(boolean isMuted); /** + * Called when the video state changes. + * + * @param videoState The current video state. + */ + @FlaggedApi(Flags.FLAG_TRANSACTIONAL_VIDEO_STATE) + default void onVideoStateChanged(@CallAttributes.CallType int videoState) {} + + /** * Telecom is informing the client user requested call streaming but the stream can't be * started. * diff --git a/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java b/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java index 467e89c78810..a2c60862f559 100644 --- a/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java +++ b/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java @@ -33,6 +33,8 @@ import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import android.util.Log; +import com.android.server.telecom.flags.Flags; + import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -148,6 +150,7 @@ public class ClientTransactionalServiceWrapper { private static final String ON_REQ_ENDPOINT_CHANGE = "onRequestEndpointChange"; private static final String ON_AVAILABLE_CALL_ENDPOINTS = "onAvailableCallEndpointsChanged"; private static final String ON_MUTE_STATE_CHANGED = "onMuteStateChanged"; + private static final String ON_VIDEO_STATE_CHANGED = "onVideoStateChanged"; private static final String ON_CALL_STREAMING_FAILED = "onCallStreamingFailed"; private static final String ON_EVENT = "onEvent"; @@ -261,6 +264,11 @@ public class ClientTransactionalServiceWrapper { handleEventCallback(callId, ON_MUTE_STATE_CHANGED, isMuted); } + @Override + public void onVideoStateChanged(String callId, int videoState) { + handleEventCallback(callId, ON_VIDEO_STATE_CHANGED, videoState); + } + public void handleEventCallback(String callId, String action, Object arg) { Log.d(TAG, TextUtils.formatSimple("hEC: [%s], callId=[%s]", action, callId)); // lookup the callEventCallback associated with the particular call @@ -281,6 +289,11 @@ public class ClientTransactionalServiceWrapper { case ON_MUTE_STATE_CHANGED: callback.onMuteStateChanged((boolean) arg); break; + case ON_VIDEO_STATE_CHANGED: + if (Flags.transactionalVideoState()) { + callback.onVideoStateChanged((int) arg); + } + break; case ON_CALL_STREAMING_FAILED: callback.onCallStreamingFailed((int) arg /* reason */); break; diff --git a/telecomm/java/com/android/internal/telecom/ICallControl.aidl b/telecomm/java/com/android/internal/telecom/ICallControl.aidl index 372e4a12ff70..ac496607abe6 100644 --- a/telecomm/java/com/android/internal/telecom/ICallControl.aidl +++ b/telecomm/java/com/android/internal/telecom/ICallControl.aidl @@ -34,4 +34,5 @@ oneway interface ICallControl { void requestCallEndpointChange(in CallEndpoint callEndpoint, in ResultReceiver callback); void setMuteState(boolean isMuted, in ResultReceiver callback); void sendEvent(String callId, String event, in Bundle extras); + void requestVideoState(int videoState, String callId, in ResultReceiver callback); }
\ No newline at end of file diff --git a/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl b/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl index 213cafbbf188..e4d6b0c79c49 100644 --- a/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl +++ b/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl @@ -45,6 +45,8 @@ oneway interface ICallEventCallback { void onCallEndpointChanged(String callId, in CallEndpoint endpoint); void onAvailableCallEndpointsChanged(String callId, in List<CallEndpoint> endpoint); void onMuteStateChanged(String callId, boolean isMuted); + // -- Video Related + void onVideoStateChanged(String callId, int videoState); // -- Events void onEvent(String callId, String event, in Bundle extras); // hidden methods that help with cleanup diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 697c8ecd96e7..d99abe882405 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3844,13 +3844,27 @@ public class CarrierConfigManager { * and if the 5G state changes to neither 'connected' not 'not_restricted_rrc_idle', the icon * will change to reflect the true state. * + * The value can be overridden by {@link #KEY_NR_ADVANCED_BANDS_SECONDARY_TIMER_SECONDS_INT} * @hide */ public static final String KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING = "5g_icon_display_secondary_grace_period_string"; /** - * Whether device reset all of NR timers when device camped on a network that haven't 5G + * The secondary grace periods in seconds to use if NR advanced icon was shown due to connecting + * to bands specified in {@link #KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY}. + * + * The default value is 0, meaning the original value in + * {@link #KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING} is used. Otherwise, it overrides + * the value in {@link #KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING}. + * + * @hide + */ + public static final String KEY_NR_ADVANCED_BANDS_SECONDARY_TIMER_SECONDS_INT = + "nr_advanced_bands_secondary_timer_seconds_int"; + + /** + * Whether device resets all of NR timers when device camped on a network that haven't 5G * capability and RRC currently in IDLE state. * * The default value is false; @@ -3861,6 +3875,30 @@ public class CarrierConfigManager { "nr_timers_reset_if_non_endc_and_rrc_idle_bool"; /** + * Whether device resets all of NR timers when device is in a voice call and QOS is established. + * The default value is false; + * + * @see #KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING + * @see #KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING + * + * @hide + */ + public static final String KEY_NR_TIMERS_RESET_ON_VOICE_QOS_BOOL = + "nr_timers_reset_on_voice_qos_bool"; + + /** + * Whether device resets all of NR timers when the PLMN changes. + * The default value is false; + * + * @see #KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING + * @see #KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING + * + * @hide + */ + public static final String KEY_NR_TIMERS_RESET_ON_PLMN_CHANGE_BOOL = + "nr_timers_reset_on_plmn_change_bool"; + + /** * A list of additional NR advanced band would map to * {@link TelephonyDisplayInfo#OVERRIDE_NETWORK_TYPE_NR_ADVANCED} when the device is on that * band. @@ -10688,7 +10726,10 @@ public class CarrierConfigManager { + "not_restricted_rrc_con:5G"); sDefaults.putString(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING, ""); sDefaults.putString(KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING, ""); + sDefaults.putInt(KEY_NR_ADVANCED_BANDS_SECONDARY_TIMER_SECONDS_INT, 0); sDefaults.putBoolean(KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL, false); + sDefaults.putBoolean(KEY_NR_TIMERS_RESET_ON_VOICE_QOS_BOOL, false); + sDefaults.putBoolean(KEY_NR_TIMERS_RESET_ON_PLMN_CHANGE_BOOL, false); /* Default value is 1 hour. */ sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000); sDefaults.putIntArray(KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY, new int[0]); diff --git a/telephony/java/android/telephony/DomainSelectionService.java b/telephony/java/android/telephony/DomainSelectionService.java index 4ff9712f0907..633694ac97da 100644 --- a/telephony/java/android/telephony/DomainSelectionService.java +++ b/telephony/java/android/telephony/DomainSelectionService.java @@ -20,6 +20,7 @@ import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.app.Service; import android.content.Intent; @@ -855,7 +856,8 @@ public abstract class DomainSelectionService extends Service { * * @return an {@link Executor} used to execute methods called remotely by the framework. */ - public @NonNull Executor onCreateExecutor() { + @SuppressLint("OnNameExpected") + public @NonNull Executor getCreateExecutor() { return Runnable::run; } @@ -869,7 +871,7 @@ public abstract class DomainSelectionService extends Service { public final @NonNull Executor getCachedExecutor() { synchronized (mExecutorLock) { if (mExecutor == null) { - Executor e = onCreateExecutor(); + Executor e = getCreateExecutor(); mExecutor = (e != null) ? e : Runnable::run; } return mExecutor; diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index cd641b8be0b6..c5f2d42389e5 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -4690,7 +4690,6 @@ public class SubscriptionManager { * @param subscriptionId the subId of the subscription * @param userHandle user handle of the user * @return {@code true} if subscription is associated with user - * {code true} if there are no subscriptions on device * else {@code false} if subscription is not associated with user. * * @throws IllegalArgumentException if subscription doesn't exist. @@ -4721,6 +4720,37 @@ public class SubscriptionManager { } /** + * Returns whether the given subscription is associated with the calling user. + * + * @param subscriptionId the subscription ID of the subscription + * @return {@code true} if the subscription is associated with the user that the current process + * is running in; {@code false} otherwise. + * + * @throws IllegalArgumentException if subscription doesn't exist. + * @throws SecurityException if the caller doesn't have permissions required. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + @FlaggedApi(Flags.FLAG_SUBSCRIPTION_USER_ASSOCIATION_QUERY) + public boolean isSubscriptionAssociatedWithUser(int subscriptionId) { + if (!isValidSubscriptionId(subscriptionId)) { + throw new IllegalArgumentException("[isSubscriptionAssociatedWithCallingUser]: " + + "Invalid subscriptionId: " + subscriptionId); + } + + try { + ISub iSub = TelephonyManager.getSubscriptionService(); + if (iSub != null) { + return iSub.isSubscriptionAssociatedWithCallingUser(subscriptionId); + } else { + throw new IllegalStateException("subscription service unavailable."); + } + } catch (RemoteException ex) { + ex.rethrowAsRuntimeException(); + } + return false; + } + + /** * Get list of subscriptions associated with user. * * @param userHandle user handle of the user diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 041822bf4ee9..fd9aae9ff835 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -15011,6 +15011,27 @@ public class TelephonyManager { } /** + * Get the emergency assistance package name. + * + * @return the package name of the emergency assistance app. + * @throws IllegalStateException if emergency assistance is not enabled. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @FlaggedApi(android.permission.flags.Flags.FLAG_GET_EMERGENCY_ROLE_HOLDER_API_ENABLED) + @NonNull + @SystemApi + public String getEmergencyAssistancePackage() { + if (!isEmergencyAssistanceEnabled()) { + throw new IllegalStateException("isEmergencyAssistanceEnabled() is false."); + } + String emergencyRole = mContext.getSystemService(RoleManager.class) + .getEmergencyRoleHolder(mContext.getUserId()); + return Objects.requireNonNull(emergencyRole, "Emergency role holder must not be null"); + } + + /** * Get the emergency number list based on current locale, sim, default, modem and network. * * <p>In each returned list, the emergency number {@link EmergencyNumber} coming from higher diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl index cc770aa65888..6678f408e720 100644 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -332,12 +332,23 @@ interface ISub { UserHandle getSubscriptionUserHandle(int subId); /** + * Returns whether the given subscription is associated with the calling user. + * + * @param subscriptionId the subscription ID of the subscription + * @return {@code true} if the subscription is associated with the user that the current process + * is running in; {@code false} otherwise. + * + * @throws IllegalArgumentException if subscription doesn't exist. + * @throws SecurityException if the caller doesn't have permissions required. + */ + boolean isSubscriptionAssociatedWithCallingUser(int subscriptionId); + + /** * Check if subscription and user are associated with each other. * * @param subscriptionId the subId of the subscription * @param userHandle user handle of the user * @return {@code true} if subscription is associated with user - * {code true} if there are no subscriptions on device * else {@code false} if subscription is not associated with user. * * @throws IllegalArgumentException if subscription is invalid. diff --git a/tests/Input/AndroidTest.xml b/tests/Input/AndroidTest.xml index 13b5f0d99ba8..f602c5124e77 100644 --- a/tests/Input/AndroidTest.xml +++ b/tests/Input/AndroidTest.xml @@ -23,4 +23,9 @@ <option name="test-timeout" value="600s" /> <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> </test> + <object class="com.android.tradefed.testtype.suite.module.TestFailureModuleController" + type="module_controller"> + <!-- Take screenshot upon test failure --> + <option name="screenshot-on-failure" value="true" /> + </object> </configuration> diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java index 9daba6a79a27..1d7be2f4f039 100644 --- a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java +++ b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java @@ -144,7 +144,7 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { mTestLooper.dispatchAll(); verify(mIpSecTransform) - .getIpSecTransformState(any(), mTransformStateReceiverCaptor.capture()); + .requestIpSecTransformState(any(), mTransformStateReceiverCaptor.capture()); return mTransformStateReceiverCaptor.getValue(); } @@ -210,7 +210,7 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { assertNull(mIpSecPacketLossDetector.getLastTransformState()); mTestLooper.moveTimeForward(POLL_IPSEC_STATE_INTERVAL_MS); mTestLooper.dispatchAll(); - verify(newTransform).getIpSecTransformState(any(), any()); + verify(newTransform).requestIpSecTransformState(any(), any()); } @Test diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt new file mode 100644 index 000000000000..83e09bf7043e --- /dev/null +++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.filters + +import com.android.hoststubgen.asm.ClassNodes +import com.android.hoststubgen.asm.toJvmClassName + +/** + * Filter to apply a policy to classes extending or implementing a class, + * either directly or indirectly. (with a breadth first search.) + * + * The policy won't apply to the super class itself. + */ +class SubclassFilter( + private val classes: ClassNodes, + fallback: OutputFilter +) : DelegatingFilter(fallback) { + private val mPolicies: MutableMap<String, FilterPolicyWithReason> = mutableMapOf() + + /** + * Add a policy to all classes extending or implementing a class, either directly or indirectly. + */ + fun addPolicy(superClassName: String, policy: FilterPolicyWithReason) { + mPolicies[superClassName.toJvmClassName()] = policy + } + + override fun getPolicyForClass(className: String): FilterPolicyWithReason { + return findPolicyForClass(className) ?: super.getPolicyForClass(className) + } + + /** + * Find a policy for a class with a breadth-first search. + */ + private fun findPolicyForClass(className: String): FilterPolicyWithReason? { + val cn = classes.findClass(className) ?: return null + + if (cn.superName == null) { + return null + } + // First, check the direct super class / interfaces. + mPolicies[cn.superName]?.let { policy -> + return policy + } + cn.interfaces?.forEach { iface -> + mPolicies[iface]?.let { policy -> + return policy + } + } + + // Then recurse. + cn.superName?.let { superName -> + findPolicyForClass(superName)?.let { policy -> + return policy + } + } + cn.interfaces?.forEach { iface -> + findPolicyForClass(iface)?.let { policy -> + return policy + } + } + return null + } +}
\ No newline at end of file diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt index 6ad83fbab083..75b5fc8f77ea 100644 --- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt +++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt @@ -58,7 +58,8 @@ fun createFilterFromTextPolicyFile( ): OutputFilter { log.i("Loading offloaded annotations from $filename ...") log.withIndent { - val imf = InMemoryOutputFilter(classes, fallback) + val subclassFilter = SubclassFilter(classes, fallback) + val imf = InMemoryOutputFilter(classes, subclassFilter) var lineNo = 0 @@ -94,6 +95,10 @@ fun createFilterFromTextPolicyFile( } className = fields[1] + // superClass is set when the class name starts with a "*". + val superClass = resolveExtendingClass(className) + + // :aidl, etc? val classType = resolveSpecialClass(className) if (fields[2].startsWith("!")) { @@ -124,8 +129,14 @@ fun createFilterFromTextPolicyFile( when (classType) { SpecialClass.NotSpecial -> { // TODO: Duplicate check, etc - imf.setPolicyForClass( - className, policy.withReason(FILTER_REASON)) + if (superClass == null) { + imf.setPolicyForClass( + className, policy.withReason(FILTER_REASON) + ) + } else { + subclassFilter.addPolicy(superClass, + policy.withReason("extends $superClass")) + } } SpecialClass.Aidl -> { if (aidlPolicy != null) { @@ -243,6 +254,13 @@ private fun resolveSpecialClass(className: String): SpecialClass { throw ParseException("Invalid special class name \"$className\"") } +private fun resolveExtendingClass(className: String): String? { + if (!className.startsWith("*")) { + return null + } + return className.substring(1) +} + private fun parsePolicy(s: String): FilterPolicy { return when (s.lowercase()) { "s", "stub" -> FilterPolicy.Stub diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt index 70f56ae37a97..78f277e8254c 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt @@ -2589,6 +2589,567 @@ SourceFile: "TinyFrameworkPackageRedirect.java" RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestWholeClassStub +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C1.class + Compiled from "C1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.C1(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/C1; +} +SourceFile: "C1.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C2.class + Compiled from "C2.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + interfaces: 0, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.C2(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/C1."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/C2; +} +SourceFile: "C2.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C3.class + Compiled from "C3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + interfaces: 0, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.C3(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/C2."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/C3; +} +SourceFile: "C3.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CA.class + Compiled from "CA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.CA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.CA(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/CA; +} +SourceFile: "CA.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CB.class + Compiled from "CB.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.CB + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.CB(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/CB; +} +SourceFile: "CB.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.class + Compiled from "Class_C1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + interfaces: 0, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/C1."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_C1; +} +SourceFile: "Class_C1.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.class + Compiled from "Class_C2.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + interfaces: 0, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/C2."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_C2; +} +SourceFile: "Class_C2.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.class + Compiled from "Class_C3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C3 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3 + interfaces: 0, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/C3."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_C3; +} +SourceFile: "Class_C3.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_CA.class + Compiled from "Class_CA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CA extends com.android.hoststubgen.test.tinyframework.subclasstest.CA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CA + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA + interfaces: 0, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CA(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/CA."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_CA; +} +SourceFile: "Class_CA.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB.class + Compiled from "Class_CB.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB extends com.android.hoststubgen.test.tinyframework.subclasstest.CB + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB + interfaces: 0, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/CB."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_CB; +} +SourceFile: "Class_CB.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA.class + Compiled from "Class_CB_IA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB_IA extends com.android.hoststubgen.test.tinyframework.subclasstest.CB implements com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB + interfaces: 1, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB_IA(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/CB."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA; +} +SourceFile: "Class_CB_IA.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.class + Compiled from "Class_I1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_I1; +} +SourceFile: "Class_I1.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.class + Compiled from "Class_I1_IA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I1,com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA + super_class: #x // java/lang/Object + interfaces: 2, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA; +} +SourceFile: "Class_I1_IA.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.class + Compiled from "Class_I2.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 implements com.android.hoststubgen.test.tinyframework.subclasstest.I2 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_I2; +} +SourceFile: "Class_I2.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.class + Compiled from "Class_I3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.I3 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_I3; +} +SourceFile: "Class_I3.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA.class + Compiled from "Class_I3_IA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I3,com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA + super_class: #x // java/lang/Object + interfaces: 2, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3_IA(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA; +} +SourceFile: "Class_I3_IA.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA.class + Compiled from "Class_IA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_IA; +} +SourceFile: "Class_IA.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1.class + Compiled from "Class_IA_I1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.IA,com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1 + super_class: #x // java/lang/Object + interfaces: 2, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I1(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1; +} +SourceFile: "Class_IA_I1.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3.class + Compiled from "Class_IA_I3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.IA,com.android.hoststubgen.test.tinyframework.subclasstest.I3 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3 + super_class: #x // java/lang/Object + interfaces: 2, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I3(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3; +} +SourceFile: "Class_IA_I3.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB.class + Compiled from "Class_IB.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB implements com.android.hoststubgen.test.tinyframework.subclasstest.IB + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_IB; +} +SourceFile: "Class_IB.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA.class + Compiled from "Class_IB_IA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.IB,com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA + super_class: #x // java/lang/Object + interfaces: 2, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB_IA(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA; +} +SourceFile: "Class_IB_IA.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_None.class + Compiled from "Class_None.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_None + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_None + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 1, attributes: 1 + public com.android.hoststubgen.test.tinyframework.subclasstest.Class_None(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + Code: + stack=1, locals=1, args_size=1 + x: aload_0 + x: invokespecial #x // Method java/lang/Object."<init>":()V + x: return + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_None; +} +SourceFile: "Class_None.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I1.class + Compiled from "I1.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1 + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 1 +} +SourceFile: "I1.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class + Compiled from "I2.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 extends com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 0, attributes: 1 +} +SourceFile: "I2.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class + Compiled from "I3.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 extends com.android.hoststubgen.test.tinyframework.subclasstest.I2 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 0, attributes: 1 +} +SourceFile: "I3.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class + Compiled from "IA.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 1 +} +SourceFile: "IA.java" +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class + Compiled from "IB.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 1 +} +SourceFile: "IB.java" ## Class: com/supported/UnsupportedClass.class Compiled from "UnsupportedClass.java" public class com.supported.UnsupportedClass diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt index b0db48347d46..406cb74bb60c 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt @@ -2055,6 +2055,166 @@ RuntimeVisibleAnnotations: RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestWholeClassStub +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C1.class + Compiled from "C1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "C1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C2.class + Compiled from "C2.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "C2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C3.class + Compiled from "C3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "C3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CA.class + Compiled from "CA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.CA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "CA.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CB.class + Compiled from "CB.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.CB + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "CB.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I1.class + Compiled from "I1.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1 + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "I1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class + Compiled from "I2.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 extends com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "I2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class + Compiled from "I3.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 extends com.android.hoststubgen.test.tinyframework.subclasstest.I2 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "I3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class + Compiled from "IA.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "IA.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class + Compiled from "IB.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "IB.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl ## Class: com/unsupported/UnsupportedClass.class Compiled from "UnsupportedClass.java" public class com.unsupported.UnsupportedClass diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt index 112f69e43c69..c67326289477 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt @@ -3371,6 +3371,264 @@ RuntimeVisibleAnnotations: RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestWholeClassStub +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C1.class + Compiled from "C1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "C1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C2.class + Compiled from "C2.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "C2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C3.class + Compiled from "C3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "C3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CA.class + Compiled from "CA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.CA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "CA.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CB.class + Compiled from "CB.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.CB + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "CB.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.class + Compiled from "Class_C1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "Class_C1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.class + Compiled from "Class_C2.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "Class_C2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.class + Compiled from "Class_C3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C3 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3 + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "Class_C3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.class + Compiled from "Class_I1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "Class_I1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.class + Compiled from "Class_I1_IA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I1,com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA + super_class: #x // java/lang/Object + interfaces: 2, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "Class_I1_IA.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.class + Compiled from "Class_I2.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 implements com.android.hoststubgen.test.tinyframework.subclasstest.I2 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "Class_I2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.class + Compiled from "Class_I3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.I3 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "Class_I3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I1.class + Compiled from "I1.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1 + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "I1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class + Compiled from "I2.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 extends com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "I2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class + Compiled from "I3.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 extends com.android.hoststubgen.test.tinyframework.subclasstest.I2 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "I3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class + Compiled from "IA.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "IA.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class + Compiled from "IB.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "IB.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl ## Class: com/supported/UnsupportedClass.class Compiled from "UnsupportedClass.java" public class com.supported.UnsupportedClass diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt index b0db48347d46..406cb74bb60c 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt @@ -2055,6 +2055,166 @@ RuntimeVisibleAnnotations: RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestWholeClassStub +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C1.class + Compiled from "C1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "C1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C2.class + Compiled from "C2.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "C2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C3.class + Compiled from "C3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "C3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CA.class + Compiled from "CA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.CA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "CA.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CB.class + Compiled from "CB.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.CB + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "CB.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I1.class + Compiled from "I1.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1 + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "I1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class + Compiled from "I2.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 extends com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "I2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class + Compiled from "I3.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 extends com.android.hoststubgen.test.tinyframework.subclasstest.I2 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "I3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class + Compiled from "IA.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "IA.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class + Compiled from "IB.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 0, attributes: 2 +} +SourceFile: "IB.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl ## Class: com/unsupported/UnsupportedClass.class Compiled from "UnsupportedClass.java" public class com.unsupported.UnsupportedClass diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt index 2357844c1e10..4fd570157071 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt @@ -4201,6 +4201,417 @@ RuntimeVisibleAnnotations: RuntimeInvisibleAnnotations: x: #x() android.hosttest.annotation.HostSideTestWholeClassStub +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C1.class + Compiled from "C1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/C1 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "C1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C2.class + Compiled from "C2.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + interfaces: 0, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/C2 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "C2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C3.class + Compiled from "C3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + interfaces: 0, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/C3 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "C3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CA.class + Compiled from "CA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.CA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/CA + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "CA.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CB.class + Compiled from "CB.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.CB + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/CB + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "CB.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.class + Compiled from "Class_C1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1 + interfaces: 0, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "Class_C1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.class + Compiled from "Class_C2.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2 + interfaces: 0, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "Class_C2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.class + Compiled from "Class_C3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C3 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3 + super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3 + interfaces: 0, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "Class_C3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.class + Compiled from "Class_I1.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "Class_I1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.class + Compiled from "Class_I1_IA.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I1,com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA + super_class: #x // java/lang/Object + interfaces: 2, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "Class_I1_IA.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.class + Compiled from "Class_I2.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 implements com.android.hoststubgen.test.tinyframework.subclasstest.I2 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "Class_I2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.class + Compiled from "Class_I3.java" +public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.I3 + minor version: 0 + major version: 61 + flags: (0x0021) ACC_PUBLIC, ACC_SUPER + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "Class_I3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I1.class + Compiled from "I1.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1 + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/I1 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "I1.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class + Compiled from "I2.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 extends com.android.hoststubgen.test.tinyframework.subclasstest.I1 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/I2 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "I2.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class + Compiled from "I3.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 extends com.android.hoststubgen.test.tinyframework.subclasstest.I2 + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3 + super_class: #x // java/lang/Object + interfaces: 1, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/I3 + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "I3.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class + Compiled from "IA.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/IA + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "IA.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl +## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class + Compiled from "IB.java" +public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB + minor version: 0 + major version: 61 + flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT + this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB + super_class: #x // java/lang/Object + interfaces: 0, fields: 0, methods: 1, attributes: 2 + private static {}; + descriptor: ()V + flags: (0x000a) ACC_PRIVATE, ACC_STATIC + Code: + stack=2, locals=0, args_size=0 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/subclasstest/IB + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V + x: return +} +SourceFile: "IB.java" +RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInStub + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl ## Class: com/supported/UnsupportedClass.class Compiled from "UnsupportedClass.java" public class com.supported.UnsupportedClass diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt index 9b6b6e4c9f5b..d30208452a40 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt @@ -17,4 +17,23 @@ class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy stub class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy ~com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded # Heuristics rule: Stub all the AIDL classes. -class :aidl stubclass
\ No newline at end of file +class :aidl stubclass + +# Default is "remove", so let's put all the base classes / interfaces in the stub first. +class com.android.hoststubgen.test.tinyframework.subclasstest.C1 stub +class com.android.hoststubgen.test.tinyframework.subclasstest.C2 stub +class com.android.hoststubgen.test.tinyframework.subclasstest.C3 stub +class com.android.hoststubgen.test.tinyframework.subclasstest.CA stub +class com.android.hoststubgen.test.tinyframework.subclasstest.CB stub +class com.android.hoststubgen.test.tinyframework.subclasstest.I1 stub +class com.android.hoststubgen.test.tinyframework.subclasstest.I2 stub +class com.android.hoststubgen.test.tinyframework.subclasstest.I3 stub +class com.android.hoststubgen.test.tinyframework.subclasstest.IA stub +class com.android.hoststubgen.test.tinyframework.subclasstest.IB stub + +# Then define inheritance based policies. +class *com.android.hoststubgen.test.tinyframework.subclasstest.C1 keep +class *com.android.hoststubgen.test.tinyframework.subclasstest.CA remove + +class *com.android.hoststubgen.test.tinyframework.subclasstest.I1 keep +class *com.android.hoststubgen.test.tinyframework.subclasstest.IA remove diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/C1.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/C1.java new file mode 100644 index 000000000000..03c9e2a7b5bb --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/C1.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class C1 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/C2.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/C2.java new file mode 100644 index 000000000000..3ca8f1f172bd --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/C2.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class C2 extends C1 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/C3.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/C3.java new file mode 100644 index 000000000000..a6c14f09b680 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/C3.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class C3 extends C2 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/CA.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/CA.java new file mode 100644 index 000000000000..2e353709fd1e --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/CA.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class CA { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/CB.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/CB.java new file mode 100644 index 000000000000..fe4cee64b2f9 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/CB.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class CB { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.java new file mode 100644 index 000000000000..12012fcdf6ca --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_C1 extends C1 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.java new file mode 100644 index 000000000000..8d48ee6f6858 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_C2 extends C2 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.java new file mode 100644 index 000000000000..6748430a8e6f --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_C3 extends C3 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_CA.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_CA.java new file mode 100644 index 000000000000..58aa5c3b74eb --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_CA.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_CA extends CA { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB.java new file mode 100644 index 000000000000..c1c3d624b126 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_CB extends CB { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA.java new file mode 100644 index 000000000000..398b56975f1c --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_CB_IA extends CB implements IA { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.java new file mode 100644 index 000000000000..44cbd8f9bffa --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_I1 implements I1 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.java new file mode 100644 index 000000000000..42355a34b65c --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_I1_IA implements I1, IA { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.java new file mode 100644 index 000000000000..09c80992e450 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_I2 implements I2 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.java new file mode 100644 index 000000000000..0806a478d756 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_I3 implements I3 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA.java new file mode 100644 index 000000000000..eaa8528a3f31 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_I3_IA implements I3, IA { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA.java new file mode 100644 index 000000000000..778c5aaf27f0 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_IA implements IA { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1.java new file mode 100644 index 000000000000..493f7c83c0f0 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_IA_I1 implements IA, I1 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3.java new file mode 100644 index 000000000000..2aa1de18b7f4 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_IA_I3 implements IA, I3 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB.java new file mode 100644 index 000000000000..d9eae0934c42 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_IB implements IB { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA.java new file mode 100644 index 000000000000..9ee42836ac9a --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_IB_IA implements IB, IA { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_None.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_None.java new file mode 100644 index 000000000000..50ec2cbc9c6e --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/Class_None.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public class Class_None { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/I1.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/I1.java new file mode 100644 index 000000000000..3f3659644a80 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/I1.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public interface I1 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/I2.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/I2.java new file mode 100644 index 000000000000..960060c8a036 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/I2.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public interface I2 extends I1 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/I3.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/I3.java new file mode 100644 index 000000000000..c678eaa789b0 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/I3.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public interface I3 extends I2 { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/IA.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/IA.java new file mode 100644 index 000000000000..1cff484c3cd8 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/IA.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public interface IA { +} diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/IB.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/IB.java new file mode 100644 index 000000000000..84e7173c71b8 --- /dev/null +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/subclasstest/IB.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.hoststubgen.test.tinyframework.subclasstest; + +public interface IB { +} diff --git a/tools/hoststubgen/scripts/run-all-tests.sh b/tools/hoststubgen/scripts/run-all-tests.sh deleted file mode 100755 index a6847ae97bae..000000000000 --- a/tools/hoststubgen/scripts/run-all-tests.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -# Copyright (C) 2023 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -source "${0%/*}"/../common.sh - -# Move to the top directory of hoststubgen -cd .. - -ATEST_ARGS="--host" - -# These tests are known to pass. -READY_TEST_MODULES=( - hoststubgen-test-tiny-test - CtsUtilTestCasesRavenwood - CtsOsTestCasesRavenwood # This one uses native sustitution, so let's run it too. -) - -MUST_BUILD_MODULES=( - "${NOT_READY_TEST_MODULES[*]}" -) - -# First, build all the test / etc modules. This shouldn't fail. -run m "${MUST_BUILD_MODULES[@]}" - -# Run the hoststubgen unittests / etc -run atest $ATEST_ARGS hoststubgentest hoststubgen-invoke-test - -# Next, run the golden check. This should always pass too. -# The following scripts _should_ pass too, but they depend on the internal paths to soong generated -# files, and they may fail when something changes in the build system. -run ./hoststubgen/test-tiny-framework/diff-and-update-golden.sh - -run ./hoststubgen/test-tiny-framework/run-test-manually.sh -run atest $ATEST_ARGS tiny-framework-dump-test - -# This script is already broken on goog/master -# run ./scripts/build-framework-hostside-jars-without-genrules.sh - -# These tests should all pass. -run atest $ATEST_ARGS ${READY_TEST_MODULES[*]} - -echo ""${0##*/}" finished, with no failures. Ready to submit!" |