diff options
723 files changed, 8325 insertions, 4071 deletions
diff --git a/apct-tests/perftests/inputmethod/AndroidManifest.xml b/apct-tests/perftests/inputmethod/AndroidManifest.xml index 3eea418fe5c7..5dd6ccccfb1c 100644 --- a/apct-tests/perftests/inputmethod/AndroidManifest.xml +++ b/apct-tests/perftests/inputmethod/AndroidManifest.xml @@ -22,7 +22,8 @@ <application> <uses-library android:name="android.test.runner" /> <activity android:name="android.perftests.utils.PerfTestActivity" - android:exported="true"> + android:theme="@android:style/Theme.DeviceDefault.NoActionBar" + android:exported="true"> <intent-filter> <action android:name="com.android.perftests.core.PERFTEST" /> </intent-filter> diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/PerfTestActivity.java b/apct-tests/perftests/utils/src/android/perftests/utils/PerfTestActivity.java index f3bea17b2f0d..0c2ee8cb238a 100644 --- a/apct-tests/perftests/utils/src/android/perftests/utils/PerfTestActivity.java +++ b/apct-tests/perftests/utils/src/android/perftests/utils/PerfTestActivity.java @@ -19,7 +19,9 @@ package android.perftests.utils; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.graphics.Insets; import android.os.Bundle; +import android.view.WindowInsets; import android.view.WindowManager; import android.widget.EditText; import android.widget.LinearLayout; @@ -42,6 +44,11 @@ public class PerfTestActivity extends Activity { if (getIntent().getBooleanExtra(INTENT_EXTRA_ADD_EDIT_TEXT, false)) { final LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); + layout.setOnApplyWindowInsetsListener((v, w) -> { + final Insets insets = w.getSystemWindowInsets(); + v.setPadding(insets.left, insets.top, insets.right, insets.bottom); + return WindowInsets.CONSUMED; + }); final EditText editText = new EditText(this); editText.setId(ID_EDITOR); diff --git a/apex/jobscheduler/service/aconfig/device_idle.aconfig b/apex/jobscheduler/service/aconfig/device_idle.aconfig index e8c99b12828f..c4d0d1850a18 100644 --- a/apex/jobscheduler/service/aconfig/device_idle.aconfig +++ b/apex/jobscheduler/service/aconfig/device_idle.aconfig @@ -2,6 +2,16 @@ package: "com.android.server.deviceidle" container: "system" flag { + name: "remove_idle_location" + namespace: "location" + description: "Remove DeviceIdleController usage of location" + bug: "332770178" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "disable_wakelocks_in_light_idle" namespace: "backstage_power" description: "Disable wakelocks for background apps while Light Device Idle is active" diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java index 4832ea624bd7..11fa7b75182f 100644 --- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java @@ -109,6 +109,7 @@ import com.android.modules.expresslog.Counter; import com.android.server.am.BatteryStatsService; import com.android.server.deviceidle.ConstraintController; import com.android.server.deviceidle.DeviceIdleConstraintTracker; +import com.android.server.deviceidle.Flags; import com.android.server.deviceidle.IDeviceIdleConstraint; import com.android.server.deviceidle.TvConstraintController; import com.android.server.net.NetworkPolicyManagerInternal; @@ -2558,7 +2559,7 @@ public class DeviceIdleController extends SystemService } boolean isLocationPrefetchEnabled() { - return mContext.getResources().getBoolean( + return !Flags.removeIdleLocation() && mContext.getResources().getBoolean( com.android.internal.R.bool.config_autoPowerModePrefetchLocation); } diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp index 1b1bc6b9afdb..f56a95011dee 100644 --- a/api/StubLibraries.bp +++ b/api/StubLibraries.bp @@ -54,34 +54,34 @@ non_updatable_exportable_droidstubs { baseline_file: ":non-updatable-lint-baseline.txt", }, }, - dists: [ - { - targets: ["sdk"], - dir: "apistubs/android/public/api", - dest: "android-non-updatable.txt", - }, - { - targets: ["sdk"], - dir: "apistubs/android/public/api", - dest: "android-non-updatable-removed.txt", - }, - ], soong_config_variables: { release_hidden_api_exportable_stubs: { dists: [ { + targets: ["sdk"], + dir: "apistubs/android/public/api", + dest: "android-non-updatable.txt", tag: ".exportable.api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/public/api", + dest: "android-non-updatable-removed.txt", tag: ".exportable.removed-api.txt", }, ], conditions_default: { dists: [ { + targets: ["sdk"], + dir: "apistubs/android/public/api", + dest: "android-non-updatable.txt", tag: ".api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/public/api", + dest: "android-non-updatable-removed.txt", tag: ".removed-api.txt", }, ], @@ -134,34 +134,34 @@ non_updatable_exportable_droidstubs { baseline_file: ":non-updatable-system-lint-baseline.txt", }, }, - dists: [ - { - targets: ["sdk"], - dir: "apistubs/android/system/api", - dest: "android-non-updatable.txt", - }, - { - targets: ["sdk"], - dir: "apistubs/android/system/api", - dest: "android-non-updatable-removed.txt", - }, - ], soong_config_variables: { release_hidden_api_exportable_stubs: { dists: [ { + targets: ["sdk"], + dir: "apistubs/android/system/api", + dest: "android-non-updatable.txt", tag: ".exportable.api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/system/api", + dest: "android-non-updatable-removed.txt", tag: ".exportable.removed-api.txt", }, ], conditions_default: { dists: [ { + targets: ["sdk"], + dir: "apistubs/android/system/api", + dest: "android-non-updatable.txt", tag: ".api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/system/api", + dest: "android-non-updatable-removed.txt", tag: ".removed-api.txt", }, ], @@ -189,56 +189,58 @@ non_updatable_exportable_droidstubs { baseline_file: ":non-updatable-test-lint-baseline.txt", }, }, - dists: [ - { - targets: ["sdk"], - dir: "apistubs/android/test/api", - dest: "android.txt", - }, - { - targets: ["sdk"], - dir: "apistubs/android/test/api", - dest: "removed.txt", - }, - { - targets: ["sdk"], - dir: "apistubs/android/test/api", - dest: "android-non-updatable.txt", - }, - { - targets: ["sdk"], - dir: "apistubs/android/test/api", - dest: "android-non-updatable-removed.txt", - }, - ], soong_config_variables: { release_hidden_api_exportable_stubs: { dists: [ { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "android.txt", tag: ".exportable.api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "removed.txt", tag: ".exportable.removed-api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "android-non-updatable.txt", tag: ".exportable.api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "android-non-updatable-removed.txt", tag: ".exportable.removed-api.txt", }, ], conditions_default: { dists: [ { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "android.txt", tag: ".api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "removed.txt", tag: ".removed-api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "android-non-updatable.txt", tag: ".api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "android-non-updatable-removed.txt", tag: ".removed-api.txt", }, ], @@ -271,34 +273,34 @@ non_updatable_exportable_droidstubs { baseline_file: ":non-updatable-module-lib-lint-baseline.txt", }, }, - dists: [ - { - targets: ["sdk"], - dir: "apistubs/android/module-lib/api", - dest: "android-non-updatable.txt", - }, - { - targets: ["sdk"], - dir: "apistubs/android/module-lib/api", - dest: "android-non-updatable-removed.txt", - }, - ], soong_config_variables: { release_hidden_api_exportable_stubs: { dists: [ { + targets: ["sdk"], + dir: "apistubs/android/module-lib/api", + dest: "android-non-updatable.txt", tag: ".exportable.api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/module-lib/api", + dest: "android-non-updatable-removed.txt", tag: ".exportable.removed-api.txt", }, ], conditions_default: { dists: [ { + targets: ["sdk"], + dir: "apistubs/android/module-lib/api", + dest: "android-non-updatable.txt", tag: ".api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/module-lib/api", + dest: "android-non-updatable-removed.txt", tag: ".removed-api.txt", }, ], diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index f64418587918..eaa23b9db166 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3727,12 +3727,6 @@ public final class ActivityThread extends ClientTransactionHandler return mActivities.get(token); } - @Nullable - @Override - public Context getWindowContext(@NonNull IBinder clientToken) { - return WindowTokenClientController.getInstance().getWindowContext(clientToken); - } - @VisibleForTesting(visibility = PACKAGE) public Configuration getConfiguration() { return mConfigurationController.getConfiguration(); diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java index 308178c8e57b..76d6547c2b70 100644 --- a/core/java/android/app/AutomaticZenRule.java +++ b/core/java/android/app/AutomaticZenRule.java @@ -671,7 +671,7 @@ public final class AutomaticZenRule implements Parcelable { private String mName; private ComponentName mOwner; private Uri mConditionId; - private int mInterruptionFilter; + private int mInterruptionFilter = NotificationManager.INTERRUPTION_FILTER_PRIORITY; private boolean mEnabled = true; private ComponentName mConfigurationActivity = null; private ZenPolicy mPolicy = null; diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java index 01153c9e7efc..f0c319673ade 100644 --- a/core/java/android/app/ClientTransactionHandler.java +++ b/core/java/android/app/ClientTransactionHandler.java @@ -23,7 +23,6 @@ import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.DestroyActivityItem; import android.app.servertransaction.PendingTransactionActions; import android.app.servertransaction.TransactionExecutor; -import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.res.Configuration; @@ -32,7 +31,6 @@ import android.util.MergedConfiguration; import android.view.SurfaceControl; import android.window.ActivityWindowInfo; import android.window.SplashScreenView.SplashScreenViewParcelable; -import android.window.WindowContext; import android.window.WindowContextInfo; import com.android.internal.annotations.VisibleForTesting; @@ -90,10 +88,6 @@ public abstract class ClientTransactionHandler { /** Get activity instance for the token. */ public abstract Activity getActivity(IBinder token); - /** Gets the {@link WindowContext} instance for the token. */ - @Nullable - public abstract Context getWindowContext(@NonNull IBinder clientToken); - // Prepare phase related logic and handlers. Methods that inform about about pending changes or // do other internal bookkeeping. diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index d9e0413e5ad5..dbde7d20f0d8 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -2655,8 +2655,16 @@ public class Notification implements Parcelable if (mAllowlistToken == null) { mAllowlistToken = processAllowlistToken; } - // Propagate this token to all pending intents that are unmarshalled from the parcel. - parcel.setClassCookie(PendingIntent.class, mAllowlistToken); + if (Flags.secureAllowlistToken()) { + // Propagate this token to all pending intents that are unmarshalled from the parcel, + // or keep the one we're already propagating, if that's the case. + if (!parcel.hasClassCookie(PendingIntent.class)) { + parcel.setClassCookie(PendingIntent.class, mAllowlistToken); + } + } else { + // Propagate this token to all pending intents that are unmarshalled from the parcel. + parcel.setClassCookie(PendingIntent.class, mAllowlistToken); + } when = parcel.readLong(); creationTime = parcel.readLong(); @@ -3210,9 +3218,29 @@ public class Notification implements Parcelable PendingIntent.addOnMarshaledListener(addedListener); } try { - // IMPORTANT: Add marshaling code in writeToParcelImpl as we - // want to intercept all pending events written to the parcel. - writeToParcelImpl(parcel, flags); + if (Flags.secureAllowlistToken()) { + boolean mustClearCookie = false; + if (!parcel.hasClassCookie(Notification.class)) { + // This is the "root" notification, and not an "inner" notification (including + // publicVersion or anything else that might be embedded in extras). + parcel.setClassCookie(Notification.class, this); + mustClearCookie = true; + } + try { + // IMPORTANT: Add marshaling code in writeToParcelImpl as we + // want to intercept all pending events written to the parcel. + writeToParcelImpl(parcel, flags); + } finally { + if (mustClearCookie) { + parcel.removeClassCookie(Notification.class, this); + } + } + } else { + // IMPORTANT: Add marshaling code in writeToParcelImpl as we + // want to intercept all pending events written to the parcel. + writeToParcelImpl(parcel, flags); + } + synchronized (this) { // Must be written last! parcel.writeArraySet(allPendingIntents); @@ -3227,7 +3255,19 @@ public class Notification implements Parcelable private void writeToParcelImpl(Parcel parcel, int flags) { parcel.writeInt(1); - parcel.writeStrongBinder(mAllowlistToken); + if (Flags.secureAllowlistToken()) { + Notification rootNotification = (Notification) parcel.getClassCookie( + Notification.class); + if (rootNotification != null && rootNotification != this) { + // Always use the same token as the root notification + parcel.writeStrongBinder(rootNotification.mAllowlistToken); + } else { + parcel.writeStrongBinder(mAllowlistToken); + } + } else { + parcel.writeStrongBinder(mAllowlistToken); + } + parcel.writeLong(when); parcel.writeLong(creationTime); if (mSmallIcon == null && icon != 0) { @@ -3620,18 +3660,23 @@ public class Notification implements Parcelable * Sets the token used for background operations for the pending intents associated with this * notification. * - * This token is automatically set during deserialization for you, you usually won't need to - * call this unless you want to change the existing token, if any. + * Note: Should <em>only</em> be invoked by NotificationManagerService, since this is normally + * populated by unparceling (and also used there). Any other usage is suspect. * * @hide */ - public void clearAllowlistToken() { - mAllowlistToken = null; + public void overrideAllowlistToken(IBinder token) { + mAllowlistToken = token; if (publicVersion != null) { - publicVersion.clearAllowlistToken(); + publicVersion.overrideAllowlistToken(token); } } + /** @hide */ + public IBinder getAllowlistToken() { + return mAllowlistToken; + } + /** * @hide */ diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig index 1f6ac2efd64f..250953e61137 100644 --- a/core/java/android/app/notification.aconfig +++ b/core/java/android/app/notification.aconfig @@ -74,6 +74,16 @@ flag { } flag { + name: "secure_allowlist_token" + namespace: "systemui" + description: "Prevents allowlist_token from leaking out and foreign tokens from being accepted" + bug: "328254922" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "update_ranking_time" namespace: "systemui" description: "Updates notification sorting criteria to highlight new content while maintaining stability" diff --git a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java index 631772556879..11d7ff86ce3d 100644 --- a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java +++ b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java @@ -23,7 +23,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; -import android.content.Context; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.os.IBinder; @@ -60,12 +59,6 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem { Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); } - @Nullable - @Override - public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { - return client.getActivity(getActivityToken()); - } - // ObjectPoolItem implementation private ActivityConfigurationChangeItem() {} diff --git a/core/java/android/app/servertransaction/ActivityRelaunchItem.java b/core/java/android/app/servertransaction/ActivityRelaunchItem.java index 6da871a74383..45bf235de2cd 100644 --- a/core/java/android/app/servertransaction/ActivityRelaunchItem.java +++ b/core/java/android/app/servertransaction/ActivityRelaunchItem.java @@ -23,7 +23,6 @@ import android.annotation.Nullable; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; import android.app.ResultInfo; -import android.content.Context; import android.content.res.CompatibilityInfo; import android.os.IBinder; import android.os.Parcel; @@ -88,12 +87,6 @@ public class ActivityRelaunchItem extends ActivityTransactionItem { client.reportRelaunch(r); } - @Nullable - @Override - public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { - return client.getActivity(getActivityToken()); - } - // ObjectPoolItem implementation private ActivityRelaunchItem() {} diff --git a/core/java/android/app/servertransaction/ClientTransactionItem.java b/core/java/android/app/servertransaction/ClientTransactionItem.java index 6e7e93009993..99ebe1b975a4 100644 --- a/core/java/android/app/servertransaction/ClientTransactionItem.java +++ b/core/java/android/app/servertransaction/ClientTransactionItem.java @@ -24,7 +24,6 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ClientTransactionHandler; -import android.content.Context; import android.os.IBinder; import android.os.Parcelable; @@ -53,16 +52,6 @@ public abstract class ClientTransactionItem implements BaseClientRequest, Parcel return true; } - // TODO(b/260873529): cleanup - /** - * If this {@link ClientTransactionItem} is updating configuration, returns the {@link Context} - * it is updating; otherwise, returns {@code null}. - */ - @Nullable - public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { - return null; - } - /** * Returns the activity token if this transaction item is activity-targeting. Otherwise, * returns {@code null}. diff --git a/core/java/android/app/servertransaction/ConfigurationChangeItem.java b/core/java/android/app/servertransaction/ConfigurationChangeItem.java index 0e327a7627d1..22da706cc7f4 100644 --- a/core/java/android/app/servertransaction/ConfigurationChangeItem.java +++ b/core/java/android/app/servertransaction/ConfigurationChangeItem.java @@ -18,9 +18,7 @@ package android.app.servertransaction; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.ActivityThread; import android.app.ClientTransactionHandler; -import android.content.Context; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.os.Parcel; @@ -48,12 +46,6 @@ public class ConfigurationChangeItem extends ClientTransactionItem { client.handleConfigurationChanged(mConfiguration, mDeviceId); } - @Nullable - @Override - public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { - return ActivityThread.currentApplication(); - } - // ObjectPoolItem implementation private ConfigurationChangeItem() {} diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java index f02cb212276b..7dcbebaeba0b 100644 --- a/core/java/android/app/servertransaction/LaunchActivityItem.java +++ b/core/java/android/app/servertransaction/LaunchActivityItem.java @@ -24,14 +24,12 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityClient; import android.app.ActivityOptions.SceneTransitionInfo; -import android.app.ActivityThread; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; import android.app.IActivityClientController; import android.app.ProfilerInfo; import android.app.ResultInfo; import android.compat.annotation.UnsupportedAppUsage; -import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.CompatibilityInfo; @@ -121,13 +119,6 @@ public class LaunchActivityItem extends ClientTransactionItem { client.countLaunchingActivities(-1); } - @Nullable - @Override - public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { - // LaunchActivityItem may update the global config with #mCurConfig. - return ActivityThread.currentApplication(); - } - // ObjectPoolItem implementation private LaunchActivityItem() {} diff --git a/core/java/android/app/servertransaction/MoveToDisplayItem.java b/core/java/android/app/servertransaction/MoveToDisplayItem.java index 0702c4594075..8706edd26406 100644 --- a/core/java/android/app/servertransaction/MoveToDisplayItem.java +++ b/core/java/android/app/servertransaction/MoveToDisplayItem.java @@ -22,7 +22,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; -import android.content.Context; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.os.IBinder; @@ -59,12 +58,6 @@ public class MoveToDisplayItem extends ActivityTransactionItem { Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); } - @Nullable - @Override - public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { - return client.getActivity(getActivityToken()); - } - // ObjectPoolItem implementation private MoveToDisplayItem() {} diff --git a/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java b/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java index cbad92ff3f38..f6a72915e639 100644 --- a/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java +++ b/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java @@ -21,7 +21,6 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ClientTransactionHandler; -import android.content.Context; import android.content.res.Configuration; import android.os.IBinder; import android.os.Parcel; @@ -46,12 +45,6 @@ public class WindowContextInfoChangeItem extends ClientTransactionItem { client.handleWindowContextInfoChanged(mClientToken, mInfo); } - @Nullable - @Override - public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { - return client.getWindowContext(mClientToken); - } - // ObjectPoolItem implementation private WindowContextInfoChangeItem() {} diff --git a/core/java/android/app/servertransaction/WindowStateResizeItem.java b/core/java/android/app/servertransaction/WindowStateResizeItem.java index 1817c5eefb14..da99096f022a 100644 --- a/core/java/android/app/servertransaction/WindowStateResizeItem.java +++ b/core/java/android/app/servertransaction/WindowStateResizeItem.java @@ -22,10 +22,7 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.ActivityThread; import android.app.ClientTransactionHandler; -import android.content.Context; -import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; import android.os.Trace; @@ -59,10 +56,6 @@ public class WindowStateResizeItem extends ClientTransactionItem { /** {@code null} if this is not an Activity window. */ @Nullable - private IBinder mActivityToken; - - /** {@code null} if this is not an Activity window. */ - @Nullable private ActivityWindowInfo mActivityWindowInfo; @Override @@ -86,14 +79,6 @@ public class WindowStateResizeItem extends ClientTransactionItem { Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); } - @Nullable - @Override - public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { - // TODO(b/260873529): dispatch for mActivityToken as well. - // WindowStateResizeItem may update the global config with #mConfiguration. - return ActivityThread.currentApplication(); - } - // ObjectPoolItem implementation private WindowStateResizeItem() {} @@ -103,8 +88,7 @@ public class WindowStateResizeItem extends ClientTransactionItem { @NonNull ClientWindowFrames frames, boolean reportDraw, @NonNull MergedConfiguration configuration, @NonNull InsetsState insetsState, boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, int syncSeqId, - boolean dragResizing, @Nullable IBinder activityToken, - @Nullable ActivityWindowInfo activityWindowInfo) { + boolean dragResizing, @Nullable ActivityWindowInfo activityWindowInfo) { WindowStateResizeItem instance = ObjectPool.obtain(WindowStateResizeItem.class); if (instance == null) { @@ -120,7 +104,6 @@ public class WindowStateResizeItem extends ClientTransactionItem { instance.mDisplayId = displayId; instance.mSyncSeqId = syncSeqId; instance.mDragResizing = dragResizing; - instance.mActivityToken = activityToken; instance.mActivityWindowInfo = activityWindowInfo != null ? new ActivityWindowInfo(activityWindowInfo) : null; @@ -140,7 +123,6 @@ public class WindowStateResizeItem extends ClientTransactionItem { mDisplayId = INVALID_DISPLAY; mSyncSeqId = -1; mDragResizing = false; - mActivityToken = null; mActivityWindowInfo = null; ObjectPool.recycle(this); } @@ -160,7 +142,6 @@ public class WindowStateResizeItem extends ClientTransactionItem { dest.writeInt(mDisplayId); dest.writeInt(mSyncSeqId); dest.writeBoolean(mDragResizing); - dest.writeStrongBinder(mActivityToken); dest.writeTypedObject(mActivityWindowInfo, flags); } @@ -176,7 +157,6 @@ public class WindowStateResizeItem extends ClientTransactionItem { mDisplayId = in.readInt(); mSyncSeqId = in.readInt(); mDragResizing = in.readBoolean(); - mActivityToken = in.readStrongBinder(); mActivityWindowInfo = in.readTypedObject(ActivityWindowInfo.CREATOR); } @@ -209,7 +189,6 @@ public class WindowStateResizeItem extends ClientTransactionItem { && mDisplayId == other.mDisplayId && mSyncSeqId == other.mSyncSeqId && mDragResizing == other.mDragResizing - && Objects.equals(mActivityToken, other.mActivityToken) && Objects.equals(mActivityWindowInfo, other.mActivityWindowInfo); } @@ -226,7 +205,6 @@ public class WindowStateResizeItem extends ClientTransactionItem { result = 31 * result + mDisplayId; result = 31 * result + mSyncSeqId; result = 31 * result + (mDragResizing ? 1 : 0); - result = 31 * result + Objects.hashCode(mActivityToken); result = 31 * result + Objects.hashCode(mActivityWindowInfo); return result; } @@ -236,7 +214,6 @@ public class WindowStateResizeItem extends ClientTransactionItem { return "WindowStateResizeItem{window=" + mWindow + ", reportDrawn=" + mReportDraw + ", configuration=" + mConfiguration - + ", activityToken=" + mActivityToken + ", activityWindowInfo=" + mActivityWindowInfo + "}"; } diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 35a3a5f32648..136c45d1695f 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -863,6 +863,28 @@ public final class Parcel { } /** @hide */ + public void removeClassCookie(Class clz, Object expectedCookie) { + if (mClassCookies != null) { + Object removedCookie = mClassCookies.remove(clz); + if (removedCookie != expectedCookie) { + Log.wtf(TAG, "Expected to remove " + expectedCookie + " (with key=" + clz + + ") but instead removed " + removedCookie); + } + } else { + Log.wtf(TAG, "Expected to remove " + expectedCookie + " (with key=" + clz + + ") but no cookies were present"); + } + } + + /** + * Whether {@link #setClassCookie} has been called with the specified {@code clz}. + * @hide + */ + public boolean hasClassCookie(Class clz) { + return mClassCookies != null && mClassCookies.containsKey(clz); + } + + /** @hide */ public final void adoptClassCookies(Parcel from) { mClassCookies = from.mClassCookies; } diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig index ec3c9789f655..23ece310b926 100644 --- a/core/java/android/permission/flags.aconfig +++ b/core/java/android/permission/flags.aconfig @@ -155,14 +155,3 @@ flag { description: "Use runtime permission state to determine appop state" bug: "266164193" } - -flag { - name: "ignore_apex_permissions" - is_fixed_read_only: true - namespace: "permissions" - description: "Ignore APEX pacakges for permissions on V+" - bug: "301320911" - metadata { - purpose: PURPOSE_BUGFIX - } -} diff --git a/core/java/android/util/PackageUtils.java b/core/java/android/util/PackageUtils.java index ea7efc79de87..c1ed19fef032 100644 --- a/core/java/android/util/PackageUtils.java +++ b/core/java/android/util/PackageUtils.java @@ -203,9 +203,8 @@ public final class PackageUtils { } File f = new File(filePath); - try { - DigestInputStream digestInputStream = new DigestInputStream(new FileInputStream(f), - messageDigest); + try (DigestInputStream digestInputStream = new DigestInputStream(new FileInputStream(f), + messageDigest)) { while (digestInputStream.read(fileBuffer) != -1); } catch (IOException e) { e.printStackTrace(); diff --git a/core/java/android/view/ImeBackAnimationController.java b/core/java/android/view/ImeBackAnimationController.java index d14e858d9fa1..665fac18be99 100644 --- a/core/java/android/view/ImeBackAnimationController.java +++ b/core/java/android/view/ImeBackAnimationController.java @@ -28,6 +28,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Insets; import android.util.Log; +import android.view.animation.BackGestureInterpolator; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; import android.window.BackEvent; @@ -44,7 +45,7 @@ public class ImeBackAnimationController implements OnBackAnimationCallback { private static final int POST_COMMIT_DURATION_MS = 200; private static final int POST_COMMIT_CANCEL_DURATION_MS = 50; private static final float PEEK_FRACTION = 0.1f; - private static final Interpolator STANDARD_DECELERATE = new PathInterpolator(0f, 0f, 0f, 1f); + private static final Interpolator BACK_GESTURE = new BackGestureInterpolator(); private static final Interpolator EMPHASIZED_DECELERATE = new PathInterpolator( 0.05f, 0.7f, 0.1f, 1f); private static final Interpolator STANDARD_ACCELERATE = new PathInterpolator(0.3f, 0f, 1f, 1f); @@ -140,7 +141,7 @@ public class ImeBackAnimationController implements OnBackAnimationCallback { float hiddenY = mWindowInsetsAnimationController.getHiddenStateInsets().bottom; float shownY = mWindowInsetsAnimationController.getShownStateInsets().bottom; float imeHeight = shownY - hiddenY; - float interpolatedProgress = STANDARD_DECELERATE.getInterpolation(progress); + float interpolatedProgress = BACK_GESTURE.getInterpolation(progress); int newY = (int) (imeHeight - interpolatedProgress * (imeHeight * PEEK_FRACTION)); mWindowInsetsAnimationController.setInsetsAndAlpha(Insets.of(0, 0, 0, newY), 1f, progress); diff --git a/core/java/android/view/animation/BackGestureInterpolator.java b/core/java/android/view/animation/BackGestureInterpolator.java new file mode 100644 index 000000000000..c1595db98998 --- /dev/null +++ b/core/java/android/view/animation/BackGestureInterpolator.java @@ -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 android.view.animation; +/** + * Decelerating interpolator with a very slight acceleration phase at the beginning. + * @hide + */ +public class BackGestureInterpolator extends PathInterpolator { + public BackGestureInterpolator() { + super(0.1f, 0.1f, 0f, 1f); + } +} diff --git a/core/java/android/window/RemoteTransitionStub.java b/core/java/android/window/RemoteTransitionStub.java new file mode 100644 index 000000000000..c9932ab31469 --- /dev/null +++ b/core/java/android/window/RemoteTransitionStub.java @@ -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 android.window; + +import android.os.IBinder; +import android.os.RemoteException; +import android.view.SurfaceControl; + +/** + * Utility base implementation of {@link IRemoteTransition} that users can extend to avoid stubbing. + * + * @hide + */ +public abstract class RemoteTransitionStub extends IRemoteTransition.Stub { + @Override + public void mergeAnimation(IBinder transition, TransitionInfo info, + SurfaceControl.Transaction t, IBinder mergeTarget, + IRemoteTransitionFinishedCallback finishCallback) throws RemoteException {} + + @Override + public void onTransitionConsumed(IBinder transition, boolean aborted) + throws RemoteException {} +} diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java index 5227724e705e..994e73288e93 100644 --- a/core/java/android/window/TransitionInfo.java +++ b/core/java/android/window/TransitionInfo.java @@ -538,6 +538,11 @@ public final class TransitionInfo implements Parcelable { // If the change has no parent (it is root), then it is independent if (change.getParent() == null) return true; + if (change.getLastParent() != null && !change.getLastParent().equals(change.getParent())) { + // If the change has been reparented, then it's independent. + return true; + } + // non-visibility changes will just be folded into the parent change, so they aren't // independent either. if (change.getMode() == TRANSIT_CHANGE) return false; diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index 76a34aec7e58..4148e00e6302 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -88,6 +88,19 @@ public final class WindowContainerTransaction implements Parcelable { } /** + * Clear the transaction object. + * This is equivalent to a new empty {@link WindowContainerTransaction} in content. + * + * @hide + */ + public void clear() { + mChanges.clear(); + mHierarchyOps.clear(); + mErrorCallbackToken = null; + mTaskFragmentOrganizer = null; + } + + /** * Resize a container. */ @NonNull diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java index 2a52264515fc..8aba36bec6f5 100644 --- a/core/java/com/android/internal/os/BatteryStatsHistory.java +++ b/core/java/com/android/internal/os/BatteryStatsHistory.java @@ -582,23 +582,6 @@ public class BatteryStatsHistory { * @param maxHistoryFiles the largest number of history buffer files to keep * @param maxHistoryBufferSize the most amount of RAM to used for buffering of history steps */ - public BatteryStatsHistory(File systemDir, int maxHistoryFiles, int maxHistoryBufferSize, - HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock, - MonotonicClock monotonicClock) { - this(systemDir, maxHistoryFiles, maxHistoryBufferSize, - stepDetailsCalculator, clock, monotonicClock, new TraceDelegate(), - new EventLogger()); - } - - public BatteryStatsHistory(File systemDir, int maxHistoryFiles, int maxHistoryBufferSize, - HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock, - MonotonicClock monotonicClock, TraceDelegate tracer, EventLogger eventLogger) { - this(Parcel.obtain(), systemDir, maxHistoryFiles, maxHistoryBufferSize, - stepDetailsCalculator, clock, monotonicClock, tracer, eventLogger); - initHistoryBuffer(); - } - - @VisibleForTesting public BatteryStatsHistory(Parcel historyBuffer, File systemDir, int maxHistoryFiles, int maxHistoryBufferSize, HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock, @@ -607,12 +590,11 @@ public class BatteryStatsHistory { clock, monotonicClock, tracer, eventLogger, null); } - private BatteryStatsHistory(Parcel historyBuffer, File systemDir, + private BatteryStatsHistory(@Nullable Parcel historyBuffer, @Nullable File systemDir, int maxHistoryFiles, int maxHistoryBufferSize, - HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock, - MonotonicClock monotonicClock, TraceDelegate tracer, EventLogger eventLogger, - BatteryStatsHistory writableHistory) { - mHistoryBuffer = historyBuffer; + @NonNull HistoryStepDetailsCalculator stepDetailsCalculator, @NonNull Clock clock, + @NonNull MonotonicClock monotonicClock, @NonNull TraceDelegate tracer, + @NonNull EventLogger eventLogger, @Nullable BatteryStatsHistory writableHistory) { mSystemDir = systemDir; mMaxHistoryBufferSize = maxHistoryBufferSize; mStepDetailsCalculator = stepDetailsCalculator; @@ -625,9 +607,16 @@ public class BatteryStatsHistory { mMutable = false; } + if (historyBuffer != null) { + mHistoryBuffer = historyBuffer; + } else { + mHistoryBuffer = Parcel.obtain(); + initHistoryBuffer(); + } + if (writableHistory != null) { mHistoryDir = writableHistory.mHistoryDir; - } else { + } else if (systemDir != null) { mHistoryDir = new BatteryHistoryDirectory(new File(systemDir, HISTORY_DIR), monotonicClock, maxHistoryFiles); mHistoryDir.load(); @@ -636,35 +625,11 @@ public class BatteryStatsHistory { activeFile = mHistoryDir.makeBatteryHistoryFile(); } setActiveFile(activeFile); + } else { + mHistoryDir = null; } } - public BatteryStatsHistory(int maxHistoryBufferSize, - HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock, - MonotonicClock monotonicClock) { - this(maxHistoryBufferSize, stepDetailsCalculator, clock, monotonicClock, - new TraceDelegate(), new EventLogger()); - } - - @VisibleForTesting - public BatteryStatsHistory(int maxHistoryBufferSize, - HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock, - MonotonicClock monotonicClock, TraceDelegate traceDelegate, - EventLogger eventLogger) { - mMaxHistoryBufferSize = maxHistoryBufferSize; - mStepDetailsCalculator = stepDetailsCalculator; - mTracer = traceDelegate; - mClock = clock; - mMonotonicClock = monotonicClock; - mEventLogger = eventLogger; - - mHistoryBuffer = Parcel.obtain(); - mSystemDir = null; - mHistoryDir = null; - mWritableHistory = null; - initHistoryBuffer(); - } - /** * Used when BatteryStatsHistory object is created from deserialization of a BatteryUsageStats * parcel. 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 8c7b360a3fcd..97ce96ec30f6 100644 --- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java +++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java @@ -1054,8 +1054,7 @@ public class ParsingPackageUtils { // An Apex package shouldn't have permission declarations final boolean isApex = (flags & PARSE_APEX) != 0; - if (android.permission.flags.Flags.ignoreApexPermissions() - && isApex && !pkg.getPermissions().isEmpty()) { + if (isApex && !pkg.getPermissions().isEmpty()) { return input.error( INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, pkg.getPackageName() diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index f5b1a47e917e..f931a762871c 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -28,6 +28,7 @@ import android.media.INearbyMediaDevicesProvider; import android.media.MediaRoute2Info; import android.os.Bundle; import android.os.ParcelFileDescriptor; +import android.os.UserHandle; import android.view.KeyEvent; import android.service.notification.StatusBarNotification; @@ -384,9 +385,11 @@ oneway interface IStatusBar /** * Shows the media output switcher dialog. * - * @param packageName of the session for which the output switcher is shown. + * @param targetPackageName The package name for which to show the output switcher. + * @param targetUserHandle The UserHandle on which the package for which to show the output + * switcher is running. */ - void showMediaOutputSwitcher(String packageName); + void showMediaOutputSwitcher(String targetPackageName, in UserHandle targetUserHandle); /** Enters desktop mode from the current focused app. * diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 63cd6b941178..08418611d902 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -259,7 +259,7 @@ <string name="global_action_emergency" msgid="1387617624177105088">"Noodgeval"</string> <string name="global_action_bug_report" msgid="5127867163044170003">"Foutverslag"</string> <string name="global_action_logout" msgid="6093581310002476511">"Beëindig sessie"</string> - <string name="global_action_screenshot" msgid="2610053466156478564">"Skermkiekie"</string> + <string name="global_action_screenshot" msgid="2610053466156478564">"Skermskoot"</string> <string name="bugreport_title" msgid="8549990811777373050">"Foutverslag"</string> <string name="bugreport_message" msgid="5212529146119624326">"Dit sal inligting oor die huidige toestand van jou toestel insamel om as \'n e-posboodskap te stuur. Dit sal \'n tydjie neem vandat die foutverslag begin is totdat dit reg is om gestuur te word; wees asseblief geduldig."</string> <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiewe verslag"</string> @@ -1426,7 +1426,7 @@ <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tik om taal en uitleg te kies"</string> <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Wys bo-oor ander programme"</string> + <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Wys bo-oor ander apps"</string> <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> word bo-oor ander programme gewys"</string> <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> wys bo-oor ander programme"</string> <string name="alert_windows_notification_message" msgid="6538171456970725333">"As jy nie wil hê dat <xliff:g id="NAME">%s</xliff:g> hierdie kenmerk gebruik nie, tik om instellings oop te maak en skakel dit af."</string> @@ -1929,12 +1929,9 @@ <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Bestuur deur <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aan"</string> <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Af"</string> - <!-- no translation found for zen_mode_trigger_summary_divider_text (7461583466043698862) --> - <skip /> - <!-- no translation found for zen_mode_trigger_summary_range_symbol_combination (1804900738798069619) --> - <skip /> - <!-- no translation found for zen_mode_trigger_event_calendar_any (2086784607921121803) --> - <skip /> + <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string> + <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string> + <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Enige kalender"</string> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> demp sekere klanke"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Daar is \'n interne probleem met jou toestel en dit sal dalk onstabiel wees totdat jy \'n fabriekterugstelling doen."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Daar is \'n interne probleem met jou toestel. Kontak jou vervaardiger vir besonderhede."</string> @@ -1973,7 +1970,7 @@ <string name="default_notification_channel_label" msgid="3697928973567217330">"Ongekategoriseer"</string> <string name="importance_from_user" msgid="2782756722448800447">"Jy stel die belangrikheid van hierdie kennisgewings."</string> <string name="importance_from_person" msgid="4235804979664465383">"Dit is belangrik as gevolg van die mense wat betrokke is."</string> - <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Gepasmaakte programkennisgewing"</string> + <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Gepasmaakte appkennisgewing"</string> <string name="user_creation_account_exists" msgid="2239146360099708035">"Laat <xliff:g id="APP">%1$s</xliff:g> toe om \'n nuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> te skep (\'n gebruiker met hierdie rekening bestaan reeds)?"</string> <string name="user_creation_adding" msgid="7305185499667958364">"Laat <xliff:g id="APP">%1$s</xliff:g> toe om \'n nuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> te skep?"</string> <string name="supervised_user_creation_label" msgid="6884904353827427515">"Voeg gebruiker onder toesig by"</string> @@ -2179,7 +2176,7 @@ <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Kitsinstellings"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Kragdialoog"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Sluitskerm"</string> - <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skermkiekie"</string> + <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skermskoot"</string> <string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Kopstuk haak"</string> <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Toeganklikheidkortpad op skerm"</string> <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Toeganklikheidkortpadkieser op skerm"</string> @@ -2397,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Toets"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Gemeenskaplik"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Appinhoud is weens sekuriteit van skermdeling verberg"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Outomaties aan satelliet gekoppel"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Jy kan boodskappe stuur en ontvang sonder ’n selfoon- of wi-fi-netwerk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Maak Boodskappe oop"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 799a7ab95a8d..86df6505ce44 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1894,7 +1894,7 @@ <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>ን አባዛ"</string> <string name="private_profile_label_badge" msgid="1712086003787839183">"የግል <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ከመንቀል በፊት ፒን ጠይቅ"</string> - <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ከመንቀል በፊት የማስከፈቻ ስርዓተ-ጥለት ጠይቅ"</string> + <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ከመንቀል በፊት የማስከፈቻ ሥርዓተ-ጥለት ጠይቅ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ከመንቀል በፊት የይለፍ ቃል ጠይቅ"</string> <string name="package_installed_device_owner" msgid="7035926868974878525">"በእርስዎ አስተዳዳሪ ተጭኗል"</string> <string name="package_updated_device_owner" msgid="7560272363805506941">"በእርስዎ አስተዳዳሪ ተዘምኗል"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ለደኅንነት ሲባል የመተግበሪያ ይዘት ከማያ ገጽ ማጋራት ተደብቋል"</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> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index fad2cd68274d..58ec95ab6c25 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -999,7 +999,7 @@ <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"صحيح!"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"أعد المحاولة"</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"أعد المحاولة"</string> - <string name="lockscreen_storage_locked" msgid="634993789186443380">"فتح قفل جميع الميزات والبيانات"</string> + <string name="lockscreen_storage_locked" msgid="634993789186443380">"فتح القفل للوصول إلى جميع الميزات والبيانات"</string> <string name="faceunlock_multiple_failures" msgid="681991538434031708">"تم تجاوز الحد الأقصى لعدد محاولات فتح الجهاز بالتعرف على الوجه"</string> <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"لا تتوفر شريحة SIM."</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"لا تتوفر شريحة SIM في الجهاز اللوحي."</string> @@ -1401,7 +1401,7 @@ <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"تم اكتشاف ملحق صوتي تناظري"</string> <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"الجهاز الذي تم توصيله بالهاتف غير متوافق معه. انقر للحصول على المزيد من المعلومات."</string> <string name="adb_active_notification_title" msgid="408390247354560331">"تم توصيل USB لتصحيح أخطاء الجهاز"</string> - <string name="adb_active_notification_message" msgid="5617264033476778211">"انقر لإيقاف تصحيح أخطاء الجهاز عبر USB."</string> + <string name="adb_active_notification_message" msgid="5617264033476778211">"انقر لإيقاف تصحيح أخطاء الجهاز عبر USB"</string> <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"اختيار إيقاف تصحيح أخطاء USB."</string> <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"تم تفعيل ميزة \"تصحيح الأخطاء اللاسلكي\"."</string> <string name="adbwifi_active_notification_message" msgid="930987922852867972">"انقر لإيقاف ميزة \"تصحيح الأخطاء اللاسلكي\"."</string> @@ -1660,7 +1660,7 @@ <string name="media_route_button_content_description" msgid="2299223698196869956">"البث"</string> <string name="media_route_chooser_title" msgid="6646594924991269208">"الاتصال بجهاز"</string> <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"بث الشاشة على الجهاز"</string> - <string name="media_route_chooser_searching" msgid="6119673534251329535">"جارٍ البحث عن الأجهزة…"</string> + <string name="media_route_chooser_searching" msgid="6119673534251329535">"جارٍ البحث عن أجهزة…"</string> <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"الإعدادات"</string> <string name="media_route_controller_disconnect" msgid="7362617572732576959">"قطع الاتصال"</string> <string name="media_route_status_scanning" msgid="8045156315309594482">"البحث عن الشبكات..."</string> @@ -1906,7 +1906,7 @@ <string name="confirm_battery_saver" msgid="5247976246208245754">"حسنًا"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"يؤدي استخدام ميزة \"توفير شحن البطارية\" إلى تفعيل وضع \"المظهر الداكن\" وتقييد أو إيقاف الأنشطة في الخلفية وبعض التأثيرات المرئية وميزات معيّنة وبعض اتصالات الشبكات."</string> <string name="battery_saver_description" msgid="8518809702138617167">"يؤدي استخدام ميزة \"توفير شحن البطارية\" إلى تفعيل وضع \"المظهر الداكن\" وتقييد أو إيقاف الأنشطة في الخلفية وبعض التأثيرات المرئية وميزات معيّنة وبعض اتصالات الشبكات."</string> - <string name="data_saver_description" msgid="4995164271550590517">"للمساعدة في خفض استخدام البيانات، تمنع ميزة \"توفير البيانات\" بعض التطبيقات من إرسال البيانات وتلقّيها في الخلفية. يمكن للتطبيقات المتاحة لديك الآن استخدام البيانات، ولكن لا يمكنها الإكثار من ذلك. وهذا يعني أن الصور مثلاً لا تظهر حتى تنقر عليها."</string> + <string name="data_saver_description" msgid="4995164271550590517">"للمساعدة في خفض استخدام البيانات، تمنع ميزة \"توفير البيانات\" بعض التطبيقات من إرسال البيانات وتلقّيها في الخلفية. يمكن للتطبيقات المتاحة لديك الآن استخدام البيانات، ولكن بمعدّل أقل. وهذا يعني أن الصور مثلاً لن تظهر حتى تنقر عليها."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"هل تريد تفعيل ميزة \"توفير البيانات\"؟"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"تفعيل"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{لمدة دقيقة واحدة (حتى {formattedTime})}zero{لمدة # دقيقة (حتى {formattedTime})}two{لمدة دقيقتين (حتى {formattedTime})}few{لمدة # دقائق (حتى {formattedTime})}many{لمدة # دقيقة (حتى {formattedTime})}other{لمدة # دقيقة (حتى {formattedTime})}}"</string> @@ -2398,8 +2398,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"تم إخفاء محتوى التطبيق بعد تفعيل ميزة \"مشاركة الشاشة\" للحفاظ على أمانك"</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> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 8b3f8324af20..618c5816fdd5 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -1726,7 +1726,7 @@ <string name="accessibility_service_warning_description" msgid="291674995220940133">"আপোনাক সাধ্য সুবিধাৰ প্ৰয়োজনসমূহৰ জৰিয়তে সহায় কৰা এপ্সমূহৰ বাবে সম্পূর্ণ নিয়ন্ত্ৰণৰ সুবিধাটো সঠিক যদিও অধিকাংশ এপৰ বাবে এয়া সঠিক নহয়।"</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"চাওক আৰু স্ক্ৰীন নিয়ন্ত্ৰণ কৰক"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ই স্ক্ৰীনত থকা আটাইখিনি সমল পঢ়িব পাৰে আৰু অন্য এপ্সমূহৰ ওপৰত সমল প্ৰদর্শন কৰিব পাৰে।"</string> - <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"কার্যসমূহ চাওক আৰু কৰক"</string> + <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"কার্যসমূহ চোৱা আৰু কৰা"</string> <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ই আপুনি কোনো এপ্ বা হার্ডৱেৰ ছেন্সৰৰ সৈতে কৰা ভাব-বিনিময় আৰু আপোনাৰ হৈ অন্য কোনো লোকে এপৰ সৈতে কৰা ভাব-বিনিময় ট্ৰেক কৰিব পাৰে।"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"অনুমতি দিয়ক"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"অস্বীকাৰ কৰক"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"সুৰক্ষাৰ বাবে এপৰ সমল স্ক্ৰীণ শ্বেয়াৰ কৰাৰ পৰা লুকুৱাই ৰখা হৈছে"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"উপগ্ৰহৰ সৈতে স্বয়ংক্ৰিয়ভাৱে সংযুক্ত হৈছে"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"আপুনি ম’বাইল বা ৱাই-ফাই নেটৱৰ্কৰ জৰিয়তে পাঠ বাৰ্তা পঠিয়াব বা লাভ কৰিব পাৰে"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খোলক"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index c0b886be2097..643c5cbc6eb9 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Kommunal"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Güvənlik üçün tətbiq kontenti ekran paylaşımından gizlədildi"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Peykə avtomatik qoşulub"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil və ya Wi-Fi şəbəkəsi olmadan mesaj göndərə və qəbul edə bilərsiniz"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajı açın"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index a275cab86042..06b6a13a184d 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -1223,7 +1223,7 @@ <string name="whichEditApplicationLabel" msgid="1463288652070140285">"Izmeni"</string> <string name="whichSendApplication" msgid="4143847974460792029">"Delite"</string> <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Delite pomoću aplikacije %1$s"</string> - <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Deli"</string> + <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Deljenje"</string> <string name="whichSendToApplication" msgid="77101541959464018">"Pošaljite pomoću:"</string> <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Pošaljite pomoću: %1$s"</string> <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Pošalji"</string> @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Zajedničko"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Sadržaj aplikacije je skriven za deljenje sadržaja ekrana zbog bezbednosti"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatski povezano sa satelitom"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete da šaljete i primate poruke bez mobilne ili WiFi mreže"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Messages"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index c0d930f2173a..43c73d146756 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -2396,8 +2396,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Змесціва праграмы выключана з абагульвання экрана ў мэтах бяспекі"</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> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 5c793e582cb1..181e6129acff 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Съдържанието на приложението е скрито от функцията за споделяне на екрана от съображения за сигурност"</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">"Отваряне на Messages"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 894660759c67..958346192a00 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -1743,7 +1743,7 @@ <string name="color_inversion_feature_name" msgid="2672824491933264951">"কালার ইনভার্সন"</string> <string name="color_correction_feature_name" msgid="7975133554160979214">"রঙ সংশোধন করা"</string> <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"এক হাতে ব্যবহার করার মোড"</string> - <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"অতিরিক্ত কম ব্রাইটনেস"</string> + <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"অতিরিক্ত কম উজ্জ্বলতা"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"হিয়ারিং ডিভাইস"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করা হয়েছে।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> বন্ধ করা হয়েছে।"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"নিরাপত্তার জন্য স্ক্রিন শেয়ার করা থেকে লুকানো অ্যাপের কন্টেন্ট"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"স্যাটেলাইটের সাথে অটোমেটিক কানেক্ট করা হয়েছে"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"আপনি কোনও মেবাইল বা ওয়াই-ফাই নেটওয়ার্ক ছাড়াই মেসেজ পাঠাতে ও পেতে পারবেন"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খুলুন"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 2d08a22dbc06..170f84e1b3bd 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Testno"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Opće"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Sadržaj aplikacije je sakriven od dijeljenja ekrana radi sigurnosti"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatski je povezano sa satelitom"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete slati i primati poruke bez mobilne ili WiFi mreže"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvorite Messages"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 263d12982dd1..ae4fbcf52d51 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -842,10 +842,10 @@ <string name="policylab_forceLock" msgid="7360335502968476434">"Bloquejar la pantalla"</string> <string name="policydesc_forceLock" msgid="1008844760853899693">"Controla com i quan es bloqueja la pantalla."</string> <string name="policylab_wipeData" msgid="1359485247727537311">"Esborrar totes les dades"</string> - <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Esborra les dades de la tauleta sense avisar, i restableix les dades de fàbrica."</string> + <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Esborra les dades de la tauleta sense avisar mitjançant el restabliment de les dades de fàbrica."</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Suprimeix les dades del dispositiu Android TV sense previ avís mitjançant el restabliment de les dades de fàbrica."</string> <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Esborra les dades del sistema d\'informació i entreteniment sense avisar mitjançant el restabliment de les dades de fàbrica."</string> - <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Esborra les dades del telèfon sense avisar, i restableix les dades de fàbrica."</string> + <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Esborra les dades del telèfon sense avisar mitjançant el restabliment de les dades de fàbrica."</string> <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Esborra les dades del perfil"</string> <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Esborrar les dades de l\'usuari"</string> <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Esborra les dades de l\'usuari desades a la tauleta sense avisar-ne."</string> @@ -996,7 +996,7 @@ <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correcte!"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Torna-ho a provar"</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Torna-ho a provar"</string> - <string name="lockscreen_storage_locked" msgid="634993789186443380">"Desbl. per accedir a totes les funcions i dades"</string> + <string name="lockscreen_storage_locked" msgid="634993789186443380">"Desbloqueja per accedir a les funcions i dades"</string> <string name="faceunlock_multiple_failures" msgid="681991538434031708">"S\'ha superat el nombre màxim d\'intents de Desbloqueig facial"</string> <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"No hi ha cap SIM"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"No hi ha cap SIM a la tauleta."</string> @@ -2032,7 +2032,7 @@ <string name="pin_specific_target" msgid="7824671240625957415">"Fixa <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="unpin_target" msgid="3963318576590204447">"No fixis"</string> <string name="unpin_specific_target" msgid="3859828252160908146">"No fixis <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="app_info" msgid="6113278084877079851">"Informació de l\'aplicació"</string> + <string name="app_info" msgid="6113278084877079851">"Informació de l\'app"</string> <string name="negative_duration" msgid="1938335096972945232">"-<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="6577581216125805905">"S\'està iniciant la demostració…"</string> <string name="demo_restarting_message" msgid="1160053183701746766">"S\'està restablint el dispositiu…"</string> @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Prova"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Compartit"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contingut de l\'aplicació amagat de la compartició de pantalla per motius de seguretat"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"S\'ha connectat automàticament a un satèl·lit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Pots enviar i rebre missatges sense una xarxa mòbil o Wi‑Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Obre Missatges"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index a8ad54362866..4318608f40e7 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -833,16 +833,16 @@ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Sledovat počet nesprávných hesel zadaných při odemykání obrazovky a uzamknout tablet nebo vymazat z tabletu všechna data, pokud bylo zadáno příliš mnoho nesprávných hesel."</string> <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Sledovat počet nesprávných hesel zadaných při odemykání obrazovky, a pokud jich bude zadáno příliš mnoho, uzamknout zařízení Android TV nebo z něj vymazat všechna data."</string> <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Monitorovat počet nesprávných hesel zadaných při odemykání obrazovky a uzamknout informační a zábavní systém nebo vymazat veškerá data v informačním a zábavním systému, pokud je zadáno příliš mnoho nesprávných hesel."</string> - <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Sledovat počet nesprávných hesel zadaných při odemykání obrazovky a uzamknout telefon nebo vymazat z telefonu všechna data, pokud bylo zadáno příliš mnoho nesprávných hesel."</string> + <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Sleduje počet nesprávných hesel zadaných při odemykání obrazovky a uzamkne telefon nebo vymaže z telefonu všechna data, pokud bylo zadáno příliš mnoho nesprávných hesel."</string> <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Monitorovat počet nesprávných hesel zadaných při odemykání obrazovky, a pokud je zadáno příliš mnoho nesprávných hesel, uzamknout tablet nebo vymazat veškerá data uživatele."</string> <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Sledovat počet nesprávných hesel zadaných při odemykání obrazovky, a pokud jich bude zadáno příliš mnoho, uzamknout zařízení Android TV nebo z něj vymazat všechna data tohoto uživatele."</string> <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Monitorovat počet nesprávných hesel zadaných při odemykání obrazovky, a pokud je zadáno příliš mnoho nesprávných hesel, uzamknout informační a zábavní systém nebo vymazat veškerá data profilu."</string> - <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Monitorovat počet nesprávných hesel zadaných při odemykání obrazovky, a pokud je zadáno příliš mnoho nesprávných hesel, uzamknout telefon nebo vymazat veškerá data uživatele."</string> + <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Monitoruje počet nesprávných hesel zadaných při odemykání obrazovky, a pokud je zadáno příliš mnoho nesprávných hesel, uzamkne telefon nebo vymaže veškerá data uživatele."</string> <string name="policylab_resetPassword" msgid="214556238645096520">"Změnit zámek obrazovky"</string> <string name="policydesc_resetPassword" msgid="4626419138439341851">"Změní se zámek obrazovky."</string> <string name="policylab_forceLock" msgid="7360335502968476434">"Uzamknout obrazovku"</string> <string name="policydesc_forceLock" msgid="1008844760853899693">"Určíte, jak a kdy se obrazovka uzamkne."</string> - <string name="policylab_wipeData" msgid="1359485247727537311">"Vymazat všechna data"</string> + <string name="policylab_wipeData" msgid="1359485247727537311">"Mazat všechna data"</string> <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Bez upozornění smazat všechna data tabletu obnovením továrních dat."</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Provést obnovení továrních dat a bez upozornění tím vymazat data v zařízení Android TV."</string> <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Bez upozornění se smažou všechna data informačního a zábavního systému obnovením továrních dat."</string> @@ -1727,9 +1727,9 @@ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Chcete službě <xliff:g id="SERVICE">%1$s</xliff:g> povolit plnou kontrolu nad vaším zařízením?"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Plná kontrola je vhodná u aplikací, které vám pomáhají s usnadněním přístupu. U většiny aplikací však vhodná není."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Zobrazení a ovládání obrazovky"</string> - <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Služba může číst veškerý obsah obrazovky a zobrazovat ho přes ostatní aplikace."</string> + <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Služba může číst veškerý obsah obrazovky a zobrazovat ho přes ostatní aplikace."</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Zobrazení a provádění akcí"</string> - <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Služba může sledovat vaše interakce s aplikací nebo hardwarovým senzorem a komunikovat s aplikacemi namísto vás."</string> + <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Služba může sledovat vaše interakce s aplikací nebo hardwarovým senzorem a komunikovat s aplikacemi za vás."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Povolit"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Zakázat"</string> <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Odinstalovat"</string> @@ -1745,7 +1745,7 @@ <string name="color_inversion_feature_name" msgid="2672824491933264951">"Převrácení barev"</string> <string name="color_correction_feature_name" msgid="7975133554160979214">"Korekce barev"</string> <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jedné ruky"</string> - <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Velmi tmavé"</string> + <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Velmi tmavé zobrazení"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Naslouchátka"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> byla vypnuta."</string> @@ -1904,7 +1904,7 @@ <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Spořič baterie zapíná tmavý motiv a omezuje či vypíná aktivitu na pozadí, některé vizuální efekty, některé funkce a připojení k některým sítím."</string> <string name="battery_saver_description" msgid="8518809702138617167">"Spořič baterie zapíná tmavý motiv a omezuje či vypíná aktivitu na pozadí, některé vizuální efekty, některé funkce a připojení k některým sítím."</string> - <string name="data_saver_description" msgid="4995164271550590517">"S cílem snížit spotřebu dat brání spořič dat některým aplikacím odesílat nebo přijímat data na pozadí. Aplikace, kterou právě používáte, data přenášet může, ale může tak činit méně často. V důsledku toho se například obrázky nemusejí zobrazit, dokud na ně neklepnete."</string> + <string name="data_saver_description" msgid="4995164271550590517">"S cílem snížit spotřebu dat brání spořič dat některým aplikacím odesílat nebo přijímat data na pozadí. Aplikace, kterou právě používáte, sice data využívat může, ale méně často. Může to například znamenat, že obrázky se zobrazí, až na ně klepnete."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Chcete zapnout Spořič dat?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Zapnout"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Na jednu minutu (do {formattedTime})}few{Na # minuty (do {formattedTime})}many{Na # minuty (do {formattedTime})}other{Na # minut (do {formattedTime})}}"</string> @@ -2396,8 +2396,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Komunální"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Obsah aplikace je z bezpečnostních důvodů při sdílení obrazovky skryt"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automaticky připojeno k satelitu"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Zprávy můžete odesílat a přijímat bez mobilní sítě nebo sítě Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otevřít Zprávy"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 59be3ddc7e8b..3f830c9d7cf1 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Fælles"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Af sikkerhedsmæssige årsager vises appindhold ikke ved skærmdeling"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Der blev automatisk oprettet forbindelse til satellit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan sende og modtage beskeder uden et mobil- eller Wi-Fi-netværk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Åbn Beskeder"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index b4882febd4a2..1c01cc76cc77 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1929,12 +1929,9 @@ <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Verwaltet von <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"An"</string> <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Aus"</string> - <!-- no translation found for zen_mode_trigger_summary_divider_text (7461583466043698862) --> - <skip /> - <!-- no translation found for zen_mode_trigger_summary_range_symbol_combination (1804900738798069619) --> - <skip /> - <!-- no translation found for zen_mode_trigger_event_calendar_any (2086784607921121803) --> - <skip /> + <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string> + <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string> + <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Alle Kalender"</string> <string name="muted_by" msgid="91464083490094950">"Einige Töne werden von <xliff:g id="THIRD_PARTY">%1$s</xliff:g> stummgeschaltet"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Es liegt ein internes Problem mit deinem Gerät vor. Möglicherweise verhält es sich instabil, bis du es auf die Werkseinstellungen zurücksetzt."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Es liegt ein internes Problem mit deinem Gerät vor. Bitte wende dich diesbezüglich an den Hersteller."</string> @@ -2397,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Gemeinsam genutzt"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App-Inhalte werden aus Sicherheitsgründen bei der Bildschirmfreigabe ausgeblendet"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch mit Satellit verbunden"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kannst Nachrichten ohne Mobilfunknetz oder WLAN senden und empfangen"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages öffnen"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 1b88a6ac809d..cafccf5992b0 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Για λόγους ασφάλειας, έγινε απόκρυψη του περιεχομένου της εφαρμογής από την κοινή χρήση οθόνης"</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">"Άνοιγμα Messages"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 5a6c6200b0e9..11fb50e03869 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App content hidden from screen share for security"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Auto-connected to satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 4972e1bc2f44..60dbcd96914f 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App content hidden from screen share for security"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Auto-connected to satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index c35c2ff84850..859d04af9037 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App content hidden from screen share for security"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Auto-connected to satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 4f7f7a72aac8..39e3d5da2227 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1728,7 +1728,7 @@ <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ver y controlar la pantalla"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Puede leer todo el contenido en la pantalla y mostrar contenido sobre otras apps."</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Ver y realizar acciones"</string> - <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Puede realizar el seguimiento de tus interacciones con una app o un sensor de hardware, así como interactuar con las apps por ti."</string> + <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Puede seguir tus interacciones con una app o un sensor de hardware, así como interactuar con las apps por ti."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permitir"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Rechazar"</string> <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Desinstalar"</string> @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Probar"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Compartido"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Se ocultó el contenido de la app durante el uso compartido de la pantalla por motivos de seguridad"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Conexión automática a satélite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Puedes enviar y recibir mensajes incluso si no tienes conexión a una red móvil o Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensajes"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index bf9d526f403a..796e5eabdf7d 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1903,7 +1903,7 @@ <string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ahorro de batería activa el tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales, ciertas funciones y algunas conexiones de red."</string> <string name="battery_saver_description" msgid="8518809702138617167">"Ahorro de batería activa el tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales, ciertas funciones y algunas conexiones de red."</string> - <string name="data_saver_description" msgid="4995164271550590517">"Para reducir el uso de datos, el ahorro de datos evita que algunas aplicaciones envíen o reciban datos en segundo plano. Si estás usando una aplicación, podrá acceder a datos, pero con menos frecuencia. Esto significa que es posible que, por ejemplo, algunas imágenes no se muestren hasta que las toques."</string> + <string name="data_saver_description" msgid="4995164271550590517">"Para reducir el uso de datos, Ahorro de datos evita que algunas aplicaciones envíen o reciban datos en segundo plano. Si estás usando una aplicación, podrá acceder a datos, pero con menos frecuencia. Esto significa que es posible que, por ejemplo, algunas imágenes no se muestren hasta que las toques."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"¿Activar Ahorro de datos?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Activar"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Durante un minuto (hasta las {formattedTime})}many{Durante # minutos (hasta las {formattedTime})}other{Durante # minutos (hasta las {formattedTime})}}"</string> @@ -2032,7 +2032,7 @@ <string name="pin_specific_target" msgid="7824671240625957415">"Fijar <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="unpin_target" msgid="3963318576590204447">"No fijar"</string> <string name="unpin_specific_target" msgid="3859828252160908146">"No fijar <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="app_info" msgid="6113278084877079851">"Información de la aplicación"</string> + <string name="app_info" msgid="6113278084877079851">"Información de la app"</string> <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="6577581216125805905">"Iniciando demostración…"</string> <string name="demo_restarting_message" msgid="1160053183701746766">"Restableciendo dispositivo…"</string> @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Prueba"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Común"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contenido de la aplicación oculto en pantalla compartida por motivos de seguridad"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automáticamente al satélite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Puedes enviar y recibir mensajes sin una red móvil o Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre Mensajes"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index cc82e47e1b43..99809d3a3311 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Jagatud"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Rakenduse sisu on ekraani jagamises turvalisuse huvides peidetud"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Satelliidiga loodi automaatselt ühendus"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Teil on võimalik sõnumeid saata ja vastu võtta ilma mobiilside- ja WiFi-võrguta"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ava rakendus Messages"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 34c066351d4d..c8c2e4575f7b 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Probakoa"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Partekatua"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Aplikazioko edukia ezkutatu egin da pantaila partekatzeko eginbidetik, segurtasuna bermatzeko"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatikoki konektatu da satelitera"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Mezuak bidal eta jaso ditzakezu sare mugikorrik edo wifi-sarerik gabe"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ireki Mezuak"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 4f2484e707e8..c59ac025787b 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"بهدلایل امنیتی، محتوای برنامه از دید همرسانی صفحهنمایش پنهان شد"</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> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 81b984827d9d..7612906d732f 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1384,7 +1384,7 @@ <string name="no_permissions" msgid="5729199278862516390">"Lupia ei tarvita"</string> <string name="perm_costs_money" msgid="749054595022779685">"tämä voi maksaa"</string> <string name="dlg_ok" msgid="5103447663504839312">"OK"</string> - <string name="usb_charging_notification_title" msgid="1674124518282666955">"Laite lataa USB-yhteydellä"</string> + <string name="usb_charging_notification_title" msgid="1674124518282666955">"Laitetta ladataan USB:llä"</string> <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Ladataan yhdistettyä laitetta USB:n kautta"</string> <string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB-tiedostonsiirto on käytössä"</string> <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP USB:n kautta on käytössä"</string> @@ -1655,7 +1655,7 @@ <string name="wireless_display_route_description" msgid="8297563323032966831">"Langaton näyttö"</string> <string name="media_route_button_content_description" msgid="2299223698196869956">"Suoratoisto"</string> <string name="media_route_chooser_title" msgid="6646594924991269208">"Yhdistä laitteeseen"</string> - <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Lähetä näyttö laitteeseen"</string> + <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Striimaa näyttö laitteeseen"</string> <string name="media_route_chooser_searching" msgid="6119673534251329535">"Etsitään laitteita…"</string> <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Asetukset"</string> <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Katkaise yhteys"</string> @@ -1903,8 +1903,8 @@ <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Virransäästö laittaa tumman teeman päälle ja rajoittaa tai laittaa pois päältä taustatoimintoja, tiettyjä ominaisuuksia sekä joitakin visuaalisia tehosteita ja verkkoyhteyksiä."</string> <string name="battery_saver_description" msgid="8518809702138617167">"Virransäästö laittaa tumman teeman päälle ja rajoittaa tai laittaa pois päältä taustatoimintoja, tiettyjä ominaisuuksia sekä joitakin visuaalisia tehosteita ja verkkoyhteyksiä."</string> <string name="data_saver_description" msgid="4995164271550590517">"Data Saver estää joitakin sovelluksia lähettämästä tai vastaanottamasta tietoja taustalla, jotta datan käyttöä voidaan vähentää. Käytössäsi oleva sovellus voi yhä käyttää dataa, mutta se saattaa tehdä niin tavallista harvemmin. Tämä voi tarkoittaa esimerkiksi sitä, että kuva ladataan vasta, kun kosketat sitä."</string> - <string name="data_saver_enable_title" msgid="7080620065745260137">"Otetaanko Data Saver käyttöön?"</string> - <string name="data_saver_enable_button" msgid="4399405762586419726">"Ota käyttöön"</string> + <string name="data_saver_enable_title" msgid="7080620065745260137">"Laitetaanko Data Saver päälle?"</string> + <string name="data_saver_enable_button" msgid="4399405762586419726">"Laita päälle"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Yhdeksi minuutiksi ({formattedTime} asti)}other{# minuutiksi ({formattedTime} asti)}}"</string> <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{Yhdeksi minuutiksi ({formattedTime} asti)}other{# minuutiksi ({formattedTime} asti)}}"</string> <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{Yhdeksi tunniksi ({formattedTime} asti)}other{# tunniksi ({formattedTime} asti)}}"</string> @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Testi"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Jaettu"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Sovelluksen sisältö piilotettu näytön jakamiselta turvallisuussyistä"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Yhdistetty automaattisesti satelliittiin"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Voit lähettää ja vastaanottaa viestejä ilman mobiili‑ tai Wi-Fi-verkkoa"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Avaa Messages"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 15d36f57b95b..7d86d83432ff 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1930,12 +1930,9 @@ <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Géré par <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activé"</string> <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Désactivé"</string> - <!-- no translation found for zen_mode_trigger_summary_divider_text (7461583466043698862) --> - <skip /> - <!-- no translation found for zen_mode_trigger_summary_range_symbol_combination (1804900738798069619) --> - <skip /> - <!-- no translation found for zen_mode_trigger_event_calendar_any (2086784607921121803) --> - <skip /> + <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string> + <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string> + <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"N\'importe quel agenda"</string> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> désactive certains sons"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne est survenu avec votre appareil. Il se peut qu\'il soit instable jusqu\'à ce que vous le réinitialisiez à ses paramètres par défaut."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Un problème interne est survenu avec votre appareil. Communiquez avec le fabricant pour obtenir plus de détails."</string> @@ -2398,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Commun"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'application est masqué du Partage d\'écran par mesure de sécurité"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Connecté au satellite automatiquement"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans avoir recours à un appareil mobile ou à un réseau Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 0346822b0639..80f1cf8db321 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -330,7 +330,7 @@ <string name="permgroupdesc_microphone" msgid="1047786732792487722">"enregistrer des fichiers audio"</string> <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activité physique"</string> <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"accéder aux données d\'activité physique"</string> - <string name="permgrouplab_camera" msgid="9090413408963547706">"Caméra"</string> + <string name="permgrouplab_camera" msgid="9090413408963547706">"Appareil photo"</string> <string name="permgroupdesc_camera" msgid="7585150538459320326">"prendre des photos et enregistrer des vidéos"</string> <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Appareils à proximité"</string> <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"détecter des appareils à proximité et s\'y connecter"</string> @@ -726,7 +726,7 @@ <skip /> <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Impossible de créer votre empreinte faciale. Réessayez."</string> <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Lunettes sombres détectées. Votre visage doit être entièrement visible."</string> - <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Visage partiellement couvert. Votre visage doit être entièrement visible."</string> + <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Masque détecté. Votre visage doit être entièrement visible."</string> <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="5085202213036026288">"Imposs. valider visage. Matériel non disponible."</string> @@ -1059,7 +1059,7 @@ <string name="keyguard_accessibility_widget" msgid="6776892679715699875">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string> <string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"Sélecteur d\'utilisateur"</string> <string name="keyguard_accessibility_status" msgid="6792745049712397237">"État"</string> - <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Caméra"</string> + <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Appareil photo"</string> <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Commandes multimédias"</string> <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"Début de la réorganisation des widgets"</string> <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Réorganisation des widgets terminée."</string> @@ -2124,7 +2124,7 @@ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Fermer"</string> <string name="notification_app_name_system" msgid="3045196791746735601">"Système"</string> <string name="notification_app_name_settings" msgid="9088548800899952531">"Paramètres"</string> - <string name="notification_appops_camera_active" msgid="8177643089272352083">"Caméra"</string> + <string name="notification_appops_camera_active" msgid="8177643089272352083">"Appareil photo"</string> <string name="notification_appops_microphone_active" msgid="581333393214739332">"Micro"</string> <string name="notification_appops_overlay_active" msgid="5571732753262836481">"se superpose aux autres applications sur l\'écran"</string> <string name="notification_feedback_indicator" msgid="663476517711323016">"Envoyer des commentaires"</string> @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Commun"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué lors du partage d\'écran pour des raisons de sécurité"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Connecté automatiquement au réseau satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans connexion au réseau mobile ou Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index fa48e96fe3de..0dbf36928683 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -995,7 +995,7 @@ <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correcto!"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Téntao de novo"</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Téntao de novo"</string> - <string name="lockscreen_storage_locked" msgid="634993789186443380">"Desbloquea para gozar todas as funcións e datos"</string> + <string name="lockscreen_storage_locked" msgid="634993789186443380">"Desbloquear para gozar de todas as funcións e datos"</string> <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Superouse o número máximo de intentos de desbloqueo facial"</string> <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"Non hai SIM"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"Non hai ningunha SIM na tableta."</string> @@ -1970,7 +1970,7 @@ <string name="default_notification_channel_label" msgid="3697928973567217330">"Sen clasificar"</string> <string name="importance_from_user" msgid="2782756722448800447">"Ti defines a importancia destas notificacións."</string> <string name="importance_from_person" msgid="4235804979664465383">"É importante polas persoas involucradas."</string> - <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificación de aplicacións personalizada"</string> + <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificación de aplicación personalizada"</string> <string name="user_creation_account_exists" msgid="2239146360099708035">"Queres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario novo con <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Xa existe un usuario con esta conta)"</string> <string name="user_creation_adding" msgid="7305185499667958364">"Queres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario novo con <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="supervised_user_creation_label" msgid="6884904353827427515">"Engadir usuario supervisado"</string> @@ -2031,7 +2031,7 @@ <string name="pin_specific_target" msgid="7824671240625957415">"Fixar a <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="unpin_target" msgid="3963318576590204447">"Deixar de fixar"</string> <string name="unpin_specific_target" msgid="3859828252160908146">"Deixar de fixar a <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="app_info" msgid="6113278084877079851">"Información da aplicación"</string> + <string name="app_info" msgid="6113278084877079851">"Información da app"</string> <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="6577581216125805905">"Iniciando demostración…"</string> <string name="demo_restarting_message" msgid="1160053183701746766">"Restablecendo dispositivo…"</string> @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Proba"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Compartido"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Por motivos de seguranza, ocultouse o contido da aplicación para que no se mostre na pantalla compartida"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Conexión automática ao satélite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Podes enviar e recibir mensaxes sen unha rede de telefonía móbil ou wifi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensaxes"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index fb202bac6fb2..b3cf16bb4e5e 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"સુરક્ષા માટે સ્ક્રીન શેર કરતી વખતે ઍપનું કન્ટેન્ટ છુપાવેલું છે"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"સેટેલાઇટ સાથે ઑટોમૅટિક રીતે કનેક્ટેડ"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"તમે મોબાઇલ અથવા વાઇ-ફાઇ નેટવર્ક વિના મેસેજ મોકલી અને પ્રાપ્ત કરી શકો છો"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ખોલો"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index fd99d19b59a5..ac070c785905 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -278,7 +278,7 @@ <string name="global_action_settings" msgid="4671878836947494217">"सेटिंग"</string> <string name="global_action_assist" msgid="2517047220311505805">"सहायता"</string> <string name="global_action_voice_assist" msgid="6655788068555086695">"आवाज़ से डिवाइस का इस्तेमाल"</string> - <string name="global_action_lockdown" msgid="2475471405907902963">"फ़ाेन लॉक करें"</string> + <string name="global_action_lockdown" msgid="2475471405907902963">"लॉकडाउन"</string> <string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string> <string name="notification_hidden_text" msgid="2835519769868187223">"नई सूचना"</string> <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"सामान्य कीबोर्ड"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"स्क्रीन शेयर करने के दौरान सुरक्षा के लिए, ऐप्लिकेशन का कॉन्टेंट छिपाया गया"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"सैटलाइट से अपने-आप कनेक्ट हो गया"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"मोबाइल या वाई-फ़ाई नेटवर्क के बिना भी मैसेज भेजे और पाए जा सकते हैं"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ऐप्लिकेशन खोलें"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 5ac09ec6fe80..02435994e2b0 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1420,7 +1420,7 @@ <string name="share_remote_bugreport_action" msgid="7630880678785123682">"DIJELI"</string> <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ODBIJ"</string> <string name="select_input_method" msgid="3971267998568587025">"Odabir načina unosa"</string> - <string name="show_ime" msgid="6406112007347443383">"Zadrži na zaslonu dok je fizička tipkovnica aktivna"</string> + <string name="show_ime" msgid="6406112007347443383">"Zadržava se na zaslonu dok je fizička tipkovnica aktivna"</string> <string name="hardware" msgid="3611039921284836033">"Upotreba zaslonske tipkovnice"</string> <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurirajte uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string> <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurirajte fizičke tipkovnice"</string> @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Zajedničko"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Sadržaj aplikacije sakriven je od dijeljenja zaslona radi sigurnosti"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatski povezano sa satelitom"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete slati i primati poruke bez mobilne mreže ili Wi-Fi mreže"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Poruke"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 06ca1b6dfbc1..9c8eb5634a33 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1723,7 +1723,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"BE"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"KI"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Teljes körű vezérlést biztosít eszköze felett a(z) <xliff:g id="SERVICE">%1$s</xliff:g> szolgáltatás számára?"</string> - <string name="accessibility_service_warning_description" msgid="291674995220940133">"A teljes vezérlés indokolt olyan alkalmazásoknál, amelyek kisegítő lehetőségeket nyújtanak, a legtöbb alkalmazásnál azonban nem."</string> + <string name="accessibility_service_warning_description" msgid="291674995220940133">"A teljes körű vezérlés indokolt olyan alkalmazásoknál, amelyek kisegítő lehetőségeket nyújtanak, a legtöbb alkalmazásnál azonban nem."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Képernyő megtekintése és kezelése"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Elolvashatja a képernyő tartalmát, és tartalmakat jeleníthet meg más alkalmazások felett."</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Műveletek megtekintése és elvégzése"</string> @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Teszt"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Közös"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"A biztonság érdekében a képernyőmegosztástól elrejtett alkalmazástartalom"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatikusan csatlakozva a műholdhoz"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Küldhet és fogadhat üzeneteket mobil- és Wi-Fi-hálózat nélkül is"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"A Messages megnyitása"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 89e087ec7100..63edfcedc523 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1970,7 +1970,7 @@ <string name="default_notification_channel_label" msgid="3697928973567217330">"Չդասակարգված"</string> <string name="importance_from_user" msgid="2782756722448800447">"Դուք սահմանել եք այս ծանուցումների կարևորությունը:"</string> <string name="importance_from_person" msgid="4235804979664465383">"Կարևոր է, քանի որ որոշակի մարդիկ են ներգրավված:"</string> - <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Հավելվածի հատուկ ծանուցում"</string> + <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Հատուկ հավելվածի ծանուցում"</string> <string name="user_creation_account_exists" msgid="2239146360099708035">"Թույլատրե՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել (նման հաշվով Օգտատեր արդեն գոյություն ունի):"</string> <string name="user_creation_adding" msgid="7305185499667958364">"Թույլատրե՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել:"</string> <string name="supervised_user_creation_label" msgid="6884904353827427515">"Ավելացնել վերահսկվող օգտատեր"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Անվտանգության նկատառումներից ելնելով՝ հավելվածի բովանդակությունը թաքցվել է էկրանի ցուցադրումից"</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">"Բացել Messages-ը"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 616b30b86ffb..8a29efd9da71 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -995,7 +995,7 @@ <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Perbaiki!"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Coba lagi"</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Coba lagi"</string> - <string name="lockscreen_storage_locked" msgid="634993789186443380">"Membuka kunci untuk semua fitur dan data"</string> + <string name="lockscreen_storage_locked" msgid="634993789186443380">"Buka kunci untuk melihat semua fitur dan data"</string> <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Percobaan Buka dengan Wajah melebihi batas maksimum"</string> <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"Tidak ada SIM"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"Tidak ada SIM di tablet."</string> @@ -1367,7 +1367,7 @@ <string name="sim_removed_message" msgid="8469588437451533845">"Jaringan seluler tidak akan tersedia sampai Anda memulai ulang dengan SIM yang valid."</string> <string name="sim_done_button" msgid="6464250841528410598">"Selesai"</string> <string name="sim_added_title" msgid="2976783426741012468">"SIM ditambahkan"</string> - <string name="sim_added_message" msgid="6602906609509958680">"Mulai ulang perangkat Anda untuk mengakses jaringan selular."</string> + <string name="sim_added_message" msgid="6602906609509958680">"Mulai ulang perangkat Anda untuk mengakses jaringan seluler."</string> <string name="sim_restart_button" msgid="8481803851341190038">"Mulai Ulang"</string> <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Aktifkan layanan seluler"</string> <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Download aplikasi operator untuk mengaktifkan SIM baru"</string> @@ -1725,9 +1725,9 @@ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Izinkan <xliff:g id="SERVICE">%1$s</xliff:g> mengontrol perangkat Anda secara penuh?"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kontrol penuh sesuai untuk aplikasi yang mendukung kebutuhan aksesibilitas Anda, tetapi tidak untuk sebagian besar aplikasi."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Melihat dan mengontrol layar"</string> - <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Voice Access dapat membaca semua konten di layar dan menampilkan konten di atas aplikasi lain."</string> + <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Membaca semua konten di layar dan menampilkan konten di atas aplikasi lain."</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Menampilkan dan melakukan tindakan"</string> - <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Voice Access dapat melacak interaksi Anda dengan aplikasi atau sensor hardware, dan berinteraksi dengan aplikasi untuk Anda."</string> + <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Melacak interaksi Anda dengan aplikasi atau sensor hardware, dan berinteraksi dengan aplikasi untuk Anda."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Izinkan"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Tolak"</string> <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Uninstal"</string> @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Pengujian"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Umum"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Konten aplikasi disembunyikan dari berbagi layar untuk alasan keamanan"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Menghubungkan otomatis ke satelit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Anda dapat mengirim dan menerima pesan tanpa jaringan seluler atau Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Message"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 5d55ba8f2a58..996c17779580 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Prófun"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Sameiginlegt"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Efni forrits falið í skjádeilingu af öryggisástæðum"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Tengdist sjálfkrafa við gervihnött"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Þú getur sent og móttekið skilaboð án tengingar við farsímakerfi eða Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Opna Messages"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 9d8d74a3c467..a5373abbc896 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1193,7 +1193,7 @@ <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Memoria insufficiente per il sistema. Assicurati di avere 250 MB di spazio libero e riavvia."</string> <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> è in esecuzione"</string> <string name="app_running_notification_text" msgid="5120815883400228566">"Tocca per ulteriori informazioni o per interrompere l\'app."</string> - <string name="ok" msgid="2646370155170753815">"OK"</string> + <string name="ok" msgid="2646370155170753815">"Ok"</string> <string name="cancel" msgid="6908697720451760115">"Annulla"</string> <string name="yes" msgid="9069828999585032361">"OK"</string> <string name="no" msgid="5122037903299899715">"Annulla"</string> @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Condiviso"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contenuti dell\'app nascosti dalla condivisione schermo per sicurezza"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Connessione automatica al satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Puoi inviare e ricevere messaggi senza una rete mobile o Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Apri Messaggi"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index c256de994bd4..e9e558595a91 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -2395,8 +2395,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"תוכן האפליקציה מוסתר משיתוף המסך מטעמי אבטחה"</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">"לפתיחת Messages"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index eee2e3dc6a17..e8dee3c625dc 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -828,14 +828,14 @@ <string name="policylab_limitPassword" msgid="4851829918814422199">"パスワードルールの設定"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"画面ロックのパスワードとPINの長さと使用できる文字を制御します。"</string> <string name="policylab_watchLogin" msgid="7599669460083719504">"画面ロック解除試行の監視"</string> - <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"画面のロック解除に正しくないパスワードを入力した回数を監視し、回数が多すぎる場合はタブレットをロックするかタブレットのデータをすべて消去します。"</string> - <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"画面のロック解除の際に入力したパスワードが間違っていた回数を監視し、回数が多すぎる場合は Android TV デバイスをロックするか Android TV デバイスのデータをすべて消去します。"</string> - <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"画面のロック解除に正しくないパスワードを入力した回数を監視し、回数が多すぎる場合はインフォテインメント システムをロックするかインフォテインメント システムのデータをすべて消去します。"</string> - <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"画面のロック解除に正しくないパスワードを入力した回数を監視し、回数が多すぎる場合はモバイルデバイスをロックするかモバイルデバイスのデータをすべて消去します。"</string> - <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"画面のロック解除の際に入力したパスワードが間違っていた回数を監視し、回数が多すぎる場合はタブレットをロックするかこのユーザーのデータをすべて消去します。"</string> - <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"画面のロック解除の際に入力したパスワードが間違っていた回数を監視し、回数が多すぎる場合は Android TV デバイスをロックするかこのユーザーのデータをすべて消去します。"</string> - <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"画面のロック解除に正しくないパスワードを入力した回数を監視し、回数が多すぎる場合はインフォテインメント システムをロックするかこのプロファイルのデータをすべて消去します。"</string> - <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"画面のロック解除の際に入力したパスワードが間違っていた回数を監視し、回数が多すぎる場合はスマートフォンをロックするかこのユーザーのデータをすべて消去します。"</string> + <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"画面のロック解除に失敗した回数を監視し、多すぎる場合はタブレットをロックするかタブレットのデータをすべて消去します。"</string> + <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"画面のロック解除に失敗した回数を監視し、多すぎる場合は Android TV デバイスをロックするか Android TV デバイスのデータをすべて消去します。"</string> + <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"画面のロック解除に失敗した回数を監視し、多すぎる場合はインフォテインメント システムをロックするかインフォテインメント システムのデータをすべて消去します。"</string> + <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"画面のロック解除に失敗した回数を監視し、多すぎる場合はモバイルデバイスをロックするかモバイルデバイスのデータをすべて消去します。"</string> + <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"画面のロック解除に失敗した回数を監視し、多すぎる場合はタブレットをロックするかこのユーザーのデータをすべて消去します。"</string> + <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"画面のロック解除に失敗した回数を監視し、多すぎる場合は Android TV デバイスをロックするかこのユーザーのデータをすべて消去します。"</string> + <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"画面のロック解除に失敗した回数を監視し、多すぎる場合はインフォテインメント システムをロックするかこのプロファイルのデータをすべて消去します。"</string> + <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"画面のロック解除に失敗した回数を監視し、多すぎる場合はスマートフォンをロックするかこのユーザーのデータをすべて消去します。"</string> <string name="policylab_resetPassword" msgid="214556238645096520">"画面ロックの変更"</string> <string name="policydesc_resetPassword" msgid="4626419138439341851">"画面ロックを変更します。"</string> <string name="policylab_forceLock" msgid="7360335502968476434">"画面のロック"</string> @@ -1420,7 +1420,7 @@ <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"共有しない"</string> <string name="select_input_method" msgid="3971267998568587025">"入力方法の選択"</string> <string name="show_ime" msgid="6406112007347443383">"物理キーボードが有効になっていても画面に表示させます"</string> - <string name="hardware" msgid="3611039921284836033">"画面キーボードの使用"</string> + <string name="hardware" msgid="3611039921284836033">"画面キーボードを使用"</string> <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>の設定"</string> <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"物理キーボードの設定"</string> <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"タップして言語とレイアウトを選択してください"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"セキュリティ上、画面共有ではアプリの内容は非表示となります"</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> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index ececd928bb6e..d4b4d12798b6 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ეკრანის გაზიარებიდან აპის კონტენტი დამალულია უსაფრთხოების მიზნით"</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">"Messages-ის გახსნა"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 38c6f7721cc3..7a2528dc03df 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -831,7 +831,7 @@ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Экран бекітпесін ашқан кезде терілген қате құпия сөздердің санын бақылау және планшетті бекіту немесе тым көп қате құпия сөздер терілген болса, планшеттің бүкіл деректерін өшіру."</string> <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Экранның құлпын ашу кезінде қате енгізілген құпия сөздердің санын бақылау, құпия сөз тым көп қате енгізілген жағдайда, Android TV құрылғысын құлыптау және Android TV құрылғыңыздың барлық деректерінен тазарту."</string> <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Экран құлпын ашқан кезде, терілген қате құпия сөздердің саны бақыланады, сондай-ақ құпия сөздер бірнеше рет қате терілсе, ақпараттық-сауықтық жүйе құлыпталады немесе оның барлық дерегі жойылады."</string> - <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Экран бекітпесін ашқан кезде терілген қате құпия сөздердің санын бақылау және телефонды бекіту немесе тым көп қате құпия сөздер терілген болса, телефонның бүкіл деректерін өшіру."</string> + <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Экран құлпын ашқан кезде терілген қате құпия сөздердің санын бақылау және құпия сөз тым көп рет қате терілгенде, телефонды құлыптау немесе оның бүкіл деректерін өшіру."</string> <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Экран бекітпесін ашқанда терілген қате құпия сөздердің санын бақылау және тым көп қате құпия сөздер терілсе, планшетті бекіту немесе осы пайдаланушының барлық деректерін өшіру."</string> <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Экранның құлпын ашу кезінде қате енгізілген құпия сөздердің санын бақылау, құпия сөз тым көп қате енгізілген жағдайда, Android TV құрылғысын құлыптау және барлық пайдаланушы деректерінен тазарту."</string> <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Экран құлпын ашқан кезде, терілген қате құпия сөздердің саны бақыланады, сондай-ақ құпия сөздер бірнеше рет қате терілсе, ақпараттық-сауықтық жүйе құлыпталады немесе осы профильдің барлық дерегі жойылады."</string> @@ -1970,7 +1970,7 @@ <string name="default_notification_channel_label" msgid="3697928973567217330">"Санатқа жатқызылмаған"</string> <string name="importance_from_user" msgid="2782756722448800447">"Сіз осы хабарландырулардың маңыздылығын орнатасыз."</string> <string name="importance_from_person" msgid="4235804979664465383">"Қатысты адамдарға байланысты бұл маңызды."</string> - <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Арнаулы хабар хабарландыруы"</string> + <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Арнаулы қолданба хабарландыруы"</string> <string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="APP">%1$s</xliff:g> қолданбасына <xliff:g id="ACCOUNT">%2$s</xliff:g> аккаунты бар жаңа пайдаланушы (мұндай аккаунтқа ие пайдаланушы бұрыннан бар) жасауға рұқсат етілсін бе?"</string> <string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="APP">%1$s</xliff:g> қолданбасына <xliff:g id="ACCOUNT">%2$s</xliff:g> аккаунты бар жаңа пайдаланушы жасауға рұқсат етілсін бе?"</string> <string name="supervised_user_creation_label" msgid="6884904353827427515">"Бақыланатын пайдаланушыны қосу"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Қауіпсіздік мақсатында қолданба контенті экранды көрсету кезінде жасырылды."</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">"Messages қолданбасын ашу"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 6c0a195be0a4..59a6e30d5abc 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -828,14 +828,14 @@ <string name="policylab_limitPassword" msgid="4851829918814422199">"កំណត់ក្បួនពាក្យសម្ងាត់"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"គ្រប់គ្រងប្រវែង និងតួអក្សរដែលអនុញ្ញាតឲ្យប្រើក្នុងពាក្យសម្ងាត់ និងលេខសម្ងាត់ចាក់សោអេក្រង់។"</string> <string name="policylab_watchLogin" msgid="7599669460083719504">"តាមដានការព្យាយាមដោះសោអេក្រង់"</string> - <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ពិនិត្យចំនួនបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវ។ ពេលដោះសោអេក្រង់ និងចាក់សោទូរស័ព្ទ ឬលុបទិន្នន័យទូរស័ព្ទទាំងអស់ ប្រសិនបើមានពាក្យសម្ងាត់បញ្ចូលមិនត្រឹមត្រូវច្រើនដងពេក។"</string> + <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ពិនិត្យមើលចំនួនដងនៃការវាយបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវ នៅពេលដោះសោអេក្រង់ និងចាក់សោថេប្លេត ឬលុបទិន្នន័យថេប្លេតទាំងអស់ ប្រសិនបើវាយបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវច្រើនដងពេក។"</string> <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"ពិនិត្យចំនួននៃការវាយបញ្ចូលពាក្យសម្ងាត់ដែលមិនត្រឹមត្រូវ នៅពេលដោះសោអេក្រង់ និងចាក់សោឧបករណ៍ Android TV របស់អ្នក ឬលុបទិន្នន័យឧបករណ៍ Android TV របស់អ្នកទាំងអស់ ប្រសិនបើវាយបញ្ចូលពាក្យសម្ងាត់ខុសច្រើនដងពេក។"</string> <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"ពិនិត្យមើលចំនួនដងនៃការវាយបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវ នៅពេលដោះសោអេក្រង់ និងចាក់សោប្រព័ន្ធព័ត៌មាននិងកម្សាន្ត ឬលុបទិន្នន័យទាំងអស់របស់ប្រព័ន្ធព័ត៌មាននិងកម្សាន្ត ប្រសិនបើវាយបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវច្រើនដងពេក។"</string> - <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"ពិនិត្យចំនួនបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវ។ ពេលដោះសោអេក្រង់ និងចាក់សោទូរស័ព្ទ ឬលុបទិន្នន័យទូរស័ព្ទទាំងអស់ ប្រសិនបើមានពាក្យសម្ងាត់បញ្ចូលមិនត្រឹមត្រូវច្រើនដងពេក។"</string> + <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"ពិនិត្យមើលចំនួនដងនៃការវាយបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវ នៅពេលដោះសោអេក្រង់ និងចាក់សោទូរសព្ទ ឬលុបទិន្នន័យទូរសព្ទទាំងអស់ ប្រសិនបើវាយបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវច្រើនដងពេក។"</string> <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"ត្រួតពិនិត្យចំនួននៃការវាយបញ្ចូលពាក្យសម្ងាត់ដែលមិនត្រឹមត្រូវ នៅពេលដោះសោអេក្រង់ និងចាក់សោថេប្លេត ឬលុបទិន្នន័យអ្នកប្រើនេះទាំងអស់ ប្រសិនបើមានការវាយបញ្ចូលពាក្យសម្ងាត់ខុសច្រើនដងពេក។"</string> <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"ពិនិត្យចំនួននៃការវាយបញ្ចូលពាក្យសម្ងាត់ដែលមិនត្រឹមត្រូវ នៅពេលដោះសោអេក្រង់ និងចាក់សោឧបករណ៍ Android TV របស់អ្នក ឬលុបទិន្នន័យរបស់អ្នកប្រើប្រាស់នេះទាំងអស់ ប្រសិនបើវាយបញ្ចូលពាក្យសម្ងាត់ខុសច្រើនដងពេក។"</string> <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"ពិនិត្យមើលចំនួនដងនៃការវាយបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវ នៅពេលដោះសោអេក្រង់ និងចាក់សោប្រព័ន្ធព័ត៌មាននិងកម្សាន្ត ឬលុបទិន្នន័យទាំងអស់របស់កម្រងព័ត៌មាននេះ ប្រសិនបើវាយបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវច្រើនដងពេក។"</string> - <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"ត្រួតពិនិត្យចំនួននៃការវាយបញ្ចូលពាក្យសម្ងាត់ដែលមិនត្រឹមត្រូវ នៅពេលដោះសោអេក្រង់ និងចាក់សោទូរស័ព្ទ ឬលុបទិន្នន័យអ្នកប្រើនេះទាំងអស់ ប្រសិនបើមានការវាយបញ្ចូលពាក្យសម្ងាត់ខុសច្រើនដងពេក។"</string> + <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"ពិនិត្យមើលចំនួនដងនៃការវាយបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវ នៅពេលដោះសោអេក្រង់ និងចាក់សោទូរសព្ទ ឬលុបទិន្នន័យទូរសព្ទទាំងអស់ ប្រសិនបើវាយបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវច្រើនដងពេក។"</string> <string name="policylab_resetPassword" msgid="214556238645096520">"ប្តូរការចាក់សោអេក្រង់"</string> <string name="policydesc_resetPassword" msgid="4626419138439341851">"ប្តូរការចាក់សោអេក្រង់។"</string> <string name="policylab_forceLock" msgid="7360335502968476434">"ចាក់សោអេក្រង់"</string> @@ -995,7 +995,7 @@ <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"ត្រឹមត្រូវ!"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"ព្យាយាមម្ដងទៀត"</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"ព្យាយាមម្ដងទៀត"</string> - <string name="lockscreen_storage_locked" msgid="634993789186443380">"ដោះសោលក្ខណៈពិសេស និងទិន្នន័យទាំងអស់"</string> + <string name="lockscreen_storage_locked" msgid="634993789186443380">"ដោះសោមុខងារ និងទិន្នន័យទាំងអស់"</string> <string name="faceunlock_multiple_failures" msgid="681991538434031708">"បានលើសការព្យាយាមដោះសោតាមទម្រង់មុខ"</string> <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"គ្មានស៊ីមទេ"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"គ្មានស៊ីមក្នុងថេប្លេតទេ។"</string> @@ -1761,7 +1761,7 @@ <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> + <string name="error_message_change_not_allowed" msgid="843159705042381454">"ការផ្លាស់ប្ដូរនេះមិនត្រូវបានអនុញ្ញាតដោយអ្នកគ្រប់គ្រងរបស់អ្នកទេ"</string> <string name="app_not_found" msgid="3429506115332341800">"រកមិនឃើញកម្មវិធី ដើម្បីគ្រប់គ្រងសកម្មភាពនេះ"</string> <string name="revoke" msgid="5526857743819590458">"ដកហូត"</string> <string name="mediasize_iso_a0" msgid="7039061159929977973">"ISO A0"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"បានលាក់ខ្លឹមសារកម្មវិធីពីការបង្ហាញអេក្រង់ដើម្បីសុវត្ថិភាព"</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">"បើកកម្មវិធី Messages"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index faa46baf666f..b1a74720d88f 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -1419,7 +1419,7 @@ <string name="share_remote_bugreport_action" msgid="7630880678785123682">"ಹಂಚಿಕೊಳ್ಳಿ"</string> <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ನಿರಾಕರಿಸಿ"</string> <string name="select_input_method" msgid="3971267998568587025">"ಇನ್ಪುಟ್ ವಿಧಾನವನ್ನು ಆರಿಸಿ"</string> - <string name="show_ime" msgid="6406112007347443383">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ ಸಕ್ರಿಯವಾಗಿರುವಾಗ ಅದನ್ನು ಪರದೆಯ ಮೇಲಿರಿಸಿ"</string> + <string name="show_ime" msgid="6406112007347443383">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ ಸಕ್ರಿಯವಾಗಿರುವಾಗ ಅದನ್ನು ಸ್ಕ್ರೀನ್ ಮೇಲಿರಿಸಿ"</string> <string name="hardware" msgid="3611039921284836033">"ಆನ್-ಸ್ಕ್ರೀನ್ ಕೀಬೋರ್ಡ್ ಬಳಸಿ"</string> <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ಕಾನ್ಫಿಗರ್ ಮಾಡಿ"</string> <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿ"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ಭದ್ರತೆಗಾಗಿ ಸ್ಕ್ರೀನ್ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯಲ್ಲಿ ಆ್ಯಪ್ ಕಂಟೆಂಟ್ ಅನ್ನು ಮರೆಮಾಡಲಾಗಿದೆ"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"ಸ್ಯಾಟಲೈಟ್ಗೆ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"ನೀವು ಮೊಬೈಲ್ ಅಥವಾ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ ಇಲ್ಲದೆಯೇ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಮತ್ತು ಸ್ವೀಕರಿಸಬಹುದು"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ಅನ್ನು ತೆರೆಯಿರಿ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 9eaa4147eb30..baa260470dae 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"보안을 위해 화면 공유에서 앱 콘텐츠가 숨겨집니다."</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> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 9efccffc829b..f02b58cd6d41 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -995,7 +995,7 @@ <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Туура!"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Дагы аракет кылыңыз"</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Дагы аракет кылыңыз"</string> - <string name="lockscreen_storage_locked" msgid="634993789186443380">"Элементтердин жана дайындардын кулпусун ачуу"</string> + <string name="lockscreen_storage_locked" msgid="634993789186443380">"Функциялар менен колдонмолордун кулпусун ачуу"</string> <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Жүзүнөн таанып ачуу аракеттеринин чегинен аштыңыз"</string> <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"SIM карта жок"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"Планшетте SIM карта жок."</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Коопсуздук үчүн колдонмодогу контент бөлүшүлгөн экрандан жашырылды"</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> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 752e68eeeeca..e94f2d386a98 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -1877,7 +1877,7 @@ <string name="restr_pin_try_later" msgid="5897719962541636727">"ລອງໃໝ່ອີກຄັ້ງໃນພາຍຫລັງ."</string> <string name="immersive_cling_title" msgid="2307034298721541791">"ການເບິ່ງເຕັມໜ້າຈໍ"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"ຫາກຕ້ອງການອອກ, ໃຫ້ຮູດຈາກທາງເທິງລົງມາທາງລຸ່ມ."</string> - <string name="immersive_cling_positive" msgid="7047498036346489883">"ໄດ້ແລ້ວ"</string> + <string name="immersive_cling_positive" msgid="7047498036346489883">"ເຂົ້າໃຈແລ້ວ"</string> <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ໝຸນເພື່ອມຸມມອງທີ່ດີຂຶ້ນ"</string> <string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"ເປີດ <xliff:g id="NAME">%s</xliff:g> ໃນໂໝດເຕັມຈໍເພື່ອມຸມມອງທີ່ດີຂຶ້ນ"</string> <string name="done_label" msgid="7283767013231718521">"ແລ້ວໆ"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ເນື້ອຫາແອັບຖືກເຊື່ອງໄວ້ຈາກການແບ່ງປັນໜ້າຈໍເພື່ອຄວາມປອດໄພ"</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">"ເປີດ Messages"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 2fd6ded698b6..da46662cf4b2 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -2396,8 +2396,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Bandymas"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Bendruomenės"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Programos turinys paslėptas bendrinant ekraną saugumo sumetimais"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatiškai prisijungta prie palydovinio ryšio"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Galite siųsti ir gauti pranešimus be mobiliojo ryšio ar „Wi-Fi“ tinklo"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Atidaryti programą „Messages“"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 066cd4bb0fce..9fcf2d1c802d 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Testēšanai"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Kopīgs"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Drošības nolūkos lietotnes saturs kopīgotajā ekrānā ir paslēpts"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automātiski izveidots savienojums ar satelītu"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Varat sūtīt un saņemt ziņojumus bez mobilā vai Wi-Fi tīkla."</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Atvērt lietotni Ziņojumi"</string> diff --git a/core/res/res/values-mcc404/config.xml b/core/res/res/values-mcc404/config.xml index 4cadef7893d3..0cb1029626b1 100644 --- a/core/res/res/values-mcc404/config.xml +++ b/core/res/res/values-mcc404/config.xml @@ -18,8 +18,6 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Whether camera shutter sound is forced or not (country specific). --> - <bool name="config_camera_sound_forced">true</bool> <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app --> <bool name="config_showAreaUpdateInfoSettings">true</bool> </resources> diff --git a/core/res/res/values-mcc405/config.xml b/core/res/res/values-mcc405/config.xml index 4cadef7893d3..0cb1029626b1 100644 --- a/core/res/res/values-mcc405/config.xml +++ b/core/res/res/values-mcc405/config.xml @@ -18,8 +18,6 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Whether camera shutter sound is forced or not (country specific). --> - <bool name="config_camera_sound_forced">true</bool> <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app --> <bool name="config_showAreaUpdateInfoSettings">true</bool> </resources> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index a8d5ea4d341c..a0afccfac08d 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1105,7 +1105,7 @@ <string name="menu_sym_shortcut_label" msgid="4037566049061218776">"копче Sym+"</string> <string name="menu_function_shortcut_label" msgid="2367112760987662566">"копче Function+"</string> <string name="menu_space_shortcut_label" msgid="5949311515646872071">"празен простор"</string> - <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"внеси"</string> + <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string> <string name="menu_delete_shortcut_label" msgid="4365787714477739080">"избриши"</string> <string name="search_go" msgid="2141477624421347086">"Пребарај"</string> <string name="search_hint" msgid="455364685740251925">"Пребарување…"</string> @@ -1674,7 +1674,7 @@ <string name="kg_wrong_password" msgid="2384677900494439426">"Погрешна лозинка"</string> <string name="kg_wrong_pin" msgid="3680925703673166482">"Погрешен PIN"</string> <string name="kg_pattern_instructions" msgid="8366024510502517748">"Употреби ја својата шема"</string> - <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Внеси PIN на SIM картичка"</string> + <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Внесете PIN за SIM-картичката"</string> <string name="kg_pin_instructions" msgid="7355933174673539021">"Впишете PIN"</string> <string name="kg_password_instructions" msgid="7179782578809398050">"Внеси лозинка"</string> <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM картичката е сега оневозможена. Внесете ПУК код за да продолжите. Контактирајте го операторот за детали."</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Од безбедносни причини, содржините на апликацијата се скриени од споделувањето екран"</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">"Отворете ја Messages"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 32f2daf9153a..44af8b6f66ed 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -831,7 +831,7 @@ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"സ്ക്രീൻ അൺലോക്കുചെയ്യുമ്പോൾ തെറ്റായി ടൈപ്പുചെയ്ത പാസ്വേഡുകളുടെ എണ്ണം നിരീക്ഷിക്കുക, വളരെയധികം തെറ്റായ പാസ്വ്ഡുകൾ ടൈപ്പുചെയ്തിട്ടുണ്ടെങ്കിൽ ടാബ്ലെറ്റ് ലോക്കുചെയ്യുകയോ ടാബ്ലെറ്റിലെ എല്ലാ ഡാറ്റയും മായ്ക്കുകയോ ചെയ്യുക."</string> <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"സ്ക്രീൻ അൺലോക്ക് ചെയ്യുമ്പോൾ തെറ്റായി ടൈപ്പ് ചെയ്ത പാസ്വേഡുകളുടെ എണ്ണം നിരീക്ഷിക്കുകയും നിരവധി തവണ തെറ്റായ പാസ്വേഡുകൾ ടൈപ്പ് ചെയ്തിട്ടുണ്ടെങ്കിൽ നിങ്ങളുടെ Android TV ലോക്ക് ചെയ്യുകയോ Android TV-യിലെ എല്ലാ ഡാറ്റയും മായ്ക്കുകയോ ചെയ്യുക."</string> <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"സ്ക്രീൻ അൺലോക്ക് ചെയ്യുമ്പോൾ തെറ്റായി ടൈപ്പ് ചെയ്ത പാസ്വേഡുകളുടെ എണ്ണം നിരീക്ഷിക്കുക. നിരവധി തെറ്റായ പാസ്വേഡുകൾ ടൈപ്പ് ചെയ്താൽ, ഇൻഫോറ്റേയിൻമെന്റ് സിസ്റ്റം ലോക്ക് ചെയ്യുകയോ ഇൻഫോറ്റേയിൻമെന്റ് സിസ്റ്റത്തിന്റെ ഡാറ്റ മുഴുവനും മായ്ക്കുകയോ ചെയ്യുക."</string> - <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"സ്ക്രീൻ അൺലോക്കുചെയ്യുമ്പോൾ തെറ്റായി ടൈപ്പുചെയ്ത പാസ്വേഡുകളുടെ എണ്ണം നിരീക്ഷിക്കുക, വളരെയധികം തെറ്റായ പാസ്വ്ഡുകൾ ടൈപ്പുചെയ്തിട്ടുണ്ടെങ്കിൽ ഫോൺ ലോക്കുചെയ്യുകയോ ഫോണിലെ എല്ലാ ഡാറ്റയും മായ്ക്കുകയോചെയ്യുക."</string> + <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"സ്ക്രീൻ അൺലോക്കുചെയ്യുമ്പോൾ തെറ്റായി ടൈപ്പുചെയ്ത പാസ്വേഡുകളുടെ എണ്ണം നിരീക്ഷിക്കുക, വളരെയധികം തെറ്റായ പാസ്വേഡുകൾ ടൈപ്പുചെയ്തിട്ടുണ്ടെങ്കിൽ ഫോൺ ലോക്കുചെയ്യുകയോ ഫോണിലെ എല്ലാ ഡാറ്റയും മായ്ക്കുകയോചെയ്യുക."</string> <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"സ്ക്രീൻ അൺലോക്കുചെയ്യുമ്പോൾ തെറ്റായി ടൈപ്പുചെയ്ത പാസ്വേഡുകളുടെ എണ്ണം നിരീക്ഷിക്കുകയും നിരവധി തവണ പാസ്വേഡ് ടൈപ്പുചെയ്തെങ്കിൽ ടാബ്ലെറ്റ് ലോക്കുചെയ്യുകയോ ഈ എല്ലാ ഉപയോക്തൃവിവരവും മായ്ക്കുകയോ ചെയ്യുക."</string> <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"സ്ക്രീൻ അൺലോക്ക് ചെയ്യുമ്പോൾ തെറ്റായി ടൈപ്പ് ചെയ്ത പാസ്വേഡുകളുടെ എണ്ണം നിരീക്ഷിക്കുകയും നിരവധി തവണ തെറ്റായ പാസ്വേഡുകൾ ടൈപ്പ് ചെയ്തിട്ടുണ്ടെങ്കിൽ നിങ്ങളുടെ Android TV ലോക്ക് ചെയ്യുകയോ ഈ ഉപയോക്തൃ ഡാറ്റയെല്ലാം മായ്ക്കുകയോ ചെയ്യുക."</string> <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"സ്ക്രീൻ അൺലോക്ക് ചെയ്യുമ്പോൾ തെറ്റായി ടൈപ്പ് ചെയ്ത പാസ്വേഡുകളുടെ എണ്ണം നിരീക്ഷിച്ച്, നിരവധി തെറ്റായ പാസ്വേഡുകൾ ടൈപ്പ് ചെയ്താൽ ഇൻഫോറ്റേയിൻമെന്റ് സിസ്റ്റം ലോക്ക് ചെയ്യുകയോ ഈ പ്രൊഫൈലിന്റെ ഡാറ്റ മുഴുവനും മായ്ക്കുകയോ ചെയ്യുക."</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ആപ്പ് ഉള്ളടക്കം, അതിന്റെ സുരക്ഷയ്ക്കായി സ്ക്രീൻ പങ്കിടലിൽ നിന്ന് മറച്ചിരിക്കുന്നു"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"സാറ്റലൈറ്റിലേക്ക് സ്വയമേവ കണക്റ്റ് ചെയ്തു"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"മൊബൈലോ വൈഫൈ നെറ്റ്വർക്കോ ഇല്ലാതെ തന്നെ സന്ദേശങ്ങൾ അയയ്ക്കാനും സ്വീകരിക്കാനും നിങ്ങൾക്ക് കഴിയും"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages തുറക്കുക"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index a926e60a02a2..beda8ee3f636 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Аюулгүй байдлын улмаас аппын контентыг дэлгэц хуваалцахаас нуусан"</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> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index c10b7413fd6a..e8b1b8853d03 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -1761,7 +1761,7 @@ <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> + <string name="error_message_change_not_allowed" msgid="843159705042381454">"या बदलासाठी तुमच्या अॅडमिनची अनुमती नाही"</string> <string name="app_not_found" msgid="3429506115332341800">"ही क्रिया हाताळण्यासाठी कोणताही ॲप्लिकेशन आढळला नाही"</string> <string name="revoke" msgid="5526857743819590458">"मागे घ्या"</string> <string name="mediasize_iso_a0" msgid="7039061159929977973">"ISO A0"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"स्क्रीन शेअर करताना सुरक्षेसाठी अॅपमधील आशय लपवला आहे"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"उपग्रहाशी आपोआप कनेक्ट केलेले आहे"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"तुम्ही मोबाइल किंवा वाय-फाय नेटवर्कशिवाय मेसेज पाठवू आणि मिळवू शकता"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages उघडा"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 4a4ea8817b94..add32bb4c6e9 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -844,7 +844,7 @@ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Memadamkan data tablet tanpa amaran dengan melakukan tetapan semula data kilang."</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Padamkan data peranti Android TV anda tanpa amaran dengan melaksanakan tetapan semula data kilang."</string> <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Memadam data sistem maklumat hibur tanpa amaran dengan melakukan tetapan semula data kilang."</string> - <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Padamkan data telefon tanpa amaran dengan melakukan tetapan semula data kilang."</string> + <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Memadam data telefon tanpa amaran dengan melakukan tetapan semula data kilang."</string> <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Padam data profil"</string> <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Padam data pengguna"</string> <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Padam data pengguna ini pada tablet ini tanpa amaran."</string> @@ -1517,7 +1517,7 @@ <string name="input_method_binding_label" msgid="1166731601721983656">"Kaedah input"</string> <string name="sync_binding_label" msgid="469249309424662147">"Penyegerakan"</string> <string name="accessibility_binding_label" msgid="1974602776545801715">"Kebolehaksesan"</string> - <string name="wallpaper_binding_label" msgid="1197440498000786738">"Kertas dinding"</string> + <string name="wallpaper_binding_label" msgid="1197440498000786738">"Hiasan latar"</string> <string name="chooser_wallpaper" msgid="3082405680079923708">"Tukar hiasan latar"</string> <string name="notification_listener_binding_label" msgid="2702165274471499713">"Pendengar pemberitahuan"</string> <string name="vr_listener_binding_label" msgid="8013112996671206429">"Pendengar VR"</string> @@ -1726,7 +1726,7 @@ <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kawalan penuh sesuai untuk apl yang membantu anda berkaitan dengan keperluan kebolehaksesan tetapi bukan untuk kebanyakan apl."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Melihat dan mengawal skrin"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ciri ini boleh membaca semua kandungan pada skrin dan memaparkan kandungan di atas apl lain."</string> - <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Lihat dan laksanakan tindakan"</string> + <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Melihat dan melaksanakan tindakan"</string> <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Ciri ini boleh menjejaki interaksi anda dengan apl atau penderia perkakasan dan berinteraksi dengan apl bagi pihak anda."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Benarkan"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Tolak"</string> @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Ujian"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Umum"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Kandungan apl disembunyikan daripada perkongsian skrin untuk keselamatan"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Disambungkan secara automatik kepada satelit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Anda boleh menghantar dan menerima mesej tanpa rangkaian mudah alih atau Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Messages"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 834613414a31..3de8fb544ac8 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -995,7 +995,7 @@ <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"မှန်ပါသည်"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"ထပ် စမ်းပါ"</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"ထပ် စမ်းပါ"</string> - <string name="lockscreen_storage_locked" msgid="634993789186443380">"ဝန်ဆောင်မှုနှင့် ဒေတာအားလုံးအတွက် လော့ခ်ဖွင့်ပါ"</string> + <string name="lockscreen_storage_locked" msgid="634993789186443380">"ဝန်ဆောင်မှုနှင့် ဒေတာအားလုံးသုံးရန် လော့ခ်ဖွင့်ပါ"</string> <string name="faceunlock_multiple_failures" msgid="681991538434031708">"မျက်မှာပြ လော့ခ်ဖွင့်ခြင်း ခွင့်ပြုသော အကြိမ်ရေထက် ကျော်လွန်သွားပါပြီ"</string> <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"ဆင်းမ်ကတ် မရှိပါ"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"တက်ဘလက်တွင် ဆင်းမ်ကတ်မရှိပါ။"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"အက်ပ်အကြောင်းအရာသည် လုံခြုံရေးအတွက် မျက်နှာပြင် မျှဝေခြင်းမှ ဖျောက်ထားသည်"</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">"Messages ဖွင့်ရန်"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 252b4138d8f0..b380199b3c36 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Felles"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Av sikkerhetsgrunner er appinnholdet skjult for skjermdelingen"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatisk tilkoblet satellitt"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan sende og motta meldinger uten mobil- eller wifi-nettverk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Åpne Meldinger"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 6035bb19312d..a4867974c880 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -340,7 +340,7 @@ <string name="permgrouplab_sensors" msgid="9134046949784064495">"बडी सेन्सरहरू"</string> <string name="permgroupdesc_sensors" msgid="2610631290633747752">"तपाईंको महत्त्वपूर्ण संकेत बारे सेन्सर डेटा पहुँच गर्नुहोस्"</string> <string name="permgrouplab_notifications" msgid="5472972361980668884">"सूचनाहरू"</string> - <string name="permgroupdesc_notifications" msgid="4608679556801506580">"सूचनाहरू देखाइयोस्"</string> + <string name="permgroupdesc_notifications" msgid="4608679556801506580">"सूचनाहरू देखाउनुहोस्"</string> <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"विन्डो सामग्रीको पुनःबहाली गर्नुहोस्।"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"तपाईँको अन्तरक्रिया भइरहेको विन्डोको सामग्रीको निरीक्षण गर्नुहोस्।"</string> <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"छोएर गरिने खोजलाई सुचारु गर्नुहोस्"</string> @@ -362,7 +362,7 @@ <string name="permdesc_statusBarService" msgid="6652917399085712557">"एपलाई स्थिति पट्टि हुन अनुमति दिन्छ।"</string> <string name="permlab_expandStatusBar" msgid="1184232794782141698">"स्थिति पट्टिलाई विस्तृत/सङ्कुचित गर्नुहोस्"</string> <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"एपलाई स्थिति पट्टि विस्तार वा संकुचन गर्न अनुमति दिन्छ।"</string> - <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लक गरिएको डिभाइसमा स्क्रिनभरि देखिने सूचनाहरू देखाइयोस्"</string> + <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लक गरिएको डिभाइसमा स्क्रिनभरि देखिने सूचनाहरू देखाउनुहोस्"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"यो अनुमति दिइएमा एपले लक गरिएको डिभाइसमा स्क्रिनभरि देखिने सूचनाहरू देखाउन सक्छ"</string> <string name="permlab_install_shortcut" msgid="7451554307502256221">"सर्टकट इन्स्टल गर्ने"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा हाल्ने अनुमति दिन्छ।"</string> @@ -395,7 +395,7 @@ <string name="permlab_receiveWapPush" msgid="4223747702856929056">"टेक्स्ट म्यासेजहरू (WAP) प्राप्त गर्नुहोस्"</string> <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"WAP म्यासेजहरू प्राप्त गर्न र प्रशोधन गर्न एपलाई अनुमति दिन्छ। यो अनुमतिमा मोनिटर गर्ने वा तपाईँलाई पठाइएका म्यासेजहरू तपाईँलाई नदेखाई मेट्ने क्षमता समावेश हुन्छ।"</string> <string name="permlab_getTasks" msgid="7460048811831750262">"चलिरहेका एपहरू पुनःबहाली गर्नुहोस्"</string> - <string name="permdesc_getTasks" msgid="7388138607018233726">"वर्तमानमा र भरखरै चलिरहेका कार्यहरू बारेको सूचना पुनःबहाली गर्न एपलाई अनुमित दिन्छ। यसले उपकरणमा प्रयोग भएका अनुप्रयोगहरूको बारेमा सूचना पत्ता लगाउन एपलाई अनुमति दिन सक्छ।"</string> + <string name="permdesc_getTasks" msgid="7388138607018233726">"वर्तमानमा र भरखरै चलिरहेका कार्यहरू बारेको सूचना पुनःबहाली गर्न एपलाई अनुमित दिन्छ। यसले उपकरणमा प्रयोग भएका एपहरूको बारेमा सूचना पत्ता लगाउन एपलाई अनुमति दिन सक्छ।"</string> <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"प्रोफाइल र यन्त्र मालिकहरूको व्यवस्थापन गराउनुहोस्"</string> <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"एपहरूलाई प्रोफाइल र यन्त्र मालिकहरू सेट गर्ने अनुमति दिनुहोस्।"</string> <string name="permlab_reorderTasks" msgid="7598562301992923804">"चलिरहेका एपहरूलाई पुनःक्रम गराउनुहोस्"</string> @@ -403,7 +403,7 @@ <string name="permlab_enableCarMode" msgid="893019409519325311">"कार मोड सक्षम गर्नुहोस्"</string> <string name="permdesc_enableCarMode" msgid="56419168820473508">"कार मोडलाई सक्षम पार्न एपलाई अनुमति दिन्छ।"</string> <string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"एपहरू बन्द गर्नुहोस्"</string> - <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"एपलाई अन्य अनुप्रयोगहरूको पृष्ठभूमि प्रक्रियाहरू बन्द गर्न अनुमति दिन्छ। यसले अन्य एपहरूलाई चल्नबाट रोक्न सक्दछ।"</string> + <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"एपलाई अन्य एपहरूको पृष्ठभूमि प्रक्रियाहरू बन्द गर्न अनुमति दिन्छ। यसले अन्य एपहरूलाई चल्नबाट रोक्न सक्दछ।"</string> <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"यो एप अन्य एपहरूमाथि देखा पर्न सक्छ"</string> <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"यो एप अन्य एपहरूमाथि वा स्क्रिनका अन्य भागहरूमा देखा पर्न सक्छ। यसले एपको सामान्य प्रयोगमा अवरोध पुर्याउन सक्छ र अन्य एपहरू देखा पर्ने तरिकालाई परिवर्तन गर्न सक्छ।"</string> <string name="permlab_hideOverlayWindows" msgid="6382697828482271802">"एपका अन्य ओभरलेहरू लुकाउने अनुमति"</string> @@ -452,7 +452,7 @@ <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"यसले एपलाई \"specialUse\" सँग सम्बन्धित फोरग्राउन्ड सेवाहरू प्रयोग गर्ने अनुमति दिन्छ"</string> <string name="permlab_getPackageSize" msgid="375391550792886641">"एप भण्डारण ठाउँको मापन गर्नुहोस्"</string> <string name="permdesc_getPackageSize" msgid="742743530909966782">"एपलाई यसको कोड, डेटा, र क्यास आकारहरू पुनःप्राप्त गर्न अनुमति दिन्छ।"</string> - <string name="permlab_writeSettings" msgid="8057285063719277394">"प्रणाली सेटिङहरू परिमार्जन गर्नुहोस्"</string> + <string name="permlab_writeSettings" msgid="8057285063719277394">"सिस्टम सेटिङ परिमार्जन गर्नुहोस्"</string> <string name="permdesc_writeSettings" msgid="8293047411196067188">"सिस्टमका सेटिङ डेटालाई परिवर्तन गर्नको लागि एपलाई अनुमति दिन्छ। खराब एपहरूले सायद तपाईँको प्रणालीको कन्फिगरेसनलाई क्षति पुर्याउन सक्छन्।"</string> <string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"स्टार्टअपमा चलाउनुहोस्"</string> <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"आनुप्रयोगलाई प्रणाली बुट प्रक्रिया पूर्ण हुने बितिकै आफैलाई सुरु गर्ने अनुमति दिन्छ। यसले ट्याब्लेट सुरु गर्नमा ढिला गर्न सक्दछ र एपलाई समग्रमा ट्याब्लेट सधैँ चालु गरेर ढिला बनाउँदछ।"</string> @@ -476,9 +476,9 @@ <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"आगमन तथा बहर्गमन डेटासहित तपाईँको ट्याब्लेटको कल लगको परिमार्जन गर्न एपलाई अनुमति दिन्छ। खराब एपहरूले यसलाई तपाईँको कल लग परिमार्जन गर्न वा मेटाउन प्रयोग गर्न सक्छन्।"</string> <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"एपलाई तपाईंको Android टिभी डिभाइसको आगमन र बहिर्गमन कलसम्बन्धी डेटासहित कल लग परिमार्जन गर्ने अनुमति दिन्छ। हानिकारक एपहरूले यसलाई तपाईंको कल लग मेटाउन वा परिमार्जन गर्न प्रयोग गर्न सक्छन्।"</string> <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"एपलाई तपाईंको फोनको आउने र बाहिर जाने कलहरूको बारेको डेटा सहित कल लग परिमार्जन गर्न अनुमति दिन्छ। खराब एपहरूले यसलाई तपाईंको कल लग मेटाउन वा परिमार्जन गर्न प्रयोग गर्न सक्दछ।"</string> - <string name="permlab_bodySensors" msgid="662918578601619569">"प्रयोग गरिएका बेला हृदयको गति जस्ता बडी सेन्सरसम्बन्धी डेटा हेरियोस् र प्रयोग गरियोस्"</string> + <string name="permlab_bodySensors" msgid="662918578601619569">"प्रयोग गरिएका बेला हृदयको गति जस्ता बडी सेन्सरसम्बन्धी डेटा हेरियोस् र प्रयोग गर्नुहोस्"</string> <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"यसले यो एप प्रयोग गरिँदै गरेका बेला यसलाई हृदयको गति, शरीरको तापक्रम तथा रगतमा रहेको अक्सिजनको प्रतिशत जस्ता बडी सेन्सरसम्बन्धी डेटा हेर्ने तथा प्रयोग गर्ने अनुमति दिन्छ।"</string> - <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ब्याकग्राउन्डमा चलेका बेला हृदयको गति जस्ता बडी सेन्सरसम्बन्धी डेटा हेरियोस् र प्रयोग गरियोस्"</string> + <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ब्याकग्राउन्डमा चलेका बेला हृदयको गति जस्ता बडी सेन्सरसम्बन्धी डेटा हेरियोस् र प्रयोग गर्नुहोस्"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"यसले यो एप ब्याकग्राउन्डमा चलेका बेला यसलाई हृदयको गति, शरीरको तापक्रम तथा रगतमा रहेको अक्सिजनको प्रतिशत जस्ता बडी सेन्सरसम्बन्धी डेटा हेर्ने तथा प्रयोग गर्ने अनुमति दिन्छ।"</string> <string name="permlab_readCalendar" msgid="6408654259475396200">"पात्रोका कार्यक्रम र विवरणहरू पढ्ने"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"यस एपले तपाईंको ट्याब्लेटमा भण्डारण गरिएका पात्रो सम्बन्धी सबै कार्यक्रमहरू पढ्न र तपाईंको पात्रोको डेटा आदान प्रदान वा सुरक्षित गर्न सक्छ।"</string> @@ -615,7 +615,7 @@ <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"कुनै सम्बन्धित पासवर्ड सुरक्षा र किलकलाई असक्षम पार्न एपलाई अनुमति दिन्छ। उदाहरणको लागि, अन्तर्गमन फोन कल प्राप्त गर्दा फोनले किलकलाई असक्षम पार्छ, त्यसपछि कल सकिएको बेला किलक पुनःसक्षम पार्छ।"</string> <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"स्क्रिन लकको जटिलतासम्बन्धी जानकारी प्राप्त गर्ने अनुरोध गर्नुहोस्"</string> <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"यसले एपलाई स्क्रिन लकको जटिलताको स्तर (उच्च, मध्यम, न्यून वा कुनै पनि होइन) थाहा पाउने अनुमति दिन्छ जसले स्क्रिन लकको लम्बाइको सम्भावित दायरा र त्यसको प्रकारलाई जनाउँछ। यसै गरी, यो एपले प्रयोगकर्ताहरूलाई स्क्रिन लक अद्यावधिक गर्ने सुझाव पनि दिन सक्छ तर प्रयोगकर्ताहरू उक्त सुझावको बेवास्ता गरी बाहिर निस्कन सक्छन्। स्क्रिन लक सादा पाठको ढाँचामा भण्डारण नगरिने हुँदा यो एपलाई वास्तविक पासवर्ड थाहा नहुने कुराको हेक्का राख्नुहोस्।"</string> - <string name="permlab_postNotification" msgid="4875401198597803658">"सूचनाहरू देखाइयोस्"</string> + <string name="permlab_postNotification" msgid="4875401198597803658">"सूचनाहरू देखाउनुहोस्"</string> <string name="permdesc_postNotification" msgid="5974977162462877075">"यो एपलाई सूचना देखाउन दिनुहोस्"</string> <string name="permlab_turnScreenOn" msgid="219344053664171492">"स्क्रिन अन गर्ने"</string> <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"यो एपलाई स्क्रिन अन गर्ने अनुमति दिन्छ।"</string> @@ -782,35 +782,35 @@ <string name="permlab_control_incall_experience" msgid="6436863486094352987">"आउने-कल प्रयोगकर्ता अनुभव प्रदान गर्नुहोस्"</string> <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"एपलाई आउने-कल प्रयोगकर्ता अनुभव प्रदान गर्न अनुमति दिन्छ।"</string> <string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"नेटवर्क उपयोगको इतिहास पढ्नुहोस्"</string> - <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"निश्चित नेटवर्कहरू र अनुप्रयोगहरूको लागि ऐतिहासिक नेटवर्क उपयोग पढ्नको लागि एपलाई अनुमति दिन्छ।"</string> + <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"निश्चित नेटवर्कहरू र एपहरूको लागि ऐतिहासिक नेटवर्क उपयोग पढ्नको लागि एपलाई अनुमति दिन्छ।"</string> <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"नेटवर्क नीति प्रबन्ध गर्नुहोस्"</string> <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"नेटवर्क नीतिहरू व्यवस्थापन गर्न र एप-विशेष नियमहरू परिभाषित गर्न एपलाई अनुमति दिन्छ।"</string> <string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"नेटवर्क उपयोग लेखालाई परिमार्जन गर्नुहोस्"</string> - <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"एपलाई कसरी अनुप्रयोगहरूको विरूद्धमा कसरी नेटवर्क उपयोगी अकाउन्टेड छ भनेर परिमार्जन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूद्वारा प्रयोगको लागि होइन।"</string> + <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"एपलाई कसरी एपहरूको विरूद्धमा कसरी नेटवर्क उपयोगी अकाउन्टेड छ भनेर परिमार्जन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूद्वारा प्रयोगको लागि होइन।"</string> <string name="permlab_accessNotifications" msgid="7130360248191984741">"सूचनाहरू पहुँच गर्नुहोस्"</string> <string name="permdesc_accessNotifications" msgid="761730149268789668">"अन्य एपहरूबाट पोस्ट गरिएकासहित पुनःप्राप्त गर्न, परीक्षण गर्न र सूचनाहरू हटाउन एपहरूलाई अनुमति दिन्छ।"</string> <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"जानकारी श्रोता सेवामा बाँध्नुहोस्"</string> <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"होल्डरलाई सूचना श्रोता सेवाको शीर्ष-स्तरको इन्टरफेस बाँध्न अनुमति दिन्छ। सामान्य एपहरूलाई कहिले पनि आवश्यक नपर्न सक्दछ।"</string> <string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"सर्त प्रदायक सेवामा जोड्न"</string> - <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"सर्त प्रदायक सेवाको माथिल्लो स्तरको इन्टरफेसमा जोड्न बाहकलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string> + <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"सर्त प्रदायक सेवाको माथिल्लो स्तरको इन्टरफेसमा जोड्न बाहकलाई अनुमति दिन्छ। साधारण एपहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string> <string name="permlab_bindDreamService" msgid="4776175992848982706">"सपना सेवामा बाँध्नुहोस्"</string> - <string name="permdesc_bindDreamService" msgid="9129615743300572973">"होल्डरलाई सपना सेवाको माथिल्लो स्तरको इन्टरफेसमा बाँध्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string> + <string name="permdesc_bindDreamService" msgid="9129615743300572973">"होल्डरलाई सपना सेवाको माथिल्लो स्तरको इन्टरफेसमा बाँध्न अनुमति दिन्छ। साधारण एपहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string> <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"वाहक-प्रदान विन्यास एप सुरु गर्नुहोस्"</string> <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"प्रयोगकर्तालाई वाहक-प्रदान विन्यास एप सुरु गर्न अनुमति दिन्छ। साधारण एपहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string> <string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"सञ्जाल अवस्थाका पर्यवेक्षणका लागि सुन्नुहोस्"</string> <string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"सञ्जाल अवस्थाका पर्यवेक्षण सुन्नका लागि एपलाई अनुमति दिन्छ।सामान्य एपलाई चाँहिदै नचाँहिन सक्छ।"</string> - <string name="permlab_setInputCalibration" msgid="932069700285223434">"इनपुट उपकरण क्यालिब्रेसन परिवर्तन गर्नुहोस्"</string> - <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"एपलाई टच स्क्रीनको प्यारामिटरहरू क्यालिब्रेसन परिमार्जन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै आवश्यक पर्दैन।"</string> + <string name="permlab_setInputCalibration" msgid="932069700285223434">"इनपुट डिभाइस क्यालिब्रेसन परिवर्तन गर्नुहोस्"</string> + <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"एपलाई टच स्क्रीनको प्यारामिटरहरू क्यालिब्रेसन परिमार्जन गर्न अनुमति दिन्छ। साधारण एपहरूको लागि कहिल्यै आवश्यक पर्दैन।"</string> <string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"DRM प्रमाणपत्रको पहुँच"</string> - <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"DRM प्रमाणपत्रहरू प्रावधान र प्रयोग गर्ने निवेदनको अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string> + <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"DRM प्रमाणपत्रहरू प्रावधान र प्रयोग गर्ने निवेदनको अनुमति दिन्छ। साधारण एपहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string> <string name="permlab_handoverStatus" msgid="7620438488137057281">"Android Beam स्थानान्तरण अवस्था प्राप्त गर्नुहोस्"</string> <string name="permdesc_handoverStatus" msgid="3842269451732571070">"यस आवेदनले वर्तमान Android Beam स्थानान्तरण बारेमा जानकारी प्राप्त गर्न अनुमति दिन्छ"</string> <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"DRM सर्टिफिकेट हटाउनुहोस्"</string> - <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"DRM प्रमाणपत्रहरू हटाउन एपलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूको लागि कहिल्यै आवश्यकता पर्दैन।"</string> + <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"DRM प्रमाणपत्रहरू हटाउन एपलाई अनुमति दिन्छ। सामान्य एपहरूको लागि कहिल्यै आवश्यकता पर्दैन।"</string> <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"वाहक मेसेजिङ सेवामा आबद्ध हुनुहोस्"</string> <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"धारकलाई वाहक मेसेजिङ सेवाको उच्च-स्तरको इन्टरफेसमा आबद्ध हुन अनुमति दिनुहोस्। सामान्य एपहरूको लागि कहिल्यै आवश्यकता पर्दैन।"</string> <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"वाहक सेवाहरु बाँध्न"</string> - <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"होल्डरलाई वाहक सेवाहरु बाँध्न अनुमति दिनुहोस्। सामान्य अनुप्रयोगहरूको लागि यो कहिल्यै आवश्यक पर्दैन।"</string> + <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"होल्डरलाई वाहक सेवाहरु बाँध्न अनुमति दिनुहोस्। सामान्य एपहरूको लागि यो कहिल्यै आवश्यक पर्दैन।"</string> <string name="permlab_access_notification_policy" msgid="5524112842876975537">"बाधा नपुर्याउँनुहोस् पहुँच गर्नुहोस्"</string> <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"बाधा नपुर्याउँनुहोस् कन्फिगरेसन पढ्न र लेख्नको लागि एपलाई अनुमति दिनुहोस्।"</string> <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"हेर्ने अनुमतिको प्रयोग सुरु गर्नुहोस्"</string> @@ -821,7 +821,7 @@ <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"होल्डरलाई एपका सुविधासम्बन्धी जानकारी हेर्न दिन्छ।"</string> <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"नमुना लिने उच्च दरमा सेन्सरसम्बन्धी डेटा प्रयोग गर्ने"</string> <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"यो अनुमति दिइएमा एपले २०० हर्जभन्दा बढी दरमा सेन्सरसम्बन्धी डेटाको नमुना लिन सक्छ"</string> - <string name="permlab_updatePackagesWithoutUserAction" msgid="3363272609642618551">"एप स्वतः अपडेट गरियोस्"</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> @@ -830,11 +830,11 @@ <string name="policylab_watchLogin" msgid="7599669460083719504">"स्क्रिन अनलक गर्न गरिएको प्रयासको अनुगमन गर्ने"</string> <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप भएको संख्या निरीक्षण गर्नुहोस् र यदि निकै धेरै गलत पासवर्डहरू टाइप भएका छन भने ट्याब्लेट लक गर्नुहोस् वा ट्याब्लेटका सबै डेटा मेट्नुहोस्।"</string> <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप गरेको सङ्ख्या निरीक्षण गर्नुहोस्, र धेरै पटक गलत पासवर्डहरू टाइप गरिएको खण्डमा आफ्नो Android टिभी यन्त्र लक गर्नुहोस् वा डिभाइसमा भएको सम्पूर्ण डेटा मेटाउनुहोस्।"</string> - <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुरा निगरानी गरियोस् र अत्यन्तै धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा यो इन्फोटेनमेन्ट प्रणाली लक गरियोस् वा यस इन्फोटेनमेन्ट प्रणालीका सबै डेटा मेटाइयोस्।"</string> + <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुरा निगरानी गर्नुहोस् र अत्यन्तै धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा यो इन्फोटेनमेन्ट प्रणाली लक गर्नुहोस् वा यस इन्फोटेनमेन्ट प्रणालीका सबै डेटा मेटाउनुहोस्।"</string> <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप भएको छ हेर्नुहोस् र निकै धेरै पटक गलत पासवर्ड टाइप भएको भने फोन लक गर्नुहोस् वा फोनका सबै डेटा मेट्नुहोस्।"</string> <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप संख्या अनुगमन गर्नुहोस्, र यदि निकै धेरै गलत पासवर्डहरू टाइप गरिएमा ट्याब्लेट लक गर्नुहोस् वा प्रयोगकर्ताको डेटा मेटाउनुहोस्।"</string> <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप गरेको सङ्ख्या निरीक्षण गर्नुहोस्, र धेरै पटक गलत पासवर्डहरू टाइप गरिएको खण्डमा आफ्नो Android टिभी यन्त्र लक गर्नुहोस् वा यो प्रयोगकर्ताको सम्पूर्ण डेटा मेटाउनुहोस्।"</string> - <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुरा निगरानी गरियोस् र अत्यन्तै धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा यो इन्फोटेनमेन्ट प्रणाली लक गरियोस् वा यस प्रोफाइलका सबै डेटा मेटाइयोस्।"</string> + <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुरा निगरानी गर्नुहोस् र अत्यन्तै धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा यो इन्फोटेनमेन्ट प्रणाली लक गर्नुहोस् वा यस प्रोफाइलका सबै डेटा मेटाउनुहोस्।"</string> <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप संख्या अनुगमन गर्नुहोस्, र यदि निकै धेरै गलत पासवर्डहरू टाइप गरिएमा फोन लक गर्नुहोस् वा प्रयोगकर्ताको डेटा मेटाउनुहोस्।"</string> <string name="policylab_resetPassword" msgid="214556238645096520">"स्क्रिन लक परिवर्तन गर्ने"</string> <string name="policydesc_resetPassword" msgid="4626419138439341851">"स्क्रिन लक परिवर्तन गर्नुहोस्।"</string> @@ -843,13 +843,13 @@ <string name="policylab_wipeData" msgid="1359485247727537311">"सबै डेटा मेट्ने"</string> <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"फ्याक्ट्रूी रिसेट गरेर चेतावनी नआउँदै ट्याबल्टको डेटा मेट्नुहोस्।"</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"फ्याक्ट्री डेटा रिसेट गरेर चेतावनी नदिइकन आफ्नो Android टिभी डिभाइसको डेटा मेटाउनुहोस्।"</string> - <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"यो इन्फोटेनमेन्ट प्रणालीको डेटा कुनै चेतावनीविनै फ्याक्ट्री डेटा रिसेट गरेर मेटाइयोस्।"</string> - <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"फ्याक्ट्रूी रिसेट गरेर चेतावनी नदिइकन फोनको डेटा मेट्न।"</string> - <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"प्रोफाइल डेटा मेटाइयोस्"</string> + <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"यो इन्फोटेनमेन्ट प्रणालीको डेटा कुनै चेतावनीविनै फ्याक्ट्री डेटा रिसेट गरेर मेटाउनुहोस्।"</string> + <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"फ्याक्ट्रूी रिसेट गरेर चेतावनी नदिइकन फोनको डेटा मेट्नुहोस्।"</string> + <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"प्रोफाइल डेटा मेटाउनुहोस्"</string> <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"प्रयोगकर्ता डेटा मेट्नुहोस्"</string> <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"चेतावनी बिना यो ट्याब्लेटमा यस प्रयोगकर्ताको डेटा मेट्नुहोस्।"</string> <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"यो Android टिभी डिभाइसमा भएको यस प्रयोगकर्ताको डेटा चेतावनी नदिइकन मेटाउनुहोस्।"</string> - <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"यो इन्फोटेनमेन्ट प्रणालीमा भएको यस प्रोफाइलको डेटा कुनै चेतावनीविनै मेटाइयोस्।"</string> + <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"यो इन्फोटेनमेन्ट प्रणालीमा भएको यस प्रोफाइलको डेटा कुनै चेतावनीविनै मेटाउनुहोस्।"</string> <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"चेतावनी बिना यो फोनमा यस प्रयोगकर्ताको डेटा मेट्नुहोस्।"</string> <string name="policylab_setGlobalProxy" msgid="215332221188670221">"उपकरण विश्वव्यापी प्रोक्सी मिलाउनुहोस्"</string> <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"नीति सक्षम हुँदा प्रयोग गरिनको लागि यन्त्र ग्लोवल प्रोक्सी सेट गर्नुहोस्। केवल यन्त्र मालिकले ग्लोवल प्रोक्सी सेट गर्न सक्नुहुन्छ।"</string> @@ -1405,7 +1405,7 @@ <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"परीक्षण प्याकेज मोड सक्षम पारियो"</string> <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"परीक्षण प्याकेज मोड असक्षम पार्न फ्याक्ट्री रिसेट गर्नुहोस्।"</string> <string name="console_running_notification_title" msgid="6087888939261635904">"क्रमसम्बन्धी कन्सोल सक्षम पारियो"</string> - <string name="console_running_notification_message" msgid="7892751888125174039">"कार्यसम्पादनमा प्रभाव परेको छ। यसलाई असक्षम पार्न बुटलोडरको जाँच गर्नुहोस्।"</string> + <string name="console_running_notification_message" msgid="7892751888125174039">"पर्फर्मेन्समा प्रभाव परेको छ। यसलाई असक्षम पार्न बुटलोडरको जाँच गर्नुहोस्।"</string> <string name="mte_override_notification_title" msgid="4731115381962792944">"परीक्षणका क्रममा रहेको MTE अन गरियो"</string> <string name="mte_override_notification_message" msgid="2441170442725738942">"पर्फर्मेन्स र स्थिरता प्रभावित हुन सक्छ। अफ गर्न रिबुट गर्नुहोस्। तपाईंले arm64.memtag.bootctl प्रयोग गरी अन गर्नुभएको थियो भने अफ गर्नुअघि यसलाई परिवर्तन गरी \"कुनै पनि होइन\" बनाउनुहोस्।"</string> <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"USB पोर्टमा तरल पदार्थ वा धुलो भएको कुरा पत्ता लाग्यो"</string> @@ -1419,14 +1419,14 @@ <string name="share_remote_bugreport_action" msgid="7630880678785123682">"सेयर गर्नुहोस्"</string> <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"अस्वीकार गर्नुहोस्"</string> <string name="select_input_method" msgid="3971267998568587025">"निवेश विधि छान्नुहोस्"</string> - <string name="show_ime" msgid="6406112007347443383">"फिजिकल किबोर्ड सक्रिय हुँदा यसलाई स्क्रिनमा राखियोस्"</string> + <string name="show_ime" msgid="6406112007347443383">"फिजिकल किबोर्ड सक्रिय हुँदा यसलाई स्क्रिनमा राख्नुहोस्"</string> <string name="hardware" msgid="3611039921284836033">"अनस्क्रिन किबोर्ड प्रयोग गर्नुहोस्"</string> <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> कन्फिगर गर्नुहोस्"</string> <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"भौतिक किबोर्डहरू कन्फिगर गर्नुहोस्"</string> <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"भाषा र लेआउट चयन गर्न ट्याप गर्नुहोस्"</string> <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"अरू एपमाथि देखाइयोस्"</string> + <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"अरू एपमाथि देखाउनुहोस्"</string> <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> अन्य एपहरूमा देखिँदैछ"</string> <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> अन्य एपहरूमा देखिँदैछ"</string> <string name="alert_windows_notification_message" msgid="6538171456970725333">"तपाईं <xliff:g id="NAME">%s</xliff:g> ले यो विशेषता प्रयोग नगरेको चाहनुहुन्न भने सेटिङहरू खोली यसलाई निष्क्रिय पार्न ट्याप गर्नुहोस्।"</string> @@ -1718,11 +1718,11 @@ <string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string> <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"<xliff:g id="SERVICE">%1$s</xliff:g> प्रयोग गर्न सर्टकट अन गर्ने हो?"</string> <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"केही सेकेन्डसम्म दुवै भोल्युम की थिचिराख्नुले <xliff:g id="SERVICE">%1$s</xliff:g> नामक पहुँचसम्बन्धी सुविधा सक्रिय गर्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nतपाईं सेटिङ > पहुँचमा गई यो सर्टकटमार्फत अर्को सुविधा खुल्ने बनाउन सक्नुहुन्छ।"</string> - <string name="accessibility_shortcut_on" msgid="5463618449556111344">"सक्रिय गरियोस्"</string> - <string name="accessibility_shortcut_off" msgid="3651336255403648739">"सक्रिय नगरियोस्"</string> + <string name="accessibility_shortcut_on" msgid="5463618449556111344">"सक्रिय गर्नुहोस्"</string> + <string name="accessibility_shortcut_off" msgid="3651336255403648739">"सक्रिय नगर्नुहोस्"</string> <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"सक्रिय"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"निष्क्रिय"</string> - <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> लाई तपाईंको यन्त्र पूर्ण रूपमा नियन्त्रण गर्न दिने हो?"</string> + <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> लाई तपाईंको डिभाइस पूर्ण रूपमा नियन्त्रण गर्न दिने हो?"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"एक्सेसिबिलिटीसम्बन्धी आवश्यकतामा सहयोग गर्ने एपको पूर्ण नियन्त्रण गर्न दिनु उपयुक्त हुन्छ तर अधिकांश एपका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"स्क्रिन हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"यसले स्क्रिनमा देखिने सबै सामग्री पढ्न सक्छ र अन्य एपहरूमा उक्त सामग्री देखाउन सक्छ।"</string> @@ -1741,10 +1741,10 @@ <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"सर्टकटलाई निष्क्रिय पार्नुहोस्"</string> <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"सर्टकट प्रयोग गर्नुहोस्"</string> <string name="color_inversion_feature_name" msgid="2672824491933264951">"कलर इन्भर्सन"</string> - <string name="color_correction_feature_name" msgid="7975133554160979214">"रङ सच्याउने सुविधा"</string> + <string name="color_correction_feature_name" msgid="7975133554160979214">"कलर करेक्सन"</string> <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"एक हाते मोड"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"अझै मधुरो"</string> - <string name="hearing_aids_feature_name" msgid="1125892105105852542">"श्रवण यन्त्रहरू"</string> + <string name="hearing_aids_feature_name" msgid="1125892105105852542">"हियरिङ डिभाइसहरू"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन भयो।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अफ भयो।"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"भोल्युम बटनहरू थिच्न छाड्नुहोस्। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन गर्न दुवै भोल्युम बटन फेरि ३ सेकेन्डसम्म थिचिराख्नुहोस्।"</string> @@ -2167,7 +2167,7 @@ <string name="car_loading_profile" msgid="8219978381196748070">"लोड गर्दै"</string> <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # फाइल}other{{file_name} + # वटा फाइल}}"</string> <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"कुनै पनि व्यक्तिसँग सेयर गर्ने सिफारिस गरिएको छैन"</string> - <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"अनुप्रयोगहरूको सूची"</string> + <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"एपहरूको सूची"</string> <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"यो एपलाई रेकर्ड गर्ने अनुमति प्रदान गरिएको छैन तर यसले यो USB यन्त्रमार्फत अडियो क्याप्चर गर्न सक्छ।"</string> <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"होम"</string> <string name="accessibility_system_action_back_label" msgid="4205361367345537608">"पछाडि फर्कनुहोस्"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"स्क्रिन सेयर गर्दा सुरक्षाका लागि एपमा भएको सामग्री लुकाइएको छ"</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">"Messages खोल्नुहोस्"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 5870ca36e92c..098162320d17 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -830,12 +830,12 @@ <string name="policylab_watchLogin" msgid="7599669460083719504">"Pogingen voor schermontgrendeling bijhouden"</string> <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Bijhouden hoe vaak onjuiste wachtwoorden worden ingevoerd wanneer het scherm wordt ontgrendeld en de tablet vergrendelen of alle gegevens op de tablet wissen als te veel onjuiste wachtwoorden worden ingevoerd."</string> <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Bijhouden hoe vaak onjuiste wachtwoorden worden ingevoerd wanneer het scherm wordt ontgrendeld en het Android TV-apparaat vergrendelen of alle gegevens van het Android TV-apparaat wissen als te veel onjuiste wachtwoorden worden ingevoerd."</string> - <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Bijhouden hoe vaak onjuiste wachtwoorden worden getypt als het scherm wordt ontgrendeld, en het infotainmentsysteem vergrendelen of alle gegevens op het infotainmentsysteem wissen als te veel onjuiste wachtwoorden worden getypt."</string> + <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Bijhouden hoe vaak onjuiste wachtwoorden worden ingevoerd wanneer het scherm wordt ontgrendeld, en het infotainmentsysteem vergrendelen of alle gegevens op het infotainmentsysteem wissen bij te veel onjuiste wachtwoorden."</string> <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Bijhouden hoe vaak onjuiste wachtwoorden worden ingevoerd wanneer het scherm wordt ontgrendeld en de telefoon vergrendelen of alle gegevens op de telefoon wissen als te veel onjuiste wachtwoorden worden ingevoerd."</string> <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Bijhouden hoe vaak onjuiste wachtwoorden worden ingevoerd wanneer het scherm wordt ontgrendeld en de tablet vergrendelen of alle gegevens van deze gebruiker wissen als te veel onjuiste wachtwoorden worden ingevoerd."</string> <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Bijhouden hoe vaak onjuiste wachtwoorden worden ingevoerd wanneer het scherm wordt ontgrendeld en het Android TV-apparaat vergrendelen of alle gegevens van deze gebruiker wissen als te veel onjuiste wachtwoorden worden ingevoerd."</string> - <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Bijhouden hoe vaak onjuiste wachtwoorden worden getypt als het scherm wordt ontgrendeld, en het infotainmentsysteem vergrendelen of alle gegevens van dit profiel wissen als te veel onjuiste wachtwoorden worden getypt."</string> - <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Bijhouden hoe vaak onjuiste wachtwoorden worden ingevoerd wanneer het scherm wordt ontgrendeld en de telefoon vergrendelen of alle gegevens van deze gebruiker wissen als te veel onjuiste wachtwoorden worden ingevoerd."</string> + <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Bijhouden hoe vaak onjuiste wachtwoorden worden ingevoerd als het scherm wordt ontgrendeld, en het infotainmentsysteem vergrendelen of alle gegevens van dit profiel wissen bij te veel onjuiste wachtwoorden."</string> + <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Bijhouden hoe vaak onjuiste wachtwoorden worden ingevoerd wanneer het scherm wordt ontgrendeld en de telefoon vergrendelen of alle gegevens van deze gebruiker wissen bij te veel onjuiste wachtwoorden."</string> <string name="policylab_resetPassword" msgid="214556238645096520">"De schermvergrendeling wijzigen"</string> <string name="policydesc_resetPassword" msgid="4626419138439341851">"Wijzig de schermvergrendeling."</string> <string name="policylab_forceLock" msgid="7360335502968476434">"Het scherm vergrendelen"</string> @@ -1902,7 +1902,7 @@ <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Met Batterijbesparing wordt het donkere thema aangezet en worden achtergrondactiviteit, bepaalde visuele effecten, bepaalde functies en sommige netwerkverbindingen beperkt of uitgezet."</string> <string name="battery_saver_description" msgid="8518809702138617167">"Met Batterijbesparing wordt het donkere thema aangezet en worden achtergrondactiviteit, bepaalde visuele effecten, bepaalde functies en sommige netwerkverbindingen beperkt of uitgezet."</string> - <string name="data_saver_description" msgid="4995164271550590517">"Databesparing beperkt het datagebruik door te voorkomen dat sommige apps gegevens sturen of ontvangen op de achtergrond. De apps die je open hebt, kunnen nog steeds data verbruiken, maar doen dit minder vaak. Afbeeldingen worden dan bijvoorbeeld niet getoond totdat je erop tikt."</string> + <string name="data_saver_description" msgid="4995164271550590517">"Databesparing beperkt het datagebruik door te voorkomen dat sommige apps gegevens sturen of ontvangen op de achtergrond. De apps die je open hebt, kunnen nog steeds data verbruiken, maar doen dit minder vaak. Afbeeldingen worden bijvoorbeeld pas getoond als je erop tikt."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Databesparing aanzetten?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Aanzetten"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Gedurende 1 minuut (tot {formattedTime})}other{Gedurende # minuten (tot {formattedTime})}}"</string> @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Gemeenschappelijk"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App-content verborgen voor scherm delen vanwege beveiligingsrisico\'s"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch verbonden met satelliet"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Je kunt berichten sturen en krijgen zonder een mobiel of wifi-netwerk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Berichten openen"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 4174d04cf1d1..8b49e6c09a81 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -831,7 +831,7 @@ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ସ୍କ୍ରୀନ୍ ଅନଲକ୍ କରିବାବେଳେ ଟାଇପ୍ କରିଥିବା ଭୁଲ ପାସୱର୍ଡର ସଂଖ୍ୟାକୁ ନୀରିକ୍ଷଣ କରେ ଏବଂ ଟାବଲେଟ୍କୁ ଲକ୍ କରିଦିଏ କିମ୍ବା ଯଦି ଅନେକ ଭୁଲ ପାସୱର୍ଡ ଟାଇପ୍ କରାଯାଇଥାଏ, ତେବେ ଟାବଲେଟ୍ର ସମସ୍ତ ଡାଟା ଲିଭାଇଦିଏ।"</string> <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"ସ୍କ୍ରିନ୍ ଅନ୍ଲକ୍ କରିବା ସମୟରେ ଟାଇପ୍ କରାଯାଇଥିବା ଭୁଲ ପାସ୍ୱାର୍ଡଗୁଡ଼ିକର ସଂଖ୍ୟାକୁ ନିରୀକ୍ଷଣ କରନ୍ତୁ ଏବଂ ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍କୁ ଲକ୍ କରନ୍ତୁ କିମ୍ବା ଯଦି ଅନେକ ଭୁଲ ପାସ୍ୱାର୍ଡ ଟାଇପ୍ କରାଯାଇଥାଏ, ତେବେ ଆପଣଙ୍କ Android TV ଡିଭାଇସ୍ର ସମସ୍ତ ଡାଟା ଲିଭାଇ ଦିଅନ୍ତୁ।"</string> <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"ସ୍କ୍ରିନ ଅନଲକ କରିବା ସମୟରେ ଟାଇପ କରାଯାଇଥିବା ଭୁଲ ପାସୱାର୍ଡର ସଂଖ୍ୟାକୁ ମନିଟର କରନ୍ତୁ ଏବଂ ଇନଫୋଟେନମେଣ୍ଟ ସିଷ୍ଟମକୁ ଲକ କରନ୍ତୁ କିମ୍ବା ଯଦି ଅନେକଗୁଡ଼ିଏ ଭୁଲ ପାସୱାର୍ଡ ଟାଇପ କରାଯାଇଥାଏ ତେବେ ଇନଫୋଟେନମେଣ୍ଟ ସିଷ୍ଟମର ସମସ୍ତ ଡାଟା ଖାଲି କରନ୍ତୁ।"</string> - <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"ଟାଇପ କରାଯାଇଥିବା ଭୁଲ ପାସୱର୍ଡର ସଂଖ୍ୟାକୁ ନୀରିକ୍ଷଣ କରେ। ସ୍କ୍ରିନ ଅନଲକ କରିବାବେଳେ ଏବଂ ଫୋନକୁ ଲକ କରିବା ସମୟରେ ଯଦି ଅନେକ ଭୁଲ ପାସୱର୍ଡ ଟାଇପ କରାଯାଇଥାଏ, ତେବେ ଫୋନର ସମସ୍ତ ଡାଟା ଡିଲିଟ କରେ।"</string> + <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"ଫୋନ ଅନଲକ କରିବା ବେଳେ ଟାଇପ କରାଯାଇଥିବା ଭୁଲ ପାସୱାର୍ଡର ସଂଖ୍ୟାକୁ ନୀରିକ୍ଷଣ କରିବା ଏବଂ ଯଦି ଏକାଧିକ ଥର ଭୁଲ ପାସୱାର୍ଡ ଟାଇପ କରାଯାଇଥାଏ ତେବେ ଫୋନକୁ ଲକ କରିବା ବା ଫୋନର ସମସ୍ତ ଡାଟା ଇରେଜ କରିବା।"</string> <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"ସ୍କ୍ରୀନ୍ ଅନଲକ୍ କରିବାବେଳେ ଟାଇପ୍ କରାଯାଇଥିବା ଭୁଲ ପାସ୍ୱର୍ଡର ସଂଖ୍ୟାକୁ ନୀରିକ୍ଷଣ କରେ ଏବଂ ଟାବଲେଟ୍କୁ ଲକ୍ କରିଦିଏ କିମ୍ବା ଯଦି ଅନେକ ଭୁଲ ପାସ୍ୱର୍ଡ ଟାଇପ୍ କରାଯାଇଥାଏ, ତେବେ ସମସ୍ତ ଡାଟା ଲିଭାଇଦିଏ।"</string> <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"ସ୍କ୍ରିନ୍ ଅନ୍ଲକ୍ କରିବା ସମୟରେ ଟାଇପ୍ କରାଯାଇଥିବା ଭୁଲ ପାସ୍ୱାର୍ଡଗୁଡ଼ିକର ସଂଖ୍ୟାକୁ ନିରୀକ୍ଷଣ କରନ୍ତୁ ଏବଂ ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍କୁ ଲକ୍ କରନ୍ତୁ କିମ୍ବା ଯଦି ଅନେକ ଭୁଲ ପାସ୍ୱାର୍ଡ ଟାଇପ୍ କରାଯାଇଥାଏ, ତେବେ ସମସ୍ତ ଡାଟା ଲିଭାଇ ଦିଅନ୍ତୁ।"</string> <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"ସ୍କ୍ରିନ ଅନଲକ କରିବା ସମୟରେ ଟାଇପ କରାଯାଇଥିବା ଭୁଲ ପାସୱାର୍ଡର ସଂଖ୍ୟାକୁ ମନିଟର କରନ୍ତୁ ଏବଂ ଇନଫୋଟେନମେଣ୍ଟ ସିଷ୍ଟମକୁ ଲକ କରନ୍ତୁ କିମ୍ବା ଯଦି ଅନେକଗୁଡ଼ିଏ ଭୁଲ ପାସୱାର୍ଡ ଟାଇପ କରାଯାଇଥାଏ ତେବେ ଏହି ପ୍ରୋଫାଇଲର ସମସ୍ତ ଡାଟା ଖାଲି କରନ୍ତୁ।"</string> @@ -844,7 +844,7 @@ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ବିନା ଚେତାବନୀରେ ଫ୍ୟାକ୍ଟୋରୀ ସେଟିଙ୍ଗ କରାଇ ଟାବ୍ଲେଟ୍ର ଡାଟା ଲିଭାଇଥାଏ।"</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"ଏକ ଫ୍ୟାକ୍ଟୋରୀ ଡାଟା ରିସେଟ୍ କରି ବିନା ଚେତାବନୀରେ ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍ର ଡାଟା ଲିଭାନ୍ତୁ।"</string> <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"ଏକ ଫ୍ୟାକ୍ଟୋରୀ ଡାଟା ରିସେଟ କରି ବିନା ଚେତାବନୀରେ ଇନଫୋଟେନମେଣ୍ଟ ସିଷ୍ଟମର ଡାଟା ଖାଲି କରନ୍ତୁ।"</string> - <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ବିନା ଚେତାବନୀରେ ଫ୍ୟାକ୍ଟୋରୀ ଡାଟା ରିସେଟ କରି ଫୋନର ଡାଟା ଲିଭାଇଥାଏ।"</string> + <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ବିନା ଚେତାବନୀରେ ଫେକ୍ଟୋରୀ ଡାଟା ରିସେଟ କରି ଫୋନର ଡାଟା ଇରେଜ କରିବା।"</string> <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"ପ୍ରୋଫାଇଲ ଡାଟା ଖାଲି କରନ୍ତୁ"</string> <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"ୟୁଜର୍ ଡାଟା ଲିଭାନ୍ତୁ"</string> <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"ବିନା ଚେତାବନୀରେ ଏହି ଟାବଲେଟରେ ଥିବା ଏହି ୟୁଜରଙ୍କ ଡାଟା ଲିଭାଇ ଦିଅନ୍ତୁ।"</string> @@ -1754,7 +1754,7 @@ <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ଫିଚରଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ।"</string> <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ଫିଚରଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ ଦୁଇଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ୍ କରି ଧରି ରଖନ୍ତୁ।"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ଫିଚରଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ, ତିନୋଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ୍ କରି ଧରି ରଖନ୍ତୁ।"</string> - <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ମ୍ୟାଗ୍ନିଫିକେସନ୍"</string> + <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ମେଗ୍ନିଫିକେସନ"</string> <string name="user_switched" msgid="7249833311585228097">"ବର୍ତ୍ତମାନର ୟୁଜର୍ ହେଉଛନ୍ତି <xliff:g id="NAME">%1$s</xliff:g>।"</string> <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> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ସୁରକ୍ଷା ପାଇଁ ସ୍କ୍ରିନ ସେୟାରରୁ ଆପ ବିଷୟବସ୍ତୁକୁ ଲୁଚାଯାଇଛି"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"ସାଟେଲାଇଟ ସହ ସ୍ୱତଃ କନେକ୍ଟ ହୋଇଛି"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"ଏକ ମୋବାଇଲ କିମ୍ବା ୱାଇ-ଫାଇ ନେଟୱାର୍କ ବିନା ଆପଣ ମେସେଜ ପଠାଇପାରିବେ ଏବଂ ପାଇପାରିବେ"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ଖୋଲନ୍ତୁ"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 3e7b27e9bb8a..282694d32188 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -844,7 +844,7 @@ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ਇੱਕ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਟੈਬਲੈੱਟ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ ਦਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਂਦਾ ਹੈ।"</string> <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਵਾਹਨ ਆਡੀਓ ਸਿਸਟਮ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string> - <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ਇੱਕ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਫ਼ੋਨ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string> + <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰ ਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਫ਼ੋਨ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string> <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"ਪ੍ਰੋਫਾਈਲ ਡਾਟਾ ਮਿਟਾਓ"</string> <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"ਉਪਭੋਗਤਾ ਡਾਟਾ ਮਿਟਾਓ"</string> <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ ਟੈਬਲੈੱਟ ਤੇ ਮੌਜੂਦ ਇਸ ਵਰਤੋਂਕਾਰ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ।"</string> @@ -1724,10 +1724,10 @@ <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ਬੰਦ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"ਕੀ <xliff:g id="SERVICE">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਪੂਰਾ ਕੰਟਰੋਲ ਦੇਣਾ ਹੈ?"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"ਪੂਰਾ ਕੰਟਰੋਲ ਉਨ੍ਹਾਂ ਐਪਾਂ ਲਈ ਢੁਕਵਾਂ ਹੈ ਜੋ ਪਹੁੰਚਯੋਗਤਾ ਸੰਬੰਧੀ ਲੋੜਾਂ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਕਰਦੀਆਂ ਹਨ, ਪਰ ਜ਼ਿਆਦਾਤਰ ਐਪਾਂ ਲਈ ਢੁਕਵਾਂ ਨਹੀਂ ਹੁੰਦਾ।"</string> - <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"ਸਕ੍ਰੀਨ ਨੂੰ ਦੇਖੋ ਅਤੇ ਕੰਟਰੋਲ ਕਰੋ"</string> + <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"ਸਕ੍ਰੀਨ ਨੂੰ ਦੇਖਣਾ ਅਤੇ ਕੰਟਰੋਲ ਕਰਨਾ"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ਇਹ ਸਕ੍ਰੀਨ \'ਤੇ ਸਾਰੀ ਸਮੱਗਰੀ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਸਮੱਗਰੀ ਨੂੰ ਦੂਜੀਆਂ ਐਪਾਂ ਦੇ ਉੱਪਰ ਦਿਖਾ ਸਕਦੀ ਹੈ।"</string> - <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"ਕਾਰਵਾਈਆਂ ਦੇਖੋ ਅਤੇ ਕਰੋ"</string> - <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ਇਹ ਕਿਸੇ ਐਪ ਜਾਂ ਹਾਰਡਵੇਅਰ ਸੈਂਸਰ ਦੇ ਨਾਲ ਤੁਹਾਡੀਆਂ ਅੰਤਰਕਿਰਿਆਵਾਂ ਨੂੰ ਟਰੈਕ ਕਰ ਸਕਦੀ ਹੈ, ਅਤੇ ਤੁਹਾਡੀ ਤਰਫ਼ੋਂ ਐਪਾਂ ਦੇ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰ ਸਕਦੀ ਹੈ।"</string> + <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"ਕਾਰਵਾਈਆਂ ਦੇਖਣਾ ਅਤੇ ਕਰਨਾ"</string> + <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ਇਹ ਕਿਸੇ ਐਪ ਜਾਂ ਹਾਰਡਵੇਅਰ ਸੈਂਸਰ ਦੇ ਨਾਲ ਤੁਹਾਡੀਆਂ ਅੰਤਰਕਿਰਿਆਵਾਂ ਨੂੰ ਟਰੈਕ ਕਰ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੀ ਤਰਫ਼ੋਂ ਐਪਾਂ ਦੇ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰ ਸਕਦੀ ਹੈ।"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ਕਰਨ ਦਿਓ"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"ਨਾ ਕਰਨ ਦਿਓ"</string> <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"ਅਣਸਥਾਪਤ ਕਰੋ"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ਐਪ ਸਮੱਗਰੀ ਨੂੰ ਸੁਰੱਖਿਆ ਲਈ ਸਕ੍ਰੀਨ ਸਾਂਝਾਕਰਨ ਤੋਂ ਲੁਕਾਇਆ ਗਿਆ ਹੈ"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"ਸੈਟੇਲਾਈਟ ਨਾਲ ਸਵੈ-ਕਨੈਕਟ ਹੋਇਆ"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"ਤੁਸੀਂ ਮੋਬਾਈਲ ਜਾਂ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਤੋਂ ਬਿਨਾਂ ਸੁਨੇਹੇ ਭੇਜ ਅਤੇ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ਐਪ ਖੋਲ੍ਹੋ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index ca126f794c06..470191581044 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -997,7 +997,7 @@ <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Poprawnie!"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Spróbuj ponownie."</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Spróbuj ponownie."</string> - <string name="lockscreen_storage_locked" msgid="634993789186443380">"Odblokowanie wszystkich funkcji i danych"</string> + <string name="lockscreen_storage_locked" msgid="634993789186443380">"Odblokuj, by używać wszystkich funkcji i danych"</string> <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Przekroczono maksymalną liczbę prób rozpoznania twarzy."</string> <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"Brak karty SIM"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"Brak karty SIM w tablecie."</string> @@ -1763,7 +1763,7 @@ <string name="owner_name" msgid="8713560351570795743">"Właściciel"</string> <string name="guest_name" msgid="8502103277839834324">"Gość"</string> <string name="error_message_title" msgid="4082495589294631966">"Błąd"</string> - <string name="error_message_change_not_allowed" msgid="843159705042381454">"Ta zmiana nie jest dozwolona przez administratora"</string> + <string name="error_message_change_not_allowed" msgid="843159705042381454">"Ta zmiana nie jest dozwolona przez administratora."</string> <string name="app_not_found" msgid="3429506115332341800">"Nie znaleziono aplikacji do obsługi tej akcji"</string> <string name="revoke" msgid="5526857743819590458">"Cofnij"</string> <string name="mediasize_iso_a0" msgid="7039061159929977973">"ISO A0"</string> @@ -1905,7 +1905,7 @@ <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Oszczędzanie baterii uruchamia ciemny motyw oraz wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne, pewne funkcje oraz wybrane połączenia sieciowe."</string> <string name="battery_saver_description" msgid="8518809702138617167">"Oszczędzanie baterii uruchamia ciemny motyw oraz wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne, pewne funkcje oraz wybrane połączenia sieciowe."</string> <string name="data_saver_description" msgid="4995164271550590517">"Oszczędzanie danych uniemożliwia niektórym aplikacjom wysyłanie i odbieranie danych w tle, zmniejszając w ten sposób ich użycie. Aplikacja, z której w tej chwili korzystasz, może uzyskiwać dostęp do danych, ale rzadziej. Może to powodować, że obrazy będą się wyświetlać dopiero po kliknięciu."</string> - <string name="data_saver_enable_title" msgid="7080620065745260137">"Włączyć Oszczędzanie danych?"</string> + <string name="data_saver_enable_title" msgid="7080620065745260137">"Włączyć oszczędzanie danych?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Włącz"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Przez 1 minutę (do {formattedTime})}few{Przez # minuty (do {formattedTime})}many{Przez # minut (do {formattedTime})}other{Przez # minuty (do {formattedTime})}}"</string> <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{Przez 1 min (do {formattedTime})}few{Przez # min (do {formattedTime})}many{Przez # min (do {formattedTime})}other{Przez # min (do {formattedTime})}}"</string> @@ -2396,8 +2396,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Testowy"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Wspólny"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Ze względów bezpieczeństwa zawartość aplikacji jest niewidoczna podczas udostępniania ekranu"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatycznie połączono z satelitą"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Możesz wymieniać wiadomości bez dostępu do sieci komórkowej lub Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otwórz Wiadomości"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index c53b1d50aa35..73121ce35ce3 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -1371,8 +1371,8 @@ <string name="sim_added_message" msgid="6602906609509958680">"Reinicie o dispositivo para acessar a rede móvel."</string> <string name="sim_restart_button" msgid="8481803851341190038">"Reiniciar"</string> <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Ativar serviço móvel"</string> - <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Faça o download do app da operadora para ativar seu novo chip"</string> - <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Faça o download do app <xliff:g id="APP_NAME">%1$s</xliff:g> para ativar seu novo chip"</string> + <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Baixe o app da operadora para ativar seu novo chip"</string> + <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Baixe o app <xliff:g id="APP_NAME">%1$s</xliff:g> para ativar seu novo chip"</string> <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Fazer download do app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Novo chip inserido"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Toque para configurar"</string> @@ -1744,7 +1744,7 @@ <string name="color_inversion_feature_name" msgid="2672824491933264951">"Inversão de cores"</string> <string name="color_correction_feature_name" msgid="7975133554160979214">"Correção de cor"</string> <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo uma mão"</string> - <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Escurecer a tela"</string> + <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Escurecer ainda mais a tela"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparelhos auditivos"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string> @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Teste"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Público"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo do app oculto no compartilhamento de tela por motivos de segurança"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 6b6f5c5af0f6..10e19cdf6c72 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -845,7 +845,7 @@ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Apagar os dados do tablet sem avisar através de uma reposição de dados de fábrica."</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Apagar os dados do seu dispositivo Android TV sem avisar ao efetuar uma reposição de dados de fábrica."</string> <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Apague os dados do sistema de infoentretenimento sem aviso ao executar uma reposição de dados de fábrica."</string> - <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Apaga os dados do telemóvel sem avisar ao efetuar uma reposição de dados de fábrica."</string> + <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Apaga os dados do telemóvel sem avisar repondo os dados de fábrica."</string> <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Apague os dados do perfil"</string> <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Apagar os dados do utilizador"</string> <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Apagar os dados deste utilizador neste tablet sem aviso."</string> @@ -1393,7 +1393,7 @@ <string name="usb_midi_notification_title" msgid="7404506788950595557">"O MIDI através de USB está ativado"</string> <string name="usb_uvc_notification_title" msgid="2030032862673400008">"Dispositivo ligado como câmara Web"</string> <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Acessório USB ligado"</string> - <string name="usb_notification_message" msgid="4715163067192110676">"Toque para obter mais opções."</string> + <string name="usb_notification_message" msgid="4715163067192110676">"Toque para ver mais opções."</string> <string name="usb_power_notification_message" msgid="7284765627437897702">"A carregar o dispositivo ligado. Toque para obter mais opções."</string> <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Acessório de áudio analógico detetado"</string> <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"O dispositivo ligado não é compatível com este telemóvel. Toque para saber mais."</string> @@ -1724,10 +1724,10 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ATIVADO"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESATIVADO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permitir que o serviço <xliff:g id="SERVICE">%1$s</xliff:g> tenha controlo total sobre o seu dispositivo?"</string> - <string name="accessibility_service_warning_description" msgid="291674995220940133">"O controlo total é adequado para aplicações que ajudam nas necessidades de acessibilidade, mas não para a maioria das apps."</string> + <string name="accessibility_service_warning_description" msgid="291674995220940133">"O controlo total é adequado para apps que ajudam nas necessidades de acessibilidade, mas não para a maioria das apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ver e controlar o ecrã"</string> - <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Pode ler todo o conteúdo do ecrã e sobrepor conteúdo a outras aplicações."</string> - <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Veja e execute ações"</string> + <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Pode ler todo o conteúdo do ecrã e sobrepor conteúdo a outras apps."</string> + <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Ver e executar ações"</string> <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Pode monitorizar as suas interações com uma app ou um sensor de hardware e interagir com apps em seu nome."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permitir"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Recusar"</string> @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Teste"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Comum"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo da app ocultado da partilha de ecrã por motivos de segurança"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Ligação de satélite estabelecida automaticamente"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Pode enviar e receber mensagens sem uma rede móvel ou Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre a app Mensagens"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index c53b1d50aa35..73121ce35ce3 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1371,8 +1371,8 @@ <string name="sim_added_message" msgid="6602906609509958680">"Reinicie o dispositivo para acessar a rede móvel."</string> <string name="sim_restart_button" msgid="8481803851341190038">"Reiniciar"</string> <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Ativar serviço móvel"</string> - <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Faça o download do app da operadora para ativar seu novo chip"</string> - <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Faça o download do app <xliff:g id="APP_NAME">%1$s</xliff:g> para ativar seu novo chip"</string> + <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Baixe o app da operadora para ativar seu novo chip"</string> + <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Baixe o app <xliff:g id="APP_NAME">%1$s</xliff:g> para ativar seu novo chip"</string> <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Fazer download do app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Novo chip inserido"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Toque para configurar"</string> @@ -1744,7 +1744,7 @@ <string name="color_inversion_feature_name" msgid="2672824491933264951">"Inversão de cores"</string> <string name="color_correction_feature_name" msgid="7975133554160979214">"Correção de cor"</string> <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo uma mão"</string> - <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Escurecer a tela"</string> + <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Escurecer ainda mais a tela"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparelhos auditivos"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string> @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Teste"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Público"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo do app oculto no compartilhamento de tela por motivos de segurança"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 5a449e3b14f0..e27603af34c9 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -2395,8 +2395,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Comun"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conținutul aplicației este ascuns de permiterea accesului la ecran din motive de securitate"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"S-a conectat automat la satelit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Poți să trimiți și să primești mesaje fără o rețea mobilă sau Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Deschide Mesaje"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 59982ef42804..a92a580e927b 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -833,7 +833,7 @@ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Отслеживает попытки ввода пароля при разблокировке экрана и блокирует планшетный ПК или удаляет с него все данные, если было сделано слишком много таких попыток."</string> <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Блокировать устройство Android TV или удалять с него все ваши данные при слишком большом количестве неудачных попыток ввести пароль для разблокировки экрана."</string> <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Блокировать информационно-развлекательную систему или удалять из нее все данные, если совершено слишком много неудачных попыток ввести пароль для разблокировки экрана."</string> - <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Отслеживает попытки ввода пароля при разблокировке экрана и блокирует телефон или удаляет с него все данные, если было сделано слишком много таких попыток."</string> + <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Отслеживать попытки ввода пароля при разблокировке экрана и блокировать телефон или удалять с него все данные, если было сделано слишком много таких попыток."</string> <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Отслеживать неверно введенные пароли при разблокировке экрана и блокировать планшет или удалять с него все данные, если сделано слишком много неудачных попыток."</string> <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Блокировать устройство Android TV или удалять с него все данные этого пользователя при слишком большом количестве неудачных попыток ввести пароль для разблокировки экрана."</string> <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Блокировать информационно-развлекательную систему или удалять все данные профиля, если совершено слишком много неудачных попыток ввести пароль для разблокировки экрана."</string> @@ -2396,8 +2396,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Содержимое приложения исключено из демонстрации экрана в целях безопасности."</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> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 04b2c52b425c..5c9f4d9004f5 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ආරක්ෂාව සඳහා යෙදුම් අන්තර්ගතය තිරය බෙදා ගැනීමෙන් සඟවා ඇත"</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">"Messages විවෘත කරන්න"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 76cad30f16ce..8dc68ca0a9bd 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -833,7 +833,7 @@ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Sledovať počet nesprávnych hesiel zadaných pri odomykaní obrazovky a zamknúť tablet alebo vymazať všetky údaje tabletu v prípade príliš veľkého počtu neplatných pokusov o zadanie hesla."</string> <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Sledovanie počtu nesprávnych hesiel zadaných pri odomykaní obrazovky a v prípade, že ich je zadaných príliš mnoho, uzamknutie zariadenia Android TV alebo vymazanie všetkých jeho údajov."</string> <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Sledujte počet nesprávnych hesiel zadaných pri odomykaní obrazovky a uzamknite palubný systém alebo vymažte všetky údaje v palubnom systéme v prípade príliš veľkého počtu neplatných pokusov o zadanie hesla."</string> - <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Sledovať počet nesprávnych hesiel zadaných pri odomykaní obrazovky a zamknúť telefón alebo vymazať všetky údaje v telefóne v prípade príliš veľkého počtu neplatných pokusov o zadanie hesla."</string> + <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Sleduje počet nesprávnych hesiel zadaných pri odomykaní obrazovky a uzamkne telefón alebo vymaže z telefónu všetky dáta, ak bolo zadaných príliš veľa nesprávnych hesiel."</string> <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Sledujte počet nesprávnych hesiel zadaných pri odomykaní obrazovky a v prípade, že ich je zadaných príliš mnoho, uzamknite tablet alebo vymažte všetky údaje tohto používateľa."</string> <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Sledovanie počtu nesprávnych hesiel zadaných pri odomykaní obrazovky a ak je ich zadaných príliš mnoho, uzamknutie zariadenia Android TV alebo vymazanie všetkých údajov tohto používateľa."</string> <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Sledujte počet nesprávnych hesiel zadaných pri odomykaní obrazovky a v prípade, že ich je zadaných príliš mnoho, uzamknite palubný systém alebo vymažte všetky údaje tohto profilu."</string> @@ -846,7 +846,7 @@ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Bez predchádzajúceho upozornenia vymazať všetky dáta obnovením výrobných nastavení tabletu."</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Vymazanie údajov v zariadení Android TV bez upozornenia obnovením výrobných nastavení."</string> <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Vymažte údaje palubného systému bez upozornenia obnovením výrobných nastavení."</string> - <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Bez predchádzajúceho upozornenia vymazať všetky dáta obnovením výrobných nastavení telefónu."</string> + <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Bez predchádzajúceho upozornenia vymaže všetky dáta obnovením výrobných nastavení telefónu."</string> <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Vymazanie údajov profilu"</string> <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Vymazať údaje používateľa"</string> <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Vymažte bez upozornenia údaje tohto používateľa na tomto tablete."</string> @@ -2396,8 +2396,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Testovací"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Spoločný"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Obsah aplikácie bol na účely zabezpečenia skrytý v zdieľaní obrazovky"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automaticky pripojené k satelitu"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Správy môžete odosielať a prijímať bez mobilnej siete či siete Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvoriť Správy"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 5983929eaed3..9118c9532c53 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -2396,8 +2396,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Preizkus"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Skupno"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Pri deljenju zaslona je vsebina aplikacije skrita zaradi varnosti"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Samodejno vzpostavljena povezava s satelitom"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Sporočila SMS lahko pošiljate in prejemate brez mobilnega omrežja ali omrežja Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Odpri Sporočila"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 5a02d565eb44..6036a1773274 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"I përbashkët"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Përmbajtja e aplikacionit është fshehur nga ndarja e ekranit për arsye sigurie"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"U lidh automatikisht me satelitin"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Mund të dërgosh dhe të marrësh mesazhe pa një rrjet celular apo rrjet Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Hap \"Mesazhet\""</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 637371ced5ce..2020f916376a 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1223,7 +1223,7 @@ <string name="whichEditApplicationLabel" msgid="1463288652070140285">"Измени"</string> <string name="whichSendApplication" msgid="4143847974460792029">"Делите"</string> <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Делите помоћу апликације %1$s"</string> - <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Дели"</string> + <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Дељење"</string> <string name="whichSendToApplication" msgid="77101541959464018">"Пошаљите помоћу:"</string> <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Пошаљите помоћу: %1$s"</string> <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Пошаљи"</string> @@ -2395,8 +2395,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Садржај апликације је скривен за дељење садржаја екрана због безбедности"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Аутоматски повезано са сателитом"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Можете да шаљете и примате поруке без мобилне или WiFi мреже"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отвори Messages"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 2dde3a8bcde5..cd334a359f19 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -50,7 +50,7 @@ <item quantity="other">Du har <xliff:g id="NUMBER_1">%d</xliff:g> försök kvar innan SIM-kortet låses.</item> <item quantity="one">Du har <xliff:g id="NUMBER_0">%d</xliff:g> försök kvar innan SIM-kortet låses.</item> </plurals> - <string name="imei" msgid="2157082351232630390">"IMEI-kod"</string> + <string name="imei" msgid="2157082351232630390">"IMEI"</string> <string name="meid" msgid="3291227361605924674">"MEID"</string> <string name="ClipMmi" msgid="4110549342447630629">"Nummerpresentatör för inkommande samtal"</string> <string name="ClirMmi" msgid="6752346475055446417">"Dölj nummerpresentatör för utgående samtal"</string> @@ -831,7 +831,7 @@ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Övervaka antalet felaktiga lösenord som angetts för skärmlåset och lås surfplattan eller ta bort alla data från surfplattan om för många felaktiga försök görs."</string> <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Övervaka antalet felaktiga lösenord som skrivits in vid upplåsning av skärmen och lås Android TV-enheten eller rensa all data på Android TV-enheten om för många felaktiga lösenord har skrivits in."</string> <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Övervaka antalet felaktiga lösenord som angetts för skärmlåset och lås infotainmentsystemet eller rensa all data från infotainmentsystemet om för många felaktiga försök görs."</string> - <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Övervaka antalet felaktiga lösenord som angivits för skärmlåset och lås mobilen eller ta bort alla data från mobilen om för många felaktiga försök görs."</string> + <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Övervaka antalet felaktiga lösenord som angivits för skärmlåset och lås telefonen eller ta bort alla data från telefonen om för många felaktiga försök görs."</string> <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Övervaka antalet felaktiga lösenord som skrivits in vid upplåsning av skärmen och lås surfplattan eller rensa alla uppgifter för den här användaren om för många felaktiga lösenord har skrivits in."</string> <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Övervaka antalet felaktiga lösenord som skrivits in vid upplåsning av skärmen och lås Android TV-enheten eller rensa alla uppgifter för den här användaren om för många felaktiga lösenord har skrivits in."</string> <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Övervaka antalet felaktiga lösenord som angetts för skärmlåset och lås infotainmentsystemet eller rensa all data från profilen om för många felaktiga lösenord har skrivits in."</string> @@ -844,7 +844,7 @@ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Ta bort data från surfplattan utan förvarning genom att återställa standardinställningarna."</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Radera data på Android TV-enheten utan förvarning genom att återställa standardinställningarna."</string> <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Rensa data från infotainmentsystemet utan förvarning genom att återställa standardinställningarna."</string> - <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Ta bort data från mobilen utan förvarning genom att återställa standardinställningarna."</string> + <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Ta bort data från telefonen utan förvarning genom att återställa standardinställningarna."</string> <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Rensa profildata"</string> <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Radera användaruppgifter"</string> <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Rensa användarens uppgifter på den här surfplattan utan förvarning."</string> @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Allmän"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Av säkerhetsskäl döljs appinnehållet vid skärmdelning"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatiskt ansluten till satellit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan skicka och ta emot meddelanden utan mobil- eller wifi-nätverk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Öppna Messages"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 2936716a67b5..b16bbcd74364 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Jaribio"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Unaoshirikiwa"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Maudhui ya programu yamefichwa ili yasionekane kwenye skrini ya pamoja kwa sababu za kiusalama"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Imeunganishwa kiotomatiki na satelaiti"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Unaweza kutuma na kupokea ujumbe bila mtandao wa simu au Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Fungua Programu ya Messages"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 28ee91ddb448..870f52e7fce5 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"பாதுகாப்பிற்காக, திரைப் பகிர்வில் இருந்து ஆப்ஸ் உள்ளடக்கம் மறைக்கப்பட்டுள்ளது"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"சாட்டிலைட்டுடன் தானாக இணைக்கப்பட்டது"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"மொபைல்/வைஃபை நெட்வொர்க் இல்லாமல் நீங்கள் மெசேஜ்களை அனுப்பலாம் பெறலாம்"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ஆப்ஸைத் திறக்கவும்"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index c64c9b6d61ee..ecd7e94592a9 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -688,7 +688,7 @@ </string-array> <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"ఏదో తప్పు జరిగింది. మళ్లీ ట్రై చేయండి."</string> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"వేలిముద్ర చిహ్నం"</string> - <string name="device_unlock_notification_name" msgid="2632928999862915709">"పరికర అన్లాక్"</string> + <string name="device_unlock_notification_name" msgid="2632928999862915709">"డివైజ్ అన్లాక్"</string> <string name="alternative_unlock_setup_notification_title" msgid="6241508547901933544">"అన్లాక్ చేయడానికి మరొక మార్గాన్ని ట్రై చేయండి"</string> <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"మీ వేళ్లు తడిగా ఉండటం లేక ఇతరత్రా కారణాల వల్ల మీ వేలిముద్రను గుర్తించకపోతే, ఫేస్ అన్లాక్ను ఉపయోగించండి"</string> <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"తగినంత వెలుతురు లేకపోవడం లేక ఇతరత్రా కారణాల వల్ల మీ ఫేస్ గుర్తించబడనప్పుడు, వేలిముద్ర అన్లాక్ను ఉపయోగించండి"</string> @@ -995,7 +995,7 @@ <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"సరైనది!"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"మళ్లీ ట్రై చేయండి"</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"మళ్లీ ట్రై చేయండి"</string> - <string name="lockscreen_storage_locked" msgid="634993789186443380">"అన్ని లక్షణాలు మరియు డేటా కోసం అన్లాక్ చేయండి"</string> + <string name="lockscreen_storage_locked" msgid="634993789186443380">"అన్ని ఫీచర్ల కోసం, డేటా కోసం అన్లాక్ చేయండి"</string> <string name="faceunlock_multiple_failures" msgid="681991538434031708">"ఫేస్ అన్లాక్ ప్రయత్నాల గరిష్ఠ పరిమితిని మించిపోయారు"</string> <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"SIM లేదు"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"టాబ్లెట్లో SIM లేదు."</string> @@ -1222,7 +1222,7 @@ <string name="whichEditApplicationLabel" msgid="1463288652070140285">"ఎడిట్"</string> <string name="whichSendApplication" msgid="4143847974460792029">"షేర్ చేయండి"</string> <string name="whichSendApplicationNamed" msgid="4470386782693183461">"%1$sతో షేర్ చేయండి"</string> - <string name="whichSendApplicationLabel" msgid="7467813004769188515">"షేర్ చేయి"</string> + <string name="whichSendApplicationLabel" msgid="7467813004769188515">"షేర్ చేయండి"</string> <string name="whichSendToApplication" msgid="77101541959464018">"దీన్ని ఉపయోగించి పంపండి"</string> <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"%1$sని ఉపయోగించి పంపండి"</string> <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"పంపండి"</string> @@ -1416,7 +1416,7 @@ <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"బగ్ రిపోర్ట్ను షేర్ చేయాలా?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"బగ్ రిపోర్ట్ను షేర్ చేస్తోంది..."</string> <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"మీ అడ్మిన్ ఈ పరికరం సమస్యకు పరిష్కారాన్ని కనుగొనడంలో సహాయం కోసం బగ్ రిపోర్ట్ను రిక్వెస్ట్ చేశారు. యాప్లు మరియు డేటా షేర్ చేయబడవచ్చు."</string> - <string name="share_remote_bugreport_action" msgid="7630880678785123682">"షేర్ చేయి"</string> + <string name="share_remote_bugreport_action" msgid="7630880678785123682">"షేర్ చేయండి"</string> <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"తిరస్కరిస్తున్నాను"</string> <string name="select_input_method" msgid="3971267998568587025">"ఇన్పుట్ పద్ధతిని ఎంచుకోండి"</string> <string name="show_ime" msgid="6406112007347443383">"దీన్ని భౌతిక కీబోర్డ్ యాక్టివ్గా ఉన్నప్పుడు స్క్రీన్పై ఉంచుతుంది"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"సెక్యూరిటీ కోసం స్క్రీన్ షేర్ నుండి యాప్ కంటెంట్ దాచబడింది"</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">"Messagesను తెరవండి"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 7555f26fd2fa..b1debfd4cf74 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ซ่อนเนื้อหาแอปจากการแชร์หน้าจอเพื่อความปลอดภัย"</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">"เปิด Messages"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 112da5cc6b3e..3547870302b0 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1222,7 +1222,7 @@ <string name="whichEditApplicationLabel" msgid="1463288652070140285">"I-edit"</string> <string name="whichSendApplication" msgid="4143847974460792029">"Ibahagi"</string> <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Ibahagi gamit ang %1$s"</string> - <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Ibahagi"</string> + <string name="whichSendApplicationLabel" msgid="7467813004769188515">"I-share"</string> <string name="whichSendToApplication" msgid="77101541959464018">"Ipadala gamit ang"</string> <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Ipadala gamit ang %1$s"</string> <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Ipadala"</string> @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Nakatago ang content ng app mula sa pagbabahagi ng screen para sa seguridad"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Awtomatikong nakakonekta sa satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Puwede kang magpadala at tumanggap ng mga mensahe nang walang mobile o Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buksan ang Messages"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 2ca545b89612..7e34e4bf97f3 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1396,8 +1396,8 @@ <string name="usb_power_notification_message" msgid="7284765627437897702">"Bağlı cihaz şarj ediliyor. Diğer seçenekler için dokunun."</string> <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Analog ses aksesuarı algılandı"</string> <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Takılan cihaz bu telefonla uyumlu değil. Daha fazla bilgi edinmek için dokunun."</string> - <string name="adb_active_notification_title" msgid="408390247354560331">"USB hata ayıklaması bağlandı"</string> - <string name="adb_active_notification_message" msgid="5617264033476778211">"USB hata ayıklamayı kapatmak için dokunun"</string> + <string name="adb_active_notification_title" msgid="408390247354560331">"USB üzerinden hata ayıklama bağlandı"</string> + <string name="adb_active_notification_message" msgid="5617264033476778211">"USB üzerinden hata ayıklamayı kapatmak için dokunun"</string> <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB hata ayıklamasını devre dışı bırakmak için seçin."</string> <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Kablosuz hata ayıklama bağlı"</string> <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Kablosuz hata ayıklamayı kapatmak için dokunun"</string> @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Paylaşılan"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Uygulama içerikleri, güvenlik nedeniyle ekran paylaşımında gizlendi"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Uyduya otomatik olarak bağlandı"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil veya kablosuz ağa bağlı olmadan mesaj alıp gönderebilirsiniz"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajlar\'ı aç"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index df2c7157b88f..34618cd243c4 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1185,7 +1185,7 @@ <string name="deleteText" msgid="4200807474529938112">"Видалити"</string> <string name="inputMethod" msgid="1784759500516314751">"Метод введення"</string> <string name="editTextMenuTitle" msgid="857666911134482176">"Дії з текстом"</string> - <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Рукописне введення не підтримується в цьому полі"</string> + <string name="error_handwriting_unsupported" msgid="7809438534946014050">"У цьому полі не підтримується рукописне введення"</string> <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Рукописне введення не підтримується в полях паролів"</string> <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Назад"</string> <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Змінити метод введення"</string> @@ -2396,8 +2396,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"З міркувань безпеки вміст додатка приховано під час показу екрана"</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> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 29bd5bec0415..caf0ca4e435a 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"سیکیورٹی کے مد نظر ایپ کا مواد اسکرین کے اشتراک سے چھپا ہوا ہے"</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> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index dddc3d6e9d81..e22c1dce2a03 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Umumiy"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Ekran namoyishida xavfsizlik maqsadida ilova kontenti berkitildi"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Sputnikka avtomatik ulandi"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil yoki Wi-Fi tarmoqsiz xabarlarni yuborishingiz va qabul qilishingiz mumkin"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Xabarlar ilovasini ochish"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 073a1a8ee7ae..d6bd1904ec21 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -2178,9 +2178,9 @@ <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Khóa màn hình"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Chụp ảnh màn hình"</string> <string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Giá treo tai nghe"</string> - <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Phím tắt hỗ trợ tiếp cận trên màn hình"</string> - <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Bộ chọn phím tắt hỗ trợ tiếp cận trên màn hình"</string> - <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Phím tắt hỗ trợ tiếp cận"</string> + <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Lối tắt hỗ trợ tiếp cận trên màn hình"</string> + <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Bộ chọn lối tắt hỗ trợ tiếp cận trên màn hình"</string> + <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Lối tắt hỗ trợ tiếp cận"</string> <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Đóng Ngăn thông báo"</string> <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Chuyển lên trên bằng bàn phím di chuyển"</string> <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Chuyển xuống dưới bằng bàn phím di chuyển"</string> @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Kiểm thử"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Dùng chung"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Nội dung ứng dụng bị ẩn khỏi tính năng chia sẻ màn hình vì lý do bảo mật"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Đã tự động kết nối với vệ tinh"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Bạn có thể gửi và nhận tin nhắn mà không cần có mạng di động hoặc mạng Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mở ứng dụng Tin nhắn"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index ff2d4fc3f886..2019249be083 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -256,7 +256,7 @@ <string name="global_action_power_off" msgid="4404936470711393203">"关机"</string> <string name="global_action_power_options" msgid="1185286119330160073">"电源"</string> <string name="global_action_restart" msgid="4678451019561687074">"重启"</string> - <string name="global_action_emergency" msgid="1387617624177105088">"紧急呼救"</string> + <string name="global_action_emergency" msgid="1387617624177105088">"紧急呼叫"</string> <string name="global_action_bug_report" msgid="5127867163044170003">"错误报告"</string> <string name="global_action_logout" msgid="6093581310002476511">"结束会话"</string> <string name="global_action_screenshot" msgid="2610053466156478564">"屏幕截图"</string> @@ -844,7 +844,7 @@ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"恢复出厂设置时,系统会在不发出警告的情况下清除平板电脑上的数据。"</string> <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"不事先发出警告就以恢复出厂设置的方式清空 Android TV 设备中的数据。"</string> <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"在不发出警告的情况下,通过恢复出厂设置来清除信息娱乐系统上的数据。"</string> - <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"恢复出厂设置时,系统会在不发出警告的情况下清除手机上的数据。"</string> + <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"恢复出厂设置,不发出警告就直接清除手机上的数据。"</string> <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"清除个人资料数据"</string> <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"清空用户数据"</string> <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"清空此用户在这台平板电脑上的数据,而不事先发出警告。"</string> @@ -990,7 +990,7 @@ <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"按 Menu 解锁或进行紧急呼救。"</string> <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"按 MENU 解锁。"</string> <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"绘制解锁图案"</string> - <string name="lockscreen_emergency_call" msgid="7500692654885445299">"紧急呼救"</string> + <string name="lockscreen_emergency_call" msgid="7500692654885445299">"紧急呼叫"</string> <string name="lockscreen_return_to_call" msgid="3156883574692006382">"返回通话"</string> <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"正确!"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"重试"</string> @@ -1012,7 +1012,7 @@ <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"停止"</string> <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"快退"</string> <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"快进"</string> - <string name="emergency_calls_only" msgid="3057351206678279851">"只能拨打紧急呼救电话"</string> + <string name="emergency_calls_only" msgid="3057351206678279851">"只能拨打紧急呼叫电话"</string> <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"网络已锁定"</string> <string name="lockscreen_sim_puk_locked_message" msgid="2867953953604224166">"SIM 卡已用 PUK 码锁定。"</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"请参阅《用户指南》或与客服人员联系。"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"为安全起见而在屏幕共享画面中处于隐藏状态的应用内容"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"自动连接到卫星"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"您无需使用移动网络或 WLAN 网络便能收发消息"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"打开“信息”应用"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 6f560bb65078..e92b7f08b6a5 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"為安全起見,應用程式內容已從分享螢幕畫面隱藏"</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> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 8b2d5343ea38..124d17a805b3 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1725,7 +1725,7 @@ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"要將裝置的完整控制權授予「<xliff:g id="SERVICE">%1$s</xliff:g>」嗎?"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"如果你有無障礙服務需求,建議可將完整控制權授予具有相關功能的應用程式,但請勿將完整控制權授予大多數的應用程式。"</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"查看及控制螢幕"</string> - <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"可讀取螢幕上的所有內容及在其他應用程式上顯示內容。"</string> + <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"可讀取螢幕上的所有內容,並在其他應用程式上顯示內容。"</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"查看及執行動作"</string> <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"可追蹤你與應用程式或硬體感應器的互動,並代表你與應用程式進行互動。"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"允許"</string> @@ -1902,7 +1902,7 @@ <string name="confirm_battery_saver" msgid="5247976246208245754">"確定"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"省電模式會開啟深色主題,並限制或關閉背景活動、某些視覺效果、特定功能和部分網路連線。"</string> <string name="battery_saver_description" msgid="8518809702138617167">"省電模式會開啟深色主題,並限制或關閉背景活動、某些視覺效果、特定功能和部分網路連線。"</string> - <string name="data_saver_description" msgid="4995164271550590517">"「數據節省模式」可防止部分應用程式在背景收發資料,以節省數據用量。你有一個使用中的應用程式仍可存取資料,但存取頻率可能會變低。舉例來說,圖片可能要等到你輕觸後才會顯示。"</string> + <string name="data_saver_description" msgid="4995164271550590517">"「數據節省模式」可防止部分應用程式在背景收發資料,以節省數據用量。目前使用中的單一應用程式仍可存取資料,但存取頻率可能會變低。舉例來說,圖片可能要等到你輕觸後才會顯示。"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"要開啟數據節省模式嗎?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"開啟"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{1 分鐘 (直到 {formattedTime})}other{# 分鐘 (直到 {formattedTime})}}"</string> @@ -2394,8 +2394,7 @@ <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 screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"為安全起見,分享螢幕畫面未顯示應用程式內容"</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> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 922172ce7f41..8ffb7a43b36c 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -2394,8 +2394,7 @@ <string name="profile_label_test" msgid="9168641926186071947">"Hlola"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Okomphakathi"</string> <string name="redacted_notification_action_title" msgid="6942924973335920935"></string> - <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) --> - <skip /> + <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Okuqukethwe kwe-app kufihliwe kusuka ekwabelaneni kwesikrini ngokuvikelwa"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Ixhumeke ngokuzenzakalelayo kusathelayithi"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Ungathumela futhi wamukele imilayezo ngaphandle kwenethiwekhi yeselula noma ye-Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Vula Imilayezo"</string> diff --git a/core/tests/coretests/src/android/app/AutomaticZenRuleTest.java b/core/tests/coretests/src/android/app/AutomaticZenRuleTest.java index a5c854561293..5765562e2383 100644 --- a/core/tests/coretests/src/android/app/AutomaticZenRuleTest.java +++ b/core/tests/coretests/src/android/app/AutomaticZenRuleTest.java @@ -189,12 +189,16 @@ public class AutomaticZenRuleTest { @Test @EnableFlags(Flags.FLAG_MODES_API) - public void builder_defaultTypeUnknown() { + public void builder_defaultsAreSensible() { AutomaticZenRule rule = new AutomaticZenRule.Builder("name", Uri.parse("conditionId")).build(); assertThat(rule.getType()).isEqualTo(AutomaticZenRule.TYPE_UNKNOWN); + assertThat(rule.getInterruptionFilter()).isEqualTo( + NotificationManager.INTERRUPTION_FILTER_PRIORITY); + assertThat(rule.isEnabled()).isTrue(); } + @Test @EnableFlags(Flags.FLAG_MODES_API) public void validate_builderWithValidType_succeeds() throws Exception { diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java index 2ce7a7d3d70d..a0aff6e7b9a0 100644 --- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java +++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java @@ -16,7 +16,6 @@ package android.app.servertransaction; -import static android.content.Context.DEVICE_ID_DEFAULT; import static android.view.Display.DEFAULT_DISPLAY; import static org.junit.Assert.assertEquals; @@ -29,9 +28,6 @@ import static org.mockito.Mockito.verify; import android.app.Activity; import android.app.ActivityThread; import android.app.ClientTransactionHandler; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.os.IBinder; import android.os.RemoteException; @@ -107,35 +103,6 @@ public class ClientTransactionItemTest { } @Test - public void testActivityConfigurationChangeItem_getContextToUpdate() { - final ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem - .obtain(mActivityToken, mConfiguration, mActivityWindowInfo); - final Context context = item.getContextToUpdate(mHandler); - - assertEquals(mActivity, context); - } - - @Test - public void testActivityRelaunchItem_getContextToUpdate() { - final ActivityRelaunchItem item = ActivityRelaunchItem - .obtain(mActivityToken, null /* pendingResults */, null /* pendingNewIntents */, - 0 /* configChange */, mMergedConfiguration, false /* preserveWindow */, - mActivityWindowInfo); - final Context context = item.getContextToUpdate(mHandler); - - assertEquals(mActivity, context); - } - - @Test - public void testConfigurationChangeItem_getContextToUpdate() { - final ConfigurationChangeItem item = ConfigurationChangeItem - .obtain(mConfiguration, DEVICE_ID_DEFAULT); - final Context context = item.getContextToUpdate(mHandler); - - assertEquals(ActivityThread.currentApplication(), context); - } - - @Test public void testDestroyActivityItem_preExecute() { final DestroyActivityItem item = DestroyActivityItem .obtain(mActivityToken, false /* finished */); @@ -166,26 +133,6 @@ public class ClientTransactionItemTest { } @Test - public void testLaunchActivityItem_getContextToUpdate() { - final LaunchActivityItem item = new TestUtils.LaunchActivityItemBuilder( - mActivityToken, new Intent(), new ActivityInfo()) - .build(); - - final Context context = item.getContextToUpdate(mHandler); - - assertEquals(ActivityThread.currentApplication(), context); - } - - @Test - public void testMoveToDisplayItem_getContextToUpdate() { - final MoveToDisplayItem item = MoveToDisplayItem - .obtain(mActivityToken, DEFAULT_DISPLAY, mConfiguration, mActivityWindowInfo); - final Context context = item.getContextToUpdate(mHandler); - - assertEquals(mActivity, context); - } - - @Test public void testWindowContextInfoChangeItem_execute() { final WindowContextInfoChangeItem item = WindowContextInfoChangeItem .obtain(mWindowClientToken, mConfiguration, DEFAULT_DISPLAY); @@ -196,17 +143,6 @@ public class ClientTransactionItemTest { } @Test - public void testWindowContextInfoChangeItem_getContextToUpdate() { - doReturn(mWindowContext).when(mHandler).getWindowContext(mWindowClientToken); - - final WindowContextInfoChangeItem item = WindowContextInfoChangeItem - .obtain(mWindowClientToken, mConfiguration, DEFAULT_DISPLAY); - final Context context = item.getContextToUpdate(mHandler); - - assertEquals(mWindowContext, context); - } - - @Test public void testWindowContextWindowRemovalItem_execute() { final WindowContextWindowRemovalItem item = WindowContextWindowRemovalItem.obtain( mWindowClientToken); @@ -220,7 +156,7 @@ public class ClientTransactionItemTest { final WindowStateResizeItem item = WindowStateResizeItem.obtain(mWindow, mFrames, true /* reportDraw */, mMergedConfiguration, mInsetsState, true /* forceLayout */, true /* alwaysConsumeSystemBars */, 123 /* displayId */, 321 /* syncSeqId */, - true /* dragResizing */, mActivityToken, mActivityWindowInfo); + true /* dragResizing */, mActivityWindowInfo); item.execute(mHandler, mPendingActions); verify(mWindow).resized(mFrames, @@ -228,16 +164,4 @@ public class ClientTransactionItemTest { true /* alwaysConsumeSystemBars */, 123 /* displayId */, 321 /* syncSeqId */, true /* dragResizing */, mActivityWindowInfo); } - - @Test - public void testWindowStateResizeItem_getContextToUpdate() { - final WindowStateResizeItem item = WindowStateResizeItem.obtain(mWindow, mFrames, - true /* reportDraw */, mMergedConfiguration, mInsetsState, true /* forceLayout */, - true /* alwaysConsumeSystemBars */, 123 /* displayId */, 321 /* syncSeqId */, - true /* dragResizing */, mActivityToken, mActivityWindowInfo); - final Context context = item.getContextToUpdate(mHandler); - - assertEquals(ActivityThread.currentApplication(), context); - } - } diff --git a/core/tests/coretests/src/android/os/ParcelTest.java b/core/tests/coretests/src/android/os/ParcelTest.java index 442394e3428a..0697c96052f6 100644 --- a/core/tests/coretests/src/android/os/ParcelTest.java +++ b/core/tests/coretests/src/android/os/ParcelTest.java @@ -16,6 +16,8 @@ package android.os; +import static com.google.common.truth.Truth.assertThat; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; @@ -24,6 +26,7 @@ import static org.junit.Assert.assertTrue; import android.platform.test.annotations.IgnoreUnderRavenwood; import android.platform.test.annotations.Presubmit; import android.platform.test.ravenwood.RavenwoodRule; +import android.util.Log; import androidx.test.runner.AndroidJUnit4; @@ -31,6 +34,8 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.ArrayList; + @Presubmit @RunWith(AndroidJUnit4.class) public class ParcelTest { @@ -349,6 +354,50 @@ public class ParcelTest { } @Test + public void testClassCookies() { + Parcel p = Parcel.obtain(); + assertThat(p.hasClassCookie(ParcelTest.class)).isFalse(); + + p.setClassCookie(ParcelTest.class, "string_cookie"); + assertThat(p.hasClassCookie(ParcelTest.class)).isTrue(); + assertThat(p.getClassCookie(ParcelTest.class)).isEqualTo("string_cookie"); + + p.removeClassCookie(ParcelTest.class, "string_cookie"); + assertThat(p.hasClassCookie(ParcelTest.class)).isFalse(); + assertThat(p.getClassCookie(ParcelTest.class)).isEqualTo(null); + + p.setClassCookie(ParcelTest.class, "to_be_discarded_cookie"); + p.recycle(); + assertThat(p.getClassCookie(ParcelTest.class)).isNull(); + } + + @Test + public void testClassCookies_removeUnexpected() { + Parcel p = Parcel.obtain(); + + assertLogsWtf(() -> p.removeClassCookie(ParcelTest.class, "not_present")); + + p.setClassCookie(ParcelTest.class, "value"); + + assertLogsWtf(() -> p.removeClassCookie(ParcelTest.class, "different")); + assertThat(p.getClassCookie(ParcelTest.class)).isNull(); // still removed + + p.recycle(); + } + + private static void assertLogsWtf(Runnable test) { + ArrayList<Log.TerribleFailure> wtfs = new ArrayList<>(); + Log.TerribleFailureHandler oldHandler = Log.setWtfHandler( + (tag, what, system) -> wtfs.add(what)); + try { + test.run(); + } finally { + Log.setWtfHandler(oldHandler); + } + assertThat(wtfs).hasSize(1); + } + + @Test @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void testHasBinders_AfterWritingBinderToParcel() { Binder binder = new Binder(); @@ -360,7 +409,6 @@ public class ParcelTest { assertTrue(pA.hasBinders()); } - @Test @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void testHasBindersInRange_AfterWritingBinderToParcel() { diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index dd6f8455f82a..b9ff5c682b42 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Maak toe"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Maak kieslys toe"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Maak kieslys oop"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimeer skerm"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Gryp skerm vas"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index 18a4ccf5c16d..81ab3ab15aad 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"ዝጋ"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string> <string name="expand_menu_text" msgid="3847736164494181168">"ምናሌን ክፈት"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"የማያ ገጹ መጠን አሳድግ"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ማያ ገጹን አሳድግ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index 7ca335e4a655..3974c39d4803 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"إغلاق"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"إغلاق القائمة"</string> <string name="expand_menu_text" msgid="3847736164494181168">"فتح القائمة"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"تكبير الشاشة إلى أقصى حدّ"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"التقاط صورة للشاشة"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index 944c4f25bf2a..a1ce1b3b9513 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"বন্ধ কৰক"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"মেনু বন্ধ কৰক"</string> <string name="expand_menu_text" msgid="3847736164494181168">"মেনু খোলক"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্ৰীন মেক্সিমাইজ কৰক"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"স্ক্ৰীন স্নেপ কৰক"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index c320e415d604..71dfe5ac6bed 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Bağlayın"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Menyunu bağlayın"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Menyunu açın"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı maksimum böyüdün"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranı çəkin"</string> </resources> 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 19ca4d300b7e..f48360991d49 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Zatvorite"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite meni"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Otvorite meni"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Povećaj ekran"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Uklopi ekran"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index 74ae1d7637d0..81d066f82261 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Закрыць"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Закрыць меню"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Адкрыць меню"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Разгарнуць на ўвесь экран"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Размясціць на палавіне экрана"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index 1b753f5359ba..8f828badcf47 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Затваряне"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Затваряне на менюто"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Отваряне на менюто"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Увеличаване на екрана"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Прилепване на екрана"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index 2ea22cc1455a..e0a2ea824be0 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"বন্ধ করুন"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"\'মেনু\' বন্ধ করুন"</string> <string name="expand_menu_text" msgid="3847736164494181168">"মেনু খুলুন"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্রিন বড় করুন"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"স্ক্রিনে অ্যাপ মানানসই হিসেবে ছোট বড় করুন"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index 13655b3c5c85..41c72c1d3a03 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Zatvaranje"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvaranje menija"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Otvaranje menija"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiziraj ekran"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snimi ekran"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index cb897c5b612d..679227248ea5 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Tanca"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Tanca el menú"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Obre el menú"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximitza la pantalla"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajusta la pantalla"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index ded2707afd1d..aafb2e16b703 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Zavřít"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Zavřít nabídku"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Otevřít nabídku"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovat obrazovku"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Rozpůlit obrazovku"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index 2bdb29d67447..8878910a4d2c 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Luk"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Luk menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Åbn menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimér skærm"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Tilpas skærm"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index e99d9d0c269a..7b5c471e074f 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Schließen"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Menü öffnen"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Bildschirm maximieren"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Bildschirm teilen"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index d8bb740535fc..14e5e2f87ab8 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Κλείσιμο"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Κλείσιμο μενού"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Άνοιγμα μενού"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Μεγιστοποίηση οθόνης"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Προβολή στο μισό της οθόνης"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index 5e1b274705dd..7427b62679be 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Close"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Open menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index 2525b321d9d7..cb9ee4f6b6b3 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Close"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Open Menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximize Screen"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap Screen"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml index 5e1b274705dd..7427b62679be 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Close"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Open menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml index 5e1b274705dd..7427b62679be 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Close"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Open menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml index 0623bef925e2..8498807f9fdb 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Close"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Open Menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximize Screen"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap Screen"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index 9fe77ddf7e28..406c1f37c455 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Cerrar"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Abrir el menú"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar pantalla"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index b88f215eb54e..0583d79da127 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Cerrar"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Abrir menú"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar pantalla"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index 529b6d10b3c6..70547f566ea6 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Sule"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Sule menüü"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Ava menüü"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Kuva täisekraanil"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Kuva poolel ekraanil"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index 7438f4240eae..4be35eac6c1f 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Itxi"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Itxi menua"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Ireki menua"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Handitu pantaila"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Zatitu pantaila"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index f7fcb2162603..32d5f5f34fb8 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"بستن"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"بستن منو"</string> <string name="expand_menu_text" msgid="3847736164494181168">"باز کردن منو"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"بزرگ کردن صفحه"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"بزرگ کردن صفحه"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index 400107317637..6f03545e5542 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Sulje"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Sulje valikko"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Avaa valikko"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Suurenna näyttö"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Jaa näyttö"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index b54f9cf2f15d..1fde4cfb76f8 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Fermer"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Ouvrir le menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Agrandir l\'écran"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Aligner l\'écran"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index 357ff91df06d..e7233ae029b5 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Fermer"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Ouvrir le menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mettre en plein écran"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fractionner l\'écran"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index a62190754129..89db32793b32 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Pechar"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Pechar o menú"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Abrir menú"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Encaixar pantalla"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index 43c178f50d15..7e3d7a373be4 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"બંધ કરો"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"મેનૂ બંધ કરો"</string> <string name="expand_menu_text" msgid="3847736164494181168">"મેનૂ ખોલો"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"સ્ક્રીન કરો મોટી કરો"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"સ્ક્રીન સ્નૅપ કરો"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index 9f6a57fa0d73..cd0f4e3618f7 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"बंद करें"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"मेन्यू बंद करें"</string> <string name="expand_menu_text" msgid="3847736164494181168">"मेन्यू खोलें"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन को बड़ा करें"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्नैप स्क्रीन"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index 4378c5642f5c..fc3942095fdf 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Zatvorite"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Otvaranje izbornika"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimalno povećaj zaslon"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Izradi snimku zaslona"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index e5f199fea647..a8cc5c120efc 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Bezárás"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Menü bezárása"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Menü megnyitása"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Képernyő méretének maximalizálása"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Igazodás a képernyő adott részéhez"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index e0a5afe13827..7f372774241a 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Փակել"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Փակել ընտրացանկը"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Բացել ընտրացանկը"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ծավալել էկրանը"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ծալել էկրանը"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index 802583771852..3cf55fa0ede2 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Tutup"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Buka Menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Perbesar Layar"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Gabungkan Layar"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index cece56ec960f..6aa56f9858ad 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Loka"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Loka valmynd"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Opna valmynd"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Stækka skjá"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Smelluskjár"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index 731db8c12825..3c1d5e4dac02 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Chiudi"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Chiudi il menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Apri menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Massimizza schermo"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Aggancia schermo"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index adf55f3696c3..a0c3b3a95ca8 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"סגירה"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"סגירת התפריט"</string> <string name="expand_menu_text" msgid="3847736164494181168">"פתיחת התפריט"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"הגדלת המסך"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"כיווץ המסך"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index 35432229dc7b..fb726c180997 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"閉じる"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"メニューを閉じる"</string> <string name="expand_menu_text" msgid="3847736164494181168">"メニューを開く"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"画面の最大化"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"画面のスナップ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index 1e6e657b5cf8..e9f620a17203 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"დახურვა"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"მენიუს დახურვა"</string> <string name="expand_menu_text" msgid="3847736164494181168">"მენიუს გახსნა"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"აპლიკაციის გაშლა სრულ ეკრანზე"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"აპლიკაციის დაპატარავება ეკრანზე"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index 6d9ff26132ea..34e41038f285 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Жабу"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Мәзірді жабу"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Мәзірді ашу"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды ұлғайту"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Экранды бөлу"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index 586ef7327a70..362bbad4ec12 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"បិទ"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"បិទម៉ឺនុយ"</string> <string name="expand_menu_text" msgid="3847736164494181168">"បើកម៉ឺនុយ"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ពង្រីកអេក្រង់"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ថតអេក្រង់"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index 78ca0c7979a9..77cc4a44f81a 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"ಮುಚ್ಚಿ"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"ಮೆನು ಮುಚ್ಚಿ"</string> <string name="expand_menu_text" msgid="3847736164494181168">"ಮೆನು ತೆರೆಯಿರಿ"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ಸ್ನ್ಯಾಪ್ ಸ್ಕ್ರೀನ್"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index 70aa3767d7dd..e8b5522838b7 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"닫기"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"메뉴 닫기"</string> <string name="expand_menu_text" msgid="3847736164494181168">"메뉴 열기"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"화면 최대화"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"화면 분할"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index b2a0a49b401a..7b7779d85d78 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Жабуу"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Менюну жабуу"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Менюну ачуу"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды чоңойтуу"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Экранды сүрөткө тартып алуу"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index 1cbdbd412631..a3519636b71f 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"ປິດ"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"ປິດເມນູ"</string> <string name="expand_menu_text" msgid="3847736164494181168">"ເປີດເມນູ"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ປັບຈໍໃຫຍ່ສຸດ"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ສະແນັບໜ້າຈໍ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index d154c57704a1..e4dd7398f679 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Uždaryti"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Uždaryti meniu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Atidaryti meniu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Išskleisti ekraną"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Sutraukti ekraną"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index ce269503ceef..99aebf626322 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Aizvērt"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Aizvērt izvēlni"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Atvērt izvēlni"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizēt ekrānu"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fiksēt ekrānu"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index 9d69c50626be..c152c60fa631 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Затворете"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Затворете го менито"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Отвори го менито"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Максимизирај го екранот"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Подели го екранот на половина"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index c0e83386d572..90275cdb517a 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"അടയ്ക്കുക"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"മെനു അടയ്ക്കുക"</string> <string name="expand_menu_text" msgid="3847736164494181168">"മെനു തുറക്കുക"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"സ്ക്രീൻ വലുതാക്കുക"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"സ്ക്രീൻ സ്നാപ്പ് ചെയ്യുക"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index ba5d283fb8a7..4a9fab92f11f 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Хаах"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Цэсийг хаах"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Цэс нээх"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Дэлгэцийг томруулах"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Дэлгэцийг таллах"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index 17601c18366a..5874bffc9199 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"बंद करा"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"मेनू बंद करा"</string> <string name="expand_menu_text" msgid="3847736164494181168">"मेनू उघडा"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन मोठी करा"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्क्रीन स्नॅप करा"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index d5547fa8a056..4de8a7b03547 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Tutup"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Buka Menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimumkan Skrin"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Tangkap Skrin"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index 07bfc990d62d..5b9e9cb7353e 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"ပိတ်ရန်"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"မီနူး ပိတ်ရန်"</string> <string name="expand_menu_text" msgid="3847736164494181168">"မီနူး ဖွင့်ရန်"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"စခရင်ကို ချဲ့မည်"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"စခရင်ကို ချုံ့မည်"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index f609d019daae..9f03d8b5b178 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Lukk"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Lukk menyen"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Åpne menyen"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimer skjermen"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fest skjermen"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index 9a26b7e25187..e4830af1bad6 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"बन्द गर्नुहोस्"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"मेनु बन्द गर्नुहोस्"</string> <string name="expand_menu_text" msgid="3847736164494181168">"मेनु खोल्नुहोस्"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रिन ठुलो बनाउनुहोस्"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्क्रिन स्न्याप गर्नुहोस्"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index a38cb7547385..0cd27c5c1457 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Sluiten"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Menu sluiten"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Menu openen"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Scherm maximaliseren"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Scherm halveren"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index e3097beb6166..bf751852a255 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"ବନ୍ଦ କରନ୍ତୁ"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"ମେନୁ ବନ୍ଦ କରନ୍ତୁ"</string> <string name="expand_menu_text" msgid="3847736164494181168">"ମେନୁ ଖୋଲନ୍ତୁ"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ସ୍କ୍ରିନକୁ ବଡ଼ କରନ୍ତୁ"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ସ୍କ୍ରିନକୁ ସ୍ନାପ କରନ୍ତୁ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index 3aea6f69749f..325c1e80c433 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"ਬੰਦ ਕਰੋ"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"ਮੀਨੂ ਬੰਦ ਕਰੋ"</string> <string name="expand_menu_text" msgid="3847736164494181168">"ਮੀਨੂ ਖੋਲ੍ਹੋ"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ਸਕ੍ਰੀਨ ਦਾ ਆਕਾਰ ਵਧਾਓ"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ਸਕ੍ਰੀਨ ਨੂੰ ਸਨੈਪ ਕਰੋ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index aec3722cefa5..a7648c8e323b 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Zamknij"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Zamknij menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Otwórz menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksymalizuj ekran"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Przyciągnij ekran"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index ba24d7b3eb07..e47d151337b2 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Fechar"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Abrir o menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar tela"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index f636da7997eb..ff77d3b2d150 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Fechar"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Abrir menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar ecrã"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Encaixar ecrã"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index ba24d7b3eb07..e47d151337b2 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Fechar"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Abrir o menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar tela"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index c20f350ae198..ae871f3dd42b 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Închide"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Închide meniul"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Deschide meniul"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizează fereastra"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Micșorează fereastra și fixeaz-o"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index 49347d2d8086..e23c1ff19563 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Закрыть"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Закрыть меню"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Открыть меню"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Развернуть на весь экран"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Свернуть"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index e5a974683e49..ef1381cbe635 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"වසන්න"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"මෙනුව වසන්න"</string> <string name="expand_menu_text" msgid="3847736164494181168">"මෙනුව විවෘත කරන්න"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"තිරය උපරිම කරන්න"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ස්නැප් තිරය"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index c2d20ddb0d3b..55a03122483b 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Zavrieť"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Zavrieť ponuku"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Otvoriť ponuku"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovať obrazovku"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Zobraziť polovicu obrazovky"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index cfe4480c6e1a..bb123dcdbfb6 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Zapri"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Zapri meni"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Odpri meni"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiraj zaslon"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Pripni zaslon"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index cba98c2fb61a..c74a8cd23338 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Mbyll"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Mbyll menynë"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Hap menynë"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizo ekranin"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Regjistro ekranin"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index 5031f5bf5d64..0694a973dc1e 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Затворите"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Затворите мени"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Отворите мени"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Повећај екран"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Уклопи екран"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index 742be37b67ef..8e0bcfe91679 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Stäng"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Stäng menyn"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Öppna menyn"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximera skärmen"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fäst skärmen"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index 68a7262d0eaf..41180abcf712 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Funga"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Funga Menyu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Fungua Menyu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Panua Dirisha kwenye Skrini"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Panga Madirisha kwenye Skrini"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index fe8fa057dc95..01ac78d984f3 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"மூடும்"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"மெனுவை மூடும்"</string> <string name="expand_menu_text" msgid="3847736164494181168">"மெனுவைத் திற"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"திரையைப் பெரிதாக்கு"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"திரையை ஸ்னாப் செய்"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 9be3f3354635..6224e72c19fe 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"మూసివేయండి"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"మెనూను మూసివేయండి"</string> <string name="expand_menu_text" msgid="3847736164494181168">"మెనూను తెరవండి"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"స్క్రీన్ సైజ్ను పెంచండి"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"స్క్రీన్ను స్నాప్ చేయండి"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index cd3bf6a626c0..407fbbbb1707 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"ปิด"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"ปิดเมนู"</string> <string name="expand_menu_text" msgid="3847736164494181168">"เปิดเมนู"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ขยายหน้าจอให้ใหญ่สุด"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"สแนปหน้าจอ"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index bf05e149ea57..786e99cfe8c8 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Isara"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Isara ang Menu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Buksan ang Menu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"I-maximize ang Screen"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"I-snap ang Screen"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index 2dfa38a76dfa..e953f5808aff 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Kapat"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Menüyü kapat"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Menüyü Aç"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı Büyüt"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranın Yarısına Tuttur"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index 57ca64f5b159..fbdf42e582d1 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Закрити"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Закрити меню"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Відкрити меню"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Розгорнути екран"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Зафіксувати екран"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index 077037373aa2..5562fa70bf09 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"بند کریں"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"مینیو بند کریں"</string> <string name="expand_menu_text" msgid="3847736164494181168">"مینو کھولیں"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"اسکرین کو بڑا کریں"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"اسکرین کا اسناپ شاٹ لیں"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index e2d1f47c210b..50e42329a1a0 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Yopish"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Menyuni yopish"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Menyuni ochish"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranni yoyish"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranni biriktirish"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index 4608b2b10c3f..6da85881210d 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Đóng"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Đóng trình đơn"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Mở Trình đơn"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mở rộng màn hình"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Điều chỉnh kích thước màn hình"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index cbb857c58611..4318caf26199 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"关闭"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"关闭菜单"</string> <string name="expand_menu_text" msgid="3847736164494181168">"打开菜单"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"最大化屏幕"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"屏幕快照"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index d89b2c29216e..72cd39d8e00a 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"關閉"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string> <string name="expand_menu_text" msgid="3847736164494181168">"打開選單"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"貼齊畫面"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index 4ce50a44e12a..c06d7b105694 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"關閉"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string> <string name="expand_menu_text" msgid="3847736164494181168">"開啟選單"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"貼齊畫面"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index fa680f6eee89..755414e52762 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -117,4 +117,6 @@ <string name="close_text" msgid="4986518933445178928">"Vala"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Vala Imenyu"</string> <string name="expand_menu_text" msgid="3847736164494181168">"Vula Imenyu"</string> + <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Khulisa Isikrini Sifike Ekugcineni"</string> + <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Thwebula Isikrini"</string> </resources> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java index 19963675ff86..ce0bf8b29374 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java @@ -17,6 +17,7 @@ package com.android.wm.shell.animation; import android.graphics.Path; +import android.view.animation.BackGestureInterpolator; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; import android.view.animation.PathInterpolator; @@ -95,6 +96,15 @@ public class Interpolators { public static final PathInterpolator DIM_INTERPOLATOR = new PathInterpolator(.23f, .87f, .52f, -0.11f); + /** + * Use this interpolator for animating progress values coming from the back callback to get + * the predictive-back-typical decelerate motion. + * + * This interpolator is similar to {@link Interpolators#STANDARD_DECELERATE} but has a slight + * acceleration phase at the start. + */ + public static final Interpolator BACK_GESTURE = new BackGestureInterpolator(); + // Create the default emphasized interpolator private static PathInterpolator createEmphasizedInterpolator() { Path path = new Path(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt index 112ed0941122..7cb56605cc12 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt @@ -87,7 +87,7 @@ class CrossActivityBackAnimation @Inject constructor( private val enteringStartOffset = context.resources.getDimension(R.dimen.cross_activity_back_entering_start_offset) - private val gestureInterpolator = Interpolators.STANDARD_DECELERATE + private val gestureInterpolator = Interpolators.BACK_GESTURE private val postCommitInterpolator = Interpolators.FAST_OUT_SLOW_IN private val verticalMoveInterpolator: Interpolator = DecelerateInterpolator() diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java index c34f30df33a2..ee898a73a291 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java @@ -93,7 +93,7 @@ public class CrossTaskBackAnimation extends ShellBackAnimation { private final PointF mInitialTouchPos = new PointF(); private final Interpolator mPostAnimationInterpolator = Interpolators.EMPHASIZED; - private final Interpolator mProgressInterpolator = Interpolators.STANDARD_DECELERATE; + private final Interpolator mProgressInterpolator = Interpolators.BACK_GESTURE; private final Interpolator mVerticalMoveInterpolator = new DecelerateInterpolator(); private final Matrix mTransformMatrix = new Matrix(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java index 00daddc13346..7a6032c60cce 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java @@ -28,7 +28,7 @@ public class ShellBackAnimationRegistry { private static final String TAG = "ShellBackPreview"; private final SparseArray<BackAnimationRunner> mAnimationDefinition = new SparseArray<>(); - private final ShellBackAnimation mDefaultCrossActivityAnimation; + private ShellBackAnimation mDefaultCrossActivityAnimation; private final ShellBackAnimation mCustomizeActivityAnimation; private final ShellBackAnimation mCrossTaskAnimation; @@ -67,10 +67,18 @@ public class ShellBackAnimationRegistry { void registerAnimation( @BackNavigationInfo.BackTargetType int type, @NonNull BackAnimationRunner runner) { mAnimationDefinition.set(type, runner); + // Only happen in test + if (BackNavigationInfo.TYPE_CROSS_ACTIVITY == type) { + mDefaultCrossActivityAnimation = null; + } } void unregisterAnimation(@BackNavigationInfo.BackTargetType int type) { mAnimationDefinition.remove(type); + // Only happen in test + if (BackNavigationInfo.TYPE_CROSS_ACTIVITY == type) { + mDefaultCrossActivityAnimation = null; + } } /** @@ -129,9 +137,15 @@ public class ShellBackAnimationRegistry { } void onConfigurationChanged(Configuration newConfig) { - mCustomizeActivityAnimation.onConfigurationChanged(newConfig); - mDefaultCrossActivityAnimation.onConfigurationChanged(newConfig); - mCrossTaskAnimation.onConfigurationChanged(newConfig); + if (mCustomizeActivityAnimation != null) { + mCustomizeActivityAnimation.onConfigurationChanged(newConfig); + } + if (mDefaultCrossActivityAnimation != null) { + mDefaultCrossActivityAnimation.onConfigurationChanged(newConfig); + } + if (mCrossTaskAnimation != null) { + mCrossTaskAnimation.onConfigurationChanged(newConfig); + } } BackAnimationRunner getAnimationRunnerAndInit(BackNavigationInfo backNavigationInfo) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java index b179b5bc3cf6..a454d48ac863 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java @@ -159,7 +159,7 @@ public class PipTransition extends PipTransitionController { @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { - if (transition == mEnterTransition) { + if (transition == mEnterTransition || info.getType() == TRANSIT_PIP) { mEnterTransition = null; if (mPipScheduler.isInSwipePipToHomeTransition()) { // If this is the second transition as a part of swipe PiP to home cuj, 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 3b4fb9fbd8a1..24cf3706e25a 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 @@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED; +import static android.view.WindowManager.TRANSIT_PIP; import static android.view.WindowManager.TRANSIT_SLEEP; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.window.TransitionInfo.FLAG_TRANSLUCENT; @@ -59,6 +60,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.IResultReceiver; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.shared.TransitionUtil; import com.android.wm.shell.sysui.ShellInit; @@ -1023,13 +1025,16 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { } if (mPipTransaction != null && sendUserLeaveHint) { SurfaceControl pipLeash = null; + TransitionInfo.Change pipChange = null; if (mPipTask != null) { - pipLeash = mInfo.getChange(mPipTask).getLeash(); + pipChange = mInfo.getChange(mPipTask); + pipLeash = pipChange.getLeash(); } else if (mPipTaskId != -1) { // find a task with taskId from #setFinishTaskTransaction() for (TransitionInfo.Change change : mInfo.getChanges()) { if (change.getTaskInfo() != null && change.getTaskInfo().taskId == mPipTaskId) { + pipChange = change; pipLeash = change.getLeash(); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "RecentsController.finishInner:" @@ -1048,6 +1053,28 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "RecentsController.finishInner: PiP transaction %s merged", mPipTransaction); + if (PipUtils.isPip2ExperimentEnabled()) { + // If this path is triggered, we are in auto-enter PiP flow in gesture + // navigation mode, which means "Recents" transition should be followed + // by a TRANSIT_PIP. Hence, we take the WCT was about to be sent + // to Core to be applied during finishTransition(), we modify it to + // factor in PiP changes, and we send it as a direct startWCT for + // a new TRANSIT_PIP type transition. Recents still sends + // finishTransition() to update visibilities, but with finishWCT=null. + TransitionRequestInfo requestInfo = new TransitionRequestInfo( + TRANSIT_PIP, null /* triggerTask */, pipChange.getTaskInfo(), + null /* remote */, null /* displayChange */, 0 /* flags */); + // Use mTransition IBinder token temporarily just to get PipTransition + // to return from its handleRequest(). The actual TRANSIT_PIP will have + // anew token once it arrives into PipTransition#startAnimation(). + Pair<Transitions.TransitionHandler, WindowContainerTransaction> + requestRes = mTransitions.dispatchRequest(mTransition, + requestInfo, null /* skip */); + wct.merge(requestRes.second, true); + mTransitions.startTransition(TRANSIT_PIP, wct, null /* handler */); + // We need to clear the WCT to send finishWCT=null for Recents. + wct.clear(); + } } mPipTaskId = -1; mPipTask = null; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt index 987aadfbdef2..74499c7e429e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt @@ -33,6 +33,7 @@ class MoveToDesktopAnimator @JvmOverloads constructor( get() = dragToDesktopAnimator.animatedValue as Float * startBounds.width() val scale: Float get() = dragToDesktopAnimator.animatedValue as Float + private val mostRecentInput = PointF() private val dragToDesktopAnimator: ValueAnimator = ValueAnimator.ofFloat(1f, DRAG_FREEFORM_SCALE) .setDuration(ANIMATION_DURATION.toLong()) @@ -40,9 +41,13 @@ class MoveToDesktopAnimator @JvmOverloads constructor( val t = SurfaceControl.Transaction() val cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context) addUpdateListener { + setTaskPosition(mostRecentInput.x, mostRecentInput.y) t.setScale(taskSurface, scale, scale) - .setCornerRadius(taskSurface, cornerRadius) - .apply() + .setCornerRadius(taskSurface, cornerRadius) + .setScale(taskSurface, scale, scale) + .setCornerRadius(taskSurface, cornerRadius) + .setPosition(taskSurface, position.x, position.y) + .apply() } } @@ -78,19 +83,28 @@ class MoveToDesktopAnimator @JvmOverloads constructor( // allow dragging beyond its stage across any region of the display. Because of that, the // rawX/Y are more true to where the gesture is on screen and where the surface should be // positioned. - position.x = ev.rawX - animatedTaskWidth / 2 - position.y = ev.rawY + mostRecentInput.set(ev.rawX, ev.rawY) - if (!allowSurfaceChangesOnMove) { + // If animator is running, allow it to set scale and position at the same time. + if (!allowSurfaceChangesOnMove || dragToDesktopAnimator.isRunning) { return } - + setTaskPosition(ev.rawX, ev.rawY) val t = transactionFactory() t.setPosition(taskSurface, position.x, position.y) t.apply() } /** + * Calculates the top left corner of task from input coordinates. + * Top left will be needed for the resulting surface control transaction. + */ + private fun setTaskPosition(x: Float, y: Float) { + position.x = x - animatedTaskWidth / 2 + position.y = y + } + + /** * Cancels the animation, intended to be used when another animator will take over. */ fun cancelAnimator() { diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt index 9e6a686861c8..bcd0f126daef 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt +++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt @@ -24,6 +24,7 @@ import android.tools.traces.parsers.WindowManagerStateHelper import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation +import com.android.server.wm.flicker.helpers.MultiWindowUtils import com.android.wm.shell.flicker.service.common.Utils import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After @@ -51,6 +52,10 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) { fun setup() { Assume.assumeTrue(tapl.isTablet) + MultiWindowUtils.executeShellCommand( + instrumentation, + "settings put system notification_cooldown_enabled 0" + ) // Send a notification sendNotificationApp.launchViaIntent(wmHelper) sendNotificationApp.postNotification(wmHelper) @@ -74,5 +79,10 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) { primaryApp.exit(wmHelper) secondaryApp.exit(wmHelper) sendNotificationApp.exit(wmHelper) + + MultiWindowUtils.executeShellCommand( + instrumentation, + "settings reset system notification_cooldown_enabled" + ) } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java index e9da25813510..2366917a0158 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java @@ -83,6 +83,7 @@ import android.window.IRemoteTransition; import android.window.IRemoteTransitionFinishedCallback; import android.window.IWindowContainerToken; import android.window.RemoteTransition; +import android.window.RemoteTransitionStub; import android.window.TransitionFilter; import android.window.TransitionInfo; import android.window.TransitionRequestInfo; @@ -280,7 +281,7 @@ public class ShellTransitionTests extends ShellTestCase { final boolean[] remoteCalled = new boolean[]{false}; final WindowContainerTransaction remoteFinishWCT = new WindowContainerTransaction(); - IRemoteTransition testRemote = new IRemoteTransition.Stub() { + IRemoteTransition testRemote = new RemoteTransitionStub() { @Override public void startAnimation(IBinder token, TransitionInfo info, SurfaceControl.Transaction t, @@ -288,16 +289,6 @@ public class ShellTransitionTests extends ShellTestCase { remoteCalled[0] = true; finishCallback.onTransitionFinished(remoteFinishWCT, null /* sct */); } - - @Override - public void mergeAnimation(IBinder token, TransitionInfo info, - SurfaceControl.Transaction t, IBinder mergeTarget, - IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { - } - - @Override - public void onTransitionConsumed(IBinder iBinder, boolean b) throws RemoteException { - } }; IBinder transitToken = new Binder(); transitions.requestStartTransition(transitToken, @@ -450,7 +441,7 @@ public class ShellTransitionTests extends ShellTestCase { transitions.replaceDefaultHandlerForTest(mDefaultHandler); final boolean[] remoteCalled = new boolean[]{false}; - IRemoteTransition testRemote = new IRemoteTransition.Stub() { + IRemoteTransition testRemote = new RemoteTransitionStub() { @Override public void startAnimation(IBinder token, TransitionInfo info, SurfaceControl.Transaction t, @@ -458,16 +449,6 @@ public class ShellTransitionTests extends ShellTestCase { remoteCalled[0] = true; finishCallback.onTransitionFinished(null /* wct */, null /* sct */); } - - @Override - public void mergeAnimation(IBinder token, TransitionInfo info, - SurfaceControl.Transaction t, IBinder mergeTarget, - IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { - } - - @Override - public void onTransitionConsumed(IBinder iBinder, boolean b) throws RemoteException { - } }; TransitionFilter filter = new TransitionFilter(); @@ -500,7 +481,7 @@ public class ShellTransitionTests extends ShellTestCase { final boolean[] remoteCalled = new boolean[]{false}; final WindowContainerTransaction remoteFinishWCT = new WindowContainerTransaction(); - IRemoteTransition testRemote = new IRemoteTransition.Stub() { + IRemoteTransition testRemote = new RemoteTransitionStub() { @Override public void startAnimation(IBinder token, TransitionInfo info, SurfaceControl.Transaction t, @@ -508,16 +489,6 @@ public class ShellTransitionTests extends ShellTestCase { remoteCalled[0] = true; finishCallback.onTransitionFinished(remoteFinishWCT, null /* sct */); } - - @Override - public void mergeAnimation(IBinder token, TransitionInfo info, - SurfaceControl.Transaction t, IBinder mergeTarget, - IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { - } - - @Override - public void onTransitionConsumed(IBinder iBinder, boolean b) throws RemoteException { - } }; final int transitType = TRANSIT_FIRST_CUSTOM + 1; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TestRemoteTransition.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TestRemoteTransition.java index 87330d2dc877..184e8955d08c 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TestRemoteTransition.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TestRemoteTransition.java @@ -20,6 +20,7 @@ import android.os.RemoteException; import android.view.SurfaceControl; import android.window.IRemoteTransition; import android.window.IRemoteTransitionFinishedCallback; +import android.window.RemoteTransitionStub; import android.window.TransitionInfo; import android.window.WindowContainerTransaction; @@ -29,7 +30,7 @@ import android.window.WindowContainerTransaction; * {@link #startAnimation(IBinder, TransitionInfo, SurfaceControl.Transaction, * IRemoteTransitionFinishedCallback)} being called. */ -public class TestRemoteTransition extends IRemoteTransition.Stub { +public class TestRemoteTransition extends RemoteTransitionStub { private boolean mCalled = false; private boolean mConsumed = false; final WindowContainerTransaction mRemoteFinishWCT = new WindowContainerTransaction(); @@ -44,12 +45,6 @@ public class TestRemoteTransition extends IRemoteTransition.Stub { } @Override - public void mergeAnimation(IBinder transition, TransitionInfo info, - SurfaceControl.Transaction t, IBinder mergeTarget, - IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { - } - - @Override public void onTransitionConsumed(IBinder iBinder, boolean b) throws RemoteException { mConsumed = true; } diff --git a/libs/hostgraphics/ANativeWindow.cpp b/libs/hostgraphics/ANativeWindow.cpp new file mode 100644 index 000000000000..fcfaf0235293 --- /dev/null +++ b/libs/hostgraphics/ANativeWindow.cpp @@ -0,0 +1,106 @@ +/* + * 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. + */ + +#include <system/window.h> + +static int32_t query(ANativeWindow* window, int what) { + int value; + int res = window->query(window, what, &value); + return res < 0 ? res : value; +} + +static int64_t query64(ANativeWindow* window, int what) { + int64_t value; + int res = window->perform(window, what, &value); + return res < 0 ? res : value; +} + +int ANativeWindow_setCancelBufferInterceptor(ANativeWindow* window, + ANativeWindow_cancelBufferInterceptor interceptor, + void* data) { + return window->perform(window, NATIVE_WINDOW_SET_CANCEL_INTERCEPTOR, interceptor, data); +} + +int ANativeWindow_setDequeueBufferInterceptor(ANativeWindow* window, + ANativeWindow_dequeueBufferInterceptor interceptor, + void* data) { + return window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR, interceptor, data); +} + +int ANativeWindow_setQueueBufferInterceptor(ANativeWindow* window, + ANativeWindow_queueBufferInterceptor interceptor, + void* data) { + return window->perform(window, NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR, interceptor, data); +} + +int ANativeWindow_setPerformInterceptor(ANativeWindow* window, + ANativeWindow_performInterceptor interceptor, void* data) { + return window->perform(window, NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR, interceptor, data); +} + +int ANativeWindow_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd) { + return window->dequeueBuffer(window, buffer, fenceFd); +} + +int ANativeWindow_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) { + return window->cancelBuffer(window, buffer, fenceFd); +} + +int ANativeWindow_setDequeueTimeout(ANativeWindow* window, int64_t timeout) { + return window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT, timeout); +} + +// extern "C", so that it can be used outside libhostgraphics (in host hwui/.../CanvasContext.cpp) +extern "C" void ANativeWindow_tryAllocateBuffers(ANativeWindow* window) { + if (!window || !query(window, NATIVE_WINDOW_IS_VALID)) { + return; + } + window->perform(window, NATIVE_WINDOW_ALLOCATE_BUFFERS); +} + +int64_t ANativeWindow_getLastDequeueStartTime(ANativeWindow* window) { + return query64(window, NATIVE_WINDOW_GET_LAST_DEQUEUE_START); +} + +int64_t ANativeWindow_getLastDequeueDuration(ANativeWindow* window) { + return query64(window, NATIVE_WINDOW_GET_LAST_DEQUEUE_DURATION); +} + +int64_t ANativeWindow_getLastQueueDuration(ANativeWindow* window) { + return query64(window, NATIVE_WINDOW_GET_LAST_QUEUE_DURATION); +} + +int32_t ANativeWindow_getWidth(ANativeWindow* window) { + return query(window, NATIVE_WINDOW_WIDTH); +} + +int32_t ANativeWindow_getHeight(ANativeWindow* window) { + return query(window, NATIVE_WINDOW_HEIGHT); +} + +int32_t ANativeWindow_getFormat(ANativeWindow* window) { + return query(window, NATIVE_WINDOW_FORMAT); +} + +void ANativeWindow_acquire(ANativeWindow* window) { + // incStrong/decStrong token must be the same, doesn't matter what it is + window->incStrong((void*)ANativeWindow_acquire); +} + +void ANativeWindow_release(ANativeWindow* window) { + // incStrong/decStrong token must be the same, doesn't matter what it is + window->decStrong((void*)ANativeWindow_acquire); +} diff --git a/libs/hostgraphics/Android.bp b/libs/hostgraphics/Android.bp index 4407af68de99..09232b64616d 100644 --- a/libs/hostgraphics/Android.bp +++ b/libs/hostgraphics/Android.bp @@ -17,26 +17,18 @@ cc_library_host_static { static_libs: [ "libbase", "libmath", + "libui-types", "libutils", ], srcs: [ - ":libui_host_common", "ADisplay.cpp", + "ANativeWindow.cpp", "Fence.cpp", "HostBufferQueue.cpp", "PublicFormat.cpp", ], - include_dirs: [ - // Here we override all the headers automatically included with frameworks/native/include. - // When frameworks/native/include will be removed from the list of automatic includes. - // We will have to copy necessary headers with a pre-build step (generated headers). - ".", - "frameworks/native/libs/arect/include", - "frameworks/native/libs/ui/include_private", - ], - header_libs: [ "libnativebase_headers", "libnativedisplay_headers", diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index 4706699039a6..7439fbc1149c 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -96,6 +96,7 @@ cc_defaults { ], cflags: [ "-Wno-unused-variable", + "-D__INTRODUCED_IN(n)=", ], }, }, @@ -539,7 +540,10 @@ cc_defaults { "pipeline/skia/ReorderBarrierDrawables.cpp", "pipeline/skia/TransformCanvas.cpp", "renderstate/RenderState.cpp", + "renderthread/CanvasContext.cpp", + "renderthread/DrawFrameTask.cpp", "renderthread/Frame.cpp", + "renderthread/RenderProxy.cpp", "renderthread/RenderTask.cpp", "renderthread/TimeLord.cpp", "hwui/AnimatedImageDrawable.cpp", @@ -589,6 +593,7 @@ cc_defaults { "SkiaCanvas.cpp", "SkiaInterpolator.cpp", "Tonemapper.cpp", + "TreeInfo.cpp", "VectorDrawable.cpp", ], @@ -617,14 +622,11 @@ cc_defaults { "pipeline/skia/VkFunctorDrawable.cpp", "pipeline/skia/VkInteropFunctorDrawable.cpp", "renderthread/CacheManager.cpp", - "renderthread/CanvasContext.cpp", - "renderthread/DrawFrameTask.cpp", "renderthread/EglManager.cpp", "renderthread/ReliableSurface.cpp", "renderthread/RenderEffectCapabilityQuery.cpp", "renderthread/VulkanManager.cpp", "renderthread/VulkanSurface.cpp", - "renderthread/RenderProxy.cpp", "renderthread/RenderThread.cpp", "renderthread/HintSessionWrapper.cpp", "service/GraphicsStatsService.cpp", @@ -636,7 +638,6 @@ cc_defaults { "Layer.cpp", "ProfileDataContainer.cpp", "Readback.cpp", - "TreeInfo.cpp", "WebViewFunctorManager.cpp", "protos/graphicsstats.proto", ], @@ -654,6 +655,8 @@ cc_defaults { srcs: [ "platform/host/renderthread/CacheManager.cpp", + "platform/host/renderthread/HintSessionWrapper.cpp", + "platform/host/renderthread/ReliableSurface.cpp", "platform/host/renderthread/RenderThread.cpp", "platform/host/ProfileDataContainer.cpp", "platform/host/Readback.cpp", diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index f526a280b113..589abb4d87f4 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -16,18 +16,6 @@ #include "RenderNode.h" -#include "DamageAccumulator.h" -#include "Debug.h" -#include "Properties.h" -#include "TreeInfo.h" -#include "VectorDrawable.h" -#include "private/hwui/WebViewFunctor.h" -#ifdef __ANDROID__ -#include "renderthread/CanvasContext.h" -#else -#include "DamageAccumulator.h" -#include "pipeline/skia/SkiaDisplayList.h" -#endif #include <SkPathOps.h> #include <gui/TraceUtils.h> #include <ui/FatVector.h> @@ -37,6 +25,14 @@ #include <sstream> #include <string> +#include "DamageAccumulator.h" +#include "Debug.h" +#include "Properties.h" +#include "TreeInfo.h" +#include "VectorDrawable.h" +#include "private/hwui/WebViewFunctor.h" +#include "renderthread/CanvasContext.h" + #ifdef __ANDROID__ #include "include/gpu/ganesh/SkImageGanesh.h" #endif @@ -186,7 +182,6 @@ void RenderNode::prepareLayer(TreeInfo& info, uint32_t dirtyMask) { } void RenderNode::pushLayerUpdate(TreeInfo& info) { -#ifdef __ANDROID__ // Layoutlib does not support CanvasContext and Layers LayerType layerType = properties().effectiveLayerType(); // If we are not a layer OR we cannot be rendered (eg, view was detached) // we need to destroy any Layers we may have had previously @@ -218,7 +213,6 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { // That might be us, so tell CanvasContext that this layer is in the // tree and should not be destroyed. info.canvasContext.markLayerInUse(this); -#endif } /** diff --git a/libs/hwui/RootRenderNode.cpp b/libs/hwui/RootRenderNode.cpp index ddbbf58b3071..5174e27ae587 100644 --- a/libs/hwui/RootRenderNode.cpp +++ b/libs/hwui/RootRenderNode.cpp @@ -18,11 +18,12 @@ #ifdef __ANDROID__ // Layoutlib does not support Looper (windows) #include <utils/Looper.h> +#else +#include "utils/MessageHandler.h" #endif namespace android::uirenderer { -#ifdef __ANDROID__ // Layoutlib does not support Looper class FinishAndInvokeListener : public MessageHandler { public: explicit FinishAndInvokeListener(PropertyValuesAnimatorSet* anim) : mAnimator(anim) { @@ -237,9 +238,13 @@ void RootRenderNode::detachVectorDrawableAnimator(PropertyValuesAnimatorSet* ani // user events, in which case the already posted listener's id will become stale, and // the onFinished callback will then be ignored. sp<FinishAndInvokeListener> message = new FinishAndInvokeListener(anim); +#ifdef __ANDROID__ // Layoutlib does not support Looper auto looper = Looper::getForThread(); LOG_ALWAYS_FATAL_IF(looper == nullptr, "Not on a looper thread?"); looper->sendMessageDelayed(ms2ns(remainingTimeInMs), message, 0); +#else + message->handleMessage(0); +#endif anim->clearOneShotListener(); } } @@ -285,22 +290,5 @@ private: AnimationContext* ContextFactoryImpl::createAnimationContext(renderthread::TimeLord& clock) { return new AnimationContextBridge(clock, mRootNode); } -#else - -void RootRenderNode::prepareTree(TreeInfo& info) { - info.errorHandler = mErrorHandler.get(); - info.updateWindowPositions = true; - RenderNode::prepareTree(info); - info.updateWindowPositions = false; - info.errorHandler = nullptr; -} - -void RootRenderNode::attachAnimatingNode(RenderNode* animatingNode) { } - -void RootRenderNode::destroy() { } - -void RootRenderNode::addVectorDrawableAnimator(PropertyValuesAnimatorSet* anim) { } - -#endif } // namespace android::uirenderer diff --git a/libs/hwui/RootRenderNode.h b/libs/hwui/RootRenderNode.h index 1d3f5a8a51e0..7a5cda7041ed 100644 --- a/libs/hwui/RootRenderNode.h +++ b/libs/hwui/RootRenderNode.h @@ -74,7 +74,6 @@ private: void detachVectorDrawableAnimator(PropertyValuesAnimatorSet* anim); }; -#ifdef __ANDROID__ // Layoutlib does not support Animations class ContextFactoryImpl : public IContextFactory { public: explicit ContextFactoryImpl(RootRenderNode* rootNode) : mRootNode(rootNode) {} @@ -84,6 +83,5 @@ public: private: RootRenderNode* mRootNode; }; -#endif } // namespace android::uirenderer diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp index efa9b1174a3a..9d16ee86739e 100644 --- a/libs/hwui/WebViewFunctorManager.cpp +++ b/libs/hwui/WebViewFunctorManager.cpp @@ -87,7 +87,7 @@ void WebViewFunctor_release(int functor) { WebViewFunctorManager::instance().releaseFunctor(functor); } -void WebViewFunctor_reportRenderingThreads(int functor, const int32_t* thread_ids, size_t size) { +void WebViewFunctor_reportRenderingThreads(int functor, const pid_t* thread_ids, size_t size) { WebViewFunctorManager::instance().reportRenderingThreads(functor, thread_ids, size); } @@ -265,8 +265,8 @@ void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) { funcs.transactionDeleteFunc(transaction); } -void WebViewFunctor::reportRenderingThreads(const int32_t* thread_ids, size_t size) { - mRenderingThreads = std::vector<int32_t>(thread_ids, thread_ids + size); +void WebViewFunctor::reportRenderingThreads(const pid_t* thread_ids, size_t size) { + mRenderingThreads = std::vector<pid_t>(thread_ids, thread_ids + size); } WebViewFunctorManager& WebViewFunctorManager::instance() { @@ -355,7 +355,7 @@ void WebViewFunctorManager::destroyFunctor(int functor) { } } -void WebViewFunctorManager::reportRenderingThreads(int functor, const int32_t* thread_ids, +void WebViewFunctorManager::reportRenderingThreads(int functor, const pid_t* thread_ids, size_t size) { std::lock_guard _lock{mLock}; for (auto& iter : mFunctors) { @@ -366,8 +366,8 @@ void WebViewFunctorManager::reportRenderingThreads(int functor, const int32_t* t } } -std::vector<int32_t> WebViewFunctorManager::getRenderingThreadsForActiveFunctors() { - std::vector<int32_t> renderingThreads; +std::vector<pid_t> WebViewFunctorManager::getRenderingThreadsForActiveFunctors() { + std::vector<pid_t> renderingThreads; std::lock_guard _lock{mLock}; for (const auto& iter : mActiveFunctors) { const auto& functorThreads = iter->getRenderingThreads(); diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h index 2d77dd8d09bc..ec17640f9b5e 100644 --- a/libs/hwui/WebViewFunctorManager.h +++ b/libs/hwui/WebViewFunctorManager.h @@ -17,13 +17,11 @@ #pragma once #include <private/hwui/WebViewFunctor.h> -#ifdef __ANDROID__ // Layoutlib does not support render thread #include <renderthread/RenderProxy.h> -#endif - #include <utils/LightRefBase.h> #include <utils/Log.h> #include <utils/StrongPointer.h> + #include <mutex> #include <vector> @@ -38,11 +36,7 @@ public: class Handle : public LightRefBase<Handle> { public: - ~Handle() { -#ifdef __ANDROID__ // Layoutlib does not support render thread - renderthread::RenderProxy::destroyFunctor(id()); -#endif - } + ~Handle() { renderthread::RenderProxy::destroyFunctor(id()); } int id() const { return mReference.id(); } @@ -60,7 +54,7 @@ public: void onRemovedFromTree() { mReference.onRemovedFromTree(); } - const std::vector<int32_t>& getRenderingThreads() const { + const std::vector<pid_t>& getRenderingThreads() const { return mReference.getRenderingThreads(); } @@ -85,8 +79,8 @@ public: ASurfaceControl* getSurfaceControl(); void mergeTransaction(ASurfaceTransaction* transaction); - void reportRenderingThreads(const int32_t* thread_ids, size_t size); - const std::vector<int32_t>& getRenderingThreads() const { return mRenderingThreads; } + void reportRenderingThreads(const pid_t* thread_ids, size_t size); + const std::vector<pid_t>& getRenderingThreads() const { return mRenderingThreads; } sp<Handle> createHandle() { LOG_ALWAYS_FATAL_IF(mCreatedHandle); @@ -107,7 +101,7 @@ private: bool mCreatedHandle = false; int32_t mParentSurfaceControlGenerationId = 0; ASurfaceControl* mSurfaceControl = nullptr; - std::vector<int32_t> mRenderingThreads; + std::vector<pid_t> mRenderingThreads; }; class WebViewFunctorManager { @@ -118,8 +112,8 @@ public: void releaseFunctor(int functor); void onContextDestroyed(); void destroyFunctor(int functor); - void reportRenderingThreads(int functor, const int32_t* thread_ids, size_t size); - std::vector<int32_t> getRenderingThreadsForActiveFunctors(); + void reportRenderingThreads(int functor, const pid_t* thread_ids, size_t size); + std::vector<pid_t> getRenderingThreadsForActiveFunctors(); sp<WebViewFunctor::Handle> handleFor(int functor); diff --git a/libs/hwui/apex/LayoutlibLoader.cpp b/libs/hwui/apex/LayoutlibLoader.cpp index 770822a049b7..fd9915a54bb5 100644 --- a/libs/hwui/apex/LayoutlibLoader.cpp +++ b/libs/hwui/apex/LayoutlibLoader.cpp @@ -164,8 +164,10 @@ static vector<string> parseCsv(JNIEnv* env, jstring csvJString) { } // namespace android using namespace android; +using namespace android::uirenderer; void init_android_graphics() { + Properties::overrideRenderPipelineType(RenderPipelineType::SkiaCpu); SkGraphics::Init(); } diff --git a/libs/hwui/jni/AnimatedImageDrawable.cpp b/libs/hwui/jni/AnimatedImageDrawable.cpp index 0f80c55d0ed0..b01e38d014a9 100644 --- a/libs/hwui/jni/AnimatedImageDrawable.cpp +++ b/libs/hwui/jni/AnimatedImageDrawable.cpp @@ -27,6 +27,8 @@ #include <hwui/ImageDecoder.h> #ifdef __ANDROID__ #include <utils/Looper.h> +#else +#include "utils/MessageHandler.h" #endif #include "ColorFilter.h" @@ -182,23 +184,6 @@ static void AnimatedImageDrawable_nSetRepeatCount(JNIEnv* env, jobject /*clazz*/ drawable->setRepetitionCount(loopCount); } -#ifndef __ANDROID__ -struct Message { - Message(int w) {} -}; - -class MessageHandler : public virtual RefBase { -protected: - virtual ~MessageHandler() override {} - -public: - /** - * Handles a message. - */ - virtual void handleMessage(const Message& message) = 0; -}; -#endif - class InvokeListener : public MessageHandler { public: InvokeListener(JNIEnv* env, jobject javaObject) { diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp index 9e21f860ce21..d4157008ca46 100644 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -1,8 +1,14 @@ // #define LOG_NDEBUG 0 #include "Bitmap.h" +#include <android-base/unique_fd.h> #include <hwui/Bitmap.h> #include <hwui/Paint.h> +#include <inttypes.h> +#include <renderthread/RenderProxy.h> +#include <string.h> + +#include <memory> #include "CreateJavaOutputStreamAdaptor.h" #include "Gainmap.h" @@ -24,16 +30,6 @@ #include "SkTypes.h" #include "android_nio_utils.h" -#ifdef __ANDROID__ // Layoutlib does not support graphic buffer, parcel or render thread -#include <android-base/unique_fd.h> -#include <renderthread/RenderProxy.h> -#endif - -#include <inttypes.h> -#include <string.h> - -#include <memory> - #define DEBUG_PARCEL 0 static jclass gBitmap_class; @@ -1105,11 +1101,9 @@ static jboolean Bitmap_sameAs(JNIEnv* env, jobject, jlong bm0Handle, jlong bm1Ha } static void Bitmap_prepareToDraw(JNIEnv* env, jobject, jlong bitmapPtr) { -#ifdef __ANDROID__ // Layoutlib does not support render thread LocalScopedBitmap bitmapHandle(bitmapPtr); if (!bitmapHandle.valid()) return; android::uirenderer::renderthread::RenderProxy::prepareToDraw(bitmapHandle->bitmap()); -#endif } static jint Bitmap_getAllocationByteCount(JNIEnv* env, jobject, jlong bitmapPtr) { diff --git a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp index 426644ee6a4e..948362c30a31 100644 --- a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp +++ b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp @@ -16,22 +16,19 @@ #include "GraphicsJNI.h" -#ifdef __ANDROID__ // Layoutlib does not support Looper and device properties +#ifdef __ANDROID__ // Layoutlib does not support Looper #include <utils/Looper.h> #endif -#include <SkRegion.h> -#include <SkRuntimeEffect.h> - +#include <CanvasProperty.h> #include <Rect.h> #include <RenderNode.h> -#include <CanvasProperty.h> +#include <SkRegion.h> +#include <SkRuntimeEffect.h> #include <hwui/Canvas.h> #include <hwui/Paint.h> #include <minikin/Layout.h> -#ifdef __ANDROID__ // Layoutlib does not support RenderThread #include <renderthread/RenderProxy.h> -#endif namespace android { @@ -85,11 +82,7 @@ static void android_view_DisplayListCanvas_resetDisplayListCanvas(CRITICAL_JNI_P } static jint android_view_DisplayListCanvas_getMaxTextureSize(JNIEnv*, jobject) { -#ifdef __ANDROID__ // Layoutlib does not support RenderProxy (RenderThread) return android::uirenderer::renderthread::RenderProxy::maxTextureSize(); -#else - return 4096; -#endif } static void android_view_DisplayListCanvas_enableZ(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp index a7d64231da80..6e03bbd0fa16 100644 --- a/libs/hwui/jni/android_graphics_RenderNode.cpp +++ b/libs/hwui/jni/android_graphics_RenderNode.cpp @@ -15,19 +15,17 @@ */ #define ATRACE_TAG ATRACE_TAG_VIEW -#include "GraphicsJNI.h" - #include <Animator.h> #include <DamageAccumulator.h> #include <Matrix.h> #include <RenderNode.h> -#ifdef __ANDROID__ // Layoutlib does not support CanvasContext -#include <renderthread/CanvasContext.h> -#endif #include <TreeInfo.h> #include <effects/StretchEffect.h> #include <gui/TraceUtils.h> #include <hwui/Paint.h> +#include <renderthread/CanvasContext.h> + +#include "GraphicsJNI.h" namespace android { @@ -640,7 +638,6 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, ATRACE_NAME("Update SurfaceView position"); -#ifdef __ANDROID__ // Layoutlib does not support CanvasContext JNIEnv* env = jnienv(); // Update the new position synchronously. We cannot defer this to // a worker pool to process asynchronously because the UI thread @@ -669,7 +666,6 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, env->DeleteGlobalRef(mListener); mListener = nullptr; } -#endif } virtual void onPositionLost(RenderNode& node, const TreeInfo* info) override { @@ -682,7 +678,6 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, ATRACE_NAME("SurfaceView position lost"); JNIEnv* env = jnienv(); -#ifdef __ANDROID__ // Layoutlib does not support CanvasContext // Update the lost position synchronously. We cannot defer this to // a worker pool to process asynchronously because the UI thread // may be unblocked by the time a worker thread can process this, @@ -698,7 +693,6 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, env->DeleteGlobalRef(mListener); mListener = nullptr; } -#endif } private: @@ -750,7 +744,6 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, StretchEffectBehavior::Shader) { JNIEnv* env = jnienv(); -#ifdef __ANDROID__ // Layoutlib does not support CanvasContext SkVector stretchDirection = effect->getStretchDirection(); jboolean keepListening = env->CallStaticBooleanMethod( gPositionListener.clazz, gPositionListener.callApplyStretch, mListener, @@ -762,7 +755,6 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, env->DeleteGlobalRef(mListener); mListener = nullptr; } -#endif } } diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp index e0216b680064..36dc933aa7b0 100644 --- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp +++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp @@ -15,22 +15,18 @@ */ #include "SkiaDisplayList.h" -#include "FunctorDrawable.h" +#include <SkImagePriv.h> +#include <SkPathOps.h> + +// clang-format off +#include "FunctorDrawable.h" // Must be included before DumpOpsCanvas.h #include "DumpOpsCanvas.h" -#ifdef __ANDROID__ // Layoutlib does not support SkiaPipeline +// clang-format on #include "SkiaPipeline.h" -#else -#include "DamageAccumulator.h" -#endif #include "TreeInfo.h" #include "VectorDrawable.h" -#ifdef __ANDROID__ #include "renderthread/CanvasContext.h" -#endif - -#include <SkImagePriv.h> -#include <SkPathOps.h> namespace android { namespace uirenderer { @@ -101,7 +97,6 @@ bool SkiaDisplayList::prepareListAndChildren( // If the prepare tree is triggered by the UI thread and no previous call to // pinImages has failed then we must pin all mutable images in the GPU cache // until the next UI thread draw. -#ifdef __ANDROID__ // Layoutlib does not support CanvasContext if (info.prepareTextures && !info.canvasContext.pinImages(mMutableImages)) { // In the event that pinning failed we prevent future pinImage calls for the // remainder of this tree traversal and also unpin any currently pinned images @@ -110,11 +105,11 @@ bool SkiaDisplayList::prepareListAndChildren( info.canvasContext.unpinImages(); } +#ifdef __ANDROID__ auto grContext = info.canvasContext.getGrContext(); for (const auto& bufferData : mMeshBufferData) { bufferData->updateBuffers(grContext); } - #endif bool hasBackwardProjectedNodesHere = false; diff --git a/libs/hwui/platform/host/WebViewFunctorManager.cpp b/libs/hwui/platform/host/WebViewFunctorManager.cpp index 1d16655bf73c..4ba206b41b39 100644 --- a/libs/hwui/platform/host/WebViewFunctorManager.cpp +++ b/libs/hwui/platform/host/WebViewFunctorManager.cpp @@ -50,6 +50,8 @@ ASurfaceControl* WebViewFunctor::getSurfaceControl() { void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {} +void WebViewFunctor::reportRenderingThreads(const pid_t* thread_ids, size_t size) {} + void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) {} WebViewFunctorManager& WebViewFunctorManager::instance() { @@ -68,6 +70,13 @@ void WebViewFunctorManager::onContextDestroyed() {} void WebViewFunctorManager::destroyFunctor(int functor) {} +void WebViewFunctorManager::reportRenderingThreads(int functor, const pid_t* thread_ids, + size_t size) {} + +std::vector<pid_t> WebViewFunctorManager::getRenderingThreadsForActiveFunctors() { + return {}; +} + sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) { return nullptr; } diff --git a/libs/hwui/platform/host/renderthread/HintSessionWrapper.cpp b/libs/hwui/platform/host/renderthread/HintSessionWrapper.cpp new file mode 100644 index 000000000000..b1b1d5830834 --- /dev/null +++ b/libs/hwui/platform/host/renderthread/HintSessionWrapper.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2022 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 "renderthread/HintSessionWrapper.h" + +namespace android { +namespace uirenderer { +namespace renderthread { + +void HintSessionWrapper::HintSessionBinding::init() {} + +HintSessionWrapper::HintSessionWrapper(pid_t uiThreadId, pid_t renderThreadId) + : mUiThreadId(uiThreadId) + , mRenderThreadId(renderThreadId) + , mBinding(std::make_shared<HintSessionBinding>()) {} + +HintSessionWrapper::~HintSessionWrapper() {} + +void HintSessionWrapper::destroy() {} + +bool HintSessionWrapper::init() { + return false; +} + +void HintSessionWrapper::updateTargetWorkDuration(long targetWorkDurationNanos) {} + +void HintSessionWrapper::reportActualWorkDuration(long actualDurationNanos) {} + +void HintSessionWrapper::sendLoadResetHint() {} + +void HintSessionWrapper::sendLoadIncreaseHint() {} + +bool HintSessionWrapper::alive() { + return false; +} + +nsecs_t HintSessionWrapper::getLastUpdate() { + return -1; +} + +void HintSessionWrapper::delayedDestroy(RenderThread& rt, nsecs_t delay, + std::shared_ptr<HintSessionWrapper> wrapperPtr) {} + +void HintSessionWrapper::setActiveFunctorThreads(std::vector<pid_t> threadIds) {} + +} /* namespace renderthread */ +} /* namespace uirenderer */ +} /* namespace android */ diff --git a/libs/hwui/platform/host/renderthread/ReliableSurface.cpp b/libs/hwui/platform/host/renderthread/ReliableSurface.cpp new file mode 100644 index 000000000000..2deaaf3b909c --- /dev/null +++ b/libs/hwui/platform/host/renderthread/ReliableSurface.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 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 "renderthread/ReliableSurface.h" + +#include <log/log_main.h> +#include <system/window.h> + +namespace android::uirenderer::renderthread { + +ReliableSurface::ReliableSurface(ANativeWindow* window) : mWindow(window) { + LOG_ALWAYS_FATAL_IF(!mWindow, "Error, unable to wrap a nullptr"); + ANativeWindow_acquire(mWindow); +} + +ReliableSurface::~ReliableSurface() { + ANativeWindow_release(mWindow); +} + +void ReliableSurface::init() {} + +int ReliableSurface::reserveNext() { + return OK; +} + +}; // namespace android::uirenderer::renderthread diff --git a/libs/hwui/platform/host/utils/MessageHandler.h b/libs/hwui/platform/host/utils/MessageHandler.h new file mode 100644 index 000000000000..51ee48e0c6d2 --- /dev/null +++ b/libs/hwui/platform/host/utils/MessageHandler.h @@ -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. + */ + +#pragma once + +#include <utils/RefBase.h> + +struct Message { + Message(int w) {} +}; + +class MessageHandler : public virtual android::RefBase { +protected: + virtual ~MessageHandler() override {} + +public: + /** + * Handles a message. + */ + virtual void handleMessage(const Message& message) = 0; +}; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 22de2f29792d..66e089627a7b 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -35,6 +35,7 @@ #include "Properties.h" #include "RenderThread.h" #include "hwui/Canvas.h" +#include "pipeline/skia/SkiaCpuPipeline.h" #include "pipeline/skia/SkiaGpuPipeline.h" #include "pipeline/skia/SkiaOpenGLPipeline.h" #include "pipeline/skia/SkiaVulkanPipeline.h" @@ -72,7 +73,7 @@ CanvasContext* ScopedActiveContext::sActiveContext = nullptr; CanvasContext* CanvasContext::create(RenderThread& thread, bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory, - int32_t uiThreadId, int32_t renderThreadId) { + pid_t uiThreadId, pid_t renderThreadId) { auto renderType = Properties::getRenderPipelineType(); switch (renderType) { @@ -84,6 +85,12 @@ CanvasContext* CanvasContext::create(RenderThread& thread, bool translucent, return new CanvasContext(thread, translucent, rootRenderNode, contextFactory, std::make_unique<skiapipeline::SkiaVulkanPipeline>(thread), uiThreadId, renderThreadId); +#ifndef __ANDROID__ + case RenderPipelineType::SkiaCpu: + return new CanvasContext(thread, translucent, rootRenderNode, contextFactory, + std::make_unique<skiapipeline::SkiaCpuPipeline>(thread), + uiThreadId, renderThreadId); +#endif default: LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType); break; @@ -182,6 +189,7 @@ static void setBufferCount(ANativeWindow* window) { } void CanvasContext::setHardwareBuffer(AHardwareBuffer* buffer) { +#ifdef __ANDROID__ if (mHardwareBuffer) { AHardwareBuffer_release(mHardwareBuffer); mHardwareBuffer = nullptr; @@ -192,6 +200,7 @@ void CanvasContext::setHardwareBuffer(AHardwareBuffer* buffer) { mHardwareBuffer = buffer; } mRenderPipeline->setHardwareBuffer(mHardwareBuffer); +#endif } void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) { @@ -561,6 +570,7 @@ Frame CanvasContext::getFrame() { } void CanvasContext::draw(bool solelyTextureViewUpdates) { +#ifdef __ANDROID__ if (auto grContext = getGrContext()) { if (grContext->abandoned()) { if (grContext->isDeviceLost()) { @@ -571,6 +581,7 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) { return; } } +#endif SkRect dirty; mDamageAccumulator.finish(&dirty); @@ -594,11 +605,13 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) { if (skippedFrameReason) { mCurrentFrameInfo->setSkippedFrameReason(*skippedFrameReason); +#ifdef __ANDROID__ if (auto grContext = getGrContext()) { // Submit to ensure that any texture uploads complete and Skia can // free its staging buffers. grContext->flushAndSubmit(); } +#endif // Notify the callbacks, even if there's nothing to draw so they aren't waiting // indefinitely diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index 1b333bfccbf1..826d00e1f32f 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -140,12 +140,14 @@ void DrawFrameTask::run() { if (CC_LIKELY(canDrawThisFrame)) { context->draw(solelyTextureViewUpdates); } else { +#ifdef __ANDROID__ // Do a flush in case syncFrameState performed any texture uploads. Since we skipped // the draw() call, those uploads (or deletes) will end up sitting in the queue. // Do them now if (GrDirectContext* grContext = mRenderThread->getGrContext()) { grContext->flushAndSubmit(); } +#endif // wait on fences so tasks don't overlap next frame context->waitOnFences(); } @@ -176,11 +178,13 @@ bool DrawFrameTask::syncFrameState(TreeInfo& info) { bool canDraw = mContext->makeCurrent(); mContext->unpinImages(); +#ifdef __ANDROID__ for (size_t i = 0; i < mLayers.size(); i++) { if (mLayers[i]) { mLayers[i]->apply(); } } +#endif mLayers.clear(); mContext->setContentDrawBounds(mContentDrawBounds); diff --git a/libs/hwui/renderthread/ReliableSurface.h b/libs/hwui/renderthread/ReliableSurface.h index 595964741049..d6a4d50d3327 100644 --- a/libs/hwui/renderthread/ReliableSurface.h +++ b/libs/hwui/renderthread/ReliableSurface.h @@ -21,7 +21,9 @@ #include <apex/window.h> #include <utils/Errors.h> #include <utils/Macros.h> +#ifdef __ANDROID__ #include <utils/NdkUtils.h> +#endif #include <utils/StrongPointer.h> #include <memory> @@ -62,9 +64,11 @@ private: mutable std::mutex mMutex; uint64_t mUsage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER; +#ifdef __ANDROID__ AHardwareBuffer_Format mFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; UniqueAHardwareBuffer mScratchBuffer; ANativeWindowBuffer* mReservedBuffer = nullptr; +#endif base::unique_fd mReservedFenceFd; bool mHasDequeuedBuffer = false; int mBufferQueueState = OK; diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index eab36050896f..715153b5083d 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -42,7 +42,11 @@ namespace renderthread { RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory) : mRenderThread(RenderThread::getInstance()), mContext(nullptr) { +#ifdef __ANDROID__ pid_t uiThreadId = pthread_gettid_np(pthread_self()); +#else + pid_t uiThreadId = 0; +#endif pid_t renderThreadId = getRenderThreadTid(); mContext = mRenderThread.queue().runSync([=, this]() -> CanvasContext* { CanvasContext* context = CanvasContext::create(mRenderThread, translucent, rootRenderNode, @@ -90,6 +94,7 @@ void RenderProxy::setName(const char* name) { } void RenderProxy::setHardwareBuffer(AHardwareBuffer* buffer) { +#ifdef __ANDROID__ if (buffer) { AHardwareBuffer_acquire(buffer); } @@ -99,6 +104,7 @@ void RenderProxy::setHardwareBuffer(AHardwareBuffer* buffer) { AHardwareBuffer_release(hardwareBuffer); } }); +#endif } void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) { @@ -216,7 +222,9 @@ void RenderProxy::cancelLayerUpdate(DeferredLayerUpdater* layer) { } void RenderProxy::detachSurfaceTexture(DeferredLayerUpdater* layer) { +#ifdef __ANDROID__ return mRenderThread.queue().runSync([&]() { layer->detachSurfaceTexture(); }); +#endif } void RenderProxy::destroyHardwareResources() { @@ -324,11 +332,13 @@ void RenderProxy::dumpGraphicsMemory(int fd, bool includeProfileData, bool reset } }); } +#ifdef __ANDROID__ if (!Properties::isolatedProcess) { std::string grallocInfo; GraphicBufferAllocator::getInstance().dump(grallocInfo); dprintf(fd, "%s\n", grallocInfo.c_str()); } +#endif } void RenderProxy::getMemoryUsage(size_t* cpuUsage, size_t* gpuUsage) { @@ -352,7 +362,11 @@ void RenderProxy::rotateProcessStatsBuffer() { } int RenderProxy::getRenderThreadTid() { +#ifdef __ANDROID__ return mRenderThread.getTid(); +#else + return 0; +#endif } void RenderProxy::addRenderNode(RenderNode* node, bool placeFront) { @@ -461,7 +475,7 @@ void RenderProxy::prepareToDraw(Bitmap& bitmap) { int RenderProxy::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) { ATRACE_NAME("HardwareBitmap readback"); RenderThread& thread = RenderThread::getInstance(); - if (gettid() == thread.getTid()) { + if (RenderThread::isCurrent()) { // TODO: fix everything that hits this. We should never be triggering a readback ourselves. return (int)thread.readback().copyHWBitmapInto(hwBitmap, bitmap); } else { @@ -472,7 +486,7 @@ int RenderProxy::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) { int RenderProxy::copyImageInto(const sk_sp<SkImage>& image, SkBitmap* bitmap) { RenderThread& thread = RenderThread::getInstance(); - if (gettid() == thread.getTid()) { + if (RenderThread::isCurrent()) { // TODO: fix everything that hits this. We should never be triggering a readback ourselves. return (int)thread.readback().copyImageInto(image, bitmap); } else { diff --git a/media/java/android/media/projection/MediaProjectionManager.java b/media/java/android/media/projection/MediaProjectionManager.java index 2a0648d87c85..7ed67dcde913 100644 --- a/media/java/android/media/projection/MediaProjectionManager.java +++ b/media/java/android/media/projection/MediaProjectionManager.java @@ -23,6 +23,9 @@ import android.annotation.SystemService; import android.annotation.TestApi; import android.app.Activity; import android.app.ActivityOptions.LaunchCookie; +import android.compat.annotation.ChangeId; +import android.compat.annotation.Disabled; +import android.compat.annotation.Overridable; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -66,6 +69,18 @@ public final class MediaProjectionManager { private static final String TAG = "MediaProjectionManager"; /** + * This change id ensures that users are presented with a choice of capturing a single app + * or the entire screen when initiating a MediaProjection session, overriding the usage of + * MediaProjectionConfig#createConfigForDefaultDisplay. + * + * @hide + */ + @ChangeId + @Overridable + @Disabled + public static final long OVERRIDE_DISABLE_MEDIA_PROJECTION_SINGLE_APP_OPTION = 316897322L; + + /** * Intent extra to customize the permission dialog based on the host app's preferences. * @hide */ diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl index 207ccbee0b50..871e9ab87299 100644 --- a/media/java/android/media/session/ISessionManager.aidl +++ b/media/java/android/media/session/ISessionManager.aidl @@ -80,4 +80,7 @@ interface ISessionManager { boolean hasCustomMediaSessionPolicyProvider(String componentName); int getSessionPolicies(in MediaSession.Token token); void setSessionPolicies(in MediaSession.Token token, int policies); + + // For testing of temporarily engaged sessions. + void expireTempEngagedSessions(); } diff --git a/packages/BackupRestoreConfirmation/AndroidManifest.xml b/packages/BackupRestoreConfirmation/AndroidManifest.xml index e67b3be43ea1..44aa1b1b8747 100644 --- a/packages/BackupRestoreConfirmation/AndroidManifest.xml +++ b/packages/BackupRestoreConfirmation/AndroidManifest.xml @@ -26,7 +26,8 @@ android:allowBackup="false" android:permission="android.permission.CONFIRM_FULL_BACKUP" > - <activity android:name=".BackupRestoreConfirmation" + <activity android:name=".BackupRestoreConfirmation" + android:theme="@style/OptOutEdgeToEdgeEnforcement" android:title="" android:windowSoftInputMode="stateAlwaysHidden" android:excludeFromRecents="true" diff --git a/packages/BackupRestoreConfirmation/res/values/styles.xml b/packages/BackupRestoreConfirmation/res/values/styles.xml new file mode 100644 index 000000000000..ce54568ed6d6 --- /dev/null +++ b/packages/BackupRestoreConfirmation/res/values/styles.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- + TODO(b/309578419): Make activities handle insets properly and then remove this. + --> + <style name="OptOutEdgeToEdgeEnforcement"> + <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item> + </style> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml index 183965e6723a..d2df0e4f5d0d 100644 --- a/packages/CompanionDeviceManager/res/values-ar/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml @@ -27,10 +27,10 @@ <string name="summary_glasses" msgid="2872254734959842579">"سيتم السماح لهذا التطبيق بالوصول إلى هذه الأذونات على \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string> <string name="title_app_streaming" msgid="2270331024626446950">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى هذه المعلومات من هاتفك"</string> <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"هل تريد منح <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> إذنًا لبث التطبيقات المُثبَّتة على هاتفك؟"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"سيتمكّن \"%1$s\" من الوصول إلى كل المحتوى المعروض أو الذي يتم تشغيله على الهاتف، بما في ذلك الملفات الصوتية والصور وكلمات المرور والرسائل.<br/><br/>سيتمكّن \"%1$s\" من بث التطبيقات إلى أنّ توقف إمكانية استخدام هذا الإذن."</string> + <string name="summary_app_streaming" msgid="295548145144086753">"سيتمكّن %1$s من الوصول إلى كل المحتوى المعروض أو الذي يتم تشغيله على الهاتف، بما في ذلك الملفات الصوتية والصور وكلمات المرور والرسائل.<br/><br/>سيتمكّن %1$s من بث التطبيقات إلى أن توقف إمكانية استخدام هذا الإذن."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"الخدمات التي تعمل بين الأجهزة"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"يطلب تطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" لبثّ محتوى التطبيقات بين أجهزتك."</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"يطلب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" لعرض التطبيقات وبثها بين أجهزتك"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"تطلب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> لعرض التطبيقات وبثها بين أجهزتك"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى هذه المعلومات من هاتفك"</string> @@ -39,7 +39,7 @@ <string name="helper_summary_computer" msgid="8774832742608187072">"يطلب تطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" للوصول إلى الصور والوسائط والإشعارات في هاتفك."</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"هل تريد السماح للتطبيق <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> باتّخاذ هذا الإجراء؟"</string> <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"هل تريد منح <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> إذنًا لبث التطبيقات والوصول إلى ميزات النظام على هاتفك؟"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"سيتمكّن \"%1$s\" من الوصول إلى كل المحتوى المعروض أو الذي يتم تشغيله على هاتفك، بما في ذلك الملفات الصوتية والصور ومعلومات الدفع وكلمات المرور والرسائل.<br/><br/>سيتمكّن \"%1$s\" من بث التطبيقات والوصول إلى ميزات النظام إلى أنّ توقف إمكانية استخدام هذا الإذن."</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"سيتمكّن %1$s من الوصول إلى كل المحتوى المعروض أو الذي يتم تشغيله على هاتفك، بما في ذلك الملفات الصوتية والصور ومعلومات الدفع وكلمات المرور والرسائل.<br/><br/>سيتمكّن %1$s من بث التطبيقات والوصول إلى ميزات النظام إلى أن توقف إمكانية استخدام هذا الإذن."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"يطلب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\" لبثّ التطبيقات وميزات النظام الأخرى إلى أجهزتك المجاورة."</string> <string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string> <string name="summary_generic" msgid="1761976003668044801">"سيتمكّن هذا التطبيق من مزامنة المعلومات، مثل اسم المتصل، بين هاتفك والجهاز المحدّد."</string> diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml index 4fb9ceed1c6c..2316baadf480 100644 --- a/packages/CompanionDeviceManager/res/values-bg/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml @@ -30,7 +30,7 @@ <string name="summary_app_streaming" msgid="295548145144086753">"%1$s ще има достъп до всичко, което се показва или възпроизвежда на телефона, включително аудиосъдържание, снимки, пароли и съобщения.<br/><br/>%1$s ще може да предава поточно приложения, докато не премахнете това разрешение."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуги за различни устройства"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> да предава поточно приложения между устройствата ви"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> да показва и да предава поточно приложения между устройствата ви"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ иска разрешение от името на <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> да показва и да предава поточно приложения между устройствата ви"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Разрешете на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да осъществява достъп до тази информация от телефона ви"</string> diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml index 231d395e2a8e..247d017f4b16 100644 --- a/packages/CompanionDeviceManager/res/values-bs/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml @@ -26,7 +26,7 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"uređaj"</string> <string name="summary_glasses" msgid="2872254734959842579">"Aplikaciji će biti dozvoljen pristup ovim odobrenjima na uređaju <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da aplikacija <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama s telefona"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Dozvoliti aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da prenosi aplikacije telefona?"</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Dozvoliti uređaju <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da prenosi aplikacije telefona?"</string> <string name="summary_app_streaming" msgid="295548145144086753">"%1$s će imati pristup svemu što je vidljivo ili se reproducira na telefonu, uključujući zvuk, fotografije, lozinke i poruke.<br/><br/>%1$s će moći prenositi aplikacije dok ne uklonite pristup ovom odobrenju."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluga na više uređaja"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string> @@ -59,7 +59,7 @@ <string name="permission_microphone" msgid="2152206421428732949">"Mikrofon"</string> <string name="permission_call_logs" msgid="5546761417694586041">"Zapisnici poziva"</string> <string name="permission_nearby_devices" msgid="7530973297737123481">"Uređaji u blizini"</string> - <string name="permission_media_routing_control" msgid="5498639511586715253">"Promijeni izlaz med. sadržaja"</string> + <string name="permission_media_routing_control" msgid="5498639511586715253">"Promjena medijskog izlaza"</string> <string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string> <string name="permission_notifications" msgid="4099418516590632909">"Obavještenja"</string> <string name="permission_app_streaming" msgid="6009695219091526422">"Aplikacije"</string> diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml index 94510e3d4ca7..3acd1798f990 100644 --- a/packages/CompanionDeviceManager/res/values-cs/strings.xml +++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml @@ -27,7 +27,7 @@ <string name="summary_glasses" msgid="2872254734959842579">"Tato aplikace bude mít ve vašem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> povolený přístup k těmto oprávněním"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Povolte aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> přístup k těmto informacím z vašeho telefonu"</string> <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Povolit zařízení <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> streamovat aplikace telefonu?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"Aplikace %1$s bude mít přístup ke všemu, co zobrazíte nebo přehrajete na telefonu, včetně zvuku, fotek, hesel a zpráv.<br/><br/>%1$s bude moci streamovat aplikace, dokud přístup k tomuto oprávnění neodeberete."</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s bude mít přístup ke všemu, co na telefonu zobrazíte nebo přehrajete, včetně zvuku, fotek, hesel a zpráv.<br/><br/>%1$s bude moci streamovat aplikace, dokud přístup k tomuto oprávnění neodeberete."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pro více zařízení"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> oprávnění ke streamování aplikací mezi zařízeními"</string> <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> oprávnění k zobrazení a streamování obsahu mezi zařízeními"</string> @@ -39,7 +39,7 @@ <string name="helper_summary_computer" msgid="8774832742608187072">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> oprávnění k přístupu k fotkám, médiím a oznámením v telefonu"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Povolit zařízení <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> podniknout tuto akci?"</string> <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Povolit zařízení <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> streamovat aplikace a systémové funkce telefonu?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"Aplikace %1$s bude mít přístup ke všemu, co zobrazíte nebo přehrajete na telefonu, včetně zvuku, fotek, platebních údajů, hesel a zpráv.<br/><br/>%1$s bude moci streamovat aplikace a systémové funkce, dokud přístup k tomuto oprávnění neodeberete."</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s bude mít přístup ke všemu, co na telefonu zobrazíte nebo přehrajete, včetně zvuku, fotek, platebních údajů, hesel a zpráv.<br/><br/>%1$s bude moci streamovat aplikace a systémové funkce, dokud přístup k tomuto oprávnění neodeberete."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> žádá jménem vašeho zařízení <xliff:g id="DEVICE_NAME">%2$s</xliff:g> o oprávnění streamovat aplikace a další systémové funkce do zařízení v okolí"</string> <string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string> <string name="summary_generic" msgid="1761976003668044801">"Tato aplikace bude moci synchronizovat údaje, jako je jméno volajícího, mezi vaším telefonem a vybraným zařízením"</string> diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml index 6b38bff17b4c..9d0846c554c0 100644 --- a/packages/CompanionDeviceManager/res/values-da/strings.xml +++ b/packages/CompanionDeviceManager/res/values-da/strings.xml @@ -28,7 +28,7 @@ <string name="title_app_streaming" msgid="2270331024626446950">"Giv <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> adgang til disse oplysninger fra din telefon"</string> <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Vil du give <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilladelse til at streame din telefons apps?"</string> <string name="summary_app_streaming" msgid="295548145144086753">"%1$s har adgang til alt, der er synligt eller afspilles på telefonen, herunder lyd, billeder, adgangskoder og beskeder.<br/><br/>%1$s kan streame apps, indtil du fjerner adgangen til denne tilladelse."</string> - <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester, som kan tilsluttes en anden enhed"</string> + <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester til flere enheder"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> til at streame apps mellem dine enheder"</string> <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> til at vise og streame apps mellem dine enheder"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml index 65e923c67857..3f730fc82b30 100644 --- a/packages/CompanionDeviceManager/res/values-de/strings.xml +++ b/packages/CompanionDeviceManager/res/values-de/strings.xml @@ -26,11 +26,11 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"Gerät"</string> <string name="summary_glasses" msgid="2872254734959842579">"Diese App darf dann auf diese Berechtigungen auf deinem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> zugreifen:"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> Zugriff auf diese Informationen von deinem Smartphone gewähren"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> erlauben, die Apps auf deinem Smartphone zu streamen?"</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Zulassen, dass <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> die Apps auf deinem Smartphone streamt?"</string> <string name="summary_app_streaming" msgid="295548145144086753">"%1$s hat dann Zugriff auf alle Inhalte, die auf deinem Smartphone sichtbar sind oder abgespielt werden, einschließlich Audio, Fotos, Passwörter und Nachrichten.<br/><br/>%1$s kann so lange Apps streamen, bis du diese Berechtigung entfernst."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Geräteübergreifende Dienste"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> um die Berechtigung zum Streamen von Apps zwischen deinen Geräten"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> um die Berechtigung zum Anzeigen und Streamen von Apps zwischen deinen Geräten"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> um die Berechtigung, gegenseitig das Anzeigen und Streamen von Apps zu erlauben"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> Zugriff auf diese Informationen von deinem Smartphone gewähren"</string> @@ -38,8 +38,8 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-Dienste"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> um die Berechtigung zum Zugriff auf die Fotos, Medien und Benachrichtigungen deines Smartphones"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Darf das Gerät <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> diese Aktion ausführen?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> erlauben, die Apps und Systemfunktionen auf deinem Smartphone zu streamen?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s hat dann Zugriff auf alle Inhalte, die auf deinem Smartphone sichtbar sind oder abgespielt werden, einschließlich Audio, Fotos, Zahlungsinformationen, Passwörter und Nachrichten.<br/><br/>%1$s kann so lange Apps und Systemfunktionen streamen, bis du diese Berechtigung entfernst."</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Zulassen, dass <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> die Apps und Systemfunktionen auf deinem Smartphone streamt?"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s hat dann Zugriff auf alle Inhalte, die auf deinem Smartphone sichtbar sind oder abgespielt werden, einschließlich Audio, Fotos, Zahlungsinformationen, Passwörter und Nachrichten.<br/><br/>%1$s kann so lange Apps und Systemfunktionen streamen, bis du diese Berechtigung entfernst."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein Gerät (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) um die Berechtigung, Apps und andere Systemfunktionen auf Geräte in der Nähe zu streamen"</string> <string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string> <string name="summary_generic" msgid="1761976003668044801">"Diese App kann dann Daten wie den Namen eines Anrufers zwischen deinem Smartphone und dem ausgewählten Gerät synchronisieren"</string> diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml index c0d1888791e4..15d97af5ce0d 100644 --- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml +++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml @@ -59,7 +59,7 @@ <string name="permission_microphone" msgid="2152206421428732949">"Micrófono"</string> <string name="permission_call_logs" msgid="5546761417694586041">"Registros de llamadas"</string> <string name="permission_nearby_devices" msgid="7530973297737123481">"Dispositivos cercanos"</string> - <string name="permission_media_routing_control" msgid="5498639511586715253">"Cambia la salida multimedia"</string> + <string name="permission_media_routing_control" msgid="5498639511586715253">"Cambiar la salida multimedia"</string> <string name="permission_storage" msgid="6831099350839392343">"Fotos y contenido multimedia"</string> <string name="permission_notifications" msgid="4099418516590632909">"Notificaciones"</string> <string name="permission_app_streaming" msgid="6009695219091526422">"Apps"</string> diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml index b7a9ff632fba..e02cb04a6489 100644 --- a/packages/CompanionDeviceManager/res/values-et/strings.xml +++ b/packages/CompanionDeviceManager/res/values-et/strings.xml @@ -26,21 +26,21 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"seade"</string> <string name="summary_glasses" msgid="2872254734959842579">"Sellele rakendusele antakse need load teie seadmes <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pääseda teie telefonis juurde sellele teabele"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Kas lubate rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> oma telefoni rakendusi voogesitada?"</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Kas lubate seadmel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> oma telefoni rakendusi voogesitada?"</string> <string name="summary_app_streaming" msgid="295548145144086753">"%1$s saab juurdepääsu kõigele, mis on telefonis nähtaval või esitatav, sh helile, fotodele, paroolidele ja sõnumitele.<br/><br/>%1$s saab rakendusi voogesitada kuni eemaldate juurdepääsu sellele loale."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Seadmeülesed teenused"</string> - <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi voogesitada"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi kuvada ja voogesitada"</string> + <string name="helper_summary_app_streaming" msgid="2396773196949578425">"Rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi voogesitada"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"Rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi kuvada ja voogesitada"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pääseda teie telefonis juurde sellele teabele"</string> <string name="summary_computer" msgid="3798467601598297062"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play teenused"</string> - <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nimel luba pääseda juurde telefoni fotodele, meediale ja märguannetele"</string> + <string name="helper_summary_computer" msgid="8774832742608187072">"Rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nimel luba pääseda juurde telefoni fotodele, meediale ja märguannetele"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Kas lubada seadmel <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> teha seda toimingut?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Kas lubate rakendusel <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> oma telefoni rakenduste ja süsteemifunktsioonidel voogesitada?"</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Kas lubate seadmel <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> oma telefoni rakendusi ja süsteemifunktsioone voogesitada?"</string> <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s saab juurdepääsu kõigele, mis on teie telefonis nähtav või esitatav, sh heli, fotod, makseteave, paroolid ja sõnumid.<br/><br/>%1$s saab voogesitada rakendusi ja süsteemifunktsioone, kuni eemaldate juurdepääsu sellele loale."</string> - <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_NAME">%2$s</xliff:g> nimel luba voogesitada rakendusi ja muid süsteemi funktsioone läheduses olevatesse seadmetesse"</string> + <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_NAME">%2$s</xliff:g> nimel luba voogesitada rakendusi ja muid süsteemi funktsioone läheduses olevatesse seadmetesse"</string> <string name="profile_name_generic" msgid="6851028682723034988">"seade"</string> <string name="summary_generic" msgid="1761976003668044801">"See rakendus saab sünkroonida teavet, näiteks helistaja nime, teie telefoni ja valitud seadme vahel"</string> <string name="consent_yes" msgid="8344487259618762872">"Luba"</string> @@ -59,7 +59,7 @@ <string name="permission_microphone" msgid="2152206421428732949">"Mikrofon"</string> <string name="permission_call_logs" msgid="5546761417694586041">"Kõnelogid"</string> <string name="permission_nearby_devices" msgid="7530973297737123481">"Läheduses olevad seadmed"</string> - <string name="permission_media_routing_control" msgid="5498639511586715253">"Muutke meediaväljundit"</string> + <string name="permission_media_routing_control" msgid="5498639511586715253">"Meediaväljundi muutmine"</string> <string name="permission_storage" msgid="6831099350839392343">"Fotod ja meedia"</string> <string name="permission_notifications" msgid="4099418516590632909">"Märguanded"</string> <string name="permission_app_streaming" msgid="6009695219091526422">"Rakendused"</string> diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml index d0dee9ba9021..ca8497077f6a 100644 --- a/packages/CompanionDeviceManager/res/values-eu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml @@ -26,8 +26,8 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"gailua"</string> <string name="summary_glasses" msgid="2872254734959842579">"Baimen hauek erabili ahalko ditu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>n aplikazioak:"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Eman informazioa telefonotik hartzeko baimena <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari zure telefonoko aplikazioak zuzenean igortzeko baimena eman nahi diozu?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"%1$s aplikazioak telefonoan ikusgai dagoen edo erreproduzitzen den eduki guztia atzitu ahal izango du, audioa, argazkiak, pasahitzak eta mezuak barne.<br/><br/>%1$s aplikazioak zuzenean igortzeko gai izango da, baimen hori kentzen diozun arte."</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gailuari zure telefonoko aplikazioak zuzenean igortzeko baimena eman nahi diozu?"</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s gailuak telefonoan ikusgai dagoen edo erreproduzitzen den eduki guztia atzitu ahal izango du, audioa, argazkiak, pasahitzak eta mezuak barne.<br/><br/>%1$s aplikazioak zuzenean igortzeko gai izango da, baimen hori kentzen diozun arte."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Gailuarteko zerbitzuak"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"Gailu batetik bestera aplikazioak igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> gailuaren izenean"</string> <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"Aplikazioak gailuen artean bistaratzeko eta zuzenean igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> gailuaren izenean"</string> @@ -38,8 +38,8 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"Telefonoko argazkiak, multimedia-edukia eta jakinarazpenak erabiltzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> gailuaren izenean"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Ekintza hau gauzatzeko baimena eman nahi diozu <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> aplikazioari?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> aplikazioari zure telefonoko aplikazioak eta sistemaren eginbideak zuzenean igortzeko baimena eman nahi diozu?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s aplikazioak telefonoan ikusgai dagoen edo erreproduzitzen den eduki guztia atzitu ahal izango du, audioa, argazkiak, ordainketa-informazioa, pasahitzak eta mezuak barne.<br/><br/>%1$s aplikazioak eta sistemaren eginbideak zuzenean igortzeko gai izango da, baimen hori kentzen diozun arte."</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> gailuari zure telefonoko aplikazioak eta sistemaren eginbideak zuzenean igortzeko baimena eman nahi diozu?"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s gailuak telefonoan ikusgai dagoen edo erreproduzitzen den eduki guztia atzitu ahal izango du, audioa, argazkiak, ordainketa-informazioa, pasahitzak eta mezuak barne.<br/><br/>%1$s aplikazioak eta sistemaren eginbideak zuzenean igortzeko gai izango da, baimen hori kentzen diozun arte."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikazioak eta sistemaren beste eginbide batzuk inguruko gailuetara igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_NAME">%2$s</xliff:g> gailuaren izenean"</string> <string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string> <string name="summary_generic" msgid="1761976003668044801">"Telefonoaren eta hautatutako gailuaren artean informazioa sinkronizatzeko gai izango da aplikazioa (esate baterako, deitzaileen izenak)"</string> diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml index 9b556698c0a8..2363886c3484 100644 --- a/packages/CompanionDeviceManager/res/values-hi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml @@ -27,10 +27,10 @@ <string name="summary_glasses" msgid="2872254734959842579">"यह ऐप्लिकेशन, आपके <xliff:g id="DEVICE_NAME">%1$s</xliff:g> पर इन अनुमतियों को ऐक्सेस कर पाएगा"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string> <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को आपके फ़ोन के ऐप्लिकेशन स्ट्रीम करने की अनुमति देनी है?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"%1$s के पास ऐसे कॉन्टेंट का ऐक्सेस होगा जो फ़ोन पर दिख रहा हो या चलाया गया हो. जैसे, ऑडियो, फ़ोटो, पासवर्ड, और मैसेज.<br/><br/>%1$s तब तक ऐप्लिकेशन स्ट्रीम करेगा, जब तक आप इस अनुमति को हटा न दें."</string> - <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s के पास ऐसे कॉन्टेंट का ऐक्सेस होगा जो फ़ोन पर दिख रहा हो या चल रहा हो. जैसे, ऑडियो, फ़ोटो, पासवर्ड, और मैसेज.<br/><br/>%1$s तब तक ऐप्लिकेशन स्ट्रीम करेगा, जब तक आप इस अनुमति को हटा न दें."</string> + <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> की ओर से, आपके डिवाइसों के बीच ऐप्लिकेशन स्ट्रीम करने की अनुमति मांग रहा है"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> की ओर से, आपके डिवाइसों के बीच ऐप्लिकेशन दिखाने और स्ट्रीम करने की अनुमति मांग रहा है"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> की ओर से, एक डिवाइस के ऐप्लिकेशन, दूसरे डिवाइस पर दिखाने और स्ट्रीम करने की अनुमति मांग रहा है"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string> @@ -39,7 +39,7 @@ <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> की ओर से, आपने फ़ोन में मौजूद फ़ोटो, मीडिया, और सूचनाओं को ऐक्सेस करने की अनुमति मांग रहा है"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"क्या <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> को यह कार्रवाई करने की अनुमति देनी है?"</string> <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> को आपके फ़ोन के ऐप्लिकेशन और सिस्टम की सुविधाएं स्ट्रीम करने की अनुमति देनी है?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s के पास ऐसे कॉन्टेंट का ऐक्सेस होगा जो फ़ोन पर दिख रहा हो या चलाया गया हो. जैसे, ऑडियो, फ़ोटो, पेमेंट से जुड़ी जानकारी, पासवर्ड, और मैसेज.<br/><br/>%1$s तब तक ऐप्लिकेशन और सिस्टम की सुविधाओं को स्ट्रीम करेगा, जब तक आप इस अनुमति को हटा न दें."</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s के पास ऐसे कॉन्टेंट का ऐक्सेस होगा जो फ़ोन पर दिख रहा हो या चल रहा हो. जैसे, ऑडियो, फ़ोटो, पेमेंट की जानकारी, पासवर्ड, और मैसेज.<br/><br/>%1$s तब तक ऐप्लिकेशन और सिस्टम की सुविधाओं को स्ट्रीम करेगा, जब तक आप इस अनुमति को हटा न दें."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_NAME">%2$s</xliff:g> की ओर से, ऐप्लिकेशन और दूसरे सिस्टम की सुविधाओं को आस-पास मौजूद डिवाइसों पर स्ट्रीम करने की अनुमति मांग रहा है"</string> <string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string> <string name="summary_generic" msgid="1761976003668044801">"यह ऐप्लिकेशन, आपके फ़ोन और चुने हुए डिवाइस के बीच जानकारी सिंक करेगा. जैसे, कॉल करने वाले व्यक्ति का नाम"</string> diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml index 1c9c218e34a4..4985ae3cde34 100644 --- a/packages/CompanionDeviceManager/res/values-hu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml @@ -59,7 +59,7 @@ <string name="permission_microphone" msgid="2152206421428732949">"Mikrofon"</string> <string name="permission_call_logs" msgid="5546761417694586041">"Hívásnaplók"</string> <string name="permission_nearby_devices" msgid="7530973297737123481">"Közeli eszközök"</string> - <string name="permission_media_routing_control" msgid="5498639511586715253">"Médiakiment módosítása"</string> + <string name="permission_media_routing_control" msgid="5498639511586715253">"Médiakimenet módosítása"</string> <string name="permission_storage" msgid="6831099350839392343">"Fotók és médiatartalmak"</string> <string name="permission_notifications" msgid="4099418516590632909">"Értesítések"</string> <string name="permission_app_streaming" msgid="6009695219091526422">"Alkalmazások"</string> diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml index c4de3cd08ade..a655a3ec3705 100644 --- a/packages/CompanionDeviceManager/res/values-hy/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml @@ -26,8 +26,8 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"սարք"</string> <string name="summary_glasses" msgid="2872254734959842579">"Այս հավելվածը կստանա հետևյալ թույլտվությունները ձեր <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ում"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Թույլատրեք <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Թույլատրե՞լ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին հեռարձակել ձեր հեռախոսի հավելվածները"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"%1$s հավելվածին հասանելի կլինի հեռախոսում ցուցադրվող կամ նվագարկվող բովանդակությունը՝ ներառյալ աուդիոն, լուսանկարները, գաղտնաբառերը և հաղորդագրությունները։<br/><br/>%1$s հավելվածը կկարողանա հավելվածներ հեռարձակել, քանի դեռ չեք չեղարկել այս թույլտվությունը։"</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Թույլատրե՞լ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-ին հեռարձակել ձեր հեռախոսի հավելվածները"</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s-ին հասանելի կլինի հեռախոսում ցուցադրվող կամ նվագարկվող բովանդակությունը՝ ներառյալ աուդիոն, լուսանկարները, գաղտնաբառերը և հաղորդագրությունները։<br/><br/>%1$s-ը կկարողանա հավելվածներ հեռարձակել, քանի դեռ չեք չեղարկել այս թույլտվությունը։"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Միջսարքային ծառայություններ"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string> <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string> @@ -38,8 +38,8 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ծառայություններ"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր հեռախոսի լուսանկարները, մեդիաֆայլերն ու ծանուցումները տեսնելու համար"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Թույլատրե՞լ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> հավելվածին կատարել այս գործողությունը"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Թույլատրե՞լ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> սարքին հեռարձակել ձեր հեռախոսի հավելվածները և համակարգի գործառույթները"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s սարքին հասանելի կլինի ձեր հեռախոսում ցուցադրվող կամ նվագարկվող բովանդակությունը՝ ներառյալ աուդիոն, լուսանկարները, վճարային տեղեկությունները, գաղտնաբառերը և հաղորդագրությունները։<br/><br/>%1$s սարքը կկարողանա հավելվածներ և համակարգի գործառույթներ հեռարձակել, քանի դեռ չեք չեղարկել այս թույլտվությունը։"</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Թույլատրե՞լ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong>-ին հեռարձակել ձեր հեռախոսի հավելվածները և համակարգի գործառույթները"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s-ին հասանելի կլինի ձեր հեռախոսում ցուցադրվող կամ նվագարկվող բովանդակությունը՝ ներառյալ աուդիոն, լուսանկարները, վճարային տեղեկությունները, գաղտնաբառերը և հաղորդագրությունները։<br/><br/>%1$s-ը կկարողանա հավելվածներ և համակարգի գործառույթներ հեռարձակել, քանի դեռ չեք չեղարկել այս թույլտվությունը։"</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_NAME">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ մոտակա սարքերին հավելվածներ և համակարգի այլ գործառույթներ հեռարձակելու համար"</string> <string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string> <string name="summary_generic" msgid="1761976003668044801">"Այս հավելվածը կկարողանա համաժամացնել ձեր հեռախոսի և ընտրված սարքի տվյալները, օր․՝ զանգողի անունը"</string> diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml index b1c4f5b01f50..1481ca136762 100644 --- a/packages/CompanionDeviceManager/res/values-in/strings.xml +++ b/packages/CompanionDeviceManager/res/values-in/strings.xml @@ -26,11 +26,11 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"perangkat"</string> <string name="summary_glasses" msgid="2872254734959842579">"Aplikasi ini akan diizinkan mengakses izin ini di <xliff:g id="DEVICE_NAME">%1$s</xliff:g> Anda"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> untuk mengakses informasi ini dari ponsel Anda"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> melakukan streaming aplikasi di ponsel Anda?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"%1$s akan memiliki akses ke konten apa pun yang ditampilkan atau dimainkan di ponsel, termasuk audio, foto, sandi, dan pesan.<br/><br/>%1$s akan dapat melakukan streaming aplikasi hingga Anda menghapus izin ini."</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> menstreaming aplikasi di ponsel Anda?"</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s akan memiliki akses ke apa pun yang ditampilkan atau diputar di ponsel, termasuk audio, foto, sandi, dan pesan.<br/><br/>%1$s akan dapat menstreaming aplikasi hingga Anda menghapus izin ini."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Layanan lintas perangkat"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> untuk menstreaming aplikasi di antara perangkat Anda"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> menggantikan <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> meminta izin untuk menampilkan dan melakukan streaming aplikasi di antara perangkat Anda"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> untuk menampilkan dan menstreaming aplikasi di antara perangkat Anda"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses informasi ini dari ponsel Anda"</string> @@ -38,8 +38,8 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Layanan Google Play"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> untuk mengakses foto, media, dan notifikasi ponsel Anda"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Izinkan <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> melakukan tindakan ini?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Izinkan <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> melakukan streaming aplikasi dan mengakses fitur sistem di ponsel Anda?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s akan memiliki akses ke konten apa pun yang ditampilkan atau dimainkan di ponsel Anda, termasuk audio, foto, info pembayaran, sandi, dan pesan.<br/><br/>%1$s akan dapat melakukan streaming aplikasi dan mengakses fitur sistem hingga Anda menghapus izin ini."</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Izinkan <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> menstreaming aplikasi dan fitur sistem di ponsel Anda?"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s akan memiliki akses ke apa pun yang ditampilkan atau diputar di ponsel Anda, termasuk audio, foto, info pembayaran, sandi, dan pesan.<br/><br/>%1$s akan dapat menstreaming aplikasi dan fitur sistem hingga Anda menghapus izin ini."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_NAME">%2$s</xliff:g> untuk menstreaming aplikasi dan fitur sistem lainnya ke perangkat di sekitar"</string> <string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string> <string name="summary_generic" msgid="1761976003668044801">"Aplikasi ini akan dapat menyinkronkan info, seperti nama penelepon, antara ponsel dan perangkat yang dipilih"</string> diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml index f1eb53477960..ce8feb5e0f72 100644 --- a/packages/CompanionDeviceManager/res/values-iw/strings.xml +++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml @@ -30,7 +30,7 @@ <string name="summary_app_streaming" msgid="295548145144086753">"ל-%1$s תהיה גישה לכל מה שרואים או מפעילים בטלפון, כולל אודיו, תמונות, סיסמאות והודעות.<br/><br/>ל-%1$s תהיה אפשרות לשדר אפליקציות עד שהגישה להרשאה הזו תוסר."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"שירותים למספר מכשירים"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור המכשיר <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה למכשיר <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> כדי להציג ולשדר אפליקציות בין המכשירים שלך"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"האפליקציה \'<xliff:g id="APP_NAME">%1$s</xliff:g>\' מבקשת הרשאה למכשיר <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> כדי להציג ולשדר אפליקציות בין המכשירים שלך"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"מתן אישור לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> לגשת למידע הזה מהטלפון שלך"</string> diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml index 7aace8292792..7dbcef0675b5 100644 --- a/packages/CompanionDeviceManager/res/values-kn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml @@ -30,7 +30,7 @@ <string name="summary_app_streaming" msgid="295548145144086753">"ಆಡಿಯೋ, ಫೋಟೋಗಳು, ಪಾಸ್ವರ್ಡ್ಗಳು ಮತ್ತು ಸಂದೇಶಗಳು ಸೇರಿದಂತೆ ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಗೋಚರಿಸುವ ಅಥವಾ ಪ್ಲೇ ಆಗುವ ಯಾವುದೇ ಕಂಟೆಂಟ್ಗೆ %1$s ಆ್ಯಕ್ಸೆಸ್ ಹೊಂದಿರುತ್ತದೆ.<br/><br/>ನೀವು ಈ ಅನುಮತಿಗೆ ಇರುವ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ತೆಗೆದುಹಾಕುವವರೆಗೆ %1$s ಗೆ ಆ್ಯಪ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ಕ್ರಾಸ್-ಡಿವೈಸ್ ಸೇವೆಗಳು"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್ಗಳನ್ನು ಪ್ರದರ್ಶಿಸಲು ಮತ್ತು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸುತ್ತಿದೆ"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್ಗಳನ್ನು ಪ್ರದರ್ಶಿಸಲು ಮತ್ತು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸುತ್ತಿವೆ"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ"</string> diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml index 86679ac147f7..925f21b0028c 100644 --- a/packages/CompanionDeviceManager/res/values-ko/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml @@ -30,7 +30,7 @@ <string name="summary_app_streaming" msgid="295548145144086753">"%1$s에서 오디오, 사진, 비밀번호, 메시지 등 휴대전화에 표시되거나 휴대전화에서 재생되는 모든 항목에 액세스할 수 있습니다.<br/><br/>이 권한에 대한 액세스를 삭제할 때까지 %1$s에서 앱을 스트리밍할 수 있습니다."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"교차 기기 서비스"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 대신 기기 간에 앱을 스트리밍할 수 있는 권한을 요청하고 있습니다."</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 대신 기기 간 앱을 표시하고 스트리밍할 권한을 요청하고 있습니다."</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 대신 연결된 기기의 앱을 표시하고 스트리밍할 권한을 요청하고 있습니다."</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>이 휴대전화에서 이 정보에 액세스하도록 허용"</string> diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml index 932b5c5339d5..1b72477f5e33 100644 --- a/packages/CompanionDeviceManager/res/values-ky/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml @@ -26,8 +26,8 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"түзмөк"</string> <string name="summary_glasses" msgid="2872254734959842579">"Бул колдонмого <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүңүздө төмөнкүлөрдү аткарууга уруксат берилет"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы колдонмолорду алып ойнотууга уруксат бересизби?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"%1$s телефондо көрүнгөн же ойнотулган бардык нерселерге, анын ичинде аудио, сүрөттөр, сырсөздөр жана билдирүүлөргө кире алат. Бул уруксатты алып салмайынча, <br/><br/>%1$s колдонмолорду алып ойното алат."</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы колдонмолорду өткөрүүгө уруксат бересизби?"</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s телефондо көрүнгөн же ойнотулган аудиофайлдар, сүрөттөр, сырсөздөр жана билдирүүлөр сыяктуу нерселерди көрө алат. Бул уруксатты алып салмайынча, <br/><br/>%1$s колдонмолорду өткөрө берет."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Түзмөктөр аралык кызматтар"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан түзмөктөрүңүздүн ортосунда колдонмолорду алып ойнотууга уруксат сурап жатат"</string> <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан түзмөктөрдүн ортосунда колдонмолорду көрсөтүү жана алып ойнотуу үчүн уруксат сурап жатат"</string> @@ -38,8 +38,8 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Google Play кызматтары"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан телефондогу сүрөттөрдү, медиа файлдарды жана билдирмелерди колдонууга уруксат сурап жатат"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> түзмөгүнө бул аракетти аткарууга уруксат бересизби?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы колдонмолорду жана тутумдун функцияларын алып ойнотууга уруксат бересизби?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s телефонуңузда көрүнгөн же ойнотулган бардык нерселерге, анын ичинде аудио, сүрөттөр, төлөм маалыматы, сырсөздөр жана билдирүүлөргө кире алат. Бул уруксатты алып салмайынча, <br/><br/>%1$s колдонмолорду жана тутум функцияларын алып ойното алат."</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы колдонмолорду жана системалык функцияларды өткөргөнгө уруксат бересизби?"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s телефонуңузда көрүнгөн же ойнотулган аудиофайлдар, сүрөттөр, төлөм маалыматы, сырсөздөр жана билдирүүлөр сыяктуу нерселерди көрө алат. Бул уруксатты алып салмайынча, <br/><br/>%1$s колдонмолорду жана системдик функцияларды өткөрө алат."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан жакын жердеги түзмөктөрдө колдонмолорду жана системанын башка функцияларын алып ойнотууга уруксат сурап жатат"</string> <string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string> <string name="summary_generic" msgid="1761976003668044801">"Бул колдонмо маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын телефон жана тандалган түзмөк менен шайкештирет"</string> diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml index fe6e4cca4e07..0c4bfcbfd6ba 100644 --- a/packages/CompanionDeviceManager/res/values-mn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml @@ -27,7 +27,7 @@ <string name="summary_glasses" msgid="2872254734959842579">"Энэ апп таны <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-н эдгээр зөвшөөрөлд хандах эрхтэй байх болно"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string> <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Таны утасны аппуудыг дамжуулахыг <strong><xliff:g id="APP_NAME">%1$s</xliff:g>-д</strong> зөвшөөрөх үү?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"%1$s аудио, зураг, нууц үг болон мессежүүдийг оруулаад утсан дээр харагдсан эсвэх тоглуулсан аливаа зүйлд хандах эрхтэй болно.<br/><br/>%1$s таныг энэ зөвшөөрлийг хасах хүртэл аппуудыг дамжуулах боломжтой байх болно."</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s аудио, зураг, нууц үг болон мессежүүдийг зэрэг утсан дээр харагдсан эсвэл тоглуулсан аливаа зүйлд хандах эрхтэй болно.<br/><br/>%1$s таныг энэ зөвшөөрлийг хасах хүртэл аппуудыг дамжуулах боломжтой байх болно."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Төхөөрөмж хоорондын үйлчилгээ"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"Таны төхөөрөмжүүд хооронд апп дамжуулахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string> <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-н өмнөөс таны төхөөрөмжүүдийн хооронд аппууд үзүүлж, дамжуулах зөвшөөрлийг хүсэж байна"</string> @@ -39,7 +39,7 @@ <string name="helper_summary_computer" msgid="8774832742608187072">"Таны утасны зураг, медиа болон мэдэгдэлд хандахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong>-д энэ үйлдлийг хийхийг зөвшөөрөх үү?"</string> <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Таны утасны апп болон системийн онцлогуудыг дамжуулахыг <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g>-д</strong> зөвшөөрөх үү?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s аудио, зураг, төлбөрийн мэдээлэл, нууц үг болон мессежүүдийг оруулаад утсан дээр харагдсан эсвэх тоглуулсан аливаа зүйлд хандах эрхтэй болно.<br/><br/>%1$s таныг энэ зөвшөөрлийг хасах хүртэл апп болон системийн онцлогуудыг дамжуулах боломжтой байх болно."</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s аудио, зураг, төлбөрийн мэдээлэл, нууц үг болон мессеж зэрэг утсан дээр харагдсан эсвэл тоглуулсан аливаа зүйлд хандах эрхтэй болно.<br/><br/>%1$s таныг энэ зөвшөөрлийг хасах хүртэл апп болон системийн онцлогуудыг дамжуулах боломжтой байх болно."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_NAME">%2$s</xliff:g>-н өмнөөс аппууд болон системийн бусад онцлогийг ойролцоох төхөөрөмжүүд рүү дамжуулах зөвшөөрөл хүсэж байна"</string> <string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string> <string name="summary_generic" msgid="1761976003668044801">"Энэ апп залгаж буй хүний нэр зэрэг мэдээллийг таны утас болон сонгосон төхөөрөмжийн хооронд синк хийх боломжтой болно"</string> diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml index d817df2678f3..4605c18eec0e 100644 --- a/packages/CompanionDeviceManager/res/values-nb/strings.xml +++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml @@ -24,7 +24,7 @@ <string name="summary_watch" msgid="7962014927042971830">"Denne appen får tillatelse til å synkronisere informasjon som navnet til noen som ringer, og har disse tillatelsene på <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Vil du la <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> administrere <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"enheten"</string> - <string name="summary_glasses" msgid="2872254734959842579">"Denne appen får disse tillatelsene på <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string> + <string name="summary_glasses" msgid="2872254734959842579">"Denne appen får disse tillatelsene på enheten din (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Gi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilgang til denne informasjonen fra telefonen din"</string> <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Vil du tillate at <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> strømmer appene på telefonen?"</string> <string name="summary_app_streaming" msgid="295548145144086753">"%1$s får tilgang til alt som er synlig eller spilles av på telefonen, inkludert lyd, bilder, passord og meldinger.<br/><br/>%1$s kan strømme apper til du fjerner denne tillatelsen."</string> diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml index 8394a82a963d..448362f619b0 100644 --- a/packages/CompanionDeviceManager/res/values-pa/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml @@ -27,7 +27,7 @@ <string name="summary_glasses" msgid="2872254734959842579">"ਇਸ ਐਪ ਨੂੰ ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> \'ਤੇ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string> <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"ਕੀ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"%1$s ਕੋਲ ਆਡੀਓ, ਫ਼ੋਟੋਆਂ, ਪਾਸਵਰਡਾਂ ਅਤੇ ਸੁਨੇਹਿਆਂ ਸਮੇਤ, ਫ਼ੋਨ \'ਤੇ ਦਿਖਾਈ ਦੇਣ ਵਾਲੀ ਜਾਂ ਚਲਾਈ ਜਾਣ ਵਾਲੀ ਕਿਸੇ ਵੀ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ।<br/><br/>%1$s ਐਪਾਂ ਨੂੰ ਉਦੋਂ ਤੱਕ ਸਟ੍ਰੀਮ ਕਰ ਸਕੇਗੀ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇਸ ਇਜਾਜ਼ਤ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹਟਾ ਦਿੰਦੇ।"</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s ਕੋਲ ਆਡੀਓ, ਫ਼ੋਟੋਆਂ, ਪਾਸਵਰਡਾਂ ਅਤੇ ਸੁਨੇਹਿਆਂ ਸਮੇਤ, ਫ਼ੋਨ \'ਤੇ ਦਿਖਾਈ ਦੇਣ ਵਾਲੀ ਜਾਂ ਚਲਾਈ ਜਾਣ ਵਾਲੀ ਕਿਸੇ ਵੀ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ।<br/><br/>%1$s ਐਪਾਂ ਨੂੰ ਉਦੋਂ ਤੱਕ ਸਟ੍ਰੀਮ ਕਰ ਸਕੇਗਾ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇਸ ਇਜਾਜ਼ਤ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹਟਾ ਦਿੰਦੇ।"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ਕ੍ਰਾਸ-ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string> <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਦਿਖਾਉਣ ਅਤੇ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string> @@ -39,7 +39,7 @@ <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੀਆਂ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"ਕੀ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> ਨੂੰ ਇਹ ਕਾਰਵਾਈ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string> <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"ਕੀ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਅਤੇ ਸਿਸਟਮ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s ਕੋਲ ਆਡੀਓ, ਫ਼ੋਟੋਆਂ, ਭੁਗਤਾਨ ਜਾਣਕਾਰੀ, ਪਾਸਵਰਡਾਂ ਅਤੇ ਸੁਨੇਹਿਆਂ ਸਮੇਤ, ਫ਼ੋਨ \'ਤੇ ਦਿਖਾਈ ਦੇਣ ਵਾਲੀ ਜਾਂ ਚਲਾਈ ਜਾਣ ਵਾਲੀ ਕਿਸੇ ਵੀ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ।<br/><br/>%1$s ਐਪਾਂ ਨੂੰ ਉਦੋਂ ਤੱਕ ਸਟ੍ਰੀਮ ਅਤੇ ਸਿਸਟਮ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕੇਗੀ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇਸ ਇਜਾਜ਼ਤ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹਟਾ ਦਿੰਦੇ।"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s ਕੋਲ ਆਡੀਓ, ਫ਼ੋਟੋਆਂ, ਭੁਗਤਾਨ ਜਾਣਕਾਰੀ, ਪਾਸਵਰਡਾਂ ਅਤੇ ਸੁਨੇਹਿਆਂ ਸਮੇਤ, ਫ਼ੋਨ \'ਤੇ ਦਿਖਾਈ ਦੇਣ ਵਾਲੀ ਜਾਂ ਚਲਾਈ ਜਾਣ ਵਾਲੀ ਕਿਸੇ ਵੀ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ।<br/><br/>%1$s ਐਪਾਂ ਨੂੰ ਉਦੋਂ ਤੱਕ ਸਟ੍ਰੀਮ ਅਤੇ ਸਿਸਟਮ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕੇਗਾ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇਸ ਇਜਾਜ਼ਤ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹਟਾ ਦਿੰਦੇ।"</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ \'ਤੇ ਐਪਾਂ ਅਤੇ ਹੋਰ ਸਿਸਟਮ ਸੰਬੰਧੀ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string> <string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string> <string name="summary_generic" msgid="1761976003668044801">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ ਅਤੇ ਚੁਣੇ ਗਏ ਡੀਵਾਈਸ ਵਿਚਕਾਰ ਕਾਲਰ ਦੇ ਨਾਮ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਿੰਕ ਕਰ ਸਕੇਗੀ"</string> diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml index 945f8491597f..757967858bea 100644 --- a/packages/CompanionDeviceManager/res/values-pl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml @@ -30,7 +30,7 @@ <string name="summary_app_streaming" msgid="295548145144086753">"%1$s będzie mieć dostęp do wszystkiego, co jest widoczne i odtwarzane na telefonie, w tym do dźwięku, zdjęć, haseł i wiadomości.<br/><br/>%1$s będzie w stanie strumieniować aplikacje, dopóki nie usuniesz dostępu do tego uprawnienia."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usługi na innym urządzeniu"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> o uprawnienia dotyczące strumieniowego odtwarzania treści z aplikacji na innym urządzeniu"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> o pozwolenie na wyświetlanie i strumieniowanie aplikacji między Twoimi urządzeniami"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> o pozwolenie na wyświetlanie i strumieniowanie aplikacji między Twoimi urządzeniami"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Zezwól aplikacji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na dostęp do tych informacji na Twoim telefonie"</string> diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml index 289d6e07f2e8..eb7b533abfc1 100644 --- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml @@ -30,7 +30,7 @@ <string name="summary_app_streaming" msgid="295548145144086753">"O app %1$s terá acesso a tudo o que estiver visível ou for aberto no smartphone, incluindo áudios, fotos, senhas e mensagens. O app <br/><br/>%1$s poderá fazer o streaming de apps até que você remova o acesso a essa permissão."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para mostrar e fazer streaming de apps entre seus dispositivos"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para mostrar e fazer streaming de apps entre seus dispositivos"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Autorizar que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string> @@ -38,8 +38,8 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> realize esta ação?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Permitir que o dispositivo <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> faça streaming dos apps e recursos do sistema do smartphone?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"O app %1$s terá acesso a tudo o que estiver visível ou for aberto no smartphone, incluindo áudios, fotos, informações de pagamento, senhas e mensagens. O app <br/><br/>%1$s poderá fazer o streaming de apps e recursos do sistema até que você remova o acesso a essa permissão."</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Permitir que <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> faça streaming de apps e recursos do sistema do smartphone?"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"O %1$s terá acesso a tudo o que estiver visível ou for aberto no smartphone, incluindo áudios, fotos, informações de pagamento, senhas e mensagens. <br/><br/>O %1$s poderá acessar e transferir informações de apps e recursos do sistema até que você remova essa permissão."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer streaming de apps e de outros recursos do sistema para dispositivos por perto"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> <string name="summary_generic" msgid="1761976003668044801">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido"</string> diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml index 9d94de7b66ce..c951334e68ff 100644 --- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml @@ -26,8 +26,8 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string> <string name="summary_glasses" msgid="2872254734959842579">"Esta app vai poder aceder a estas autorizações no seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Permita que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aceda a estas informações do seu telemóvel"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Permitir que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> faça stream das apps do telemóvel?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"%1$s vai ter acesso a tudo o que seja visível ou reproduzido no telemóvel, incluindo áudio, fotos, palavras-passe e mensagens.<br/><br/>%1$s vai poder fazer stream de apps até remover o acesso a esta autorização."</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Permitir que o dispositivo <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> faça stream das apps do telemóvel?"</string> + <string name="summary_app_streaming" msgid="295548145144086753">"O dispositivo %1$s vai ter acesso a tudo o que seja visível ou reproduzido no telemóvel, incluindo áudio, fotos, palavras-passe e mensagens.<br/><br/>O %1$s vai poder fazer stream de apps até remover o acesso a esta autorização."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string> <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para apresentar e fazer stream de apps entre os seus dispositivos"</string> @@ -39,7 +39,7 @@ <string name="helper_summary_computer" msgid="8774832742608187072">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para aceder às fotos, ao conteúdo multimédia e às notificações do seu telemóvel"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> faça esta ação?"</string> <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Permitir que o dispositivo <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> faça stream das apps e das funcionalidades do sistema do telemóvel?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s vai ter acesso a tudo o que seja visível ou reproduzido no telemóvel, incluindo áudio, fotos, informações de pagamento, palavras-passe e mensagens.<br/><br/>%1$s vai poder fazer stream de apps e funcionalidades do sistema até remover o acesso a esta autorização."</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"O dispositivo %1$s vai ter acesso a tudo o que seja visível ou reproduzido no telemóvel, incluindo áudio, fotos, informações de pagamento, palavras-passe e mensagens.<br/><br/>O %1$s vai poder fazer stream de apps e funcionalidades do sistema até remover o acesso a esta autorização."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer stream de apps e outras funcionalidades do sistema para dispositivos próximos"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> <string name="summary_generic" msgid="1761976003668044801">"Esta app vai poder sincronizar informações, como o nome do autor de uma chamada, entre o telemóvel e o dispositivo escolhido"</string> diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml index 289d6e07f2e8..eb7b533abfc1 100644 --- a/packages/CompanionDeviceManager/res/values-pt/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml @@ -30,7 +30,7 @@ <string name="summary_app_streaming" msgid="295548145144086753">"O app %1$s terá acesso a tudo o que estiver visível ou for aberto no smartphone, incluindo áudios, fotos, senhas e mensagens. O app <br/><br/>%1$s poderá fazer o streaming de apps até que você remova o acesso a essa permissão."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para mostrar e fazer streaming de apps entre seus dispositivos"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para mostrar e fazer streaming de apps entre seus dispositivos"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Autorizar que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string> @@ -38,8 +38,8 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> realize esta ação?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Permitir que o dispositivo <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> faça streaming dos apps e recursos do sistema do smartphone?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"O app %1$s terá acesso a tudo o que estiver visível ou for aberto no smartphone, incluindo áudios, fotos, informações de pagamento, senhas e mensagens. O app <br/><br/>%1$s poderá fazer o streaming de apps e recursos do sistema até que você remova o acesso a essa permissão."</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Permitir que <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> faça streaming de apps e recursos do sistema do smartphone?"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"O %1$s terá acesso a tudo o que estiver visível ou for aberto no smartphone, incluindo áudios, fotos, informações de pagamento, senhas e mensagens. <br/><br/>O %1$s poderá acessar e transferir informações de apps e recursos do sistema até que você remova essa permissão."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer streaming de apps e de outros recursos do sistema para dispositivos por perto"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> <string name="summary_generic" msgid="1761976003668044801">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido"</string> diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml index ce65c702aa8c..15456aaac3ea 100644 --- a/packages/CompanionDeviceManager/res/values-ru/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml @@ -26,11 +26,11 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"устройстве"</string> <string name="summary_glasses" msgid="2872254734959842579">"Это приложение получит указанные разрешения на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string> <string name="title_app_streaming" msgid="2270331024626446950">"Разрешите приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> получать эту информацию с вашего телефона"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Разрешить приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> транслировать приложения с вашего телефона?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"Приложение \"%1$s\" получит доступ ко всему, что показывается или воспроизводится на телефоне, включая аудиофайлы, фотографии, пароли и сообщения.<br/><br/>Приложение \"%1$s\" сможет транслировать приложения, пока вы не отзовете это разрешение."</string> - <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервисы стриминга приложений"</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Разрешить устройству <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> транслировать приложения с вашего телефона?"</string> + <string name="summary_app_streaming" msgid="295548145144086753">"У устройства \"%1$s\" будет доступ ко всему, что показывается или воспроизводится на телефоне, включая аудиофайлы, фотографии, пароли и сообщения.<br/><br/><br/>Устройство \"%1$s\" сможет транслировать приложения, пока вы не отзовете это разрешение."</string> + <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервисы для нескольких устройств"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>, чтобы транслировать приложения между устройствами."</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>, чтобы транслировать приложения между устройствами."</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" от имени вашего устройства \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" запрашивает разрешение на трансляцию приложений между устройствами."</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Разрешите приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> получать эту информацию с вашего телефона"</string> @@ -38,8 +38,8 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Сервисы Google Play"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>, чтобы получить доступ к фотографиям, медиаконтенту и уведомлениям на телефоне."</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Разрешить приложению <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> выполнять это действие?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Разрешить приложению <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> транслировать приложения и системные функции с вашего телефона?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"Приложение \"%1$s\" получит доступ ко всему, что показывается или воспроизводится на вашем телефоне, включая аудиофайлы, фотографии, платежные данные, пароли и сообщения.<br/><br/>Приложение \"%1$s\" сможет транслировать приложения и системные функции, пока вы не отзовете это разрешение."</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Разрешить устройству <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> транслировать приложения и системные функции с вашего телефона?"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"У устройства \"%1$s\" будет доступ ко всему, что показывается или воспроизводится на вашем телефоне, включая аудиофайлы, фотографии, платежные данные, пароли и сообщения.<br/><br/>Устройство \"%1$s\" сможет транслировать приложения и системные функции, пока вы не отзовете это разрешение."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" от имени вашего устройства \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\" запрашивает разрешение транслировать приложения и системные функции на устройства поблизости."</string> <string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string> <string name="summary_generic" msgid="1761976003668044801">"Приложение сможет синхронизировать информацию между телефоном и выбранным устройством, например данные из журнала звонков."</string> diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml index bbee596d56f4..c0d27f1e32e1 100644 --- a/packages/CompanionDeviceManager/res/values-sk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml @@ -26,11 +26,11 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"zariadenie"</string> <string name="summary_glasses" msgid="2872254734959842579">"Táto aplikácia bude mať prístup k týmto povoleniam v zariadení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prístup k týmto informáciám z vášho telefónu"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Chcete povoliť aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> streamovať aplikácie vo svojom telefóne?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"%1$s bude mať prístup k všetkému obsahu viditeľnému alebo prehrávanému v telefóne vrátane zvuku, fotiek, hesiel a správ.<br/><br/>%1$s bude môcť streamovať aplikácie, kým prístup k tomuto povoleniu neodstránite."</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Chcete povoliť zariadeniu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> streamovať aplikácie telefónu?"</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s bude mať prístup k všetkému, čo v telefóne zobrazíte alebo prehrajete, vrátane zvuku, fotiek, hesiel a správ.<br/><br/>%1$s bude môcť streamovať aplikácie, kým toto povolenie neodstránite."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pre viacero zariadení"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje pre zariadenie <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> povolenie streamovať aplikácie medzi vašimi zariadeniami."</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje pre zariadenie <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> povolenie zobrazovať a streamovať aplikácie medzi zariadeniami"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje v mene zariadenia <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> povolenie zobrazovať a streamovať aplikácie medzi zariadeniami"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prístup k týmto informáciám z vášho telefónu"</string> @@ -38,8 +38,8 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje pre zariadenie <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> povolenie na prístup k fotkám, médiám a upozorneniam vášho telefónu"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Chcete povoliť zariadeniu <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> vykonať túto akciu?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Chcete povoliť aplikácii <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> streamovať aplikácie a systémové funkcie vo svojom telefóne?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s bude mať prístup k všetkému obsahu viditeľnému alebo prehrávanému v telefóne vrátane zvuku, fotiek, platobných údajov, hesiel a správ.<br/><br/>%1$s bude môcť streamovať aplikácie, kým prístup k tomuto povoleniu neodstránite."</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Chcete povoliť zariadeniu <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> streamovať aplikácie a systémové funkcie telefónu?"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s bude mať prístup k všetkému, čo v telefóne zobrazíte alebo prehrajete, vrátane zvuku, fotiek, platobných údajov, hesiel a správ.<br/><br/>%1$s bude môcť streamovať aplikácie a systémové funkcie, kým toto povolenie neodstránite."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje pre zariadenie <xliff:g id="DEVICE_NAME">%2$s</xliff:g> povolenie streamovať aplikácie a ďalšie systémové funkcie do zariadení v okolí"</string> <string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string> <string name="summary_generic" msgid="1761976003668044801">"Táto aplikácia bude môcť synchronizovať informácie, napríklad meno volajúceho, medzi telefónom a vybraným zariadením"</string> diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml index 346fbaee9625..a895c25bf075 100644 --- a/packages/CompanionDeviceManager/res/values-sl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml @@ -28,7 +28,7 @@ <string name="title_app_streaming" msgid="2270331024626446950">"Dovolite, da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dostopa do teh podatkov v vašem telefonu"</string> <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Ali aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dovolite, da pretočno predvaja aplikacije telefona?"</string> <string name="summary_app_streaming" msgid="295548145144086753">"Aplikacija %1$s bo imela dostop do vsega, kar je prikazano ali se predvaja v telefonu, vključno z zvokom, fotografijami, gesli in sporočili.<br/><br/>Aplikacija %1$s bo lahko pretočno predvajala aplikacije, dokler ne odstranite dostopa do tega dovoljenja."</string> - <string name="helper_title_app_streaming" msgid="4151687003439969765">"Storitve za zunanje naprave"</string> + <string name="helper_title_app_streaming" msgid="4151687003439969765">"Storitve v več napravah"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij v vaših napravah."</string> <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>« zahteva dovoljenje za prikaz in pretočno predvajanje aplikacij v vaših napravah."</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml index 76f623a1d2f5..63e8cb6a4c32 100644 --- a/packages/CompanionDeviceManager/res/values-sq/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml @@ -27,20 +27,20 @@ <string name="summary_glasses" msgid="2872254734959842579">"Këtij aplikacioni do t\'i lejohet qasja te këto leje në <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ketë qasje në këtë informacion nga telefoni yt"</string> <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Të lejohet që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të transmetojë aplikacionet e telefonit tënd?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"%1$s do të ketë qasje te çdo gjë që është e dukshme ose luhet në telefon, duke përfshirë audion, fotografitë, fjalëkalimet dhe mesazhet.<br/><br/>%1$s do të mund të transmetojë aplikacionet derisa ta heqësh qasjen për këtë leje."</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s do të ketë qasje te çdo gjë që është e dukshme ose që luhet në telefon, duke përfshirë audion, fotografitë, fjalëkalimet dhe mesazhet.<br/><br/>%1$s do të mund t\'i transmetojë aplikacionet derisa ta heqësh qasjen për këtë leje."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Shërbimet mes pajisjeve"</string> - <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> për të transmetuar aplikacione ndërmjet pajisjeve të tua"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> për të shfaqur dhe transmetuar aplikacionet mes pajisjeve të tua"</string> + <string name="helper_summary_app_streaming" msgid="2396773196949578425">"\"<xliff:g id="APP_NAME">%1$s</xliff:g>\" po kërkon leje në emër të <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> për të transmetuar aplikacione ndërmjet pajisjeve të tua"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"\"<xliff:g id="APP_NAME">%1$s</xliff:g>\" po kërkon leje në emër të <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> për të shfaqur dhe transmetuar aplikacionet mes pajisjeve të tua"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ketë qasje në këtë informacion nga telefoni yt"</string> <string name="summary_computer" msgid="3798467601598297062"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Shërbimet e Google Play"</string> - <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> për të marrë qasje te fotografitë, media dhe njoftimet e telefonit tënd"</string> + <string name="helper_summary_computer" msgid="8774832742608187072">"\"<xliff:g id="APP_NAME">%1$s</xliff:g>\" po kërkon leje në emër të <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> për të marrë qasje te fotografitë, media dhe njoftimet e telefonit tënd"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Të lejohet që <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> të ndërmarrë këtë veprim?"</string> <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Të lejohet që <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> të transmetojë aplikacionet dhe veçoritë e sistemit të telefonit tënd?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s do të ketë qasje te çdo gjë që është e dukshme ose luhet në telefon, duke përfshirë audion, fotografitë, informacionet për pagesën, fjalëkalimet dhe mesazhet.<br/><br/>%1$s do të mund të transmetojë aplikacionet dhe veçoritë e sistemit derisa ta heqësh qasjen për këtë leje."</string> - <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) tënde për të transmetuar aplikacione dhe veçori të tjera të sistemit te pajisjet në afërsi"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s do të ketë qasje te çdo gjë që është e dukshme ose që luhet në telefon, duke përfshirë audion, fotografitë, informacionet për pagesën, fjalëkalimet dhe mesazhet.<br/><br/>%1$s do të mund t\'i transmetojë aplikacionet dhe veçoritë e sistemit derisa ta heqësh qasjen për këtë leje."</string> + <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"\"<xliff:g id="APP_NAME">%1$s</xliff:g>\" po kërkon leje në emër të (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) tënde për të transmetuar aplikacione dhe veçori të tjera të sistemit te pajisjet në afërsi"</string> <string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string> <string name="summary_generic" msgid="1761976003668044801">"Ky aplikacion do të mund të sinkronizojë informacione, si p.sh emrin e dikujt që po telefonon, mes telefonit tënd dhe pajisjes së zgjedhur."</string> <string name="consent_yes" msgid="8344487259618762872">"Lejo"</string> diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml index ede266e23464..2643b2d4c19b 100644 --- a/packages/CompanionDeviceManager/res/values-te/strings.xml +++ b/packages/CompanionDeviceManager/res/values-te/strings.xml @@ -28,7 +28,7 @@ <string name="title_app_streaming" msgid="2270331024626446950">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> యాప్ను అనుమతించండి"</string> <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"మీ ఫోన్ యాప్లను స్ట్రీమ్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ను అనుమతించాలా?"</string> <string name="summary_app_streaming" msgid="295548145144086753">"ఆడియో, ఫోటోలు, పాస్వర్డ్లు, మెసేజ్లతో సహా ఫోన్లో కనిపించే లేదా ప్లే అయ్యే దేనికైనా %1$sకు యాక్సెస్ ఉంటుంది.<br/><br/>మీరు ఈ అనుమతికి యాక్సెస్ను తీసివేసే వరకు %1$s యాప్లను స్ట్రీమ్ చేయగలదు."</string> - <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> + <string name="helper_title_app_streaming" msgid="4151687003439969765">"క్రాస్-డివైజ్ సర్వీసులు"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"మీ పరికరాల మధ్య యాప్లను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string> <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"మీ పరికరాలలో యాప్లను డిస్ప్లే చేయడానికి, స్ట్రీమ్ చేయడానికి <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> తరఫున <xliff:g id="APP_NAME">%1$s</xliff:g> అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml index 3efc29925a21..5852657a01b5 100644 --- a/packages/CompanionDeviceManager/res/values-tr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml @@ -26,7 +26,7 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"Cihaz"</string> <string name="summary_glasses" msgid="2872254734959842579">"Bu uygulamanın <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızda şu izinlere erişmesine izin verilecek:"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> adlı uygulamanın telefonunuzdaki uygulamaları aktarmasına izin verilsin mi?"</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> adlı cihazın telefonunuzdaki uygulamaları aktarmasına izin verilsin mi?"</string> <string name="summary_app_streaming" msgid="295548145144086753">"%1$s; ses, fotoğraflar, şifreler ve mesajlar da dahil olmak üzere telefonda görünen veya oynatılan her şeye erişebilecek.<br/><br/>%1$s siz bu iznin erişimini kaldırana kadar uygulamaları aktarabilecek."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlar arası hizmetler"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g>, cihazlarınız arasında uygulama akışı gerçekleştirmek için <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> cihazınız adına izin istiyor"</string> @@ -38,7 +38,7 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Hizmetleri"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g>, telefonunuzdaki fotoğraf, medya ve bildirimlere erişmek için <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> cihazınız adına izin istiyor"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> cihazının bu işlemi yapmasına izin verilsin mi?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> adlı uygulamanın telefonunuzdaki uygulamaları ve sistem özelliklerini aktarmasına izin verilsin mi?"</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> adlı cihazın telefonunuzdaki uygulamaları ve sistem özelliklerini aktarmasına izin verilsin mi?"</string> <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s; ses, fotoğraflar, ödeme bilgileri, şifreler ve mesajlar da dahil olmak üzere telefonunuzda görünen veya oynatılan her şeye erişebilecek.<br/><br/>%1$s siz bu iznin erişimini kaldırana kadar uygulamaları ve diğer sistem özelliklerini aktarabilecek."</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması <xliff:g id="DEVICE_NAME">%2$s</xliff:g> cihazınız adına uygulamaları ve diğer sistem özelliklerini yakındaki cihazlara aktarmak için izin istiyor"</string> <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string> diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml index 109a011bccd6..d92a2e088f25 100644 --- a/packages/CompanionDeviceManager/res/values-ur/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml @@ -27,7 +27,7 @@ <string name="summary_glasses" msgid="2872254734959842579">"اس ایپ کو آپ کے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> پر ان اجازتوں تک رسائی کی اجازت ہوگی"</string> <string name="title_app_streaming" msgid="2270331024626446950">"اپنے فون سے ان معلومات تک رسائی حاصل کرنے کی <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو اجازت دیں"</string> <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"اجازت دیں<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> اپنے فون کی ایپس کو سلسلہ بندی کرنے کے لیے؟"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"%1$s کو فون پر دکھائی دینے والی یا چلائی جانے والی کسی بھی چیز تک رسائی حاصل ہوگی، بشمول آڈیو، تصاویر، پاس ورڈز اور پیغامات۔<br/><br/>%1$s اس وقت تک ایپس کو اسٹریم کر سکے گید جب تک آپ اس اجازت تک رسائی کو ہٹا دیتے ہیں۔"</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s کو فون پر دکھائی دینے والی یا چلائی جانے والی کسی بھی چیز تک رسائی حاصل ہوگی، بشمول آڈیو، تصاویر، پاس ورڈز اور پیغامات۔<br/><br/>اس وقت تک %1$s ایپس کو اسٹریم کر سکے گا جب تک آپ اس اجازت تک رسائی کو ہٹا نہیں دیتے۔"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"کراس ڈیوائس سروسز"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> کی جانب سے آپ کے آلات کے درمیان ایپس کی سلسلہ بندی کرنے کی اجازت کی درخواست کر رہی ہے"</string> <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> آپ کے <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> کی جانب سے آپ کے آلات کے درمیان ایپس کو ڈسپلے اور اسٹریم کرنے کے لیے اجازت کی درخواست کر رہی ہے"</string> @@ -38,7 +38,7 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Google Play سروسز"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> کی جانب سے آپ کے فون کی تصاویر، میڈیا اور اطلاعات تک رسائی کی اجازت کی درخواست کر رہی ہے"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> کو یہ کارروائی انجام دینے کی اجازت دیں؟"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"اجازت دیں <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> اپنے فون کی ایپس اور سسٹم کی خصوصیات کو سلسلہ بندی کرنے کے لیے؟"</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"آپ کے فون کی ایپس اور سسٹم کی خصوصیات کو سلسلہ بندی کرنے کی <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> کو اجازت دیں؟"</string> <!-- String.format failed for translation --> <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) --> <skip /> diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml index 750ff0d5ce4e..6daf4ff20b54 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml @@ -26,11 +26,11 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"设备"</string> <string name="summary_glasses" msgid="2872254734959842579">"该应用将可以获得您<xliff:g id="DEVICE_NAME">%1$s</xliff:g>上的以下权限"</string> <string name="title_app_streaming" msgid="2270331024626446950">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”<strong></strong>访问您手机中的这项信息"</string> - <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"允许 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 流式传输手机的应用?"</string> - <string name="summary_app_streaming" msgid="295548145144086753">"“%1$s”将能够访问手机上可见或播放的任何内容,包括音频、照片、密码和消息。<br/><br/>“%1$s”将能够流式传输应用,除非您撤消此访问权限。"</string> + <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"要允许 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 流式传输手机的应用吗?"</string> + <string name="summary_app_streaming" msgid="295548145144086753">"%1$s 将能够访问手机上可见或播放的任何内容,包括音频、照片、密码和消息。<br/><br/>%1$s 将能够流式传输应用,除非您撤消此访问权限。"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨设备服务"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>请求在您的设备之间流式传输应用内容"</string> - <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>请求在设备之间显示和流式传输应用"</string> + <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 请求在设备之间显示和流式传输应用"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"允许 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 访问您手机中的这项信息"</string> @@ -38,8 +38,8 @@ <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服务"</string> <string name="helper_summary_computer" msgid="8774832742608187072">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>请求访问您手机上的照片、媒体内容和通知"</string> <string name="title_nearby_device_streaming" msgid="7269956847378799794">"允许<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong>进行此操作?"</string> - <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"允许 <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> 流式传输手机的应用和系统功能?"</string> - <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"“%1$s”将能够访问手机上可见或播放的任何内容,包括音频、照片、付款信息、密码和消息。<br/><br/>“%1$s”将能够流式传输应用和系统功能,除非您撤消此访问权限。"</string> + <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"要允许 <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> 流式传输手机的应用和系统功能吗?"</string> + <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s 将能够访问手机上可见或播放的任何内容,包括音频、照片、付款信息、密码和消息。<br/><br/>%1$s 将能够流式传输应用和系统功能,除非您撤消此访问权限。"</string> <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_NAME">%2$s</xliff:g>请求将应用和其他系统功能流式传输到附近的设备"</string> <string name="profile_name_generic" msgid="6851028682723034988">"设备"</string> <string name="summary_generic" msgid="1761976003668044801">"此应用将能在您的手机和所选设备之间同步信息,例如来电者的姓名"</string> diff --git a/packages/CredentialManager/res/values-af/strings.xml b/packages/CredentialManager/res/values-af/strings.xml index a24134b3ff3f..b17293dbe4e2 100644 --- a/packages/CredentialManager/res/values-af/strings.xml +++ b/packages/CredentialManager/res/values-af/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Skep toegangsleutel om by <xliff:g id="APP_NAME">%1$s</xliff:g> aan te meld?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Stoor wagwoord om by <xliff:g id="APP_NAME">%1$s</xliff:g> aan te meld?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Stoor aanmeldinligting vir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Gebruik jou skermslot om ’n toegangsleutel vir <xliff:g id="APP_NAME">%1$s</xliff:g> te skep?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Gebruik jou skermslot om ’n wagwoord vir <xliff:g id="APP_NAME">%1$s</xliff:g> te skep?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Gebruik jou skermslot om aanmeldinligting vir <xliff:g id="APP_NAME">%1$s</xliff:g> te stoor?"</string> <string name="passkey" msgid="632353688396759522">"toegangsleutel"</string> <string name="password" msgid="6738570945182936667">"wagwoord"</string> <string name="passkeys" msgid="5733880786866559847">"toegangsleutels"</string> diff --git a/packages/CredentialManager/res/values-am/strings.xml b/packages/CredentialManager/res/values-am/strings.xml index 0554d81c0d6b..4ee07883d23e 100644 --- a/packages/CredentialManager/res/values-am/strings.xml +++ b/packages/CredentialManager/res/values-am/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"ወደ <xliff:g id="APP_NAME">%1$s</xliff:g> ለመግባት የይለፍ ቁልፍ ይፈጠር?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"ወደ <xliff:g id="APP_NAME">%1$s</xliff:g> ለመግባት የይለፍ ቃል ይቀመጥ?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"የ<xliff:g id="APP_NAME">%1$s</xliff:g> የመግቢያ መረጃ ይቀመጥ?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"ለ<xliff:g id="APP_NAME">%1$s</xliff:g> የይለፍ ቁልፍ ለመፍጠር የማያ ገጽ መቆለፊያዎን መጠቀም ይፈልጋሉ?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"ለ<xliff:g id="APP_NAME">%1$s</xliff:g> የይለፍ ቃል ለመፍጠር የማያ ገጽ መቆለፊያዎን መጠቀም ይፈልጋሉ?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"የ<xliff:g id="APP_NAME">%1$s</xliff:g> መግቢያ መረጃን ለማስቀመጥ የማያ ገጽ መቆለፊያዎን መጠቀም ይፈልጋሉ?"</string> <string name="passkey" msgid="632353688396759522">"የይለፍ ቁልፍ"</string> <string name="password" msgid="6738570945182936667">"የይለፍ ቃል"</string> <string name="passkeys" msgid="5733880786866559847">"የይለፍ ቁልፎች"</string> diff --git a/packages/CredentialManager/res/values-ar/strings.xml b/packages/CredentialManager/res/values-ar/strings.xml index 5e089fe5a301..7e141c244516 100644 --- a/packages/CredentialManager/res/values-ar/strings.xml +++ b/packages/CredentialManager/res/values-ar/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"هل تريد إنشاء مفتاح مرور لتسجيل الدخول إلى \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"هل تريد حفظ كلمة المرور لتسجيل الدخول إلى \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"هل تريد حفظ معلومات تسجيل الدخول إلى \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"هل تريد استخدام قفل الشاشة لإنشاء مفتاح مرور لتطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"هل تريد استخدام قفل الشاشة لإنشاء كلمة مرور لتطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"هل تريد استخدام قفل الشاشة لحفظ معلومات تسجيل الدخول لتطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string> <string name="passkey" msgid="632353688396759522">"مفتاح المرور"</string> <string name="password" msgid="6738570945182936667">"كلمة المرور"</string> <string name="passkeys" msgid="5733880786866559847">"مفاتيح المرور"</string> diff --git a/packages/CredentialManager/res/values-as/strings.xml b/packages/CredentialManager/res/values-as/strings.xml index 95a0e1b6a36d..cde91123d08b 100644 --- a/packages/CredentialManager/res/values-as/strings.xml +++ b/packages/CredentialManager/res/values-as/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g>ত ছাইন ইন কৰিবলৈ পাছকী সৃষ্টি কৰিবনে?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g>ত ছাইন ইন কৰিবলৈ পাছৱৰ্ড ছেভ কৰিবনে?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে ছাইন ইনৰ তথ্য ছেভ কৰিবনে?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে পাছকী সৃষ্টি কৰিবলৈ আপোনাৰ স্ক্ৰীন লক ব্যৱহাৰ কৰিবনে?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে পাছৱৰ্ড সৃষ্টি কৰিবলৈ আপোনাৰ স্ক্ৰীন লক ব্যৱহাৰ কৰিবনে?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে ছাইন ইনৰ তথ্য ছেভ কৰিবলৈ আপোনাৰ স্ক্ৰীন লক ব্যৱহাৰ কৰিবনে?"</string> <string name="passkey" msgid="632353688396759522">"পাছকী"</string> <string name="password" msgid="6738570945182936667">"পাছৱৰ্ড"</string> <string name="passkeys" msgid="5733880786866559847">"পাছকী"</string> diff --git a/packages/CredentialManager/res/values-az/strings.xml b/packages/CredentialManager/res/values-az/strings.xml index 00a671847a38..1623ec4b292b 100644 --- a/packages/CredentialManager/res/values-az/strings.xml +++ b/packages/CredentialManager/res/values-az/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinə daxil olmaq üçün giriş açarı yaradılsın?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinə daxil olmaq üçün parol yadda saxlansın?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün giriş məlumatları yadda saxlansın?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün giriş açarı yaratmaq məqsədilə ekran kilidi istifadə edilsin?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün parol yaratmaq məqsədilə ekran kilidi istifadə edilsin?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün giriş məlumatını yadda saxlamaq məqsədilə ekran kilidi istifadə edilsin?"</string> <string name="passkey" msgid="632353688396759522">"açar"</string> <string name="password" msgid="6738570945182936667">"parol"</string> <string name="passkeys" msgid="5733880786866559847">"açarlar"</string> diff --git a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml index 390c7742cde6..23c021e2528d 100644 --- a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml +++ b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Želite da napravite pristupni ključ da biste se prijavili u <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Želite da sačuvate lozinku da biste se prijavili u <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Želite da sačuvate podatke za prijavljivanje za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Želite da koristite otključavanje ekrana da biste napravili pristupni ključ za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Želite da koristite otključavanje ekrana da biste napravili lozinku za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Želite da koristite otključavanje ekrana da biste sačuvali podatke za prijavljivanje za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"pristupni kôd"</string> <string name="password" msgid="6738570945182936667">"lozinka"</string> <string name="passkeys" msgid="5733880786866559847">"pristupni kodovi"</string> diff --git a/packages/CredentialManager/res/values-be/strings.xml b/packages/CredentialManager/res/values-be/strings.xml index 6922e7052d91..d27f68bf56de 100644 --- a/packages/CredentialManager/res/values-be/strings.xml +++ b/packages/CredentialManager/res/values-be/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Стварыць ключ доступу для ўваходу ў праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Захаваць пароль для ўваходу ў праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Захаваць даныя для ўваходу ў праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"ключ доступу"</string> <string name="password" msgid="6738570945182936667">"пароль"</string> <string name="passkeys" msgid="5733880786866559847">"ключы доступу"</string> diff --git a/packages/CredentialManager/res/values-bg/strings.xml b/packages/CredentialManager/res/values-bg/strings.xml index 3d33c8fd91f4..780699b450f7 100644 --- a/packages/CredentialManager/res/values-bg/strings.xml +++ b/packages/CredentialManager/res/values-bg/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Искате ли да създадете ключ за достъп, с който да влизате в(ъв) <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Искате ли да запазите паролата за влизане в(ъв) <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Искате ли да запазите данните за вход за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"код за достъп"</string> <string name="password" msgid="6738570945182936667">"парола"</string> <string name="passkeys" msgid="5733880786866559847">"ключове за достъп"</string> diff --git a/packages/CredentialManager/res/values-bn/strings.xml b/packages/CredentialManager/res/values-bn/strings.xml index fe42ed6f2ad1..9d429d4746a2 100644 --- a/packages/CredentialManager/res/values-bn/strings.xml +++ b/packages/CredentialManager/res/values-bn/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপে সাইন-ইন করার জন্য পাসকী তৈরি করবেন?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপে সাইন-ইন করার জন্য পাসওয়ার্ড সেভ করবেন?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপের জন্য সাইন-ইন সংক্রান্ত তথ্য সেভ করবেন?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"পাসকী"</string> <string name="password" msgid="6738570945182936667">"পাসওয়ার্ড"</string> <string name="passkeys" msgid="5733880786866559847">"পাসকী"</string> diff --git a/packages/CredentialManager/res/values-bs/strings.xml b/packages/CredentialManager/res/values-bs/strings.xml index f6e6d811f2a6..00c211b48e01 100644 --- a/packages/CredentialManager/res/values-bs/strings.xml +++ b/packages/CredentialManager/res/values-bs/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Kreirati pristupni ključ da se prijavite u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Sačuvati lozinku da se prijavite u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Sačuvati podatke za prijavu u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Želite li upotrijebiti zaključavanje zaslona za izradu pristupnog ključa za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Želite li upotrijebiti zaključavanje zaslona za izradu zaporke za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Želite li upotrijebiti zaključavanje zaslona za spremanje podataka za prijavu za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"pristupni ključ"</string> <string name="password" msgid="6738570945182936667">"lozinka"</string> <string name="passkeys" msgid="5733880786866559847">"pristupni ključevi"</string> diff --git a/packages/CredentialManager/res/values-ca/strings.xml b/packages/CredentialManager/res/values-ca/strings.xml index 3809d9251f7c..cf08741ebc2f 100644 --- a/packages/CredentialManager/res/values-ca/strings.xml +++ b/packages/CredentialManager/res/values-ca/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vols crear una clau d\'accés per iniciar la sessió a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vols desar la contrasenya per iniciar la sessió a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vols desar la informació d\'inici de sessió per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"clau d\'accés"</string> <string name="password" msgid="6738570945182936667">"contrasenya"</string> <string name="passkeys" msgid="5733880786866559847">"claus d\'accés"</string> diff --git a/packages/CredentialManager/res/values-cs/strings.xml b/packages/CredentialManager/res/values-cs/strings.xml index 6e6857c209d9..5e0d42e2d25f 100644 --- a/packages/CredentialManager/res/values-cs/strings.xml +++ b/packages/CredentialManager/res/values-cs/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vytvořit přístupový klíč k přihlašování do aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Uložit heslo k přihlašování do aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Uložit přihlašovací údaje pro aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"přístupový klíč"</string> <string name="password" msgid="6738570945182936667">"heslo"</string> <string name="passkeys" msgid="5733880786866559847">"přístupové klíče"</string> diff --git a/packages/CredentialManager/res/values-da/strings.xml b/packages/CredentialManager/res/values-da/strings.xml index ae7c3cfaf96e..e978b8e86890 100644 --- a/packages/CredentialManager/res/values-da/strings.xml +++ b/packages/CredentialManager/res/values-da/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vil du oprette en adgangsnøgle for at logge ind på <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vil du gemme adgangskoden for at logge ind på <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vil du gemme loginoplysningerne til <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"adgangsnøgle"</string> <string name="password" msgid="6738570945182936667">"adgangskode"</string> <string name="passkeys" msgid="5733880786866559847">"adgangsnøgler"</string> diff --git a/packages/CredentialManager/res/values-de/strings.xml b/packages/CredentialManager/res/values-de/strings.xml index 4fa669baa9d9..b338b1d92e48 100644 --- a/packages/CredentialManager/res/values-de/strings.xml +++ b/packages/CredentialManager/res/values-de/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Passkey zur Anmeldung in <xliff:g id="APP_NAME">%1$s</xliff:g> erstellen?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Passwort zur Anmeldung in <xliff:g id="APP_NAME">%1$s</xliff:g> speichern?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Anmeldedaten für <xliff:g id="APP_NAME">%1$s</xliff:g> speichern?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"Passkey"</string> <string name="password" msgid="6738570945182936667">"Passwort"</string> <string name="passkeys" msgid="5733880786866559847">"Passkeys"</string> diff --git a/packages/CredentialManager/res/values-el/strings.xml b/packages/CredentialManager/res/values-el/strings.xml index b6b2728b8961..29ad56951449 100644 --- a/packages/CredentialManager/res/values-el/strings.xml +++ b/packages/CredentialManager/res/values-el/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Δημιουργία κλειδιού πρόσβασης για σύνδεση στην εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Αποθήκευση κωδικού πρόσβασης για σύνδεση στην εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Αποθήκευση πληροφοριών σύνδεσης για την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"κλειδί πρόσβασης"</string> <string name="password" msgid="6738570945182936667">"κωδικός πρόσβασης"</string> <string name="passkeys" msgid="5733880786866559847">"κλειδιά πρόσβασης"</string> diff --git a/packages/CredentialManager/res/values-en-rAU/strings.xml b/packages/CredentialManager/res/values-en-rAU/strings.xml index f177cf981e8c..b8bef997a383 100644 --- a/packages/CredentialManager/res/values-en-rAU/strings.xml +++ b/packages/CredentialManager/res/values-en-rAU/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Create passkey to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Save password to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Save sign-in info for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> <string name="passkeys" msgid="5733880786866559847">"passkeys"</string> diff --git a/packages/CredentialManager/res/values-en-rCA/strings.xml b/packages/CredentialManager/res/values-en-rCA/strings.xml index df4cd86e6d20..3fb3d55e655d 100644 --- a/packages/CredentialManager/res/values-en-rCA/strings.xml +++ b/packages/CredentialManager/res/values-en-rCA/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Create passkey to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Save password to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Save sign-in info for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Use your screen lock to create a passkey for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Use your screen lock to create a password for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Use your screen lock to save sign in info for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> <string name="passkeys" msgid="5733880786866559847">"passkeys"</string> diff --git a/packages/CredentialManager/res/values-en-rGB/strings.xml b/packages/CredentialManager/res/values-en-rGB/strings.xml index f177cf981e8c..b8bef997a383 100644 --- a/packages/CredentialManager/res/values-en-rGB/strings.xml +++ b/packages/CredentialManager/res/values-en-rGB/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Create passkey to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Save password to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Save sign-in info for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> <string name="passkeys" msgid="5733880786866559847">"passkeys"</string> diff --git a/packages/CredentialManager/res/values-en-rIN/strings.xml b/packages/CredentialManager/res/values-en-rIN/strings.xml index f177cf981e8c..b8bef997a383 100644 --- a/packages/CredentialManager/res/values-en-rIN/strings.xml +++ b/packages/CredentialManager/res/values-en-rIN/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Create passkey to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Save password to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Save sign-in info for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> <string name="passkeys" msgid="5733880786866559847">"passkeys"</string> diff --git a/packages/CredentialManager/res/values-en-rXC/strings.xml b/packages/CredentialManager/res/values-en-rXC/strings.xml index 77ae53afc700..b642c87bf28a 100644 --- a/packages/CredentialManager/res/values-en-rXC/strings.xml +++ b/packages/CredentialManager/res/values-en-rXC/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Create passkey to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Save password to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Save sign-in info for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Use your screen lock to create a passkey for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Use your screen lock to create a password for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Use your screen lock to save sign in info for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> <string name="passkeys" msgid="5733880786866559847">"passkeys"</string> diff --git a/packages/CredentialManager/res/values-es-rUS/strings.xml b/packages/CredentialManager/res/values-es-rUS/strings.xml index 6ccfec3d8a15..3b4392d924e7 100644 --- a/packages/CredentialManager/res/values-es-rUS/strings.xml +++ b/packages/CredentialManager/res/values-es-rUS/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"¿Quieres crear una llave de acceso para acceder a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"¿Quieres guardar la contraseña para acceder a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"¿Quieres guardar la información de acceso para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"llave de acceso"</string> <string name="password" msgid="6738570945182936667">"contraseña"</string> <string name="passkeys" msgid="5733880786866559847">"llaves de acceso"</string> diff --git a/packages/CredentialManager/res/values-es/strings.xml b/packages/CredentialManager/res/values-es/strings.xml index b2c1c6fe4915..427ed1d69c25 100644 --- a/packages/CredentialManager/res/values-es/strings.xml +++ b/packages/CredentialManager/res/values-es/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"¿Crear llave de acceso para iniciar sesión en <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"¿Guardar contraseña para iniciar sesión en <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"¿Guardar la información de inicio de sesión de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"llave de acceso"</string> <string name="password" msgid="6738570945182936667">"contraseña"</string> <string name="passkeys" msgid="5733880786866559847">"llaves de acceso"</string> diff --git a/packages/CredentialManager/res/values-et/strings.xml b/packages/CredentialManager/res/values-et/strings.xml index 823a016e8d8f..44b907e4b08d 100644 --- a/packages/CredentialManager/res/values-et/strings.xml +++ b/packages/CredentialManager/res/values-et/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Kas luua rakendusse <xliff:g id="APP_NAME">%1$s</xliff:g> sisselogimiseks pääsuvõti?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Kas salvestada rakendusse <xliff:g id="APP_NAME">%1$s</xliff:g> sisselogimiseks parool?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Kas salvestada rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> jaoks sisselogimisteave?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"pääsuvõti"</string> <string name="password" msgid="6738570945182936667">"parool"</string> <string name="passkeys" msgid="5733880786866559847">"pääsuvõtmed"</string> diff --git a/packages/CredentialManager/res/values-eu/strings.xml b/packages/CredentialManager/res/values-eu/strings.xml index 8507b3f21997..afc91ea2cdb2 100644 --- a/packages/CredentialManager/res/values-eu/strings.xml +++ b/packages/CredentialManager/res/values-eu/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan saioa hasteko sarbide-gako bat sortu nahi duzu?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan saioa hasteko pasahitza gorde nahi duzu?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan saioa hasteko informazioa gorde nahi duzu?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"sarbide-gakoa"</string> <string name="password" msgid="6738570945182936667">"pasahitza"</string> <string name="passkeys" msgid="5733880786866559847">"sarbide-gakoak"</string> @@ -75,7 +81,7 @@ <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan saioa hasteko aukerak desblokeatu nahi dituzu?"</string> <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Aukeratu <xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako gordetako sarbide-gakoa"</string> <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Aukeratu <xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako gordetako pasahitza"</string> - <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Aukeratu <xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako gordetako kredentzialak"</string> + <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Aukeratu <xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako gordetako saioa hasteko moduak"</string> <string name="get_dialog_title_choose_sign_in_for" msgid="3048870756117876514">"Aukeratu <xliff:g id="APP_NAME">%1$s</xliff:g> zerbitzuan saioa hasteko kredentzialak"</string> <string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako aukera bat hautatu nahi duzu?"</string> <string name="get_dialog_title_use_info_on" msgid="8863708099535435146">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan erabili nahi duzu informazio hori?"</string> @@ -89,10 +95,10 @@ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"Desblokeatzeko, sakatu hau"</string> <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="8131725029983174901">"Ez dago saioa hasteko informaziorik"</string> <string name="no_sign_in_info_in" msgid="2641118151920288356">"Ez dago saioa hasteko informaziorik <xliff:g id="SOURCE">%1$s</xliff:g> kontuan"</string> - <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Kudeatu kredentzialak"</string> + <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Kudeatu saioa hasteko moduak"</string> <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Beste gailu batean gordetakoak"</string> <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Erabili beste gailu bat"</string> <string name="request_cancelled_by" msgid="3735222326886267820">"Utzi du bertan behera eskaera <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak"</string> - <string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"Saioa hasteko aukerak"</string> + <string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"Saioa hasteko moduak"</string> <string name="more_options_content_description" msgid="1323427365788198808">"Gehiago"</string> </resources> diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml index 656c789a72b8..095cb0614ca5 100644 --- a/packages/CredentialManager/res/values-fa/strings.xml +++ b/packages/CredentialManager/res/values-fa/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"برای ورود به سیستم <xliff:g id="APP_NAME">%1$s</xliff:g>، گذرکلید ایجاد شود؟"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"برای ورود به سیستم <xliff:g id="APP_NAME">%1$s</xliff:g>، گذرواژه ذخیره شود؟"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"اطلاعات ورود به سیستم <xliff:g id="APP_NAME">%1$s</xliff:g> ذخیره شود؟"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"گذرکلید"</string> <string name="password" msgid="6738570945182936667">"گذرواژه"</string> <string name="passkeys" msgid="5733880786866559847">"گذرکلیدها"</string> diff --git a/packages/CredentialManager/res/values-fi/strings.xml b/packages/CredentialManager/res/values-fi/strings.xml index f2f1bfbb4d1e..7de1151f2117 100644 --- a/packages/CredentialManager/res/values-fi/strings.xml +++ b/packages/CredentialManager/res/values-fi/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Luodaanko avainkoodi sisäänkirjautumista (<xliff:g id="APP_NAME">%1$s</xliff:g>) varten?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Tallennetaanko salasana sisäänkirjautumista (<xliff:g id="APP_NAME">%1$s</xliff:g>) varten?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Tallennetaanko kirjautumistiedot (<xliff:g id="APP_NAME">%1$s</xliff:g>)?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"avainkoodi"</string> <string name="password" msgid="6738570945182936667">"salasana"</string> <string name="passkeys" msgid="5733880786866559847">"avainkoodit"</string> diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml index 891e98791449..519b14ace029 100644 --- a/packages/CredentialManager/res/values-fr-rCA/strings.xml +++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Créer une clé d\'accès pour se connecter à <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Enregistrer un mot de passe pour se connecter à <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Enregistrer les renseignements de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"clé d\'accès"</string> <string name="password" msgid="6738570945182936667">"mot de passe"</string> <string name="passkeys" msgid="5733880786866559847">"clés d\'accès"</string> diff --git a/packages/CredentialManager/res/values-fr/strings.xml b/packages/CredentialManager/res/values-fr/strings.xml index f2ca1fc4028c..f63c7c2aee2b 100644 --- a/packages/CredentialManager/res/values-fr/strings.xml +++ b/packages/CredentialManager/res/values-fr/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Créer une clé d\'accès pour se connecter à <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Enregistrer un mot de passe pour se connecter à <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Enregistrer les informations de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"clé d\'accès"</string> <string name="password" msgid="6738570945182936667">"mot de passe"</string> <string name="passkeys" msgid="5733880786866559847">"clés d\'accès"</string> @@ -75,7 +81,7 @@ <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Déverrouiller les options de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string> <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Choisir une clé d\'accès enregistrée pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Choisir un mot de passe enregistré pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Choisir des informations de connexion enregistrées pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Choisissez les identifiants à utiliser pour la connexion à <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="get_dialog_title_choose_sign_in_for" msgid="3048870756117876514">"Choisir des infos de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"Choisir une option pour <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string> <string name="get_dialog_title_use_info_on" msgid="8863708099535435146">"Utiliser ces informations dans <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string> diff --git a/packages/CredentialManager/res/values-gl/strings.xml b/packages/CredentialManager/res/values-gl/strings.xml index 7117e1c00794..d756200c11d4 100644 --- a/packages/CredentialManager/res/values-gl/strings.xml +++ b/packages/CredentialManager/res/values-gl/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Queres crear unha clave de acceso para iniciar sesión en <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Queres gardar o contrasinal para iniciar sesión en <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Queres gardar a información de inicio de sesión de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"clave de acceso"</string> <string name="password" msgid="6738570945182936667">"contrasinal"</string> <string name="passkeys" msgid="5733880786866559847">"claves de acceso"</string> @@ -75,7 +81,7 @@ <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Queres desbloquear as opcións de inicio de sesión para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Escolle unha clave de acceso gardada para <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Escolle un contrasinal gardado para <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Escolle un método de inicio de sesión gardado para <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Escolle un inicio de sesión gardado para <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="get_dialog_title_choose_sign_in_for" msgid="3048870756117876514">"Escolle un inicio de sesión para <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"Queres escoller unha opción para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="get_dialog_title_use_info_on" msgid="8863708099535435146">"Queres usar esta información en <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-gu/strings.xml b/packages/CredentialManager/res/values-gu/strings.xml index 98b4686716ec..ed081288bffb 100644 --- a/packages/CredentialManager/res/values-gu/strings.xml +++ b/packages/CredentialManager/res/values-gu/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g>માં સાઇન ઇન કરવા માટે પાસકી બનાવીએ?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g>માં સાઇન ઇન કરવા માટે પાસવર્ડ સાચવીએ?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> માટે સાઇન-ઇન કરવાની માહિતી સાચવીએ?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"<xliff:g id="APP_NAME">%1$s</xliff:g> માટે કોઈ પાસકી બનાવવા માટે, શું તમારા સ્ક્રીન લૉકનો ઉપયોગ કરીએ?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"<xliff:g id="APP_NAME">%1$s</xliff:g> માટે કોઈ પાસવર્ડ બનાવવા માટે, શું તમારા સ્ક્રીન લૉકનો ઉપયોગ કરીએ?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"<xliff:g id="APP_NAME">%1$s</xliff:g> માટે સાઇન ઇનની માહિતી સાચવવા માટે, શું તમારા સ્ક્રીન લૉકનો ઉપયોગ કરીએ?"</string> <string name="passkey" msgid="632353688396759522">"પાસકી"</string> <string name="password" msgid="6738570945182936667">"પાસવર્ડ"</string> <string name="passkeys" msgid="5733880786866559847">"પાસકી"</string> diff --git a/packages/CredentialManager/res/values-hi/strings.xml b/packages/CredentialManager/res/values-hi/strings.xml index 9bc5feb6e9e9..16f04c5432b2 100644 --- a/packages/CredentialManager/res/values-hi/strings.xml +++ b/packages/CredentialManager/res/values-hi/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"क्या आपको <xliff:g id="APP_NAME">%1$s</xliff:g> में साइन इन करने के लिए पासकी बनानी है?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"क्या आपको <xliff:g id="APP_NAME">%1$s</xliff:g> में साइन इन करने के लिए पासवर्ड सेव करना है?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"क्या आपको <xliff:g id="APP_NAME">%1$s</xliff:g> के लिए साइन-इन की जानकारी सेव करनी है?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"क्या स्क्रीन लॉक का इस्तेमाल करके, <xliff:g id="APP_NAME">%1$s</xliff:g> के लिए पासकी बनानी है?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"क्या स्क्रीन लॉक का इस्तेमाल करके, <xliff:g id="APP_NAME">%1$s</xliff:g> के लिए पासवर्ड बनाना है?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"क्या स्क्रीन लॉक का इस्तेमाल करके, <xliff:g id="APP_NAME">%1$s</xliff:g> में साइन इन करने की जानकारी सेव करनी है?"</string> <string name="passkey" msgid="632353688396759522">"पासकी"</string> <string name="password" msgid="6738570945182936667">"पासवर्ड"</string> <string name="passkeys" msgid="5733880786866559847">"पासकी"</string> @@ -75,24 +78,24 @@ <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"क्या आपको <xliff:g id="APP_NAME">%1$s</xliff:g> में साइन इन करने के विकल्पों को अनलॉक करना है?"</string> <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए सेव की गई पासकी चुनें"</string> <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए सेव किया गया पासवर्ड चुनें"</string> - <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए सेव किया गया साइन इन क्रेडेंशियल चुनें"</string> + <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए सेव किया गया क्रेडेंशियल चुनें"</string> <string name="get_dialog_title_choose_sign_in_for" msgid="3048870756117876514">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए साइन-इन क्रेडेंशियल चुनें"</string> <string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"<xliff:g id="APP_NAME">%1$s</xliff:g> में साइन इन करने के लिए सेव किए गए विकल्पों में से किसी को चुनना है?"</string> <string name="get_dialog_title_use_info_on" msgid="8863708099535435146">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए, क्या इस जानकारी का इस्तेमाल करना है?"</string> <string name="get_dialog_use_saved_passkey_for" msgid="4618100798664888512">"किसी दूसरे तरीके से साइन इन करें"</string> <string name="snackbar_action" msgid="37373514216505085">"विकल्प देखें"</string> <string name="get_dialog_button_label_continue" msgid="6446201694794283870">"जारी रखें"</string> - <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"साइन इन करने के विकल्प"</string> + <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"साइन-इन करने के लिए विकल्प"</string> <string name="button_label_view_more" msgid="3429098227286495651">"ज़्यादा देखें"</string> <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> के लिए"</string> <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"लॉक किए गए पासवर्ड मैनेजर"</string> <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"अनलॉक करने के लिए टैप करें"</string> <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="8131725029983174901">"साइन-इन करने से जुड़ी कोई जानकारी उपलब्ध नहीं है"</string> <string name="no_sign_in_info_in" msgid="2641118151920288356">"<xliff:g id="SOURCE">%1$s</xliff:g> में साइन-इन की जानकारी नहीं है"</string> - <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"साइन इन करने की सुविधा को मैनेज करें"</string> + <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"साइन-इन किए गए खाते मैनेज करें"</string> <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> - <string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"साइन-इन करने के विकल्प"</string> + <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/CredentialManager/res/values-hr/strings.xml b/packages/CredentialManager/res/values-hr/strings.xml index 968a7472d58e..2c10c2122ce3 100644 --- a/packages/CredentialManager/res/values-hr/strings.xml +++ b/packages/CredentialManager/res/values-hr/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Želite li izraditi pristupni ključ za prijavu u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Želite li spremiti zaporku za prijavu u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Želite li spremiti informacije o prijavi za <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Želite li upotrijebiti zaključavanje zaslona za izradu pristupnog ključa za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Želite li upotrijebiti zaključavanje zaslona za izradu zaporke za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Želite li upotrijebiti zaključavanje zaslona za spremanje podataka za prijavu za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"pristupni ključ"</string> <string name="password" msgid="6738570945182936667">"zaporka"</string> <string name="passkeys" msgid="5733880786866559847">"pristupni ključevi"</string> diff --git a/packages/CredentialManager/res/values-hu/strings.xml b/packages/CredentialManager/res/values-hu/strings.xml index e601da676a2f..fe749f6129a8 100644 --- a/packages/CredentialManager/res/values-hu/strings.xml +++ b/packages/CredentialManager/res/values-hu/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Létrehoz azonosítókulcsot a következőbe való bejelentkezéshez: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Menti a jelszót a következőbe való bejelentkezéshez: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Menti a bejelentkezési adatokat a következőhöz: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"azonosítókulcs"</string> <string name="password" msgid="6738570945182936667">"jelszó"</string> <string name="passkeys" msgid="5733880786866559847">"azonosítókulcsait"</string> @@ -75,7 +81,7 @@ <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Feloldja a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> bejelentkezési lehetőségeit?"</string> <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Mentett azonosítókulcs kiválasztása a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazáshoz"</string> <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Mentett jelszó kiválasztása a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazáshoz"</string> - <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Mentett bejelentkezési adatok kiválasztása a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazáshoz"</string> + <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Mentett bejelentkezési adatok kiválasztása – <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="get_dialog_title_choose_sign_in_for" msgid="3048870756117876514">"Válasszon bejelentkezési adatokat – <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"Kiválaszt egy lehetőséget a következőbe való bejelentkezéshez: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="get_dialog_title_use_info_on" msgid="8863708099535435146">"Használni szeretná ezt az információt a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazásban?"</string> diff --git a/packages/CredentialManager/res/values-hy/strings.xml b/packages/CredentialManager/res/values-hy/strings.xml index 79a2624e980f..452acb7a18b2 100644 --- a/packages/CredentialManager/res/values-hy/strings.xml +++ b/packages/CredentialManager/res/values-hy/strings.xml @@ -27,7 +27,7 @@ <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Անցաբառերի հետ ավելի ապահով է"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Անցաբառերի շնորհիվ դուք բարդ գաղտնաբառեր ստեղծելու կամ հիշելու անհրաժեշտություն չեք ունենա"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Անցաբառերը գաղտնագրված թվային բանալիներ են, որոնք ստեղծվում են մատնահետքի, դեմքով ապակողպման կամ էկրանի կողպման օգտագործմամբ"</string> - <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Դուք կարող եք մուտք գործել այլ սարքերում, քանի որ անցաբառերը պահվում են գաղտնաբառերի կառավարիչում"</string> + <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Դուք կարող եք մուտք գործել այլ սարքերում, քանի որ մուտքի բանալիները պահվում են գաղտնաբառերի կառավարիչում"</string> <string name="more_about_passkeys_title" msgid="7797903098728837795">"Ավելին՝ անցաբառերի մասին"</string> <string name="passwordless_technology_title" msgid="2497513482056606668">"Գաղտնաբառեր չպահանջող տեխնոլոգիա"</string> <string name="passwordless_technology_detail" msgid="6853928846532955882">"Անցաբառերը ձեզ թույլ են տալիս մուտք գործել առանց գաղտնաբառերի։ Ձեզ պարզապես հարկավոր է օգտագործել ձեր մատնահետքը, դիմաճանաչումը, PIN կոդը կամ նախշը՝ ձեր ինքնությունը հաստատելու և անցաբառ ստեղծելու համար։"</string> @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Ստեղծե՞լ անցաբառ՝ <xliff:g id="APP_NAME">%1$s</xliff:g> հավելված մուտք գործելու համար"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Պահե՞լ գաղտնաբառը՝ <xliff:g id="APP_NAME">%1$s</xliff:g> հավելված մուտք գործելու համար"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Պահե՞լ «<xliff:g id="APP_NAME">%1$s</xliff:g>» հավելվածի մուտքի տվյալները"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"անցաբառ"</string> <string name="password" msgid="6738570945182936667">"գաղտնաբառ"</string> <string name="passkeys" msgid="5733880786866559847">"անցաբառեր"</string> @@ -53,7 +59,7 @@ <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Պահե՞լ գաղտնաբառն այլ սարքում"</string> <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Պահե՞լ մուտքի տվյալներն այլ սարքում"</string> <string name="use_provider_for_all_title" msgid="4201020195058980757">"Միշտ մուտք գործե՞լ <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> հավելվածի միջոցով"</string> - <string name="use_provider_for_all_description" msgid="1998772715863958997">"Այս գաղտնաբառերի կառավարչում <xliff:g id="USERNAME">%1$s</xliff:g> օգտատերը կկարողանա պահել իր գաղտնաբառերն ու անցաբառերը, որպեսզի հետագայում ավելի արագ մուտք գործի հաշիվ"</string> + <string name="use_provider_for_all_description" msgid="1998772715863958997">"Այս գաղտնաբառերի կառավարչում <xliff:g id="USERNAME">%1$s</xliff:g> օգտատերը կկարողանա պահել իր գաղտնաբառերն ու մուտքի բանալիները, որպեսզի հետագայում ավելի արագ մուտք գործի հաշիվ"</string> <string name="set_as_default" msgid="4415328591568654603">"Նշել որպես կանխադրված"</string> <string name="settings" msgid="6536394145760913145">"Կարգավորումներ"</string> <string name="use_once" msgid="9027366575315399714">"Օգտագործել մեկ անգամ"</string> diff --git a/packages/CredentialManager/res/values-in/strings.xml b/packages/CredentialManager/res/values-in/strings.xml index e7556b01d730..3eac6e97f986 100644 --- a/packages/CredentialManager/res/values-in/strings.xml +++ b/packages/CredentialManager/res/values-in/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Buat kunci sandi untuk login ke <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Simpan sandi untuk login ke <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Simpan info login untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Gunakan kunci layar Anda untuk membuat kunci sandi untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Gunakan kunci layar Anda untuk membuat sandi untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Gunakan kunci layar Anda untuk menyimpan info login untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"kunci sandi"</string> <string name="password" msgid="6738570945182936667">"sandi"</string> <string name="passkeys" msgid="5733880786866559847">"kunci sandi"</string> diff --git a/packages/CredentialManager/res/values-is/strings.xml b/packages/CredentialManager/res/values-is/strings.xml index 970a2e647c8a..9fd552b11568 100644 --- a/packages/CredentialManager/res/values-is/strings.xml +++ b/packages/CredentialManager/res/values-is/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Búa til aðgangslykil til að skrá þig inn á <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vista aðgangsorð til að skrá þig inn á <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Viltu vista innskráningarupplýsingar fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Nota skjálásinn til að búa til aðgangslykil fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Nota skjálásinn til að búa til aðgangsorð fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Nota skjálásinn til að vista innskráningarupplýsingar fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"aðgangslykill"</string> <string name="password" msgid="6738570945182936667">"aðgangsorð"</string> <string name="passkeys" msgid="5733880786866559847">"aðgangslykla"</string> diff --git a/packages/CredentialManager/res/values-it/strings.xml b/packages/CredentialManager/res/values-it/strings.xml index a04a840b5148..ce04dbc556b5 100644 --- a/packages/CredentialManager/res/values-it/strings.xml +++ b/packages/CredentialManager/res/values-it/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Creare passkey per accedere all\'app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Salvare password per accedere all\'app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vuoi salvare i dati di accesso di <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> <string name="passkeys" msgid="5733880786866559847">"passkey"</string> diff --git a/packages/CredentialManager/res/values-iw/strings.xml b/packages/CredentialManager/res/values-iw/strings.xml index 87dee5fa8d5f..07b26b7d9c59 100644 --- a/packages/CredentialManager/res/values-iw/strings.xml +++ b/packages/CredentialManager/res/values-iw/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"ליצור מפתח גישה כדי להיכנס לחשבון ב-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"לשמור את הסיסמה כדי להיכנס לחשבון ב-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"לשמור את פרטי הכניסה של <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"מפתח גישה"</string> <string name="password" msgid="6738570945182936667">"סיסמה"</string> <string name="passkeys" msgid="5733880786866559847">"מפתחות גישה"</string> diff --git a/packages/CredentialManager/res/values-ja/strings.xml b/packages/CredentialManager/res/values-ja/strings.xml index 71746dc63994..f12bb5e50937 100644 --- a/packages/CredentialManager/res/values-ja/strings.xml +++ b/packages/CredentialManager/res/values-ja/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> にログインするためにパスキーを作成しますか?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> にログインするためにパスワードを保存しますか?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> のログイン情報を保存しますか?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"パスキー"</string> <string name="password" msgid="6738570945182936667">"パスワード"</string> <string name="passkeys" msgid="5733880786866559847">"パスキー"</string> diff --git a/packages/CredentialManager/res/values-ka/strings.xml b/packages/CredentialManager/res/values-ka/strings.xml index 51f1332eba1d..4c6154040a7d 100644 --- a/packages/CredentialManager/res/values-ka/strings.xml +++ b/packages/CredentialManager/res/values-ka/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"შესასვლელად წვდომის გასაღების შექმნა: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"შესასვლელი პაროლის შენახვა: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"აპში შესვლის ინფორმაციის შენახვა: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"წვდომის გასაღები"</string> <string name="password" msgid="6738570945182936667">"პაროლი"</string> <string name="passkeys" msgid="5733880786866559847">"წვდომის გასაღები"</string> diff --git a/packages/CredentialManager/res/values-kk/strings.xml b/packages/CredentialManager/res/values-kk/strings.xml index 7393ca08c1bc..5b76ac89f47e 100644 --- a/packages/CredentialManager/res/values-kk/strings.xml +++ b/packages/CredentialManager/res/values-kk/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасына кіру үшін кіру кілті жасалсын ба?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасына кіру үшін құпия сөз сақталсын ба?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін кіру мәліметін сақтау керек пе?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"Кіру кілті"</string> <string name="password" msgid="6738570945182936667">"құпия сөз"</string> <string name="passkeys" msgid="5733880786866559847">"кіру кілттері"</string> @@ -75,7 +81,7 @@ <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін кіру опциялары ашылсын ба?"</string> <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін сақталған кіру кілтін таңдаңыз"</string> <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін сақталған құпия сөзді таңдаңыз"</string> - <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін сақталған тіркелу деректерін таңдаңыз"</string> + <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін сақталған кіру деректерін таңдаңыз"</string> <string name="get_dialog_title_choose_sign_in_for" msgid="3048870756117876514">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасына кіру деректерін таңдаңыз"</string> <string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін опция таңдайсыз ба?"</string> <string name="get_dialog_title_use_info_on" msgid="8863708099535435146">"Бұл ақпарат <xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасында сақталсын ба?"</string> diff --git a/packages/CredentialManager/res/values-km/strings.xml b/packages/CredentialManager/res/values-km/strings.xml index ac0d42704389..279474f96cb1 100644 --- a/packages/CredentialManager/res/values-km/strings.xml +++ b/packages/CredentialManager/res/values-km/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"បង្កើតកូដសម្ងាត់ ដើម្បីចូលគណនី <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"រក្សាទុកពាក្យសម្ងាត់ ដើម្បីចូលគណនី <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"រក្សាទុកព័ត៌មានចូលគណនីសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"ប្រើមុខងារចាក់សោអេក្រង់របស់អ្នក ដើម្បីបង្កើតកូដសម្ងាត់សម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"ប្រើមុខងារចាក់សោអេក្រង់របស់អ្នក ដើម្បីបង្កើតពាក្យសម្ងាត់សម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"ប្រើមុខងារចាក់សោអេក្រង់របស់អ្នក ដើម្បីរក្សាទុកព័ត៌មានចូលគណនីសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string> <string name="passkey" msgid="632353688396759522">"កូដសម្ងាត់"</string> <string name="password" msgid="6738570945182936667">"ពាក្យសម្ងាត់"</string> <string name="passkeys" msgid="5733880786866559847">"កូដសម្ងាត់"</string> diff --git a/packages/CredentialManager/res/values-kn/strings.xml b/packages/CredentialManager/res/values-kn/strings.xml index 031fa65114bf..01d0f59fe985 100644 --- a/packages/CredentialManager/res/values-kn/strings.xml +++ b/packages/CredentialManager/res/values-kn/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಲು ಪಾಸ್ಕೀ ಯನ್ನು ರಚಿಸಬೇಕೇ?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಲು ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ಸೇವ್ ಮಾಡಬೇಕೇ?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗಾಗಿ ಸೈನ್-ಇನ್ ಮಾಹಿತಿಯನ್ನು ಸೇವ್ ಮಾಡಬೇಕೇ?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"ಪಾಸ್ಕೀ"</string> <string name="password" msgid="6738570945182936667">"ಪಾಸ್ವರ್ಡ್"</string> <string name="passkeys" msgid="5733880786866559847">"ಪಾಸ್ಕೀಗಳು"</string> diff --git a/packages/CredentialManager/res/values-ko/strings.xml b/packages/CredentialManager/res/values-ko/strings.xml index e29ae68f7dc9..1f1fa2990d87 100644 --- a/packages/CredentialManager/res/values-ko/strings.xml +++ b/packages/CredentialManager/res/values-ko/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"패스키를 생성하여 <xliff:g id="APP_NAME">%1$s</xliff:g>에 로그인하시겠습니까?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"비밀번호를 저장하여 <xliff:g id="APP_NAME">%1$s</xliff:g>에 로그인하시겠습니까?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g>의 로그인 정보를 저장하시겠습니까?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"패스키"</string> <string name="password" msgid="6738570945182936667">"비밀번호"</string> <string name="passkeys" msgid="5733880786866559847">"패스키"</string> diff --git a/packages/CredentialManager/res/values-ky/strings.xml b/packages/CredentialManager/res/values-ky/strings.xml index 5e48ae5b2b2e..4e3fed1e1874 100644 --- a/packages/CredentialManager/res/values-ky/strings.xml +++ b/packages/CredentialManager/res/values-ky/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосуна кирүү үчүн киргизүүчү ачкычты түзөсүзбү?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосуна кирүү үчүн сырсөздү сактайсызбы?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> үчүн кирүү маалыматы сакталсынбы?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу үчүн киргизүүчү ачкыч катары экрандын кулпусун колдоносузбу?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу үчүн сырсөз катары экрандын кулпусун колдоносузбу?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу үчүн кирүү маалыматы катары экрандын кулпусун колдоносузбу?"</string> <string name="passkey" msgid="632353688396759522">"киргизүүчү ачкыч"</string> <string name="password" msgid="6738570945182936667">"сырсөз"</string> <string name="passkeys" msgid="5733880786866559847">"киргизүүчү ачкычтар"</string> diff --git a/packages/CredentialManager/res/values-lo/strings.xml b/packages/CredentialManager/res/values-lo/strings.xml index c3733a3ef1c3..e0f8839f1465 100644 --- a/packages/CredentialManager/res/values-lo/strings.xml +++ b/packages/CredentialManager/res/values-lo/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"ສ້າງກະແຈຜ່ານເພື່ອເຂົ້າສູ່ລະບົບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"ບັນທຶກລະຫັດຜ່ານເພື່ອເຂົ້າສູ່ລະບົບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"ບັນທຶກຂໍ້ມູນການເຂົ້າສູ່ລະບົບສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"ໃຊ້ລັອກໜ້າຈໍຂອງທ່ານເພື່ອສ້າງກະແຈຜ່ານສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"ໃຊ້ລັອກໜ້າຈໍຂອງທ່ານເພື່ອສ້າງລະຫັດຜ່ານສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"ໃຊ້ລັອກໜ້າຈໍຂອງທ່ານເພື່ອບັນທຶກຂໍ້ມູນການເຂົ້າສູ່ລະບົບສຳລັບ<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string> <string name="passkey" msgid="632353688396759522">"ກະແຈຜ່ານ"</string> <string name="password" msgid="6738570945182936667">"ລະຫັດຜ່ານ"</string> <string name="passkeys" msgid="5733880786866559847">"ກະແຈຜ່ານ"</string> diff --git a/packages/CredentialManager/res/values-lt/strings.xml b/packages/CredentialManager/res/values-lt/strings.xml index 453a0e0236eb..3b0124cf2249 100644 --- a/packages/CredentialManager/res/values-lt/strings.xml +++ b/packages/CredentialManager/res/values-lt/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Sukurti prieigos raktą, skirtą prisijungti prie „<xliff:g id="APP_NAME">%1$s</xliff:g>“?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Sukurti slaptažodį, skirtą prisijungti prie „<xliff:g id="APP_NAME">%1$s</xliff:g>“?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Išsaugoti prisijungimo prie „<xliff:g id="APP_NAME">%1$s</xliff:g>“ informaciją?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"„passkey“"</string> <string name="password" msgid="6738570945182936667">"slaptažodis"</string> <string name="passkeys" msgid="5733880786866559847">"prieigos raktas"</string> diff --git a/packages/CredentialManager/res/values-lv/strings.xml b/packages/CredentialManager/res/values-lv/strings.xml index 4da1051fe8fd..095fbeeea072 100644 --- a/packages/CredentialManager/res/values-lv/strings.xml +++ b/packages/CredentialManager/res/values-lv/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vai izveidot piekļuves atslēgu, lai pierakstītos lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vai saglabāt paroli, lai pierakstītos lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vai saglabāt pierakstīšanās informāciju lietotnei <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"piekļuves atslēga"</string> <string name="password" msgid="6738570945182936667">"parole"</string> <string name="passkeys" msgid="5733880786866559847">"piekļuves atslēgas"</string> @@ -93,6 +99,6 @@ <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"No citas ierīces"</string> <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Izmantot citu ierīci"</string> <string name="request_cancelled_by" msgid="3735222326886267820">"<xliff:g id="APP_NAME">%1$s</xliff:g> atcēla pieprasījumu"</string> - <string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"Pierakstīšanās iespējas"</string> + <string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"Pierakstīšanās opcijas"</string> <string name="more_options_content_description" msgid="1323427365788198808">"Vairāk"</string> </resources> diff --git a/packages/CredentialManager/res/values-mk/strings.xml b/packages/CredentialManager/res/values-mk/strings.xml index 95554a2330fb..0f22f6fc81fa 100644 --- a/packages/CredentialManager/res/values-mk/strings.xml +++ b/packages/CredentialManager/res/values-mk/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Да се создаде криптографски клуч за најавување на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Да се зачува лозинката за најавување на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Да се зачуваат податоците за најавување за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"криптографски клуч"</string> <string name="password" msgid="6738570945182936667">"лозинка"</string> <string name="passkeys" msgid="5733880786866559847">"криптографски клучеви"</string> diff --git a/packages/CredentialManager/res/values-ml/strings.xml b/packages/CredentialManager/res/values-ml/strings.xml index eccfb511b16c..f7d74fe2b05a 100644 --- a/packages/CredentialManager/res/values-ml/strings.xml +++ b/packages/CredentialManager/res/values-ml/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്യാൻ പാസ്കീ സൃഷ്ടിക്കണോ?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്യാൻ പാസ്വേഡ് സംരക്ഷിക്കണോ?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനായി സൈൻ ഇൻ വിവരങ്ങൾ സംരക്ഷിക്കണോ?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനായി പാസ്കീ സൃഷ്ടിക്കാൻ നിങ്ങളുടെ സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കണോ?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനായി പാസ്വേഡ് സൃഷ്ടിക്കാൻ നിങ്ങളുടെ സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കണോ?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനായി സൈൻ ഇൻ വിവരങ്ങൾ സംരക്ഷിക്കാൻ നിങ്ങളുടെ സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കണോ?"</string> <string name="passkey" msgid="632353688396759522">"പാസ്കീ"</string> <string name="password" msgid="6738570945182936667">"പാസ്വേഡ്"</string> <string name="passkeys" msgid="5733880786866559847">"പാസ്കീകൾ"</string> diff --git a/packages/CredentialManager/res/values-mn/strings.xml b/packages/CredentialManager/res/values-mn/strings.xml index 5b1cbe90c63a..5554670b4d2d 100644 --- a/packages/CredentialManager/res/values-mn/strings.xml +++ b/packages/CredentialManager/res/values-mn/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g>-д нэвтрэхийн тулд нэвтрэх түлхүүр үүсгэх үү?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g>-д нэвтрэхийн тулд нууц үгийг хадгалах уу?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g>-н нэвтрэх мэдээллийг хадгалах уу?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"нууц үг"</string> <string name="passkeys" msgid="5733880786866559847">"нэвтрэх түлхүүрүүд"</string> diff --git a/packages/CredentialManager/res/values-mr/strings.xml b/packages/CredentialManager/res/values-mr/strings.xml index a0a4a7de1146..ce415f5efd41 100644 --- a/packages/CredentialManager/res/values-mr/strings.xml +++ b/packages/CredentialManager/res/values-mr/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> मध्ये साइन इन करण्यासाठी पासकी तयार करायची आहे का?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> मध्ये साइन इन करण्यासाठी पासवर्ड सेव्ह करायचा आहे का?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी साइन-इनसंबंधित माहिती सेव्ह करायची का?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"पासकी"</string> <string name="password" msgid="6738570945182936667">"पासवर्ड"</string> <string name="passkeys" msgid="5733880786866559847">"पासकी"</string> @@ -82,7 +88,7 @@ <string name="get_dialog_use_saved_passkey_for" msgid="4618100798664888512">"दुसऱ्या मार्गाने साइन इन करा"</string> <string name="snackbar_action" msgid="37373514216505085">"पर्याय पहा"</string> <string name="get_dialog_button_label_continue" msgid="6446201694794283870">"पुढे सुरू ठेवा"</string> - <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"साइन इन पर्याय"</string> + <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"साइन-इन पर्याय"</string> <string name="button_label_view_more" msgid="3429098227286495651">"आणखी पहा"</string> <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> साठी"</string> <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"लॉक केलेले पासवर्ड व्यवस्थापक"</string> @@ -93,6 +99,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> - <string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"साइन इन करण्याचे पर्याय"</string> + <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/CredentialManager/res/values-ms/strings.xml b/packages/CredentialManager/res/values-ms/strings.xml index c866013d9478..62a7deb2f553 100644 --- a/packages/CredentialManager/res/values-ms/strings.xml +++ b/packages/CredentialManager/res/values-ms/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Buat kunci laluan untuk log masuk ke <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Simpan kata laluan untuk log masuk ke <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Simpan maklumat log masuk untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Gunakan kunci skrin anda untuk membuat kunci laluan bagi <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Gunakan kunci skrin anda untuk membuat kata laluan bagi <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Gunakan kunci skrin anda untuk menyimpan maklumat log masuk bagi <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"kunci laluan"</string> <string name="password" msgid="6738570945182936667">"kata laluan"</string> <string name="passkeys" msgid="5733880786866559847">"kunci laluan"</string> diff --git a/packages/CredentialManager/res/values-my/strings.xml b/packages/CredentialManager/res/values-my/strings.xml index a66e7b67c85e..5af7b72a48a6 100644 --- a/packages/CredentialManager/res/values-my/strings.xml +++ b/packages/CredentialManager/res/values-my/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> သို့ လက်မှတ်ထိုးဝင်ရန် လျှို့ဝှက်ကီး ပြုလုပ်မလား။"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> သို့ လက်မှတ်ထိုးဝင်ရန် စကားဝှက်ကို သိမ်းမလား။"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် လက်မှတ်ထိုးဝင်ရန် အချက်အလက်ကို သိမ်းမလား။"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"လျှို့ဝှက်ကီး"</string> <string name="password" msgid="6738570945182936667">"စကားဝှက်"</string> <string name="passkeys" msgid="5733880786866559847">"လျှို့ဝှက်ကီးများ"</string> diff --git a/packages/CredentialManager/res/values-nb/strings.xml b/packages/CredentialManager/res/values-nb/strings.xml index 7f4fa6ba8dfb..b6a679a49be6 100644 --- a/packages/CredentialManager/res/values-nb/strings.xml +++ b/packages/CredentialManager/res/values-nb/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vil du opprette en passnøkkel for å logge på <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vil du lagre passordet for å logge på <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vil du lagre påloggingsinformasjon for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"passnøkkel"</string> <string name="password" msgid="6738570945182936667">"passord"</string> <string name="passkeys" msgid="5733880786866559847">"passnøkler"</string> diff --git a/packages/CredentialManager/res/values-ne/strings.xml b/packages/CredentialManager/res/values-ne/strings.xml index 6e6947626ff0..161a16d6dbc5 100644 --- a/packages/CredentialManager/res/values-ne/strings.xml +++ b/packages/CredentialManager/res/values-ne/strings.xml @@ -22,8 +22,8 @@ <string name="string_continue" msgid="1346732695941131882">"जारी राख्नुहोस्"</string> <string name="string_more_options" msgid="2763852250269945472">"अर्को तरिकाले सेभ गर्नुहोस्"</string> <string name="string_learn_more" msgid="4541600451688392447">"थप जान्नुहोस्"</string> - <string name="content_description_show_password" msgid="3283502010388521607">"पासवर्ड देखाइयोस्"</string> - <string name="content_description_hide_password" msgid="6841375971631767996">"पासवर्ड लुकाइयोस्"</string> + <string name="content_description_show_password" msgid="3283502010388521607">"पासवर्ड देखाउनुहोस्"</string> + <string name="content_description_hide_password" msgid="6841375971631767996">"पासवर्ड लुकाउनुहोस्"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"पासकीका सहायताले सुरक्षित रहनुहोस्"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"तपाईंले पासकी बनाउनुभयो भने तपाईंले जटिल पासवर्ड बनाउनु वा तिनलाई याद गरिराख्नु पर्दैन"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"पासकी भनेको तपाईंले आफ्नो फिंगरप्रिन्ट, अनुहार वा स्क्रिन लक प्रयोग गरेर बनाएको इन्क्रिप्ट गरिएको डिजिटल की हो"</string> @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन इन गर्न पासकी बनाउने हो?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन इन गर्न पासवर्ड सेभ गर्ने हो?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन गर्न प्रयोग गरिने जानकारी सेभ गर्ने हो?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा पासकी बनाउन आफ्नो स्क्रिन लक प्रयोग गर्ने हो?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा पासवर्ड राख्न आफ्नो स्क्रिन लक प्रयोग गर्ने हो?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन इनसम्बन्धी जानकारी सेभ गर्न आफ्नो स्क्रिन लक प्रयोग गर्ने हो?"</string> <string name="passkey" msgid="632353688396759522">"पासकी"</string> <string name="password" msgid="6738570945182936667">"पासवर्ड"</string> <string name="passkeys" msgid="5733880786866559847">"पासकीहरू"</string> diff --git a/packages/CredentialManager/res/values-nl/strings.xml b/packages/CredentialManager/res/values-nl/strings.xml index 50eefc7e5e9b..06ebc08d9725 100644 --- a/packages/CredentialManager/res/values-nl/strings.xml +++ b/packages/CredentialManager/res/values-nl/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Toegangssleutel maken om in te loggen bij <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Wachtwoord opslaan om in te loggen bij <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Inloggegevens opslaan voor <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"Toegangssleutel"</string> <string name="password" msgid="6738570945182936667">"wachtwoord"</string> <string name="passkeys" msgid="5733880786866559847">"toegangssleutels"</string> @@ -82,7 +88,7 @@ <string name="get_dialog_use_saved_passkey_for" msgid="4618100798664888512">"Op een andere manier inloggen"</string> <string name="snackbar_action" msgid="37373514216505085">"Opties bekijken"</string> <string name="get_dialog_button_label_continue" msgid="6446201694794283870">"Doorgaan"</string> - <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opties voor inloggen"</string> + <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Inlogopties"</string> <string name="button_label_view_more" msgid="3429098227286495651">"Meer bekijken"</string> <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Voor <xliff:g id="USERNAME">%1$s</xliff:g>"</string> <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Vergrendelde wachtwoordmanagers"</string> @@ -93,6 +99,6 @@ <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Via een ander apparaat"</string> <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Een ander apparaat gebruiken"</string> <string name="request_cancelled_by" msgid="3735222326886267820">"Verzoek geannuleerd door <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"Opties voor inloggen"</string> + <string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"Inlogopties"</string> <string name="more_options_content_description" msgid="1323427365788198808">"Meer"</string> </resources> diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml index 56e585d015bd..9781c49d945c 100644 --- a/packages/CredentialManager/res/values-or/strings.xml +++ b/packages/CredentialManager/res/values-or/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g>ରେ ସାଇନ ଇନ କରିବାକୁ ପାସକୀ ତିଆରି କରିବେ?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g>ରେ ସାଇନ ଇନ କରିବାକୁ ପାସୱାର୍ଡ ସେଭ କରିବେ?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ସାଇନ-ଇନର ସୂଚନା ସେଭ କରିବେ?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ଏକ ପାସକୀ ତିଆରି କରିବାକୁ ଆପଣଙ୍କ ସ୍କ୍ରିନ ଲକ ବ୍ୟବହାର କରିବେ?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ଏକ ପାସୱାର୍ଡ ତିଆରି କରିବାକୁ ଆପଣଙ୍କ ସ୍କ୍ରିନ ଲକ ବ୍ୟବହାର କରିବେ?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ସାଇନ ଇନ ସୂଚନା ସେଭ କରିବାକୁ ଆପଣଙ୍କ ସ୍କ୍ରିନ ଲକ ବ୍ୟବହାର କରିବେ?"</string> <string name="passkey" msgid="632353688396759522">"ପାସକୀ"</string> <string name="password" msgid="6738570945182936667">"ପାସୱାର୍ଡ"</string> <string name="passkeys" msgid="5733880786866559847">"ପାସକୀଗୁଡ଼ିକ"</string> diff --git a/packages/CredentialManager/res/values-pa/strings.xml b/packages/CredentialManager/res/values-pa/strings.xml index d23d20956b11..4cf8e17172c0 100644 --- a/packages/CredentialManager/res/values-pa/strings.xml +++ b/packages/CredentialManager/res/values-pa/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਵਿੱਚ ਸਾਈਨ-ਇਨ ਕਰਨ ਲਈ ਪਾਸਕੀ ਬਣਾਉਣੀ ਹੈ?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਵਿੱਚ ਸਾਈਨ-ਇਨ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਸਾਈਨ-ਇਨ ਜਾਣਕਾਰੀ ਰੱਖਿਅਤ ਕਰਨੀ ਹੈ?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"ਪਾਸਕੀ"</string> <string name="password" msgid="6738570945182936667">"ਪਾਸਵਰਡ"</string> <string name="passkeys" msgid="5733880786866559847">"ਪਾਸਕੀਆਂ"</string> diff --git a/packages/CredentialManager/res/values-pl/strings.xml b/packages/CredentialManager/res/values-pl/strings.xml index 5fa26b49a9e6..eca8699d0a55 100644 --- a/packages/CredentialManager/res/values-pl/strings.xml +++ b/packages/CredentialManager/res/values-pl/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Utworzyć klucz dostępu do logowania w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Zapisać hasło do logowania w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Zapisać dane używane do logowania w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Użyć metody odblokowania ekranu do utworzenia klucza dostępu do aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Użyć metody odblokowania ekranu do utworzenia hasła do aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Użyć metody odblokowania ekranu do zapisania danych logowania do aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"klucz"</string> <string name="password" msgid="6738570945182936667">"hasło"</string> <string name="passkeys" msgid="5733880786866559847">"klucze dostępu"</string> diff --git a/packages/CredentialManager/res/values-pt-rBR/strings.xml b/packages/CredentialManager/res/values-pt-rBR/strings.xml index 994bc553102d..e49387143fef 100644 --- a/packages/CredentialManager/res/values-pt-rBR/strings.xml +++ b/packages/CredentialManager/res/values-pt-rBR/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Criar chave de acesso para fazer login no app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Salvar senha para fazer login no app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Salvar informações de login do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"chave de acesso"</string> <string name="password" msgid="6738570945182936667">"senha"</string> <string name="passkeys" msgid="5733880786866559847">"chaves de acesso"</string> diff --git a/packages/CredentialManager/res/values-pt-rPT/strings.xml b/packages/CredentialManager/res/values-pt-rPT/strings.xml index 26c6491ad591..8b6b2b2e6450 100644 --- a/packages/CredentialManager/res/values-pt-rPT/strings.xml +++ b/packages/CredentialManager/res/values-pt-rPT/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Criar a chave de acesso para iniciar sessão na app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Guardar a palavra-passe para iniciar sessão na app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Guardar as informações de início de sessão da app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Usar o bloqueio de ecrã para criar uma chave de acesso para a app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Usar o bloqueio de ecrã para criar uma palavra-passe para a app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Usar o bloqueio de ecrã para guardar as informações de início de sessão para a app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"chave de acesso"</string> <string name="password" msgid="6738570945182936667">"palavra-passe"</string> <string name="passkeys" msgid="5733880786866559847">"chaves de acesso"</string> diff --git a/packages/CredentialManager/res/values-pt/strings.xml b/packages/CredentialManager/res/values-pt/strings.xml index 994bc553102d..e49387143fef 100644 --- a/packages/CredentialManager/res/values-pt/strings.xml +++ b/packages/CredentialManager/res/values-pt/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Criar chave de acesso para fazer login no app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Salvar senha para fazer login no app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Salvar informações de login do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"chave de acesso"</string> <string name="password" msgid="6738570945182936667">"senha"</string> <string name="passkeys" msgid="5733880786866559847">"chaves de acesso"</string> diff --git a/packages/CredentialManager/res/values-ro/strings.xml b/packages/CredentialManager/res/values-ro/strings.xml index 342b6ab77e8b..87b551b62f22 100644 --- a/packages/CredentialManager/res/values-ro/strings.xml +++ b/packages/CredentialManager/res/values-ro/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Creezi o cheie de acces pentru a te conecta la <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Salvezi parola pentru a te conecta la <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Salvezi informațiile de conectare pentru <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"cheia de acces"</string> <string name="password" msgid="6738570945182936667">"parolă"</string> <string name="passkeys" msgid="5733880786866559847">"cheile de acces"</string> @@ -89,7 +95,7 @@ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"Atinge pentru a debloca"</string> <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="8131725029983174901">"Fără informații de conectare"</string> <string name="no_sign_in_info_in" msgid="2641118151920288356">"Nu există informații de conectare în contul <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Gestionează acreditările"</string> + <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Gestionează conectările"</string> <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"De pe alt dispozitiv"</string> <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Folosește alt dispozitiv"</string> <string name="request_cancelled_by" msgid="3735222326886267820">"Solicitare anulată de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> diff --git a/packages/CredentialManager/res/values-ru/strings.xml b/packages/CredentialManager/res/values-ru/strings.xml index e4726957d650..c9c8dcccfbf0 100644 --- a/packages/CredentialManager/res/values-ru/strings.xml +++ b/packages/CredentialManager/res/values-ru/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Создать ключ доступа для входа в приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Сохранить пароль для входа в приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Сохранить данные для входа в приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Использовать способ разблокировки экрана, чтобы создать ключ доступа для приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Использовать способ разблокировки экрана, чтобы создать пароль для приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Использовать способ разблокировки экрана, чтобы сохранить данные для входа в приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> <string name="passkey" msgid="632353688396759522">"ключ доступа"</string> <string name="password" msgid="6738570945182936667">"пароль"</string> <string name="passkeys" msgid="5733880786866559847">"ключи доступа"</string> diff --git a/packages/CredentialManager/res/values-si/strings.xml b/packages/CredentialManager/res/values-si/strings.xml index ce0b9cd048eb..ab78c062bba1 100644 --- a/packages/CredentialManager/res/values-si/strings.xml +++ b/packages/CredentialManager/res/values-si/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> වෙත පුරනය වීමට මුරයතුරක් තනන්න ද?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> වෙත පුරනය වීමට මුරපදය සුරකින්න ද?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා පුරනය වීමේ තතු සුරකින්න ද?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"මුරයතුර"</string> <string name="password" msgid="6738570945182936667">"මුරපදය"</string> <string name="passkeys" msgid="5733880786866559847">"මුරයතුරු"</string> diff --git a/packages/CredentialManager/res/values-sk/strings.xml b/packages/CredentialManager/res/values-sk/strings.xml index 62a2e690edae..c2626eaebeca 100644 --- a/packages/CredentialManager/res/values-sk/strings.xml +++ b/packages/CredentialManager/res/values-sk/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Chcete vytvoriť prístupový kľúč na prihlasovanie do aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Chcete uložiť heslo na prihlasovanie do aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Chcete uložiť prihlasovacie údaje pre aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Chcete pomocou zámky obrazovky vytvoriť prístupový kľúč pre <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Chcete pomocou zámky obrazovky vytvoriť heslo pre <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Chcete pomocou zámky obrazovky uložiť prihlasovacie údaje pre <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"prístupový kľúč"</string> <string name="password" msgid="6738570945182936667">"heslo"</string> <string name="passkeys" msgid="5733880786866559847">"prístupové kľúče"</string> diff --git a/packages/CredentialManager/res/values-sl/strings.xml b/packages/CredentialManager/res/values-sl/strings.xml index d2aaf685032a..79c8c72d2f94 100644 --- a/packages/CredentialManager/res/values-sl/strings.xml +++ b/packages/CredentialManager/res/values-sl/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Želite ustvariti ključ za dostop za prijavo v aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Želite shraniti geslo za prijavo v aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Želite shraniti podatke za prijavo za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Želite uporabiti zaklepanje zaslona za ustvarjanje ključa za dostop za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Želite uporabiti zaklepanje zaslona za ustvarjanje gesla za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Želite uporabiti zaklepanje zaslona za shranjevanje podatkov za prijavo za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"ključ za dostop"</string> <string name="password" msgid="6738570945182936667">"geslo"</string> <string name="passkeys" msgid="5733880786866559847">"ključi za dostop"</string> diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml index f31d16aabe1e..8038cea71aed 100644 --- a/packages/CredentialManager/res/values-sq/strings.xml +++ b/packages/CredentialManager/res/values-sq/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Të krijohet një çelës kalimi për t\'u identifikuar në <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Të ruhet fjalëkalimi për t\'u identifikuar në <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Të ruhen informacionet e identifikimit për <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"çelësin e kalimit"</string> <string name="password" msgid="6738570945182936667">"fjalëkalimi"</string> <string name="passkeys" msgid="5733880786866559847">"çelësat e kalimit"</string> @@ -89,7 +95,7 @@ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"Trokit për të shkyçur"</string> <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="8131725029983174901">"Nuk ka informacione për identifikimin"</string> <string name="no_sign_in_info_in" msgid="2641118151920288356">"Nuk ka informacione regjistrimi në <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Identifikimet e menaxhimit"</string> + <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Menaxho identifikimet"</string> <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Nga një pajisje tjetër"</string> <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Përdor një pajisje tjetër"</string> <string name="request_cancelled_by" msgid="3735222326886267820">"Kërkesa u anulua nga <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> diff --git a/packages/CredentialManager/res/values-sr/strings.xml b/packages/CredentialManager/res/values-sr/strings.xml index e68a20cc4f3b..58110aacdc36 100644 --- a/packages/CredentialManager/res/values-sr/strings.xml +++ b/packages/CredentialManager/res/values-sr/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Желите да направите приступни кључ да бисте се пријавили у <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Желите да сачувате лозинку да бисте се пријавили у <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Желите да сачувате податке за пријављивање за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Желите да користите откључавање екрана да бисте направили приступни кључ за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Желите да користите откључавање екрана да бисте направили лозинку за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Желите да користите откључавање екрана да бисте сачували податке за пријављивање за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"приступни кôд"</string> <string name="password" msgid="6738570945182936667">"лозинка"</string> <string name="passkeys" msgid="5733880786866559847">"приступни кодови"</string> diff --git a/packages/CredentialManager/res/values-sv/strings.xml b/packages/CredentialManager/res/values-sv/strings.xml index e18fea1049ea..6379df248b8d 100644 --- a/packages/CredentialManager/res/values-sv/strings.xml +++ b/packages/CredentialManager/res/values-sv/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vill du skapa en nyckel för att logga in i <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vill du spara lösenordet för att logga in i <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vill du spara inloggningsuppgifterna för <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"nyckel"</string> <string name="password" msgid="6738570945182936667">"lösenord"</string> <string name="passkeys" msgid="5733880786866559847">"nycklar"</string> diff --git a/packages/CredentialManager/res/values-sw/strings.xml b/packages/CredentialManager/res/values-sw/strings.xml index 65672d5696ef..888b01c7550c 100644 --- a/packages/CredentialManager/res/values-sw/strings.xml +++ b/packages/CredentialManager/res/values-sw/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Ungependa kubuni ufunguo wa siri wa kuingia katika akaunti ya <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Ungependa kuhifadhi nenosiri la kuingia katika akaunti ya <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Ungependa kuhifadhi maelezo ya kuingia katika akaunti ya <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Ungependa kutumia mbinu yako ya kufunga skrini kubuni ufunguo wa siri wa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Ungependa kutumia mbinu yako ya kufunga skrini kubuni nenosiri la <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Ungependa kutumia mbinu yako ya kufunga skrini kuhifadhi maelezo ya kuingia katika akaunti ya <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"ufunguo wa siri"</string> <string name="password" msgid="6738570945182936667">"nenosiri"</string> <string name="passkeys" msgid="5733880786866559847">"funguo za siri"</string> diff --git a/packages/CredentialManager/res/values-ta/strings.xml b/packages/CredentialManager/res/values-ta/strings.xml index 49d17101abb2..008baaba0ec9 100644 --- a/packages/CredentialManager/res/values-ta/strings.xml +++ b/packages/CredentialManager/res/values-ta/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸில் உள்நுழைய கடவுச்சாவியை உருவாக்கவா?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸில் உள்நுழைய கடவுச்சொல்லைச் சேமிக்கவா?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸுக்கான உள்நுழைவுத் தகவலைச் சேமிக்கவா?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"கடவுச்சாவி"</string> <string name="password" msgid="6738570945182936667">"கடவுச்சொல்"</string> <string name="passkeys" msgid="5733880786866559847">"கடவுச்சாவிகள்"</string> diff --git a/packages/CredentialManager/res/values-te/strings.xml b/packages/CredentialManager/res/values-te/strings.xml index 742a42279169..e2e362bb37aa 100644 --- a/packages/CredentialManager/res/values-te/strings.xml +++ b/packages/CredentialManager/res/values-te/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g>కు సైన్ ఇన్ చేయడానికి పాస్-కీని క్రియేట్ చేయాలా?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g>కు సైన్ ఇన్ చేయడానికి పాస్వర్డ్ను సేవ్ చేయాలా?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం సైన్ ఇన్ సమాచారాన్ని సేవ్ చేయాలా?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"మీ స్క్రీన్ లాక్ను ఉపయోగించి <xliff:g id="APP_NAME">%1$s</xliff:g>కు పాస్-కీని క్రియేట్ చేయాలా?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"మీ స్క్రీన్ లాక్ను ఉపయోగించి <xliff:g id="APP_NAME">%1$s</xliff:g>కు పాస్వర్డ్ను క్రియేట్ చేయాలా?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"మీ స్క్రీన్ లాక్ను ఉపయోగించి <xliff:g id="APP_NAME">%1$s</xliff:g>కు సంబంధించిన సైన్-ఇన్ సమాచారాన్ని సేవ్ చేయాలా?"</string> <string name="passkey" msgid="632353688396759522">"పాస్-కీ"</string> <string name="password" msgid="6738570945182936667">"పాస్వర్డ్"</string> <string name="passkeys" msgid="5733880786866559847">"పాస్-కీలు"</string> diff --git a/packages/CredentialManager/res/values-th/strings.xml b/packages/CredentialManager/res/values-th/strings.xml index 3f9de268ecf4..876371a9c7f5 100644 --- a/packages/CredentialManager/res/values-th/strings.xml +++ b/packages/CredentialManager/res/values-th/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"สร้างพาสคีย์เพื่อลงชื่อเข้าใช้ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"บันทึกรหัสผ่านเพื่อลงชื่อเข้าใช้ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"บันทึกข้อมูลการลงชื่อเข้าใช้สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"ต้องการใช้ฟีเจอร์ล็อกหน้าจอเพื่อสร้างพาสคีย์สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ใช่ไหม"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"ต้องการใช้ฟีเจอร์ล็อกหน้าจอเพื่อสร้างรหัสผ่านสำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ใช่ไหม"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"ต้องการใช้ฟีเจอร์ล็อกหน้าจอเพื่อบันทึกข้อมูลการลงชื่อเข้าใช้สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ใช่ไหม"</string> <string name="passkey" msgid="632353688396759522">"พาสคีย์"</string> <string name="password" msgid="6738570945182936667">"รหัสผ่าน"</string> <string name="passkeys" msgid="5733880786866559847">"พาสคีย์"</string> diff --git a/packages/CredentialManager/res/values-tl/strings.xml b/packages/CredentialManager/res/values-tl/strings.xml index 659c1ec031b0..163e93aaf4f9 100644 --- a/packages/CredentialManager/res/values-tl/strings.xml +++ b/packages/CredentialManager/res/values-tl/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Gumawa ng passkey para mag-sign in sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"I-save ang password para mag-sign in sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"I-save ang impormasyon sa pag-sign in para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"Gamitin ang iyong lock ng screen para gumawa ng passkey para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"Gamitin ang iyong lock ng screen para gumawa ng password para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"Gamitin ang iyong lock ng screen para mag-save ng impormasyon sa pag-sign in para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> <string name="passkeys" msgid="5733880786866559847">"mga passkey"</string> diff --git a/packages/CredentialManager/res/values-tr/strings.xml b/packages/CredentialManager/res/values-tr/strings.xml index 5139a6789f7a..96a1c0083fa5 100644 --- a/packages/CredentialManager/res/values-tr/strings.xml +++ b/packages/CredentialManager/res/values-tr/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında oturum açmak için geçiş anahtarı oluşturulsun mu?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında oturum açmak için şifre kaydedilsin mi?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> için oturum açma bilgileri kaydedilsin mi?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"Geçiş anahtarı"</string> <string name="password" msgid="6738570945182936667">"Şifre"</string> <string name="passkeys" msgid="5733880786866559847">"Geçiş anahtarlarınızın"</string> diff --git a/packages/CredentialManager/res/values-uk/strings.xml b/packages/CredentialManager/res/values-uk/strings.xml index 62eac9afc737..b867903855a5 100644 --- a/packages/CredentialManager/res/values-uk/strings.xml +++ b/packages/CredentialManager/res/values-uk/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Створити ключ доступу для входу в додаток <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Зберегти пароль для входу в додаток <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Зберегти дані для входу для додатка <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"ключ доступу"</string> <string name="password" msgid="6738570945182936667">"пароль"</string> <string name="passkeys" msgid="5733880786866559847">"ключі доступу"</string> diff --git a/packages/CredentialManager/res/values-ur/strings.xml b/packages/CredentialManager/res/values-ur/strings.xml index 9fad27318f80..67cf20ae7ae2 100644 --- a/packages/CredentialManager/res/values-ur/strings.xml +++ b/packages/CredentialManager/res/values-ur/strings.xml @@ -42,6 +42,9 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> میں سائن ان کرنے کیلئے پاس کی تخلیق کریں؟"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> میں سائن ان کرنے کیلئے پاس ورڈ محفوظ کریں؟"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے سائن ان کی معلومات محفوظ کریں؟"</string> + <string name="choose_create_single_tap_passkey_title" msgid="3872793514041774218">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے پاس کی بنانے کے لیے اپنا اسکرین لاک استعمال کریں؟"</string> + <string name="choose_create_single_tap_password_title" msgid="5231871886818921622">"<xliff:g id="APP_NAME">%1$s</xliff:g> کا پاس ورڈ بنانے کے لیے اپنا اسکرین لاک استعمال کریں؟"</string> + <string name="choose_create_single_tap_sign_in_title" msgid="256498714574099587">"<xliff:g id="APP_NAME">%1$s</xliff:g> کی سائن ان کی معلومات محفوظ کرنے کے لیے اپنا اسکرین لاک استعمال کریں؟"</string> <string name="passkey" msgid="632353688396759522">"پاس کی"</string> <string name="password" msgid="6738570945182936667">"پاس ورڈ"</string> <string name="passkeys" msgid="5733880786866559847">"پاس کیز"</string> diff --git a/packages/CredentialManager/res/values-uz/strings.xml b/packages/CredentialManager/res/values-uz/strings.xml index a3d20250a249..796bd87e76e6 100644 --- a/packages/CredentialManager/res/values-uz/strings.xml +++ b/packages/CredentialManager/res/values-uz/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga kirish uchun kirish kaliti yaratilsinmi?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga kirish uchun parol saqlansinmi?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun kirish maʼlumoti saqlansinmi?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"kalit"</string> <string name="password" msgid="6738570945182936667">"parol"</string> <string name="passkeys" msgid="5733880786866559847">"kalitlar"</string> diff --git a/packages/CredentialManager/res/values-vi/strings.xml b/packages/CredentialManager/res/values-vi/strings.xml index da04efd82896..59bd541061b4 100644 --- a/packages/CredentialManager/res/values-vi/strings.xml +++ b/packages/CredentialManager/res/values-vi/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Tạo khoá truy cập để đăng nhập vào <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Lưu mật khẩu để đăng nhập vào <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Lưu thông tin đăng nhập cho <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"khoá đăng nhập"</string> <string name="password" msgid="6738570945182936667">"mật khẩu"</string> <string name="passkeys" msgid="5733880786866559847">"khoá truy cập"</string> @@ -82,7 +88,7 @@ <string name="get_dialog_use_saved_passkey_for" msgid="4618100798664888512">"Đăng nhập bằng cách khác"</string> <string name="snackbar_action" msgid="37373514216505085">"Xem các lựa chọn"</string> <string name="get_dialog_button_label_continue" msgid="6446201694794283870">"Tiếp tục"</string> - <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Tuỳ chọn đăng nhập"</string> + <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Lựa chọn đăng nhập"</string> <string name="button_label_view_more" msgid="3429098227286495651">"Xem thêm"</string> <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Cho <xliff:g id="USERNAME">%1$s</xliff:g>"</string> <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Trình quản lý mật khẩu đã khoá"</string> diff --git a/packages/CredentialManager/res/values-zh-rCN/strings.xml b/packages/CredentialManager/res/values-zh-rCN/strings.xml index 968e978801d4..e9ac45a73088 100644 --- a/packages/CredentialManager/res/values-zh-rCN/strings.xml +++ b/packages/CredentialManager/res/values-zh-rCN/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"要创建通行密钥以便登录“<xliff:g id="APP_NAME">%1$s</xliff:g>”吗?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"要保存密码以便登录“<xliff:g id="APP_NAME">%1$s</xliff:g>”吗?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"要保存“<xliff:g id="APP_NAME">%1$s</xliff:g>”的登录信息吗?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"通行密钥"</string> <string name="password" msgid="6738570945182936667">"密码"</string> <string name="passkeys" msgid="5733880786866559847">"通行密钥"</string> diff --git a/packages/CredentialManager/res/values-zh-rHK/strings.xml b/packages/CredentialManager/res/values-zh-rHK/strings.xml index 7a375c9c7aea..77855b51c7c4 100644 --- a/packages/CredentialManager/res/values-zh-rHK/strings.xml +++ b/packages/CredentialManager/res/values-zh-rHK/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"要建立密鑰以登入 <xliff:g id="APP_NAME">%1$s</xliff:g> 嗎?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"要儲存密碼以登入 <xliff:g id="APP_NAME">%1$s</xliff:g> 嗎?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"要儲存 <xliff:g id="APP_NAME">%1$s</xliff:g> 的登入資料嗎?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"密鑰"</string> <string name="password" msgid="6738570945182936667">"密碼"</string> <string name="passkeys" msgid="5733880786866559847">"密鑰"</string> diff --git a/packages/CredentialManager/res/values-zh-rTW/strings.xml b/packages/CredentialManager/res/values-zh-rTW/strings.xml index 029908872a71..520d9a8049e7 100644 --- a/packages/CredentialManager/res/values-zh-rTW/strings.xml +++ b/packages/CredentialManager/res/values-zh-rTW/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"要建立用於登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」的密碼金鑰嗎?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"要儲存用於登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」的密碼嗎?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"要儲存「<xliff:g id="APP_NAME">%1$s</xliff:g>」的登入資訊嗎?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"密碼金鑰"</string> <string name="password" msgid="6738570945182936667">"密碼"</string> <string name="passkeys" msgid="5733880786866559847">"密碼金鑰"</string> diff --git a/packages/CredentialManager/res/values-zu/strings.xml b/packages/CredentialManager/res/values-zu/strings.xml index 4f888f42b686..8cb25cb2ce9c 100644 --- a/packages/CredentialManager/res/values-zu/strings.xml +++ b/packages/CredentialManager/res/values-zu/strings.xml @@ -42,6 +42,12 @@ <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Sungula ukhiye wokudlula ukuze ungene ngemvume ku-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_password_title" msgid="4481366993598649224">"Londoloza iphasiwedi ukuze ungene ngemvume ku-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Londoloza ulwazi lokungena lwe-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_single_tap_passkey_title (3872793514041774218) --> + <skip /> + <!-- no translation found for choose_create_single_tap_password_title (5231871886818921622) --> + <skip /> + <!-- no translation found for choose_create_single_tap_sign_in_title (256498714574099587) --> + <skip /> <string name="passkey" msgid="632353688396759522">"ukhiye wokudlula"</string> <string name="password" msgid="6738570945182936667">"iphasiwedi"</string> <string name="passkeys" msgid="5733880786866559847">"okhiye bokudlula"</string> diff --git a/packages/CredentialManager/wear/res/values/colors.xml b/packages/CredentialManager/wear/res/values/colors.xml new file mode 100644 index 000000000000..bf10bb3d7178 --- /dev/null +++ b/packages/CredentialManager/wear/res/values/colors.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources> + <color name="wear_material_almond">#FFFCF7EB</color> + <color name="wear_material_almond_dark">#FF262523</color> +</resources>
\ No newline at end of file diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/AccountRow.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/AccountRow.kt index 8b19e1b659d2..3088fed83c02 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/AccountRow.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/AccountRow.kt @@ -21,35 +21,25 @@ import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.wear.compose.material.MaterialTheme -import androidx.wear.compose.material.Text +import com.android.credentialmanager.common.ui.components.WearDisplayNameText +import com.android.credentialmanager.common.ui.components.WearUsernameText import com.google.android.horologist.compose.tools.WearPreview @Composable fun AccountRow( primaryText: String, secondaryText: String? = null, - modifier: Modifier = Modifier, ) { - Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) { - Text( + Column(modifier = Modifier.padding(bottom = 12.dp), + horizontalAlignment = Alignment.CenterHorizontally) { + WearDisplayNameText( text = primaryText, - color = Color(0xFFE6FF7B), - overflow = TextOverflow.Ellipsis, - maxLines = 1, - style = MaterialTheme.typography.title2 ) if (secondaryText != null) { - Text( + WearUsernameText( text = secondaryText, - modifier = Modifier.padding(top = 7.dp), - color = Color(0xFFCAC5BC), - overflow = TextOverflow.Ellipsis, - maxLines = 2, - style = MaterialTheme.typography.body1, + modifier = Modifier.padding(top = 8.dp) ) } } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt index 8e5a8666621f..18c9f3102409 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt @@ -22,12 +22,9 @@ import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.wear.compose.material.Chip @@ -35,11 +32,13 @@ import androidx.core.graphics.drawable.toBitmap import androidx.wear.compose.material.ChipColors import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.text.style.TextAlign import androidx.wear.compose.material.ChipDefaults -import androidx.wear.compose.material.Text import com.android.credentialmanager.R +import com.android.credentialmanager.common.ui.components.WearButtonText +import com.android.credentialmanager.common.ui.components.WearSecondaryLabel import com.android.credentialmanager.model.get.AuthenticationEntryInfo -import com.android.credentialmanager.ui.components.CredentialsScreenChip.TOPPADDING /* Used as credential suggestion or user action chip. */ @Composable @@ -49,36 +48,62 @@ fun CredentialsScreenChip( secondaryLabel: String? = null, icon: Drawable? = null, isAuthenticationEntryLocked: Boolean = false, + textAlign: TextAlign = TextAlign.Center, modifier: Modifier = Modifier, - colors: ChipColors = ChipDefaults.secondaryChipColors(), + colors: ChipColors = ChipDefaults.secondaryChipColors() ) { + return CredentialsScreenChip( + onClick, + text = { + WearButtonText( + text = label, + textAlign = textAlign, + maxLines = if (secondaryLabel != null) 1 else 2 + ) + }, + secondaryLabel, + icon, + isAuthenticationEntryLocked, + modifier, + colors + ) +} + + + +/* Used as credential suggestion or user action chip. */ +@Composable +fun CredentialsScreenChip( + onClick: () -> Unit, + text: @Composable () -> Unit, + secondaryLabel: String? = null, + icon: Drawable? = null, + isAuthenticationEntryLocked: Boolean = false, + modifier: Modifier = Modifier, + colors: ChipColors = + ChipDefaults.chipColors(backgroundColor = colorResource(R.color.wear_material_almond)), + ) { val labelParam: (@Composable RowScope.() -> Unit) = { - Text( - text = label, - overflow = TextOverflow.Ellipsis, - maxLines = if (secondaryLabel != null) 1 else 2, - ) + text() } val secondaryLabelParam: (@Composable RowScope.() -> Unit)? = secondaryLabel?.let { { Row { - Text( + WearSecondaryLabel( text = secondaryLabel, - overflow = TextOverflow.Ellipsis, - maxLines = 1, ) if (isAuthenticationEntryLocked) - // TODO(b/324465527) change this to lock icon and correct size once figma mocks are - // updated + // TODO(b/324465527) change this to lock icon and correct size once figma mocks are + // updated Icon( bitmap = checkNotNull(icon?.toBitmap()?.asImageBitmap()), // Decorative purpose only. contentDescription = null, - modifier = Modifier.size(20.dp), + modifier = Modifier.size(10.dp), tint = Color.Unspecified ) } @@ -92,7 +117,7 @@ fun CredentialsScreenChip( bitmap = it, // Decorative purpose only. contentDescription = null, - modifier = Modifier.size(32.dp), + modifier = Modifier.size(24.dp), tint = Color.Unspecified ) } @@ -117,9 +142,6 @@ fun CredentialsScreenChipPreview() { onClick = { }, secondaryLabel = "beckett_bakery@gmail.com", icon = null, - modifier = Modifier - .clipToBounds() - .padding(top = 2.dp) ) } @@ -127,9 +149,8 @@ fun CredentialsScreenChipPreview() { fun SignInOptionsChip(onClick: () -> Unit) { CredentialsScreenChip( label = stringResource(R.string.dialog_sign_in_options_button), + textAlign = TextAlign.Start, onClick = onClick, - modifier = Modifier - .padding(top = TOPPADDING) ) } @@ -142,11 +163,16 @@ fun SignInOptionsChipPreview() { @Composable fun ContinueChip(onClick: () -> Unit) { CredentialsScreenChip( - label = stringResource(R.string.dialog_continue_button), onClick = onClick, - modifier = Modifier - .padding(top = TOPPADDING), - colors = ChipDefaults.primaryChipColors(), + text = { + WearButtonText( + text = stringResource(R.string.dialog_continue_button), + textAlign = TextAlign.Center, + color = colorResource(R.color.wear_material_almond_dark), + ) + }, + colors = + ChipDefaults.chipColors(backgroundColor = colorResource(R.color.wear_material_almond)), ) } @@ -161,21 +187,8 @@ fun DismissChip(onClick: () -> Unit) { CredentialsScreenChip( label = stringResource(R.string.dialog_dismiss_button), onClick = onClick, - modifier = Modifier - .padding(top = TOPPADDING), - ) -} - -@Composable -fun SignInOnPhoneChip(onClick: () -> Unit) { - CredentialsScreenChip( - label = stringResource(R.string.sign_in_on_phone_button), - onClick = onClick, - modifier = Modifier - .padding(top = TOPPADDING), ) } - @Composable fun LockedProviderChip( authenticationEntryInfo: AuthenticationEntryInfo, @@ -191,9 +204,9 @@ fun LockedProviderChip( label = authenticationEntryInfo.title, icon = authenticationEntryInfo.icon, secondaryLabel = secondaryLabel, + textAlign = TextAlign.Start, isAuthenticationEntryLocked = !authenticationEntryInfo.isUnlockedAndEmpty, onClick = onClick, - modifier = Modifier.padding(top = TOPPADDING), ) } @@ -203,7 +216,3 @@ fun DismissChipPreview() { DismissChip({}) } -private object CredentialsScreenChip { - val TOPPADDING = 8.dp -} - diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/PasswordRow.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/PasswordRow.kt index 97900b723bc3..62e1c8501d7a 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/PasswordRow.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/PasswordRow.kt @@ -21,33 +21,22 @@ import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.wear.compose.material.MaterialTheme -import androidx.wear.compose.material.Text +import com.android.credentialmanager.common.ui.components.WearDisplayNameText +import com.android.credentialmanager.common.ui.components.WearUsernameText import com.google.android.horologist.compose.tools.WearPreview @Composable fun PasswordRow( email: String, - modifier: Modifier = Modifier, ) { - Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) { - Text( + Column(modifier = Modifier.padding(bottom = 12.dp), + horizontalAlignment = Alignment.CenterHorizontally) { + WearDisplayNameText( text = email, - color = Color(0xFFE6FF7B), - overflow = TextOverflow.Ellipsis, - maxLines = 2, - style = MaterialTheme.typography.title2 ) - Text( - text = "••••••••••••••", - modifier = Modifier.padding(top = 7.dp), - color = Color(0xFFCAC5BC), - overflow = TextOverflow.Ellipsis, - maxLines = 1, - style = MaterialTheme.typography.body1, + WearUsernameText( + text = "••••••••••••••" ) } } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/SignInHeader.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/SignInHeader.kt index 423662c30d6e..437a699abcee 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/SignInHeader.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/SignInHeader.kt @@ -18,49 +18,44 @@ package com.android.credentialmanager.ui.components import android.graphics.drawable.Drawable import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size +import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.unit.dp import androidx.core.graphics.drawable.toBitmap -import androidx.wear.compose.material.Text -import androidx.compose.ui.graphics.Color -import androidx.compose.material3.Icon -import androidx.wear.compose.material.MaterialTheme as WearMaterialTheme -import androidx.compose.ui.text.style.TextAlign +import com.android.credentialmanager.common.ui.components.WearTitleText /* Used as header across Credential Selector screens. */ @Composable fun SignInHeader( icon: Drawable?, title: String, - modifier: Modifier = Modifier, ) { Column( - modifier = modifier, + modifier = Modifier, horizontalAlignment = Alignment.CenterHorizontally ) { if (icon != null) { Icon( bitmap = icon.toBitmap().asImageBitmap(), - modifier = Modifier.size(32.dp), + modifier = Modifier.size(24.dp), // Decorative purpose only. contentDescription = null, tint = Color.Unspecified, ) } + Spacer(modifier = Modifier.size(8.dp)) - Text( + WearTitleText( text = title, - textAlign = TextAlign.Center, - modifier = Modifier - .padding(top = 6.dp) - .padding(horizontal = 10.dp), - style = WearMaterialTheme.typography.title3 ) + + Spacer(modifier = Modifier.size(12.dp)) } } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Spacers.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Spacers.kt new file mode 100644 index 000000000000..c87f176bc06c --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Spacers.kt @@ -0,0 +1,39 @@ +/* + * 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.credentialmanager.ui.components + +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +/** + * Space beneath all elements of screen + */ +@Composable +fun BottomSpacer() { + Spacer(modifier = Modifier.size(40.dp)) + } + +/** + * Usual space between Credential Screen Chips + */ +@Composable +fun CredentialsScreenChipSpacer() { + Spacer(modifier = Modifier.size(4.dp)) +}
\ No newline at end of file diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Texts.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Texts.kt new file mode 100644 index 000000000000..e7a854f2a4d4 --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Texts.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.credentialmanager.common.ui.components + +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextLayoutResult +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import com.android.compose.theme.LocalAndroidColorScheme +import androidx.wear.compose.material.MaterialTheme as WearMaterialTheme + +@Composable +fun WearTitleText(text: String, modifier: Modifier = Modifier) { + Text( + modifier = modifier.wrapContentSize(), + text = text, + color = LocalAndroidColorScheme.current.onSurface, + textAlign = TextAlign.Center, + style = WearMaterialTheme.typography.title3, + ) +} + +@Composable +fun WearDisplayNameText(text: String, modifier: Modifier = Modifier) { + Text( + modifier = modifier.wrapContentSize(), + text = text, + color = LocalAndroidColorScheme.current.onSurface, + textAlign = TextAlign.Center, + overflow = TextOverflow.Ellipsis, + maxLines = 2, + style = WearMaterialTheme.typography.title2, + ) +} + +@Composable +fun WearUsernameText( + text: String, + modifier: Modifier = Modifier, + onTextLayout: (TextLayoutResult) -> Unit = {}, +) { + Text( + modifier = modifier.padding(start = 8.dp, end = 8.dp).wrapContentSize(), + text = text, + color = LocalAndroidColorScheme.current.onSurfaceVariant, + style = WearMaterialTheme.typography.caption1, + overflow = TextOverflow.Ellipsis, + textAlign = TextAlign.Center, + maxLines = 2, + onTextLayout = onTextLayout, + ) +} + +@Composable +fun WearButtonText( + text: String, + textAlign: TextAlign, + maxLines: Int = 1, + modifier: Modifier = Modifier, + color: Color = LocalAndroidColorScheme.current.onSurface, + onTextLayout: (TextLayoutResult) -> Unit = {}, +) { + Text( + modifier = modifier.wrapContentSize(), + text = text, + color = color, + style = WearMaterialTheme.typography.button, + overflow = TextOverflow.Ellipsis, + textAlign = textAlign, + maxLines = maxLines, + onTextLayout = onTextLayout, + ) +} + +@Composable +fun WearSecondaryLabel( + text: String, + modifier: Modifier = Modifier, + onTextLayout: (TextLayoutResult) -> Unit = {}, +) { + Text( + modifier = modifier.wrapContentSize(), + text = text, + color = LocalAndroidColorScheme.current.onSurfaceVariant, + style = WearMaterialTheme.typography.button, + overflow = TextOverflow.Ellipsis, + textAlign = TextAlign.Start, + maxLines = 1, + onTextLayout = onTextLayout, + ) +} diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/LoadingScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/LoadingScreen.kt index b3ab0c4212db..0b07643056da 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/LoadingScreen.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/LoadingScreen.kt @@ -17,12 +17,9 @@ package com.android.credentialmanager.ui.screens import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier @Composable -fun LoadingScreen( - modifier: Modifier = Modifier -) { +fun LoadingScreen() { // Don't display anything, assuming that there should be minimal latency // to parse the Credential Manager intent and define the state of the // app. If latency is big, then a "loading" screen should be displayed diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt index d54103cd66e8..a545e48eec0f 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt @@ -15,20 +15,21 @@ */ package com.android.credentialmanager.ui.screens.multiple +import com.android.credentialmanager.ui.components.CredentialsScreenChip import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.wear.compose.material.MaterialTheme -import androidx.wear.compose.material.Text -import com.android.credentialmanager.ui.components.SignInHeader import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry import com.android.credentialmanager.FlowEngine import com.android.credentialmanager.R +import com.android.credentialmanager.common.ui.components.WearButtonText +import com.android.credentialmanager.common.ui.components.WearDisplayNameText import com.android.credentialmanager.model.get.CredentialEntryInfo -import com.android.credentialmanager.ui.components.CredentialsScreenChip +import com.android.credentialmanager.ui.components.CredentialsScreenChipSpacer import com.google.android.horologist.annotations.ExperimentalHorologistApi import com.google.android.horologist.compose.layout.ScalingLazyColumn import com.google.android.horologist.compose.layout.ScalingLazyColumnState @@ -55,20 +56,18 @@ fun MultiCredentialsFlattenScreen( ) { item { // make this credential specific if all credentials are same - SignInHeader( - icon = null, - title = stringResource(R.string.sign_in_options_title), + WearButtonText( + text = stringResource(R.string.sign_in_options_title), + textAlign = TextAlign.Start, ) } credentialSelectorUiState.accounts.forEach { userNameEntries -> item { - Text( + WearDisplayNameText( text = userNameEntries.userName, - modifier = Modifier - .padding(top = 6.dp) - .padding(horizontal = 10.dp), - style = MaterialTheme.typography.title3 + modifier = Modifier.padding(top = 16.dp, bottom = 8.dp, start = 14.dp, + end = 14.dp) ) } @@ -79,21 +78,20 @@ fun MultiCredentialsFlattenScreen( onClick = { selectEntry(credential, false) }, secondaryLabel = credential.credentialTypeDisplayName, icon = credential.icon, + textAlign = TextAlign.Start ) + + CredentialsScreenChipSpacer() } } } item { - Text( + WearDisplayNameText( text = stringResource(R.string.provider_list_title), - modifier = Modifier - .padding(top = 6.dp) - .padding(horizontal = 10.dp), - style = MaterialTheme.typography.title3 + modifier = Modifier.padding(top = 12.dp, bottom = 8.dp, start = 14.dp, end = 14.dp) ) } - - credentialSelectorUiState.actionEntryList.forEach {actionEntry -> + credentialSelectorUiState.actionEntryList.forEach { actionEntry -> item { CredentialsScreenChip( label = actionEntry.title, @@ -101,9 +99,8 @@ fun MultiCredentialsFlattenScreen( secondaryLabel = null, icon = actionEntry.icon, ) + CredentialsScreenChipSpacer() } } } } - - diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt index 6f32c9906a1d..acf4eca64c0b 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt @@ -16,10 +16,11 @@ package com.android.credentialmanager.ui.screens.multiple +import androidx.compose.foundation.layout.Spacer import com.android.credentialmanager.R import androidx.compose.ui.res.stringResource import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @@ -35,6 +36,8 @@ import com.google.android.horologist.annotations.ExperimentalHorologistApi import com.google.android.horologist.compose.layout.ScalingLazyColumn import com.google.android.horologist.compose.layout.ScalingLazyColumnState import com.android.credentialmanager.model.CredentialType +import com.android.credentialmanager.ui.components.BottomSpacer +import com.android.credentialmanager.ui.components.CredentialsScreenChipSpacer /** * Screen that shows multiple credentials to select from. @@ -67,8 +70,6 @@ fun MultiCredentialsFoldScreen( SignInHeader( icon = null, title = title, - modifier = Modifier - .padding(top = 6.dp), ) } @@ -80,20 +81,26 @@ fun MultiCredentialsFoldScreen( secondaryLabel = credential.credentialTypeDisplayName, icon = credential.icon, ) + CredentialsScreenChipSpacer() } } credentialSelectorUiState.authenticationEntryList.forEach { authenticationEntryInfo -> item { LockedProviderChip(authenticationEntryInfo) { - selectEntry(authenticationEntryInfo, false) } + selectEntry(authenticationEntryInfo, false) + } + CredentialsScreenChipSpacer() } } item { + Spacer(modifier = Modifier.size(12.dp)) SignInOptionsChip { flowEngine.openSecondaryScreen() } + CredentialsScreenChipSpacer() } item { DismissChip { flowEngine.cancel() } + BottomSpacer() } } } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/passkey/SinglePasskeyScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/passkey/SinglePasskeyScreen.kt index 56b1c2e3d5a4..de7c1f19e193 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/passkey/SinglePasskeyScreen.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/passkey/SinglePasskeyScreen.kt @@ -29,17 +29,19 @@ import com.android.credentialmanager.model.get.CredentialEntryInfo import com.android.credentialmanager.R import com.android.credentialmanager.ui.components.AccountRow import com.android.credentialmanager.ui.components.ContinueChip +import com.android.credentialmanager.ui.components.CredentialsScreenChipSpacer import com.android.credentialmanager.ui.components.DismissChip import com.android.credentialmanager.ui.components.SignInHeader import com.android.credentialmanager.ui.components.SignInOptionsChip import com.android.credentialmanager.ui.screens.single.SingleAccountScreen import com.google.android.horologist.annotations.ExperimentalHorologistApi import com.google.android.horologist.compose.layout.ScalingLazyColumnState +import com.android.credentialmanager.ui.components.BottomSpacer /** - * Screen that shows sign in with provider credential. + * Screen that shows single passkey credential. * - * @param entry The password entry + * @param entry The passkey entry * @param columnState ScalingLazyColumn configuration to be be applied to SingleAccountScreen * @param modifier styling for composable * @param flowEngine [FlowEngine] that updates ui state for this screen @@ -49,7 +51,6 @@ import com.google.android.horologist.compose.layout.ScalingLazyColumnState fun SinglePasskeyScreen( entry: CredentialEntryInfo, columnState: ScalingLazyColumnState, - modifier: Modifier = Modifier, flowEngine: FlowEngine, ) { SingleAccountScreen( @@ -63,18 +64,20 @@ fun SinglePasskeyScreen( AccountRow( primaryText = checkNotNull(entry.displayName), secondaryText = entry.userName, - modifier = Modifier.padding(top = 10.dp), ) }, columnState = columnState, - modifier = modifier.padding(horizontal = 10.dp) + modifier = Modifier.padding(horizontal = 10.dp) ) { item { val selectEntry = flowEngine.getEntrySelector() Column { ContinueChip { selectEntry(entry, false) } + CredentialsScreenChipSpacer() SignInOptionsChip{ flowEngine.openSecondaryScreen() } + CredentialsScreenChipSpacer() DismissChip { flowEngine.cancel() } + BottomSpacer() } } } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt index 2ca8ef13c0cf..818723bf52bf 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt @@ -33,11 +33,13 @@ import com.android.credentialmanager.ui.components.SignInHeader import com.android.credentialmanager.ui.components.SignInOptionsChip import com.android.credentialmanager.ui.screens.single.SingleAccountScreen import com.android.credentialmanager.model.get.CredentialEntryInfo +import com.android.credentialmanager.ui.components.BottomSpacer +import com.android.credentialmanager.ui.components.CredentialsScreenChipSpacer import com.google.android.horologist.annotations.ExperimentalHorologistApi import com.google.android.horologist.compose.layout.ScalingLazyColumnState /** - * Screen that shows sign in with provider credential. + * Screen that shows password credential. * * @param entry The password entry. * @param columnState ScalingLazyColumn configuration to be be applied to SingleAccountScreen @@ -49,7 +51,6 @@ import com.google.android.horologist.compose.layout.ScalingLazyColumnState fun SinglePasswordScreen( entry: CredentialEntryInfo, columnState: ScalingLazyColumnState, - modifier: Modifier = Modifier, flowEngine: FlowEngine, ) { val selectEntry = flowEngine.getEntrySelector() @@ -63,17 +64,19 @@ fun SinglePasswordScreen( accountContent = { PasswordRow( email = entry.userName, - modifier = Modifier.padding(top = 10.dp), ) }, columnState = columnState, - modifier = modifier.padding(horizontal = 10.dp) + modifier = Modifier.padding(horizontal = 10.dp) ) { item { Column { ContinueChip { selectEntry(entry, false) } + CredentialsScreenChipSpacer() SignInOptionsChip{ flowEngine.openSecondaryScreen() } + CredentialsScreenChipSpacer() DismissChip { flowEngine.cancel() } + BottomSpacer() } } } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/signInWithProvider/SignInWithProviderScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/signInWithProvider/SignInWithProviderScreen.kt index 3a86feb4203b..884d9f6e5e16 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/signInWithProvider/SignInWithProviderScreen.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/signInWithProvider/SignInWithProviderScreen.kt @@ -24,7 +24,9 @@ import androidx.compose.ui.unit.dp import com.android.credentialmanager.FlowEngine import com.android.credentialmanager.model.get.CredentialEntryInfo import com.android.credentialmanager.ui.components.AccountRow +import com.android.credentialmanager.ui.components.BottomSpacer import com.android.credentialmanager.ui.components.ContinueChip +import com.android.credentialmanager.ui.components.CredentialsScreenChipSpacer import com.android.credentialmanager.ui.components.DismissChip import com.android.credentialmanager.ui.components.SignInHeader import com.android.credentialmanager.ui.components.SignInOptionsChip @@ -35,7 +37,7 @@ import com.google.android.horologist.compose.layout.ScalingLazyColumnState /** * Screen that shows sign in with provider credential. * - * @param entry The password entry. + * @param entry The custom credential entry. * @param columnState ScalingLazyColumn configuration to be be applied to SingleAccountScreen * @param modifier styling for composable * @param flowEngine [FlowEngine] that updates ui state for this screen @@ -61,12 +63,10 @@ fun SignInWithProviderScreen( AccountRow( primaryText = displayName, secondaryText = entry.userName, - modifier = Modifier.padding(top = 10.dp), ) } else { AccountRow( primaryText = entry.userName, - modifier = Modifier.padding(top = 10.dp), ) } }, @@ -77,8 +77,11 @@ fun SignInWithProviderScreen( val selectEntry = flowEngine.getEntrySelector() Column { ContinueChip { selectEntry(entry, false) } + CredentialsScreenChipSpacer() SignInOptionsChip{ flowEngine.openSecondaryScreen() } + CredentialsScreenChipSpacer() DismissChip { flowEngine.cancel() } + BottomSpacer() } } } diff --git a/packages/InputDevices/res/values-af/strings.xml b/packages/InputDevices/res/values-af/strings.xml index 7208894e1517..5d0c02211345 100644 --- a/packages/InputDevices/res/values-af/strings.xml +++ b/packages/InputDevices/res/values-af/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarussies"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongools"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgies"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-am/strings.xml b/packages/InputDevices/res/values-am/strings.xml index 16981501d4aa..39d57173dbfd 100644 --- a/packages/InputDevices/res/values-am/strings.xml +++ b/packages/InputDevices/res/values-am/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"ቤላሩስኛ"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"ሞንጎሊያኛ"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ጂዮርጂያኛ"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ar/strings.xml b/packages/InputDevices/res/values-ar/strings.xml index 8ed19722c6ce..431585349bb3 100644 --- a/packages/InputDevices/res/values-ar/strings.xml +++ b/packages/InputDevices/res/values-ar/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"البيلاروسية"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"المنغولية"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"الجورجية"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-as/strings.xml b/packages/InputDevices/res/values-as/strings.xml index 9744a7d39ef9..01714424dcfd 100644 --- a/packages/InputDevices/res/values-as/strings.xml +++ b/packages/InputDevices/res/values-as/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"বেলাৰুছিয়ান"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolian"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-az/strings.xml b/packages/InputDevices/res/values-az/strings.xml index ee3a337e3ac4..39a12b7daa79 100644 --- a/packages/InputDevices/res/values-az/strings.xml +++ b/packages/InputDevices/res/values-az/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarus dili"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Monqol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gürcü"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-b+sr+Latn/strings.xml b/packages/InputDevices/res/values-b+sr+Latn/strings.xml index 1fc84f3aee11..64aa7f63490c 100644 --- a/packages/InputDevices/res/values-b+sr+Latn/strings.xml +++ b/packages/InputDevices/res/values-b+sr+Latn/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"beloruski"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongolska"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzijska"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-be/strings.xml b/packages/InputDevices/res/values-be/strings.xml index 50c591088563..a8c11bee63af 100644 --- a/packages/InputDevices/res/values-be/strings.xml +++ b/packages/InputDevices/res/values-be/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Беларуская"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Мангольская"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Грузінская"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-bg/strings.xml b/packages/InputDevices/res/values-bg/strings.xml index 1ee9565a666b..6d82a0b03bf4 100644 --- a/packages/InputDevices/res/values-bg/strings.xml +++ b/packages/InputDevices/res/values-bg/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"беларуски"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"монголски"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"грузински"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-bn/strings.xml b/packages/InputDevices/res/values-bn/strings.xml index a9965385fdbc..3fc13157d5d6 100644 --- a/packages/InputDevices/res/values-bn/strings.xml +++ b/packages/InputDevices/res/values-bn/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"বেলারুশীয়"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"মঙ্গোলিয়ান"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"জর্জিয়ান"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-bs/strings.xml b/packages/InputDevices/res/values-bs/strings.xml index c6cacbc93552..b2cf5257010d 100644 --- a/packages/InputDevices/res/values-bs/strings.xml +++ b/packages/InputDevices/res/values-bs/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"bjeloruska"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongolski"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzijski"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ca/strings.xml b/packages/InputDevices/res/values-ca/strings.xml index 761c248bcdf7..ed04b9434061 100644 --- a/packages/InputDevices/res/values-ca/strings.xml +++ b/packages/InputDevices/res/values-ca/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Bielorús"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgià"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-cs/strings.xml b/packages/InputDevices/res/values-cs/strings.xml index 3f1b3d0629bd..5cd3ff5708b8 100644 --- a/packages/InputDevices/res/values-cs/strings.xml +++ b/packages/InputDevices/res/values-cs/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"běloruština"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongolština"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzínština"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-da/strings.xml b/packages/InputDevices/res/values-da/strings.xml index b160341d003a..4a6c70cb1342 100644 --- a/packages/InputDevices/res/values-da/strings.xml +++ b/packages/InputDevices/res/values-da/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Hviderussisk"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolsk"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgisk"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-de/strings.xml b/packages/InputDevices/res/values-de/strings.xml index 17d6e4ad8b03..628a7423043d 100644 --- a/packages/InputDevices/res/values-de/strings.xml +++ b/packages/InputDevices/res/values-de/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarussisch"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolisch"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgisch"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-el/strings.xml b/packages/InputDevices/res/values-el/strings.xml index 1b9b42e0f946..7b9651c1f847 100644 --- a/packages/InputDevices/res/values-el/strings.xml +++ b/packages/InputDevices/res/values-el/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Λευκορωσικά"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Μογγολικά"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Γεωργιανά"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-en-rAU/strings.xml b/packages/InputDevices/res/values-en-rAU/strings.xml index ab48729d5006..76bb2f16abcc 100644 --- a/packages/InputDevices/res/values-en-rAU/strings.xml +++ b/packages/InputDevices/res/values-en-rAU/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusian"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolian"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-en-rCA/strings.xml b/packages/InputDevices/res/values-en-rCA/strings.xml index 116178300348..aa4614b600c7 100644 --- a/packages/InputDevices/res/values-en-rCA/strings.xml +++ b/packages/InputDevices/res/values-en-rCA/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusian"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolian"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-en-rGB/strings.xml b/packages/InputDevices/res/values-en-rGB/strings.xml index ab48729d5006..76bb2f16abcc 100644 --- a/packages/InputDevices/res/values-en-rGB/strings.xml +++ b/packages/InputDevices/res/values-en-rGB/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusian"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolian"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-en-rIN/strings.xml b/packages/InputDevices/res/values-en-rIN/strings.xml index ab48729d5006..76bb2f16abcc 100644 --- a/packages/InputDevices/res/values-en-rIN/strings.xml +++ b/packages/InputDevices/res/values-en-rIN/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusian"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolian"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-en-rXC/strings.xml b/packages/InputDevices/res/values-en-rXC/strings.xml index 92c5a5c2f65e..58dbc43add8e 100644 --- a/packages/InputDevices/res/values-en-rXC/strings.xml +++ b/packages/InputDevices/res/values-en-rXC/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusian"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolian"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-es-rUS/strings.xml b/packages/InputDevices/res/values-es-rUS/strings.xml index b9fe046aa28c..05f5473b691a 100644 --- a/packages/InputDevices/res/values-es-rUS/strings.xml +++ b/packages/InputDevices/res/values-es-rUS/strings.xml @@ -4,7 +4,7 @@ <string name="app_label" msgid="8016145283189546017">"Dispositivos de entrada"</string> <string name="keyboard_layouts_label" msgid="6688773268302087545">"Teclado de Android"</string> <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglés (Reino Unido)"</string> - <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglés (EE. UU.)"</string> + <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglés (EE.UU.)"</string> <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Inglés (EE. UU.), internacional"</string> <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Inglés (EE. UU.), Colemak"</string> <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Inglés (EE. UU.), Dvorak"</string> @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Bielorruso"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-es/strings.xml b/packages/InputDevices/res/values-es/strings.xml index 216e79fb2599..cd68ad870845 100644 --- a/packages/InputDevices/res/values-es/strings.xml +++ b/packages/InputDevices/res/values-es/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Bielorruso"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-et/strings.xml b/packages/InputDevices/res/values-et/strings.xml index 87c486f086cf..9b37264324bf 100644 --- a/packages/InputDevices/res/values-et/strings.xml +++ b/packages/InputDevices/res/values-et/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"valgevene"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongoli"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruusia"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-eu/strings.xml b/packages/InputDevices/res/values-eu/strings.xml index 64628a82fe35..61c64157fdc2 100644 --- a/packages/InputDevices/res/values-eu/strings.xml +++ b/packages/InputDevices/res/values-eu/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Bielorrusiarra"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongoliarra"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiarra"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-fa/strings.xml b/packages/InputDevices/res/values-fa/strings.xml index a086060a6a17..43892051ba65 100644 --- a/packages/InputDevices/res/values-fa/strings.xml +++ b/packages/InputDevices/res/values-fa/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"بلاروسی"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"مغولی"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"گرجستانی"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-fi/strings.xml b/packages/InputDevices/res/values-fi/strings.xml index f3bef4d97117..0e8efff287cb 100644 --- a/packages/InputDevices/res/values-fi/strings.xml +++ b/packages/InputDevices/res/values-fi/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"valkovenäjä"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongoli"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"georgia"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-fr-rCA/strings.xml b/packages/InputDevices/res/values-fr-rCA/strings.xml index 636358248937..e176c7ef2ff3 100644 --- a/packages/InputDevices/res/values-fr-rCA/strings.xml +++ b/packages/InputDevices/res/values-fr-rCA/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Biélorusse"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Géorgien"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-fr/strings.xml b/packages/InputDevices/res/values-fr/strings.xml index 37cde0517feb..4388ec1b396b 100644 --- a/packages/InputDevices/res/values-fr/strings.xml +++ b/packages/InputDevices/res/values-fr/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Biélorusse"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Géorgien"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-gl/strings.xml b/packages/InputDevices/res/values-gl/strings.xml index 9995f79ee732..827071e5c17b 100644 --- a/packages/InputDevices/res/values-gl/strings.xml +++ b/packages/InputDevices/res/values-gl/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belaruso"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Xeorxiano"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-gu/strings.xml b/packages/InputDevices/res/values-gu/strings.xml index 9dfda76c59bc..df095ae6cf7a 100644 --- a/packages/InputDevices/res/values-gu/strings.xml +++ b/packages/InputDevices/res/values-gu/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"બેલારુશિયન"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"મોંગોલિયન"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"જ્યોર્જિઅન"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-hi/strings.xml b/packages/InputDevices/res/values-hi/strings.xml index 2562854378d1..550759d185a2 100644 --- a/packages/InputDevices/res/values-hi/strings.xml +++ b/packages/InputDevices/res/values-hi/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"बेलारूसी"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"मंगोलियन"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"जॉर्जियन कीबोर्ड का लेआउट"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-hr/strings.xml b/packages/InputDevices/res/values-hr/strings.xml index 6832437e1a4a..e955e77c24c9 100644 --- a/packages/InputDevices/res/values-hr/strings.xml +++ b/packages/InputDevices/res/values-hr/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"bjeloruski"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolski"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gruzijska"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-hu/strings.xml b/packages/InputDevices/res/values-hu/strings.xml index f2ac8a2b8085..565bf69a63d6 100644 --- a/packages/InputDevices/res/values-hu/strings.xml +++ b/packages/InputDevices/res/values-hu/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"belarusz"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"grúz"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-hy/strings.xml b/packages/InputDevices/res/values-hy/strings.xml index a6676fe9875a..9722342ff209 100644 --- a/packages/InputDevices/res/values-hy/strings.xml +++ b/packages/InputDevices/res/values-hy/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"բելառուսերեն"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Մոնղոլերեն"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"վրացերեն"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-in/strings.xml b/packages/InputDevices/res/values-in/strings.xml index 92bd24df2791..19fd692e6822 100644 --- a/packages/InputDevices/res/values-in/strings.xml +++ b/packages/InputDevices/res/values-in/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusia"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolia"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgia"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-is/strings.xml b/packages/InputDevices/res/values-is/strings.xml index b761a7eb36f0..f76d9d74d52b 100644 --- a/packages/InputDevices/res/values-is/strings.xml +++ b/packages/InputDevices/res/values-is/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"hvítrússneska"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongólska"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"georgíska"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-it/strings.xml b/packages/InputDevices/res/values-it/strings.xml index a992b8666ba8..ccde851a9dd7 100644 --- a/packages/InputDevices/res/values-it/strings.xml +++ b/packages/InputDevices/res/values-it/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Bielorusso"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolo"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-iw/strings.xml b/packages/InputDevices/res/values-iw/strings.xml index de9b2767dbd6..4a8b802d7dd1 100644 --- a/packages/InputDevices/res/values-iw/strings.xml +++ b/packages/InputDevices/res/values-iw/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"בלארוסית"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"מונגולית"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"גיאורגית"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ja/strings.xml b/packages/InputDevices/res/values-ja/strings.xml index 6be0b4c7a8e7..b9bab69cbb98 100644 --- a/packages/InputDevices/res/values-ja/strings.xml +++ b/packages/InputDevices/res/values-ja/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"ベラルーシ語"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"モンゴル語"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ジョージア語"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ka/strings.xml b/packages/InputDevices/res/values-ka/strings.xml index 92d94705b0fe..1610d2679735 100644 --- a/packages/InputDevices/res/values-ka/strings.xml +++ b/packages/InputDevices/res/values-ka/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"ბელორუსული"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"მონღოლური"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ქართული"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-kk/strings.xml b/packages/InputDevices/res/values-kk/strings.xml index c8ab7968d844..43bea18f824a 100644 --- a/packages/InputDevices/res/values-kk/strings.xml +++ b/packages/InputDevices/res/values-kk/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Белорус"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Моңғол"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Грузин"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-km/strings.xml b/packages/InputDevices/res/values-km/strings.xml index fd63ab33cd03..eb4324715940 100644 --- a/packages/InputDevices/res/values-km/strings.xml +++ b/packages/InputDevices/res/values-km/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"បេឡារុស"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"មុងហ្គោលី"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ហ្សកហ្ស៊ី"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-kn/strings.xml b/packages/InputDevices/res/values-kn/strings.xml index 761b7ccef00e..575058515cc7 100644 --- a/packages/InputDevices/res/values-kn/strings.xml +++ b/packages/InputDevices/res/values-kn/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"ಬೆಲರೂಸಿಯನ್"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"ಮಂಗೋಲಿಯನ್"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ಜಾರ್ಜಿಯನ್"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ko/strings.xml b/packages/InputDevices/res/values-ko/strings.xml index 2a1cbb00174b..b44249208bae 100644 --- a/packages/InputDevices/res/values-ko/strings.xml +++ b/packages/InputDevices/res/values-ko/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"벨라루스어"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"몽골어"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"조지아어"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ky/strings.xml b/packages/InputDevices/res/values-ky/strings.xml index 70295e1859a8..36cd53990d1d 100644 --- a/packages/InputDevices/res/values-ky/strings.xml +++ b/packages/InputDevices/res/values-ky/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Беларусча"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Монголчо"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Грузинче"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-lo/strings.xml b/packages/InputDevices/res/values-lo/strings.xml index 2b8946b43d64..ab64e24ae5db 100644 --- a/packages/InputDevices/res/values-lo/strings.xml +++ b/packages/InputDevices/res/values-lo/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"ເບລາຣັສຊຽນ"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"ມອງໂກລຽນ"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ຈໍຈຽນ"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-lt/strings.xml b/packages/InputDevices/res/values-lt/strings.xml index 5fca46bf3e5a..ec9893753c94 100644 --- a/packages/InputDevices/res/values-lt/strings.xml +++ b/packages/InputDevices/res/values-lt/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Baltarusių k."</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolų"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gruzinų"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-lv/strings.xml b/packages/InputDevices/res/values-lv/strings.xml index d2253297c8ff..05e5d2f79bc9 100644 --- a/packages/InputDevices/res/values-lv/strings.xml +++ b/packages/InputDevices/res/values-lv/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Baltkrievu"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongoļu"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gruzīnu"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-mk/strings.xml b/packages/InputDevices/res/values-mk/strings.xml index d98b58b8d799..c2bc8c076187 100644 --- a/packages/InputDevices/res/values-mk/strings.xml +++ b/packages/InputDevices/res/values-mk/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"белоруски"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"монголски"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"грузиски"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ml/strings.xml b/packages/InputDevices/res/values-ml/strings.xml index f3468810decd..33f8f2252236 100644 --- a/packages/InputDevices/res/values-ml/strings.xml +++ b/packages/InputDevices/res/values-ml/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"ബെലാറുഷ്യൻ"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"മംഗോളിയൻ"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ജോര്ജ്ജിയൻ"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-mn/strings.xml b/packages/InputDevices/res/values-mn/strings.xml index 16970971243a..7aad90dc6c92 100644 --- a/packages/InputDevices/res/values-mn/strings.xml +++ b/packages/InputDevices/res/values-mn/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Беларусь хэл"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Монгол"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Гүрж"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-mr/strings.xml b/packages/InputDevices/res/values-mr/strings.xml index 6382f6fc4d61..db607e3960e6 100644 --- a/packages/InputDevices/res/values-mr/strings.xml +++ b/packages/InputDevices/res/values-mr/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"बेलारुशियन"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"मंगोलियन"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"जॉर्जियन"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ms/strings.xml b/packages/InputDevices/res/values-ms/strings.xml index 9bff171385ee..9a001260ac7e 100644 --- a/packages/InputDevices/res/values-ms/strings.xml +++ b/packages/InputDevices/res/values-ms/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Bahasa Belarus"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Bahasa Mongolia"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Bahasa Georgia"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-my/strings.xml b/packages/InputDevices/res/values-my/strings.xml index 01b55074d9f7..d87a7b4cf9a1 100644 --- a/packages/InputDevices/res/values-my/strings.xml +++ b/packages/InputDevices/res/values-my/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"ဘီလာရုဇ်"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"မွန်ဂိုလီးယား"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ဂျော်ဂျီယာ"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-nb/strings.xml b/packages/InputDevices/res/values-nb/strings.xml index 40eb25ad9f23..fbefd3866520 100644 --- a/packages/InputDevices/res/values-nb/strings.xml +++ b/packages/InputDevices/res/values-nb/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusisk"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolsk"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgisk"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ne/strings.xml b/packages/InputDevices/res/values-ne/strings.xml index 6e98bf6d9384..642fc5c73bcc 100644 --- a/packages/InputDevices/res/values-ne/strings.xml +++ b/packages/InputDevices/res/values-ne/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"बेलारुसियाली"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"मङ्गोलियाली"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"जर्जियाली"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-nl/strings.xml b/packages/InputDevices/res/values-nl/strings.xml index f3a58142f461..a93772f7b23d 100644 --- a/packages/InputDevices/res/values-nl/strings.xml +++ b/packages/InputDevices/res/values-nl/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Wit-Russisch"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongools"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgisch"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-or/strings.xml b/packages/InputDevices/res/values-or/strings.xml index 5b6aaea9ddf9..47af22e3a879 100644 --- a/packages/InputDevices/res/values-or/strings.xml +++ b/packages/InputDevices/res/values-or/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"ବେଲାରୁସିଆନ୍"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"ମଙ୍ଗୋଲିଆନ୍"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ଜର୍ଜିଆନ୍"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-pa/strings.xml b/packages/InputDevices/res/values-pa/strings.xml index 988b4492d5f3..c634223f0d79 100644 --- a/packages/InputDevices/res/values-pa/strings.xml +++ b/packages/InputDevices/res/values-pa/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"ਬੇਲਾਰੂਸੀ"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"ਮੰਗੋਲੀਆਈ"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ਜਾਰਜੀਆਈ"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-pl/strings.xml b/packages/InputDevices/res/values-pl/strings.xml index 4d1821594736..232a50590f36 100644 --- a/packages/InputDevices/res/values-pl/strings.xml +++ b/packages/InputDevices/res/values-pl/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"białoruski"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongolski"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruziński"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-pt-rBR/strings.xml b/packages/InputDevices/res/values-pt-rBR/strings.xml index e44f4ae131f9..aba7afc444fb 100644 --- a/packages/InputDevices/res/values-pt-rBR/strings.xml +++ b/packages/InputDevices/res/values-pt-rBR/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Bielorrusso"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-pt-rPT/strings.xml b/packages/InputDevices/res/values-pt-rPT/strings.xml index 3ad3e638a680..3d7c603abc79 100644 --- a/packages/InputDevices/res/values-pt-rPT/strings.xml +++ b/packages/InputDevices/res/values-pt-rPT/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Bielorrusso"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-pt/strings.xml b/packages/InputDevices/res/values-pt/strings.xml index e44f4ae131f9..aba7afc444fb 100644 --- a/packages/InputDevices/res/values-pt/strings.xml +++ b/packages/InputDevices/res/values-pt/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Bielorrusso"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ro/strings.xml b/packages/InputDevices/res/values-ro/strings.xml index 3867e1cae1d6..4cdd54afcb0f 100644 --- a/packages/InputDevices/res/values-ro/strings.xml +++ b/packages/InputDevices/res/values-ro/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusă"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolă"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiană"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ru/strings.xml b/packages/InputDevices/res/values-ru/strings.xml index 7c5c95aebe68..fcdd405cb239 100644 --- a/packages/InputDevices/res/values-ru/strings.xml +++ b/packages/InputDevices/res/values-ru/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"белорусский"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"монгольский"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"грузинский"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-si/strings.xml b/packages/InputDevices/res/values-si/strings.xml index f4147f3008ee..44dfd6038174 100644 --- a/packages/InputDevices/res/values-si/strings.xml +++ b/packages/InputDevices/res/values-si/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"බෙලරුසියානු"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"මොන්ගෝලියානු"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ජෝර්ජියානු"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-sk/strings.xml b/packages/InputDevices/res/values-sk/strings.xml index 2a375529c3c7..f02b0be1d412 100644 --- a/packages/InputDevices/res/values-sk/strings.xml +++ b/packages/InputDevices/res/values-sk/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"bieloruské"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongolské"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzínske"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-sl/strings.xml b/packages/InputDevices/res/values-sl/strings.xml index 334326c0954a..ab70e0800f8f 100644 --- a/packages/InputDevices/res/values-sl/strings.xml +++ b/packages/InputDevices/res/values-sl/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"beloruščina"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongolščina"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzinščina"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-sq/strings.xml b/packages/InputDevices/res/values-sq/strings.xml index 0863138423b4..d01b2bcf1af0 100644 --- a/packages/InputDevices/res/values-sq/strings.xml +++ b/packages/InputDevices/res/values-sq/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Bjellorusisht"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolisht"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gjeorgjisht"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-sr/strings.xml b/packages/InputDevices/res/values-sr/strings.xml index 973b833e6a6a..88978f65712b 100644 --- a/packages/InputDevices/res/values-sr/strings.xml +++ b/packages/InputDevices/res/values-sr/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"белоруски"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"монголска"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"грузијска"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-sv/strings.xml b/packages/InputDevices/res/values-sv/strings.xml index b1e5d755b788..a255d248e1f8 100644 --- a/packages/InputDevices/res/values-sv/strings.xml +++ b/packages/InputDevices/res/values-sv/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"vitryska"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongoliska"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"georgiska"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-sw/strings.xml b/packages/InputDevices/res/values-sw/strings.xml index 0f4c8466e47e..00979e5fc691 100644 --- a/packages/InputDevices/res/values-sw/strings.xml +++ b/packages/InputDevices/res/values-sw/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Kibelarusi"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Kimongolia"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Kijojia"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ta/strings.xml b/packages/InputDevices/res/values-ta/strings.xml index d3535d440981..355f78dc40c9 100644 --- a/packages/InputDevices/res/values-ta/strings.xml +++ b/packages/InputDevices/res/values-ta/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"பெலரூசியன்"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"மங்கோலியன்"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ஜார்ஜியன்"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-te/strings.xml b/packages/InputDevices/res/values-te/strings.xml index 5a10f6e03f71..1fe885d4d467 100644 --- a/packages/InputDevices/res/values-te/strings.xml +++ b/packages/InputDevices/res/values-te/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"బెలారష్యన్"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"మంగోలియన్"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"జార్జియన్"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-th/strings.xml b/packages/InputDevices/res/values-th/strings.xml index 131c53613beb..f1b433b7e358 100644 --- a/packages/InputDevices/res/values-th/strings.xml +++ b/packages/InputDevices/res/values-th/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"เบลารุส"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"ภาษามองโกเลีย"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"ภาษาจอร์เจีย"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-tl/strings.xml b/packages/InputDevices/res/values-tl/strings.xml index c42adbcbd785..21ad90927f2e 100644 --- a/packages/InputDevices/res/values-tl/strings.xml +++ b/packages/InputDevices/res/values-tl/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusian"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolian"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-tr/strings.xml b/packages/InputDevices/res/values-tr/strings.xml index 1a84d0acf276..a1ac7fd5003a 100644 --- a/packages/InputDevices/res/values-tr/strings.xml +++ b/packages/InputDevices/res/values-tr/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusça"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Moğolca"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gürcüce"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-uk/strings.xml b/packages/InputDevices/res/values-uk/strings.xml index 71b3496c929f..dcc5bcf52a59 100644 --- a/packages/InputDevices/res/values-uk/strings.xml +++ b/packages/InputDevices/res/values-uk/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Білоруська"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Монгольська"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Грузинська"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ur/strings.xml b/packages/InputDevices/res/values-ur/strings.xml index 0cc9b61ed5ec..e8f327c05c7e 100644 --- a/packages/InputDevices/res/values-ur/strings.xml +++ b/packages/InputDevices/res/values-ur/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"بيلاروسی"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"منگؤلی"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"جارجیائی"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-uz/strings.xml b/packages/InputDevices/res/values-uz/strings.xml index 52ecdfca5492..0968d7a68bdf 100644 --- a/packages/InputDevices/res/values-uz/strings.xml +++ b/packages/InputDevices/res/values-uz/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarus"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongol"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gruzin"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-vi/strings.xml b/packages/InputDevices/res/values-vi/strings.xml index 0c638faaecd0..f7c3658e9b08 100644 --- a/packages/InputDevices/res/values-vi/strings.xml +++ b/packages/InputDevices/res/values-vi/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Tiếng Belarus"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Tiếng Mông Cổ"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Tiếng Georgia"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-zh-rCN/strings.xml b/packages/InputDevices/res/values-zh-rCN/strings.xml index b24977982bce..7d0a12838889 100644 --- a/packages/InputDevices/res/values-zh-rCN/strings.xml +++ b/packages/InputDevices/res/values-zh-rCN/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"白俄罗斯语"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"蒙古语"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"格鲁吉亚语"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-zh-rHK/strings.xml b/packages/InputDevices/res/values-zh-rHK/strings.xml index 60a52e98ae98..a0c3c1a52ca5 100644 --- a/packages/InputDevices/res/values-zh-rHK/strings.xml +++ b/packages/InputDevices/res/values-zh-rHK/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"白俄羅斯文"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"蒙古文"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"格魯吉亞文"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-zh-rTW/strings.xml b/packages/InputDevices/res/values-zh-rTW/strings.xml index c3217e368492..1b8484171953 100644 --- a/packages/InputDevices/res/values-zh-rTW/strings.xml +++ b/packages/InputDevices/res/values-zh-rTW/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"白俄羅斯文"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"蒙古文"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"喬治亞文"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-zu/strings.xml b/packages/InputDevices/res/values-zu/strings.xml index 88d55f2ff32a..c4b5d7a73acc 100644 --- a/packages/InputDevices/res/values-zu/strings.xml +++ b/packages/InputDevices/res/values-zu/strings.xml @@ -50,4 +50,6 @@ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusian"</string> <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"isi-Mongolian"</string> <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string> + <!-- no translation found for keyboard_layout_thai_kedmanee (6637147314580760938) --> + <skip /> </resources> diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml index e788bf7e2f8f..55f960d3af2b 100644 --- a/packages/PackageInstaller/res/values-ky/strings.xml +++ b/packages/PackageInstaller/res/values-ky/strings.xml @@ -63,7 +63,7 @@ <string name="archive_application_text_all_users" msgid="3151229641681672580">"Бул колдонмо бардык колдонуучулар үчүн архивделсинби? Жеке маалыматыңыз сакталат"</string> <string name="archive_application_text_current_user_work_profile" msgid="1450487362134779752">"Бул колдонмо жумуш профилиңизде архивделсинби? Жеке маалыматыңыз сакталат"</string> <string name="archive_application_text_user" msgid="2586558895535581451">"Бул колдонмо <xliff:g id="USERNAME">%1$s</xliff:g> үчүн архивделсинби? Жеке маалыматыңыз сакталат"</string> - <string name="archive_application_text_current_user_private_profile" msgid="1958423158655599132">"Бул колдонмо жеке чөйрөдөн архивделсинби? Жеке маалыматыңыз сакталат"</string> + <string name="archive_application_text_current_user_private_profile" msgid="1958423158655599132">"Бул колдонмо жеке мейкиндиктен архивделсинби? Жеке маалыматыңыз сакталат"</string> <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Бул колдонмо "<b>"бардык"</b>" колдонуучулардан алынып салынсынбы? Бул колдонмо жана анын дайындары бул түзмөктүн "<b>"бардык"</b>" колдонуучуларынан өчүрүлөт."</string> <string name="uninstall_application_text_user" msgid="498072714173920526">"Бул колдонмону <xliff:g id="USERNAME">%1$s</xliff:g> үчүн чыгарып саласызбы?"</string> <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Бул колдонмону жумуш профилиңизден чыгарып саласызбы?"</string> @@ -72,7 +72,7 @@ <string name="uninstall_keep_data" msgid="7002379587465487550">"Колдонмонун <xliff:g id="SIZE">%1$s</xliff:g> дайындарын сактоо."</string> <string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Бул колдонмону өчүрөсүзбү?"</string> <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Бул колдонмону чыгарып саласызбы? <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клону да өчүрүлөт."</string> - <string name="uninstall_application_text_current_user_private_profile" msgid="867004464945674674">"Бул колдонмону жеке чөйрөдөн чыгарып саласызбы?"</string> + <string name="uninstall_application_text_current_user_private_profile" msgid="867004464945674674">"Бул колдонмону жеке мейкиндиктен чыгарып саласызбы?"</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"Чыгарылып салынууда"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Чыгарылып салынбай калгандар"</string> <string name="uninstalling" msgid="8709566347688966845">"Чыгарылып салынууда…"</string> diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml index 149783d9f5f8..bd288e4bde17 100644 --- a/packages/PackageInstaller/res/values-nl/strings.xml +++ b/packages/PackageInstaller/res/values-nl/strings.xml @@ -98,7 +98,7 @@ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Uit veiligheidsoverwegingen heeft je tv momenteel geen toestemming om onbekende apps van deze bron te installeren. Je kunt dit wijzigen via Instellingen."</string> <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"Uit veiligheidsoverwegingen heeft je smartwatch momenteel geen toestemming om onbekende apps van deze bron te installeren. Je kunt dit wijzigen via Instellingen."</string> <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Uit veiligheidsoverwegingen heeft je telefoon momenteel geen toestemming om onbekende apps van deze bron te installeren. Je kunt dit wijzigen via Instellingen."</string> - <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Je telefoon en persoonsgegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je telefoon of gegevensverlies als gevolg van het gebruik van de app."</string> + <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Je telefoon en persoonsgegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Door deze app te installeren, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je telefoon of gegevensverlies als gevolg van het gebruik van de app."</string> <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Je tablet en persoonsgegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je tablet of gegevensverlies als gevolg van het gebruik van de app."</string> <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Je tv en persoonsgegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je tv of gegevensverlies als gevolg van het gebruik van de app."</string> <string name="cloned_app_label" msgid="7503612829833756160">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-kloon"</string> diff --git a/packages/PackageInstaller/res/values-th/strings.xml b/packages/PackageInstaller/res/values-th/strings.xml index 7f3708432a19..739d2726b56c 100644 --- a/packages/PackageInstaller/res/values-th/strings.xml +++ b/packages/PackageInstaller/res/values-th/strings.xml @@ -94,10 +94,10 @@ <string name="Parse_error_dlg_text" msgid="1661404001063076789">"พบปัญหาในการแยกวิเคราะห์แพ็กเกจ"</string> <string name="message_staging" msgid="8032722385658438567">"กำลังปรับสภาพแวดล้อมของแอป…"</string> <string name="app_name_unknown" msgid="6881210203354323926">"ไม่ทราบ"</string> - <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"เพื่อความปลอดภัย ปัจจุบันไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในแท็บเล็ต คุณเปลี่ยนแปลงได้ในการตั้งค่า"</string> - <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"เพื่อความปลอดภัย ปัจจุบันไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในทีวี คุณเปลี่ยนแปลงได้ในการตั้งค่า"</string> - <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"ปัจจุบันนาฬิกาไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้เพื่อความปลอดภัยของคุณ คุณเปลี่ยนค่านี้ได้ในการตั้งค่า"</string> - <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"เพื่อความปลอดภัย ปัจจุบันไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในโทรศัพท์ ซึ่งคุณเปลี่ยนเป็นอนุญาตได้ในการตั้งค่า"</string> + <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"เพื่อความปลอดภัย โทรศัพท์ของคุณไม่ได้รับอนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ คุณสามารถเปลี่ยนแปลงได้ที่ \"การตั้งค่า\""</string> + <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"เพื่อความปลอดภัย โทรศัพท์ของคุณไม่ได้รับอนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ คุณสามารถเปลี่ยนแปลงได้ที่ \"การตั้งค่า\""</string> + <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"เพื่อความปลอดภัย นาฬิกาของคุณไม่ได้รับอนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ คุณสามารถเปลี่ยนแปลงได้ที่ \"การตั้งค่า\""</string> + <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"เพื่อความปลอดภัย โทรศัพท์ของคุณไม่ได้รับอนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ คุณสามารถเปลี่ยนแปลงได้ที่ \"การตั้งค่า\""</string> <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"โทรศัพท์และข้อมูลส่วนตัวของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้แสดงว่าคุณยอมรับว่าจะรับผิดชอบต่อความเสียหายใดๆ ที่จะเกิดขึ้นกับโทรศัพท์หรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string> <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"แท็บเล็ตและข้อมูลส่วนตัวของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้แสดงว่าคุณยอมรับว่าจะรับผิดชอบต่อความเสียหายใดๆ ที่จะเกิดขึ้นกับแท็บเล็ตหรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string> <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ทีวีและข้อมูลส่วนตัวของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้แสดงว่าคุณยอมรับว่าจะรับผิดชอบต่อความเสียหายใดๆ ที่จะเกิดขึ้นกับทีวีหรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string> diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml index 5298f8b329ba..6ffad709b2f3 100644 --- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml +++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml @@ -35,7 +35,7 @@ <string name="install_for_print_preview" msgid="6366303997385509332">"Installer un lecteur PDF pour voir l\'aperçu"</string> <string name="printing_app_crashed" msgid="854477616686566398">"L\'application à l\'origine de l\'impression a planté"</string> <string name="generating_print_job" msgid="3119608742651698916">"Génération tâche impression…"</string> - <string name="save_as_pdf" msgid="5718454119847596853">"Enregistrer en format PDF"</string> + <string name="save_as_pdf" msgid="5718454119847596853">"Enregistrer au format PDF"</string> <string name="all_printers" msgid="5018829726861876202">"Toutes les imprimantes…"</string> <string name="print_dialog" msgid="32628687461331979">"Boîte de dialogue d\'impression"</string> <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> sur <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string> diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml index fa5df16bf35a..b5534b9c9246 100644 --- a/packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml +++ b/packages/SettingsLib/RestrictedLockUtils/res/values-hi/strings.xml @@ -18,5 +18,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="enabled_by_admin" msgid="6630472777476410137">"एडमिन की ओर से चालू किया गया"</string> - <string name="disabled_by_admin" msgid="4023569940620832713">"एडमिन की ओर से बंद किया गया"</string> + <string name="disabled_by_admin" msgid="4023569940620832713">"एडमिन ने यह सुविधा बंद की है"</string> </resources> diff --git a/packages/SettingsLib/SearchWidget/res/values-bn/strings.xml b/packages/SettingsLib/SearchWidget/res/values-bn/strings.xml index 23f46bf3d655..473231a10bfc 100644 --- a/packages/SettingsLib/SearchWidget/res/values-bn/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-bn/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1914043873178389845">"সেটিংসে সার্চ করুন"</string> + <string name="search_menu" msgid="1914043873178389845">"সার্চ সেটিংস"</string> </resources> diff --git a/packages/SettingsLib/SearchWidget/res/values-ms/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ms/strings.xml index 0d3a4daf2213..99a9b05b9a62 100644 --- a/packages/SettingsLib/SearchWidget/res/values-ms/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-ms/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1914043873178389845">"Tetapan carian"</string> + <string name="search_menu" msgid="1914043873178389845">"Cari tetapan"</string> </resources> diff --git a/packages/SettingsLib/Spa/gradle/libs.versions.toml b/packages/SettingsLib/Spa/gradle/libs.versions.toml index 0ee9d595d875..85ad160f6d66 100644 --- a/packages/SettingsLib/Spa/gradle/libs.versions.toml +++ b/packages/SettingsLib/Spa/gradle/libs.versions.toml @@ -15,7 +15,7 @@ # [versions] -agp = "8.3.1" +agp = "8.3.2" compose-compiler = "1.5.11" dexmaker-mockito = "2.28.3" jvm = "17" diff --git a/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.6-bin.zip b/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.7-bin.zip Binary files differindex 5c9634782bbe..7a9ac5afe013 100644 --- a/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.6-bin.zip +++ b/packages/SettingsLib/Spa/gradle/wrapper/gradle-8.7-bin.zip diff --git a/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties b/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties index 50ff9dff549b..182095e76e76 100644 --- a/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties +++ b/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties @@ -16,6 +16,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=gradle-8.6-bin.zip +distributionUrl=gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/SettingsLib/Spa/spa/build.gradle.kts b/packages/SettingsLib/Spa/spa/build.gradle.kts index 2f2ac2467a6c..6344501ce789 100644 --- a/packages/SettingsLib/Spa/spa/build.gradle.kts +++ b/packages/SettingsLib/Spa/spa/build.gradle.kts @@ -65,7 +65,7 @@ dependencies { api("androidx.lifecycle:lifecycle-runtime-compose") api("androidx.navigation:navigation-compose:2.8.0-alpha05") api("com.github.PhilJay:MPAndroidChart:v3.1.0-alpha") - api("com.google.android.material:material:1.7.0-alpha03") + api("com.google.android.material:material:1.11.0") debugApi("androidx.compose.ui:ui-tooling:$jetpackComposeVersion") implementation("com.airbnb.android:lottie-compose:5.2.0") diff --git a/packages/SettingsLib/SpaPrivileged/res/values-ar/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-ar/strings.xml index 9a8e7ddc6ef5..f259541fc0d4 100644 --- a/packages/SettingsLib/SpaPrivileged/res/values-ar/strings.xml +++ b/packages/SettingsLib/SpaPrivileged/res/values-ar/strings.xml @@ -20,8 +20,8 @@ <string name="no_applications" msgid="5800789569715871963">"ليس هناك أي تطبيقات."</string> <string name="menu_show_system" msgid="906304605807554788">"إظهار عمليات النظام"</string> <string name="menu_hide_system" msgid="374571689914923020">"إخفاء عمليات النظام"</string> - <string name="app_permission_summary_allowed" msgid="6115213465364138103">"مسموح به"</string> - <string name="app_permission_summary_not_allowed" msgid="58396132188553920">"غير مسموح به"</string> + <string name="app_permission_summary_allowed" msgid="6115213465364138103">"تطبيق مسموح به"</string> + <string name="app_permission_summary_not_allowed" msgid="58396132188553920">"تطبيق غير مسموح به"</string> <string name="version_text" msgid="4001669804596458577">"الإصدار <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string> <string name="cloned_app_info_label" msgid="1765651167024478391">"نسخة طبق الأصل من \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\""</string> </resources> diff --git a/packages/SettingsLib/SpaPrivileged/res/values-in/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-in/strings.xml index a2a4289c1bf5..b1d572195391 100644 --- a/packages/SettingsLib/SpaPrivileged/res/values-in/strings.xml +++ b/packages/SettingsLib/SpaPrivileged/res/values-in/strings.xml @@ -17,7 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="no_applications" msgid="5800789569715871963">"Tidak ada aplikasi."</string> + <string name="no_applications" msgid="5800789569715871963">"Tidak ada aplikasi"</string> <string name="menu_show_system" msgid="906304605807554788">"Tampilkan sistem"</string> <string name="menu_hide_system" msgid="374571689914923020">"Sembunyikan sistem"</string> <string name="app_permission_summary_allowed" msgid="6115213465364138103">"Diizinkan"</string> diff --git a/packages/SettingsLib/SpaPrivileged/res/values-ne/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-ne/strings.xml index 7f3a52325814..87d0762cf1e9 100644 --- a/packages/SettingsLib/SpaPrivileged/res/values-ne/strings.xml +++ b/packages/SettingsLib/SpaPrivileged/res/values-ne/strings.xml @@ -18,8 +18,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="no_applications" msgid="5800789569715871963">"कुनै पनि एप छैन।"</string> - <string name="menu_show_system" msgid="906304605807554788">"सिस्टम देखाइयोस्"</string> - <string name="menu_hide_system" msgid="374571689914923020">"सिस्टम लुकाइयोस्"</string> + <string name="menu_show_system" msgid="906304605807554788">"सिस्टम देखाउनुहोस्"</string> + <string name="menu_hide_system" msgid="374571689914923020">"सिस्टम लुकाउनुहोस्"</string> <string name="app_permission_summary_allowed" msgid="6115213465364138103">"अनुमति दिइएका एप"</string> <string name="app_permission_summary_not_allowed" msgid="58396132188553920">"अनुमति नदिइएका एप"</string> <string name="version_text" msgid="4001669804596458577">"संस्करण <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index 7e6b004be9b8..4640de304ed8 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -1148,6 +1148,16 @@ <!-- [CHAR_LIMIT=80] Label for battery charging future pause --> <string name="power_charging_future_paused"><xliff:g id="level">%1$s</xliff:g> - Charging</string> + <!-- [CHAR_LIMIT=40] Label for battery level when fast charging with duration. --> + <string name="power_fast_charging_duration_v2"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="status">%2$s</xliff:g> - Full by <xliff:g id="time">%3$s</xliff:g></string> + <!-- [CHAR_LIMIT=40] Label for battery level when non-fast charging with duration. --> + <string name="power_charging_duration_v2"><xliff:g id="level">%1$s</xliff:g> - Fully charged by <xliff:g id="time">%2$s</xliff:g></string> + + <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging. --> + <string name="power_remaining_charging_duration_only_v2">Fully charged by <xliff:g id="time">%1$s</xliff:g></string> + <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging. --> + <string name="power_remaining_fast_charging_duration_only_v2">Full by <xliff:g id="time">%1$s</xliff:g></string> + <!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed --> <string name="battery_info_status_unknown">Unknown</string> <!-- [CHAR_LIMIT=20] Battery use screen. Battery status shown in chart label when charging from an unknown source. --> @@ -1171,6 +1181,11 @@ <!-- [CHAR_LIMIT=None] Battery Info screen. Value for a status item. A state which device charging on hold --> <string name="battery_info_status_charging_on_hold">Charging on hold</string> + <!-- [CHAR_LIMIT=20] Battery use screen. Battery status shown in chart label when charging isn't fast. --> + <string name="battery_info_status_charging_v2">Charging</string> + <!-- [CHAR_LIMIT=20] Battery use screen. Battery status shown in chart label when charging speed is fast. --> + <string name="battery_info_status_charging_fast_v2">Fast charging</string> + <!-- Summary for settings preference disabled by administrator [CHAR LIMIT=50] --> <string name="disabled_by_admin_summary_text">Controlled by admin</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java index e95a506376fd..563f02d95f3c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/Utils.java +++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java @@ -65,6 +65,7 @@ import com.android.launcher3.icons.IconFactory; import com.android.launcher3.util.UserIconInfo; import com.android.settingslib.drawable.UserIconDrawable; import com.android.settingslib.fuelgauge.BatteryStatus; +import com.android.settingslib.fuelgauge.BatteryUtils; import com.android.settingslib.utils.BuildCompatUtils; import java.util.List; @@ -246,25 +247,23 @@ public class Utils { } else { if (status == BatteryManager.BATTERY_STATUS_CHARGING) { if (compactStatus) { - statusString = res.getString(R.string.battery_info_status_charging); + statusString = getRegularChargingStatusString(res); } else if (batteryStatus.isPluggedInWired()) { switch (batteryStatus.getChargingSpeed(context)) { case BatteryStatus.CHARGING_FAST: - statusString = - res.getString(R.string.battery_info_status_charging_fast); + statusString = getFastChargingStatusString(res); break; case BatteryStatus.CHARGING_SLOWLY: - statusString = - res.getString(R.string.battery_info_status_charging_slow); + statusString = getSlowChargingStatusString(res); break; default: - statusString = res.getString(R.string.battery_info_status_charging); + statusString = getRegularChargingStatusString(res); break; } } else if (batteryStatus.isPluggedInDock()) { - statusString = res.getString(R.string.battery_info_status_charging_dock); + statusString = getDockChargingStatusString(res); } else { - statusString = res.getString(R.string.battery_info_status_charging_wireless); + statusString = getWirelessChargingStatusString(res); } } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) { statusString = res.getString(R.string.battery_info_status_discharging); @@ -276,6 +275,41 @@ public class Utils { return statusString; } + private static String getFastChargingStatusString(Resources res) { + return res.getString( + BatteryUtils.isChargingStringV2Enabled() + ? R.string.battery_info_status_charging_fast_v2 + : R.string.battery_info_status_charging_fast); + } + + private static String getSlowChargingStatusString(Resources res) { + return res.getString( + BatteryUtils.isChargingStringV2Enabled() + ? R.string.battery_info_status_charging_v2 + : R.string.battery_info_status_charging_slow); + } + + private static String getRegularChargingStatusString(Resources res) { + return res.getString( + BatteryUtils.isChargingStringV2Enabled() + ? R.string.battery_info_status_charging_v2 + : R.string.battery_info_status_charging); + } + + private static String getWirelessChargingStatusString(Resources res) { + return res.getString( + BatteryUtils.isChargingStringV2Enabled() + ? R.string.battery_info_status_charging_v2 + : R.string.battery_info_status_charging_wireless); + } + + private static String getDockChargingStatusString(Resources res) { + return res.getString( + BatteryUtils.isChargingStringV2Enabled() + ? R.string.battery_info_status_charging_v2 + : R.string.battery_info_status_charging_dock); + } + public static ColorStateList getColorAccent(Context context) { return getColorAttr(context, android.R.attr.colorAccent); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index 0996d52b0e30..e926b1684348 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -57,6 +57,7 @@ public class BluetoothEventManager { private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final LocalBluetoothAdapter mLocalAdapter; + private final LocalBluetoothManager mBtManager; private final CachedBluetoothDeviceManager mDeviceManager; private final IntentFilter mAdapterIntentFilter, mProfileIntentFilter; private final Map<String, Handler> mHandlerMap; @@ -80,10 +81,15 @@ public class BluetoothEventManager { * userHandle passed in is {@code null}, we register event receiver for the * {@code context.getUser()} handle. */ - BluetoothEventManager(LocalBluetoothAdapter adapter, - CachedBluetoothDeviceManager deviceManager, Context context, - android.os.Handler handler, @Nullable UserHandle userHandle) { + BluetoothEventManager( + LocalBluetoothAdapter adapter, + LocalBluetoothManager btManager, + CachedBluetoothDeviceManager deviceManager, + Context context, + android.os.Handler handler, + @Nullable UserHandle userHandle) { mLocalAdapter = adapter; + mBtManager = btManager; mDeviceManager = deviceManager; mAdapterIntentFilter = new IntentFilter(); mProfileIntentFilter = new IntentFilter(); @@ -210,11 +216,27 @@ public class BluetoothEventManager { } } - void dispatchProfileConnectionStateChanged(@NonNull CachedBluetoothDevice device, int state, - int bluetoothProfile) { + void dispatchProfileConnectionStateChanged( + @NonNull CachedBluetoothDevice device, int state, int bluetoothProfile) { for (BluetoothCallback callback : mCallbacks) { callback.onProfileConnectionStateChanged(device, state, bluetoothProfile); } + + // Trigger updateFallbackActiveDeviceIfNeeded when ASSISTANT profile disconnected when + // audio sharing is enabled. + if (bluetoothProfile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT + && state == BluetoothAdapter.STATE_DISCONNECTED + && BluetoothUtils.isAudioSharingEnabled()) { + LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager(); + if (profileManager != null + && profileManager.getLeAudioBroadcastProfile() != null + && profileManager.getLeAudioBroadcastProfile().isProfileReady() + && profileManager.getLeAudioBroadcastAssistantProfile() != null + && profileManager.getLeAudioBroadcastAssistantProfile().isProfileReady()) { + Log.d(TAG, "updateFallbackActiveDeviceIfNeeded, ASSISTANT profile disconnected"); + profileManager.getLeAudioBroadcastProfile().updateFallbackActiveDeviceIfNeeded(); + } + } } private void dispatchConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { @@ -536,7 +558,6 @@ public class BluetoothEventManager { default: Log.w(TAG, "ActiveDeviceChangedHandler: unknown action " + action); return; - } dispatchAclStateChanged(activeDevice, state); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java index 53c6075ccff4..c4300d214c0c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java @@ -21,11 +21,11 @@ import android.os.Handler; import android.os.UserHandle; import android.util.Log; -import java.lang.ref.WeakReference; - import androidx.annotation.Nullable; import androidx.annotation.RequiresPermission; +import java.lang.ref.WeakReference; + /** * LocalBluetoothManager provides a simplified interface on top of a subset of * the Bluetooth API. Note that {@link #getInstance} will return null @@ -111,10 +111,17 @@ public class LocalBluetoothManager { mContext = context.getApplicationContext(); mLocalAdapter = adapter; mCachedDeviceManager = new CachedBluetoothDeviceManager(mContext, this); - mEventManager = new BluetoothEventManager(mLocalAdapter, mCachedDeviceManager, mContext, - handler, userHandle); - mProfileManager = new LocalBluetoothProfileManager(mContext, - mLocalAdapter, mCachedDeviceManager, mEventManager); + mEventManager = + new BluetoothEventManager( + mLocalAdapter, + this, + mCachedDeviceManager, + mContext, + handler, + userHandle); + mProfileManager = + new LocalBluetoothProfileManager( + mContext, mLocalAdapter, mCachedDeviceManager, mEventManager); mProfileManager.updateLocalProfiles(); mEventManager.readPairedDevices(); diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryUtils.java index 92db50878a70..327e470e7d22 100644 --- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryUtils.java @@ -21,11 +21,14 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.provider.Settings; +import android.os.SystemProperties; import android.os.UserManager; +import android.provider.Settings; import android.util.ArraySet; import android.view.accessibility.AccessibilityManager; +import androidx.annotation.VisibleForTesting; + import java.util.List; public final class BatteryUtils { @@ -33,6 +36,9 @@ public final class BatteryUtils { /** The key to get the time to full from Settings.Global */ public static final String GLOBAL_TIME_TO_FULL_MILLIS = "time_to_full_millis"; + /** The system property key to check whether the charging string v2 is enabled or not. */ + public static final String PROPERTY_CHARGING_STRING_V2_KEY = "charging_string.apply_v2"; + /** Gets the latest sticky battery intent from the Android system. */ public static Intent getBatteryIntent(Context context) { return context.registerReceiver( @@ -75,4 +81,25 @@ public final class BatteryUtils { final UserManager userManager = context.getSystemService(UserManager.class); return userManager.isManagedProfile() && !userManager.isSystemUser(); } + + private static Boolean sChargingStringV2Enabled = null; + + /** Returns {@code true} if the charging string v2 is enabled. */ + public static boolean isChargingStringV2Enabled() { + if (sChargingStringV2Enabled == null) { + sChargingStringV2Enabled = + SystemProperties.getBoolean(PROPERTY_CHARGING_STRING_V2_KEY, false); + } + return sChargingStringV2Enabled; + } + + + /** Used to override the system property to enable or reset for charging string V2. */ + @VisibleForTesting + public static void setChargingStringV2Enabled(Boolean enabled) { + SystemProperties.set( + BatteryUtils.PROPERTY_CHARGING_STRING_V2_KEY, + enabled == null ? "" : String.valueOf(enabled)); + BatteryUtils.sChargingStringV2Enabled = enabled; + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java index 22726549ce05..5ed59996bee3 100644 --- a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java +++ b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java @@ -33,7 +33,7 @@ import java.util.Date; import java.util.Locale; import java.util.concurrent.TimeUnit; -/** Utility class for keeping power related strings consistent**/ +/** Utility class for keeping power related strings consistent. **/ public class PowerUtil { private static final long SEVEN_MINUTES_MILLIS = TimeUnit.MINUTES.toMillis(7); @@ -221,4 +221,19 @@ public class PowerUtil { return time - remainder + multiple; } } + + /** Gets the rounded target time string in a short format. */ + public static String getTargetTimeShortString( + Context context, long targetTimeOffsetMs, long currentTimeMs) { + final long roundedTimeOfDayMs = + roundTimeToNearestThreshold( + currentTimeMs + targetTimeOffsetMs, FIFTEEN_MINUTES_MILLIS); + + // convert the time to a properly formatted string. + String skeleton = android.text.format.DateFormat.getTimeFormatString(context); + DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton); + Date date = Date.from(Instant.ofEpochMilli(roundedTimeOfDayMs)); + return fmt.format(date); + } } + diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/bluetooth/BluetoothEventManagerIntegTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/bluetooth/BluetoothEventManagerIntegTest.java index 50f5b9d81000..69f6305fa1b2 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/bluetooth/BluetoothEventManagerIntegTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/bluetooth/BluetoothEventManagerIntegTest.java @@ -20,6 +20,8 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; +import static java.util.concurrent.TimeUnit.SECONDS; + import android.app.ActivityManager; import android.content.Context; import android.content.Intent; @@ -37,13 +39,11 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import static java.util.concurrent.TimeUnit.SECONDS; - import java.util.concurrent.CountDownLatch; /** - * Test that verifies that BluetoothEventManager can receive broadcasts for non-current - * users for all bluetooth events. + * Test that verifies that BluetoothEventManager can receive broadcasts for non-current users for + * all bluetooth events. * * <p>Creation and deletion of users takes a long time, so marking this as a LargeTest. */ @@ -64,9 +64,14 @@ public class BluetoothEventManagerIntegTest { mContext = InstrumentationRegistry.getTargetContext(); mUserManager = UserManager.get(mContext); - mBluetoothEventManager = new BluetoothEventManager( - mock(LocalBluetoothAdapter.class), mock(CachedBluetoothDeviceManager.class), - mContext, /* handler= */ null, UserHandle.ALL); + mBluetoothEventManager = + new BluetoothEventManager( + mock(LocalBluetoothAdapter.class), + mock(LocalBluetoothManager.class), + mock(CachedBluetoothDeviceManager.class), + mContext, + /* handler= */ null, + UserHandle.ALL); // Create and start another user in the background. mOtherUser = mUserManager.createUser("TestUser", /* flags= */ 0); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java index 48bbf4ea6a65..b1489be943e6 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java @@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -29,35 +30,47 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothStatusCodes; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.UserHandle; +import android.platform.test.flag.junit.SetFlagsRule; import android.telephony.TelephonyManager; import com.android.settingslib.R; +import com.android.settingslib.flags.Flags; +import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import java.util.ArrayList; import java.util.Collections; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothAdapter.class}) public class BluetoothEventManagerTest { + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private static final String DEVICE_NAME = "test_device_name"; @Mock private LocalBluetoothAdapter mLocalAdapter; @Mock + private LocalBluetoothManager mBtManager; + @Mock private CachedBluetoothDeviceManager mCachedDeviceManager; @Mock private BluetoothCallback mBluetoothCallback; @@ -96,8 +109,15 @@ public class BluetoothEventManagerTest { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; - mBluetoothEventManager = new BluetoothEventManager(mLocalAdapter, - mCachedDeviceManager, mContext, /* handler= */ null, /* userHandle= */ null); + mBluetoothEventManager = + new BluetoothEventManager( + mLocalAdapter, + mBtManager, + mCachedDeviceManager, + mContext, + /* handler= */ null, + /* userHandle= */ null); + when(mBtManager.getProfileManager()).thenReturn(mLocalProfileManager); when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice); when(mHfpProfile.isProfileReady()).thenReturn(true); when(mA2dpProfile.isProfileReady()).thenReturn(true); @@ -113,8 +133,13 @@ public class BluetoothEventManagerTest { public void ifUserHandleIsNull_registerReceiverIsCalled() { Context mockContext = mock(Context.class); BluetoothEventManager eventManager = - new BluetoothEventManager(mLocalAdapter, mCachedDeviceManager, mockContext, - /* handler= */ null, /* userHandle= */ null); + new BluetoothEventManager( + mLocalAdapter, + mBtManager, + mCachedDeviceManager, + mockContext, + /* handler= */ null, + /* userHandle= */ null); verify(mockContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class), eq(null), eq(null), eq(Context.RECEIVER_EXPORTED)); @@ -124,8 +149,13 @@ public class BluetoothEventManagerTest { public void ifUserHandleSpecified_registerReceiverAsUserIsCalled() { Context mockContext = mock(Context.class); BluetoothEventManager eventManager = - new BluetoothEventManager(mLocalAdapter, mCachedDeviceManager, mockContext, - /* handler= */ null, UserHandle.ALL); + new BluetoothEventManager( + mLocalAdapter, + mBtManager, + mCachedDeviceManager, + mockContext, + /* handler= */ null, + UserHandle.ALL); verify(mockContext).registerReceiverAsUser(any(BroadcastReceiver.class), eq(UserHandle.ALL), any(IntentFilter.class), eq(null), eq(null), eq(Context.RECEIVER_EXPORTED)); @@ -172,6 +202,160 @@ public class BluetoothEventManagerTest { BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); } + /** + * dispatchProfileConnectionStateChanged should not call {@link + * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded when audio sharing flag is off. + */ + @Test + public void dispatchProfileConnectionStateChanged_flagOff_noUpdateFallbackDevice() { + ShadowBluetoothAdapter shadowBluetoothAdapter = + Shadow.extract(BluetoothAdapter.getDefaultAdapter()); + shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + LocalBluetoothLeBroadcast broadcast = mock(LocalBluetoothLeBroadcast.class); + when(broadcast.isProfileReady()).thenReturn(true); + LocalBluetoothLeBroadcastAssistant assistant = + mock(LocalBluetoothLeBroadcastAssistant.class); + when(assistant.isProfileReady()).thenReturn(true); + LocalBluetoothProfileManager profileManager = mock(LocalBluetoothProfileManager.class); + when(profileManager.getLeAudioBroadcastProfile()).thenReturn(broadcast); + when(profileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(assistant); + when(mBtManager.getProfileManager()).thenReturn(profileManager); + mBluetoothEventManager.dispatchProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); + + verify(broadcast, times(0)).updateFallbackActiveDeviceIfNeeded(); + } + + /** + * dispatchProfileConnectionStateChanged should not call {@link + * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded when the device does not + * support audio sharing. + */ + @Test + public void dispatchProfileConnectionStateChanged_notSupport_noUpdateFallbackDevice() { + ShadowBluetoothAdapter shadowBluetoothAdapter = + Shadow.extract(BluetoothAdapter.getDefaultAdapter()); + shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_NOT_SUPPORTED); + shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + LocalBluetoothLeBroadcast broadcast = mock(LocalBluetoothLeBroadcast.class); + when(broadcast.isProfileReady()).thenReturn(true); + LocalBluetoothLeBroadcastAssistant assistant = + mock(LocalBluetoothLeBroadcastAssistant.class); + when(assistant.isProfileReady()).thenReturn(true); + LocalBluetoothProfileManager profileManager = mock(LocalBluetoothProfileManager.class); + when(profileManager.getLeAudioBroadcastProfile()).thenReturn(broadcast); + when(profileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(assistant); + when(mBtManager.getProfileManager()).thenReturn(profileManager); + mBluetoothEventManager.dispatchProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); + + verify(broadcast, times(0)).updateFallbackActiveDeviceIfNeeded(); + } + + /** + * dispatchProfileConnectionStateChanged should not call {@link + * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded when audio sharing profile is + * not ready. + */ + @Test + public void dispatchProfileConnectionStateChanged_profileNotReady_noUpdateFallbackDevice() { + ShadowBluetoothAdapter shadowBluetoothAdapter = + Shadow.extract(BluetoothAdapter.getDefaultAdapter()); + shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + LocalBluetoothLeBroadcast broadcast = mock(LocalBluetoothLeBroadcast.class); + when(broadcast.isProfileReady()).thenReturn(false); + LocalBluetoothLeBroadcastAssistant assistant = + mock(LocalBluetoothLeBroadcastAssistant.class); + when(assistant.isProfileReady()).thenReturn(true); + LocalBluetoothProfileManager profileManager = mock(LocalBluetoothProfileManager.class); + when(profileManager.getLeAudioBroadcastProfile()).thenReturn(broadcast); + when(profileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(assistant); + when(mBtManager.getProfileManager()).thenReturn(profileManager); + mBluetoothEventManager.dispatchProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); + + verify(broadcast, times(0)).updateFallbackActiveDeviceIfNeeded(); + } + + /** + * dispatchProfileConnectionStateChanged should not call {@link + * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded when triggered for profile + * other than LE_AUDIO_BROADCAST_ASSISTANT or state other than STATE_DISCONNECTED. + */ + @Test + public void dispatchProfileConnectionStateChanged_notAssistantProfile_noUpdateFallbackDevice() { + ShadowBluetoothAdapter shadowBluetoothAdapter = + Shadow.extract(BluetoothAdapter.getDefaultAdapter()); + shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + LocalBluetoothLeBroadcast broadcast = mock(LocalBluetoothLeBroadcast.class); + when(broadcast.isProfileReady()).thenReturn(true); + LocalBluetoothLeBroadcastAssistant assistant = + mock(LocalBluetoothLeBroadcastAssistant.class); + when(assistant.isProfileReady()).thenReturn(true); + LocalBluetoothProfileManager profileManager = mock(LocalBluetoothProfileManager.class); + when(profileManager.getLeAudioBroadcastProfile()).thenReturn(broadcast); + when(profileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(assistant); + when(mBtManager.getProfileManager()).thenReturn(profileManager); + mBluetoothEventManager.dispatchProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.LE_AUDIO); + + verify(broadcast, times(0)).updateFallbackActiveDeviceIfNeeded(); + } + + /** + * dispatchProfileConnectionStateChanged should call {@link + * LocalBluetoothLeBroadcast}#updateFallbackActiveDeviceIfNeeded when assistant profile is + * disconnected and audio sharing is enabled. + */ + @Test + public void dispatchProfileConnectionStateChanged_audioSharing_updateFallbackDevice() { + ShadowBluetoothAdapter shadowBluetoothAdapter = + Shadow.extract(BluetoothAdapter.getDefaultAdapter()); + shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + LocalBluetoothLeBroadcast broadcast = mock(LocalBluetoothLeBroadcast.class); + when(broadcast.isProfileReady()).thenReturn(true); + LocalBluetoothLeBroadcastAssistant assistant = + mock(LocalBluetoothLeBroadcastAssistant.class); + when(assistant.isProfileReady()).thenReturn(true); + LocalBluetoothProfileManager profileManager = mock(LocalBluetoothProfileManager.class); + when(profileManager.getLeAudioBroadcastProfile()).thenReturn(broadcast); + when(profileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(assistant); + when(mBtManager.getProfileManager()).thenReturn(profileManager); + mBluetoothEventManager.dispatchProfileConnectionStateChanged( + mCachedBluetoothDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); + + verify(broadcast).updateFallbackActiveDeviceIfNeeded(); + } + @Test public void dispatchAclConnectionStateChanged_aclDisconnected_shouldDispatchCallback() { mBluetoothEventManager.registerCallback(mBluetoothCallback); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java index 4f8fa2fdb96e..cef083584744 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java @@ -56,7 +56,8 @@ import java.util.List; @Config(shadows = {ShadowBluetoothAdapter.class}) public class LocalBluetoothProfileManagerTest { private final static long HISYNCID = 10; - + @Mock + private LocalBluetoothManager mBtManager; @Mock private CachedBluetoothDeviceManager mDeviceManager; @Mock @@ -77,13 +78,21 @@ public class LocalBluetoothProfileManagerTest { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); mLocalBluetoothAdapter = LocalBluetoothAdapter.getInstance(); - mEventManager = spy(new BluetoothEventManager(mLocalBluetoothAdapter, mDeviceManager, - mContext, /* handler= */ null, /* userHandle= */ null)); + mEventManager = + spy( + new BluetoothEventManager( + mLocalBluetoothAdapter, + mBtManager, + mDeviceManager, + mContext, + /* handler= */ null, + /* userHandle= */ null)); mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); when(mDeviceManager.findDevice(mDevice)).thenReturn(mCachedBluetoothDevice); when(mCachedBluetoothDevice.getDevice()).thenReturn(mDevice); - mProfileManager = new LocalBluetoothProfileManager(mContext, mLocalBluetoothAdapter, - mDeviceManager, mEventManager); + mProfileManager = + new LocalBluetoothProfileManager( + mContext, mLocalBluetoothAdapter, mDeviceManager, mEventManager); } /** diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java index 2e7905f2e1e4..cbc382b6b920 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java @@ -20,30 +20,24 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.spy; +import android.app.AlarmManager; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import java.time.Duration; +import java.time.Instant; +import java.util.Locale; import java.util.regex.Pattern; @RunWith(RobolectricTestRunner.class) public class PowerUtilTest { - private static final String TEST_BATTERY_LEVEL_10 = "10%"; - private static final long TEN_SEC_MILLIS = Duration.ofSeconds(10).toMillis(); - private static final long SEVENTEEN_MIN_MILLIS = Duration.ofMinutes(17).toMillis(); - private static final long FIVE_MINUTES_MILLIS = Duration.ofMinutes(5).toMillis(); - private static final long TEN_MINUTES_MILLIS = Duration.ofMinutes(10).toMillis(); - private static final long THREE_DAYS_MILLIS = Duration.ofDays(3).toMillis(); - private static final long TEN_HOURS_MILLIS = Duration.ofHours(10).toMillis(); - private static final long THIRTY_HOURS_MILLIS = Duration.ofHours(30).toMillis(); - private static final String NORMAL_CASE_EXPECTED_PREFIX = "Should last until about"; - private static final String ENHANCED_SUFFIX = " based on your usage"; private static final String BATTERY_RUN_OUT_PREFIX = "Battery may run out by"; // matches a time (ex: '1:15 PM', '2 AM', '23:00') private static final String TIME_OF_DAY_REGEX = " (\\d)+:?(\\d)* ((AM)*)|((PM)*)"; @@ -55,29 +49,31 @@ public class PowerUtilTest { @Before public void setup() { MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); + mContext = spy(ApplicationProvider.getApplicationContext()); } @Test public void getBatteryTipStringFormatted_moreThanOneDay_usesCorrectString() { - String info = PowerUtil.getBatteryTipStringFormatted(mContext, - THREE_DAYS_MILLIS); + var threeDayMillis = Duration.ofDays(3).toMillis(); + + String batteryTipString = PowerUtil.getBatteryTipStringFormatted(mContext, threeDayMillis); - assertThat(info).isEqualTo("More than 3 days left"); + assertThat(batteryTipString).isEqualTo("More than 3 days left"); } @Test public void getBatteryTipStringFormatted_lessThanOneDay_usesCorrectString() { - String info = PowerUtil.getBatteryTipStringFormatted(mContext, - SEVENTEEN_MIN_MILLIS); + var drainTimeMs = Duration.ofMinutes(17).toMillis(); + + String batteryTipString = PowerUtil.getBatteryTipStringFormatted(mContext, drainTimeMs); // ex: Battery may run out by 1:15 PM - assertThat(info).containsMatch(Pattern.compile( - BATTERY_RUN_OUT_PREFIX + TIME_OF_DAY_REGEX)); + assertThat(batteryTipString) + .containsMatch(Pattern.compile(BATTERY_RUN_OUT_PREFIX + TIME_OF_DAY_REGEX)); } @Test - public void testRoundToNearestThreshold_roundsCorrectly() { + public void roundTimeToNearestThreshold_roundsCorrectly() { // test some pretty normal values assertThat(PowerUtil.roundTimeToNearestThreshold(1200, 1000)).isEqualTo(1000); assertThat(PowerUtil.roundTimeToNearestThreshold(800, 1000)).isEqualTo(1000); @@ -89,4 +85,17 @@ public class PowerUtilTest { assertThat(PowerUtil.roundTimeToNearestThreshold(-120, 100)).isEqualTo(100); assertThat(PowerUtil.roundTimeToNearestThreshold(-200, -75)).isEqualTo(225); } + + @Test + public void getTargetTimeShortString_returnsTimeShortString() { + mContext.getSystemService(AlarmManager.class).setTimeZone("UTC"); + mContext.getResources().getConfiguration().setLocale(Locale.US); + var currentTimeMs = Instant.parse("2024-06-06T15:00:00Z").toEpochMilli(); + var remainingTimeMs = Duration.ofMinutes(30).toMillis(); + + var actualTimeString = + PowerUtil.getTargetTimeShortString(mContext, remainingTimeMs, currentTimeMs); + + assertThat(actualTimeString).isEqualTo("3:30 PM"); + } } diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java index c7e96bcdb856..00e47729a796 100644 --- a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java +++ b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java @@ -38,6 +38,8 @@ public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBlueto private List<BluetoothDevice> mMostRecentlyConnectedDevices; private BluetoothProfile.ServiceListener mServiceListener; private ParcelUuid[] mParcelUuids; + private int mIsLeAudioBroadcastSourceSupported; + private int mIsLeAudioBroadcastAssistantSupported; @Implementation protected boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener, @@ -97,4 +99,22 @@ public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBlueto public void setUuids(ParcelUuid[] uuids) { mParcelUuids = uuids; } + + @Implementation + protected int isLeAudioBroadcastSourceSupported() { + return mIsLeAudioBroadcastSourceSupported; + } + + public void setIsLeAudioBroadcastSourceSupported(int isSupported) { + mIsLeAudioBroadcastSourceSupported = isSupported; + } + + @Implementation + protected int isLeAudioBroadcastAssistantSupported() { + return mIsLeAudioBroadcastAssistantSupported; + } + + public void setIsLeAudioBroadcastAssistantSupported(int isSupported) { + mIsLeAudioBroadcastAssistantSupported = isSupported; + } } diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index 17d9f1b87fac..097840ead0d3 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -338,4 +338,7 @@ <!-- Value to use as default scale for fonts --> <item name="def_device_font_scale" format="float" type="dimen">1.0</item> + + <!-- The default ringer mode. See `AudioManager` for list of valid values. --> + <integer name="def_ringer_mode">2</integer> </resources> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 1ead14ab6f4c..096cccc1f94a 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -3943,8 +3943,10 @@ public class SettingsProvider extends ContentProvider { globalSettings.updateSettingLocked(Settings.Global.ZEN_MODE, Integer.toString(Settings.Global.ZEN_MODE_OFF), null, true, SettingsState.SYSTEM_PACKAGE_NAME); + final int defaultRingerMode = + getContext().getResources().getInteger(R.integer.def_ringer_mode); globalSettings.updateSettingLocked(Settings.Global.MODE_RINGER, - Integer.toString(AudioManager.RINGER_MODE_NORMAL), null, + Integer.toString(defaultRingerMode), null, true, SettingsState.SYSTEM_PACKAGE_NAME); } currentVersion = 119; diff --git a/packages/Shell/res/values-af/strings.xml b/packages/Shell/res/values-af/strings.xml index b52a83c2fd54..90f0962867f7 100644 --- a/packages/Shell/res/values-af/strings.xml +++ b/packages/Shell/res/values-af/strings.xml @@ -35,7 +35,7 @@ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Kon nie foutverslagbesonderhede by ZIP-lêer voeg nie"</string> <string name="bugreport_unnamed" msgid="2800582406842092709">"naamloos"</string> <string name="bugreport_info_action" msgid="2158204228510576227">"Besonderhede"</string> - <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skermkiekie"</string> + <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skermskoot"</string> <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Skermkiekie is suksesvol geneem."</string> <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Kon nie skermkiekie neem nie."</string> <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Foutverslag <xliff:g id="ID">#%d</xliff:g> se besonderhede"</string> diff --git a/packages/SimAppDialog/res/values-pt-rBR/strings.xml b/packages/SimAppDialog/res/values-pt-rBR/strings.xml index abf8dbd27ecc..fe31aa0d8b37 100644 --- a/packages/SimAppDialog/res/values-pt-rBR/strings.xml +++ b/packages/SimAppDialog/res/values-pt-rBR/strings.xml @@ -22,5 +22,5 @@ <string name="install_carrier_app_description" msgid="4014303558674923797">"Para que o novo chip funcione corretamente, instale o app <xliff:g id="ID_1">%1$s</xliff:g>"</string> <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Para que o novo chip funcione corretamente, instale o app da operadora"</string> <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Agora não"</string> - <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Fazer o download do app"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Baixar o app"</string> </resources> diff --git a/packages/SimAppDialog/res/values-pt/strings.xml b/packages/SimAppDialog/res/values-pt/strings.xml index abf8dbd27ecc..fe31aa0d8b37 100644 --- a/packages/SimAppDialog/res/values-pt/strings.xml +++ b/packages/SimAppDialog/res/values-pt/strings.xml @@ -22,5 +22,5 @@ <string name="install_carrier_app_description" msgid="4014303558674923797">"Para que o novo chip funcione corretamente, instale o app <xliff:g id="ID_1">%1$s</xliff:g>"</string> <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Para que o novo chip funcione corretamente, instale o app da operadora"</string> <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Agora não"</string> - <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Fazer o download do app"</string> + <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Baixar o app"</string> </resources> diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-af/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-af/strings.xml index cbb5ad732b2b..56fd06c71366 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-af/strings.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-af/strings.xml @@ -12,7 +12,7 @@ <string name="lockscreen_label" msgid="648347953557887087">"Sluitskerm"</string> <string name="quick_settings_label" msgid="2999117381487601865">"Kitsinstellings"</string> <string name="notifications_label" msgid="6829741046963013567">"Kennisgewings"</string> - <string name="screenshot_label" msgid="863978141223970162">"Skermkiekie"</string> + <string name="screenshot_label" msgid="863978141223970162">"Skermskoot"</string> <string name="screenshot_utterance" msgid="1430760563401895074">"Neem skermkiekie"</string> <string name="volume_up_label" msgid="8592766918780362870">"Volume harder"</string> <string name="volume_down_label" msgid="8574981863656447346">"Volume sagter"</string> diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fi/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fi/strings.xml index 5e317394cb31..8f2abaccbdd7 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fi/strings.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fi/strings.xml @@ -21,7 +21,7 @@ <string name="previous_button_content_description" msgid="840869171117765966">"Siirry edelliselle näytöllä"</string> <string name="next_button_content_description" msgid="6810058269847364406">"Siirry seuraavalle näytölle"</string> <string name="accessibility_menu_description" msgid="4458354794093858297">"Saavutettavuusvalikko on suuri näyttövalikko, josta voit ohjata laitettasi. Voit esimerkiksi lukita laitteen, säätää äänenvoimakkuutta ja kirkkautta sekä ottaa kuvakaappauksia."</string> - <string name="accessibility_menu_summary" msgid="340071398148208130">"Ohjaa laitetta suurella valikolla"</string> + <string name="accessibility_menu_summary" msgid="340071398148208130">"Ohjaa laitetta suuren valikon avulla"</string> <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Saavutettavuusvalikon asetukset"</string> <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Suuret painikkeet"</string> <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Suurenna saavutettavuusvalikon painikkeita"</string> diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml index 1cb9b5e3a73d..3d59c0b62ac4 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml @@ -2,7 +2,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="accessibility_menu_service_name" msgid="730136711554740131">"सुलभता मेन्यू"</string> - <string name="accessibility_menu_intro" msgid="3164193281544042394">"सुलभता मेन्यू, स्क्रीन पर दिखने वाला एक बड़ा मेन्यू होता है. इसकी मदद से, अपने डिवाइस को कंट्रोल किया जा सकता है. इस मेन्यू में जाकर, अपना डिवाइस लॉक करने, स्क्रीनशॉट लेने, स्क्रीन की रोशनी और आवाज़ कंट्रोल करने जैसे कई दूसरे काम किए जा सकते हैं."</string> + <string name="accessibility_menu_intro" msgid="3164193281544042394">"सुलभता मेन्यू, डिवाइस की स्क्रीन पर दिखने वाला एक बड़ा मेन्यू होता है. इस मेन्यू में जाकर, डिवाइस को लॉक करने, स्क्रीनशॉट लेने, स्क्रीन की रोशनी और आवाज़ को कंट्रोल करने जैसे कई काम किए जा सकते हैं."</string> <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string> <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string> <string name="a11y_settings_label" msgid="3977714687248445050">"सुलभता सेटिंग"</string> @@ -20,7 +20,7 @@ <string name="brightness_down_label" msgid="7115662941913272072">"स्क्रीन की रोशनी कम करें"</string> <string name="previous_button_content_description" msgid="840869171117765966">"पिछली स्क्रीन पर जाएं"</string> <string name="next_button_content_description" msgid="6810058269847364406">"अगली स्क्रीन पर जाएं"</string> - <string name="accessibility_menu_description" msgid="4458354794093858297">"सुलभता मेन्यू, स्क्रीन पर दिखने वाला एक बड़ा मेन्यू होता है. इसकी मदद से, अपने डिवाइस को कंट्रोल किया जा सकता है. इस मेन्यू में जाकर, अपना डिवाइस लॉक करने, स्क्रीनशॉट लेने, स्क्रीन की रोशनी और आवाज़ कंट्रोल करने जैसे कई दूसरे काम किए जा सकते हैं."</string> + <string name="accessibility_menu_description" msgid="4458354794093858297">"सुलभता मेन्यू, डिवाइस की स्क्रीन पर दिखने वाला एक बड़ा मेन्यू होता है. इस मेन्यू में जाकर, डिवाइस को लॉक करने, स्क्रीनशॉट लेने, स्क्रीन की रोशनी और आवाज़ को कंट्रोल करने जैसे कई काम किए जा सकते हैं."</string> <string name="accessibility_menu_summary" msgid="340071398148208130">"बड़े मेन्यू की मदद से डिवाइस को कंट्रोल करें"</string> <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"सुलभता मेन्यू सेटिंग"</string> <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"बड़े बटन"</string> diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ky/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ky/strings.xml index fa8b587e62c7..98c91ed65056 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ky/strings.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ky/strings.xml @@ -21,7 +21,7 @@ <string name="previous_button_content_description" msgid="840869171117765966">"Мурунку экранга өтүү"</string> <string name="next_button_content_description" msgid="6810058269847364406">"Кийинки экранга өтүү"</string> <string name="accessibility_menu_description" msgid="4458354794093858297">"Атайын мүмкүнчүлүктөр менюсу — бул түзмөгүңүздү көзөмөлдөөнү жеңилдетүүгө ылайыкташтырылган экрандагы чоң меню. Түзмөгүңүздү кулпулап, үнүнүн катуулугун жана экрандын жарыктыгын көзөмөлдөп, скриншотторду тартып жана башка аракеттерди аткара аласыз."</string> - <string name="accessibility_menu_summary" msgid="340071398148208130">"Түзмөктү чоң менюдан башкаруу"</string> + <string name="accessibility_menu_summary" msgid="340071398148208130">"Түзмөктү чоң менюдан башкарасыз"</string> <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Атайын мүмкүнчүлүктөр менюсунун параметрлери"</string> <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Чоң баскычтар"</string> <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Атайын мүмкүнчүлүктөр менюсундагы баскычтардын өлчөмүн чоңойтот"</string> diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ms/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ms/strings.xml index 9c1ea75d90f3..fd347324d05b 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ms/strings.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ms/strings.xml @@ -2,14 +2,14 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu Kebolehaksesan"</string> - <string name="accessibility_menu_intro" msgid="3164193281544042394">"Menu Kebolehaksesan menyediakan menu pada skrin yang besar untuk mengawal peranti anda. Anda boleh mengunci peranti anda, mengawal kelantangan dan kecerahan, mengambil tangkapan skrin dan banyak lagi."</string> + <string name="accessibility_menu_intro" msgid="3164193281544042394">"Menu Kebolehaksesan menyediakan menu yang besar pada skrin untuk mengawal peranti anda. Anda boleh mengunci peranti, mengawal kelantangan dan kecerahan, mengambil tangkapan skrin dan banyak lagi."</string> <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string> <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string> <string name="a11y_settings_label" msgid="3977714687248445050">"Tetapan Kebolehaksesan"</string> <string name="power_label" msgid="7699720321491287839">"Kuasa"</string> <string name="power_utterance" msgid="7444296686402104807">"Pilihan kuasa"</string> <string name="recent_apps_label" msgid="6583276995616385847">"Apl terbaharu"</string> - <string name="lockscreen_label" msgid="648347953557887087">"Kunci skrin"</string> + <string name="lockscreen_label" msgid="648347953557887087">"Skrin kunci"</string> <string name="quick_settings_label" msgid="2999117381487601865">"Tetapan Pantas"</string> <string name="notifications_label" msgid="6829741046963013567">"Pemberitahuan"</string> <string name="screenshot_label" msgid="863978141223970162">"Tangkapan skrin"</string> diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml index a8d6a0bc090c..3f72d955cc99 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml @@ -2,7 +2,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="accessibility_menu_service_name" msgid="730136711554740131">"Toegankelijkheidsmenu"</string> - <string name="accessibility_menu_intro" msgid="3164193281544042394">"Het toegankelijkheidsmenu is een groot menu op het scherm waarmee je je apparaat kunt bedienen. Je kunt onder meer je apparaat vergrendelen, het volume en de helderheid beheren en screenshots maken."</string> + <string name="accessibility_menu_intro" msgid="3164193281544042394">"Het toegankelijkheidsmenu is een groot menu op het scherm waarmee je je apparaat kunt bedienen. Je kunt onder meer je apparaat vergrendelen, het volume en de helderheid aanpassen en screenshots maken."</string> <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string> <string name="assistant_utterance" msgid="65509599221141377">"Assistent"</string> <string name="a11y_settings_label" msgid="3977714687248445050">"Instellingen voor toegankelijkheid"</string> @@ -21,7 +21,7 @@ <string name="previous_button_content_description" msgid="840869171117765966">"Ga naar vorig scherm"</string> <string name="next_button_content_description" msgid="6810058269847364406">"Ga naar volgend scherm"</string> <string name="accessibility_menu_description" msgid="4458354794093858297">"Het toegankelijkheidsmenu is een groot menu op het scherm waarmee je je apparaat kunt bedienen. Je kunt onder meer je apparaat vergrendelen, het volume en de helderheid aanpassen en screenshots maken."</string> - <string name="accessibility_menu_summary" msgid="340071398148208130">"Bedien apparaat via groot menu"</string> + <string name="accessibility_menu_summary" msgid="340071398148208130">"Bedien het apparaat via een groot menu"</string> <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Instellingen toegankelijkheidsmenu"</string> <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Grote knoppen"</string> <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Vergroot knoppen in het toegankelijkheidsmenu"</string> diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt-rPT/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt-rPT/strings.xml index 44aff75d1021..0cc2f58e13b5 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt-rPT/strings.xml @@ -21,7 +21,7 @@ <string name="previous_button_content_description" msgid="840869171117765966">"Ir para o ecrã anterior"</string> <string name="next_button_content_description" msgid="6810058269847364406">"Ir para o ecrã seguinte"</string> <string name="accessibility_menu_description" msgid="4458354794093858297">"O menu Acessibilidade disponibiliza um menu grande no ecrã para controlar o dispositivo. Pode bloquear o dispositivo, controlar o volume e o brilho, fazer capturas de ecrã e muito mais."</string> - <string name="accessibility_menu_summary" msgid="340071398148208130">"Controle o dispositivo através do menu grande"</string> + <string name="accessibility_menu_summary" msgid="340071398148208130">"Controlar dispositivo através do menu grande"</string> <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Definições do menu Acessibilidade"</string> <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Botões grandes"</string> <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Aumentar o tamanho dos botões do menu Acessibilidade"</string> diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml index 264749814e6c..62f63a8739d4 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml @@ -2,7 +2,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="accessibility_menu_service_name" msgid="730136711554740131">"Ponuka Dostupnosť"</string> - <string name="accessibility_menu_intro" msgid="3164193281544042394">"Ponukou dostupnosti sa rozumie veľká ponuka na obrazovke, pomocou ktorej môžete ovládať zariadenie. Môžete ho uzamknúť, ovládať hlasitosť a jas, vytvárať snímky obrazovky a mnoho ďalšieho."</string> + <string name="accessibility_menu_intro" msgid="3164193281544042394">"Ponukou Dostupnosť sa rozumie veľká ponuka na obrazovke, pomocou ktorej môžete ovládať zariadenie. Môžete ho uzamknúť, ovládať hlasitosť a jas, vytvárať snímky obrazovky a mnoho ďalšieho."</string> <string name="assistant_label" msgid="6796392082252272356">"Asistent"</string> <string name="assistant_utterance" msgid="65509599221141377">"Asistent"</string> <string name="a11y_settings_label" msgid="3977714687248445050">"Nastavenia dostupnosti"</string> @@ -21,7 +21,7 @@ <string name="previous_button_content_description" msgid="840869171117765966">"Prejsť na predchádzajúcu obrazovku"</string> <string name="next_button_content_description" msgid="6810058269847364406">"Prejsť na ďalšiu obrazovku"</string> <string name="accessibility_menu_description" msgid="4458354794093858297">"Ponuka dostupnosti spustí na obrazovke telefónu veľkú ponuku, pomocou ktorej môžete ovládať svoje zariadenie. Môžete ho uzamknúť, ovládať hlasitosť a jas, vytvárať snímky obrazovky a mnoho ďalšieho."</string> - <string name="accessibility_menu_summary" msgid="340071398148208130">"Ovládať zariadenie pomocou veľkej ponuky"</string> + <string name="accessibility_menu_summary" msgid="340071398148208130">"Ovládanie zariadenia pomocou veľkej ponuky"</string> <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Nastavenia ponuky dostupnosti"</string> <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Veľké tlačidlá"</string> <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Zväčšiť tlačidlá ponuky dostupnosti"</string> diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index fd2fa07f5e9d..b105a4e3b05a 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -746,8 +746,28 @@ flag { } flag { + name: "remove_dream_overlay_hide_on_touch" + namespace: "systemui" + description: "Removes logic to hide the dream overlay on user interaction, as it conflicts with various transitions" + bug: "329091030" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "keyboard_docking_indicator" namespace: "systemui" description: "Glow bar indicator reveals upon keyboard docking." bug: "324600132" } + +flag { + name: "dream_overlay_bouncer_swipe_direction_filtering" + namespace: "systemui" + description: "do not initiate bouncer swipe when the direction is opposite of the expansion" + bug: "333632464" + metadata { + purpose: PURPOSE_BUGFIX + } +}
\ No newline at end of file diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java index e20425d4b98c..94f884673fbd 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java @@ -36,6 +36,7 @@ import android.view.WindowManager; import android.view.WindowManager.TransitionOldType; import android.window.IRemoteTransition; import android.window.IRemoteTransitionFinishedCallback; +import android.window.RemoteTransitionStub; import android.window.TransitionInfo; import com.android.wm.shell.shared.CounterRotator; @@ -69,8 +70,8 @@ public abstract class RemoteAnimationRunnerCompat extends IRemoteAnimationRunner } /** Wraps a remote animation runner in a remote-transition. */ - public static IRemoteTransition.Stub wrap(IRemoteAnimationRunner runner) { - return new IRemoteTransition.Stub() { + public static RemoteTransitionStub wrap(IRemoteAnimationRunner runner) { + return new RemoteTransitionStub() { final ArrayMap<IBinder, Runnable> mFinishRunnables = new ArrayMap<>(); @Override @@ -233,11 +234,6 @@ public abstract class RemoteAnimationRunnerCompat extends IRemoteAnimationRunner runner.onAnimationCancelled(); finishRunnable.run(); } - - @Override - public void onTransitionConsumed(IBinder iBinder, boolean aborted) - throws RemoteException { - } }; } } diff --git a/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt b/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt index 4a89e31bcea8..36e6909a15cf 100644 --- a/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt +++ b/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt @@ -25,7 +25,6 @@ import androidx.compose.foundation.Canvas import androidx.compose.foundation.background import androidx.compose.foundation.interaction.DragInteraction import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -63,7 +62,6 @@ import androidx.compose.ui.layout.Placeable import androidx.compose.ui.layout.layoutId import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection -import androidx.compose.ui.res.colorResource import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntOffset @@ -458,40 +456,19 @@ object PlatformSliderDefaults { @Composable fun defaultPlatformSliderColors(): PlatformSliderColors = - if (isSystemInDarkTheme()) darkThemePlatformSliderColors() - else lightThemePlatformSliderColors() + PlatformSliderColors( + trackColor = MaterialTheme.colorScheme.secondaryContainer, + indicatorColor = MaterialTheme.colorScheme.primary, + iconColor = MaterialTheme.colorScheme.onPrimary, + labelColorOnIndicator = MaterialTheme.colorScheme.onPrimary, + labelColorOnTrack = MaterialTheme.colorScheme.onSecondaryContainer, + disabledTrackColor = MaterialTheme.colorScheme.surfaceContainerHighest, + disabledIndicatorColor = MaterialTheme.colorScheme.surfaceContainerHighest, + disabledIconColor = MaterialTheme.colorScheme.outline, + disabledLabelColor = MaterialTheme.colorScheme.onSurfaceVariant, + ) } -/** [PlatformSliderColors] for the light theme */ -@Composable -private fun lightThemePlatformSliderColors() = - PlatformSliderColors( - trackColor = colorResource(android.R.color.system_accent3_200), - indicatorColor = MaterialTheme.colorScheme.tertiary, - iconColor = MaterialTheme.colorScheme.onTertiary, - labelColorOnIndicator = MaterialTheme.colorScheme.onTertiary, - labelColorOnTrack = MaterialTheme.colorScheme.onTertiaryContainer, - disabledTrackColor = MaterialTheme.colorScheme.surfaceContainerHighest, - disabledIndicatorColor = MaterialTheme.colorScheme.surfaceContainerHighest, - disabledIconColor = MaterialTheme.colorScheme.outline, - disabledLabelColor = MaterialTheme.colorScheme.onSurfaceVariant, - ) - -/** [PlatformSliderColors] for the dark theme */ -@Composable -private fun darkThemePlatformSliderColors() = - PlatformSliderColors( - trackColor = colorResource(android.R.color.system_accent3_600), - indicatorColor = MaterialTheme.colorScheme.tertiary, - iconColor = MaterialTheme.colorScheme.onTertiary, - labelColorOnIndicator = MaterialTheme.colorScheme.onTertiary, - labelColorOnTrack = colorResource(android.R.color.system_accent3_900), - disabledTrackColor = MaterialTheme.colorScheme.surfaceContainerHighest, - disabledIndicatorColor = MaterialTheme.colorScheme.surfaceContainerHighest, - disabledIconColor = MaterialTheme.colorScheme.outline, - disabledLabelColor = MaterialTheme.colorScheme.onSurfaceVariant, - ) - private fun PlatformSliderColors.getTrackColor(isEnabled: Boolean): Color = if (isEnabled) trackColor else disabledTrackColor diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt index 3ec5508c81b3..d59f1f5bbe25 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt @@ -22,11 +22,8 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.android.compose.animation.scene.Back import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.SceneScope -import com.android.compose.animation.scene.Swipe -import com.android.compose.animation.scene.SwipeDirection import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.systemui.bouncer.ui.BouncerDialogFactory @@ -35,9 +32,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.ui.composable.ComposableScene import javax.inject.Inject -import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow object Bouncer { object Elements { @@ -57,13 +52,7 @@ constructor( override val key = Scenes.Bouncer override val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> = - MutableStateFlow( - mapOf( - Back to UserActionResult(Scenes.Lockscreen), - Swipe(SwipeDirection.Down) to UserActionResult(Scenes.Lockscreen), - ) - ) - .asStateFlow() + viewModel.destinationScenes @Composable override fun SceneScope.Content( diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncPopup.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncPopup.kt index 2af042aac5b4..e1ee01e78566 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncPopup.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncPopup.kt @@ -28,11 +28,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.slice.Slice +import com.android.internal.logging.UiEventLogger import com.android.systemui.animation.Expandable import com.android.systemui.res.R import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.volume.panel.component.anc.ui.viewmodel.AncViewModel import com.android.systemui.volume.panel.component.popup.ui.composable.VolumePanelPopup +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import javax.inject.Inject /** ANC popup up displaying ANC control [Slice]. */ @@ -41,10 +43,12 @@ class AncPopup constructor( private val volumePanelPopup: VolumePanelPopup, private val viewModel: AncViewModel, + private val uiEventLogger: UiEventLogger, ) { /** Shows a popup with the [expandable] animation. */ fun show(expandable: Expandable?) { + uiEventLogger.log(VolumePanelUiEvent.VOLUME_PANEL_ANC_POPUP_SHOWN) volumePanelPopup.show(expandable, { Title() }, { Content(it) }) } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt index eed54dab6faf..9a98bdeec8f1 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt @@ -26,6 +26,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign +import com.android.internal.logging.UiEventLogger import com.android.systemui.animation.Expandable import com.android.systemui.common.ui.compose.Icon import com.android.systemui.common.ui.compose.toColor @@ -34,6 +35,7 @@ import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.volume.panel.component.popup.ui.composable.VolumePanelPopup import com.android.systemui.volume.panel.component.selector.ui.composable.VolumePanelRadioButtonBar import com.android.systemui.volume.panel.component.spatial.ui.viewmodel.SpatialAudioViewModel +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import javax.inject.Inject class SpatialAudioPopup @@ -41,10 +43,17 @@ class SpatialAudioPopup constructor( private val viewModel: SpatialAudioViewModel, private val volumePanelPopup: VolumePanelPopup, + private val uiEventLogger: UiEventLogger, ) { /** Shows a popup with the [expandable] animation. */ fun show(expandable: Expandable) { + uiEventLogger.logWithPosition( + VolumePanelUiEvent.VOLUME_PANEL_SPATIAL_AUDIO_POP_UP_SHOWN, + 0, + null, + viewModel.spatialAudioButtons.value.indexOfFirst { it.button.isChecked } + ) volumePanelPopup.show(expandable, { Title() }, { Content(it) }) } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt index f89669c8456c..a54d005c990a 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt @@ -85,6 +85,7 @@ fun ColumnVolumeSliders( onValueChange = { newValue: Float -> sliderViewModel.onValueChanged(sliderState, newValue) }, + onValueChangeFinished = { sliderViewModel.onValueChangeFinished() }, onIconTapped = { sliderViewModel.toggleMuted(sliderState) }, sliderColors = sliderColors, ) @@ -131,6 +132,7 @@ fun ColumnVolumeSliders( onValueChange = { newValue: Float -> sliderViewModel.onValueChanged(sliderState, newValue) }, + onValueChangeFinished = { sliderViewModel.onValueChangeFinished() }, onIconTapped = { sliderViewModel.toggleMuted(sliderState) }, sliderColors = sliderColors, ) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/GridVolumeSliders.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/GridVolumeSliders.kt index b284c691ef0e..bb17499f021f 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/GridVolumeSliders.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/GridVolumeSliders.kt @@ -46,6 +46,7 @@ fun GridVolumeSliders( onValueChange = { newValue: Float -> sliderViewModel.onValueChanged(sliderState, newValue) }, + onValueChangeFinished = { sliderViewModel.onValueChangeFinished() }, onIconTapped = { sliderViewModel.toggleMuted(sliderState) }, sliderColors = sliderColors, ) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt index 28cd37ea9327..228d29259038 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt @@ -51,6 +51,7 @@ import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.Sl fun VolumeSlider( state: SliderState, onValueChange: (newValue: Float) -> Unit, + onValueChangeFinished: (() -> Unit)? = null, onIconTapped: () -> Unit, modifier: Modifier = Modifier, sliderColors: PlatformSliderColors, @@ -85,6 +86,7 @@ fun VolumeSlider( value = value, valueRange = state.valueRange, onValueChange = onValueChange, + onValueChangeFinished = onValueChangeFinished, enabled = state.isEnabled, icon = { state.icon?.let { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt index 3afca96e07a0..0db0e0767767 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt @@ -18,6 +18,10 @@ package com.android.systemui.bouncer.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.compose.animation.scene.Back +import com.android.compose.animation.scene.Swipe +import com.android.compose.animation.scene.SwipeDirection +import com.android.compose.animation.scene.UserActionResult import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository @@ -34,7 +38,10 @@ import com.android.systemui.flags.Flags import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.kosmos.testScope import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags +import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.scene.shared.model.fakeSceneDataSource import com.android.systemui.testKosmos +import com.android.systemui.truth.containsEntriesExactly import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -193,6 +200,23 @@ class BouncerViewModelTest : SysuiTestCase() { assertThat(isFoldSplitRequired).isTrue() } + @Test + fun destinationScenes() = + testScope.runTest { + val destinationScenes by collectLastValue(underTest.destinationScenes) + kosmos.fakeSceneDataSource.changeScene(Scenes.QuickSettings) + runCurrent() + + kosmos.fakeSceneDataSource.changeScene(Scenes.Bouncer) + runCurrent() + + assertThat(destinationScenes) + .containsEntriesExactly( + Back to UserActionResult(Scenes.QuickSettings), + Swipe(SwipeDirection.Down) to UserActionResult(Scenes.QuickSettings), + ) + } + private fun authMethodsToTest(): List<AuthenticationMethodModel> { return listOf(None, Pin, Password, Pattern, Sim) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt index 8bc6a00a3426..6b2a1d59e62d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt @@ -66,6 +66,7 @@ import com.android.systemui.keyguard.data.repository.fakeTrustRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.kosmos.testDispatcher @@ -820,21 +821,37 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { } @Test - fun isAuthenticatedIsResetToFalseWhenKeyguardDoneAnimationsFinished() = + fun isAuthenticatedIsResetToFalseWhenFinishedTransitioningToGoneAndStatusBarStateShade() = testScope.runTest { initCollectors() allPreconditionsToRunFaceAuthAreTrue() triggerFaceAuth(false) + keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) authenticationCallback.value.onAuthenticationSucceeded( mock(FaceManager.AuthenticationResult::class.java) ) assertThat(authenticated()).isTrue() - keyguardRepository.keyguardDoneAnimationsFinished() + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + ) + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.FINISHED, + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + ) + ) + assertThat(authenticated()).isTrue() + keyguardRepository.setStatusBarState(StatusBarState.SHADE) assertThat(authenticated()).isFalse() } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java index 315a24bfd945..a43415869580 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java @@ -16,6 +16,8 @@ package com.android.systemui.dreams.complication; +import static com.android.systemui.Flags.FLAG_REMOVE_DREAM_OVERLAY_HIDE_ON_TOUCH; + import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; @@ -23,6 +25,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.os.Handler; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.view.MotionEvent; import android.view.View; @@ -90,6 +94,7 @@ public class HideComplicationTouchHandlerTest extends SysuiTestCase { * Ensures no actions are taken when there multiple sessions. */ @Test + @DisableFlags(FLAG_REMOVE_DREAM_OVERLAY_HIDE_ON_TOUCH) public void testSessionEndOnMultipleSessions() { final HideComplicationTouchHandler touchHandler = new HideComplicationTouchHandler( mVisibilityController, @@ -122,6 +127,7 @@ public class HideComplicationTouchHandlerTest extends SysuiTestCase { * Ensures no actions are taken when the bouncer is showing. */ @Test + @DisableFlags(FLAG_REMOVE_DREAM_OVERLAY_HIDE_ON_TOUCH) public void testSessionEndWhenBouncerShowing() { final HideComplicationTouchHandler touchHandler = new HideComplicationTouchHandler( mVisibilityController, @@ -154,6 +160,7 @@ public class HideComplicationTouchHandlerTest extends SysuiTestCase { * Ensures no actions are taken when there multiple sessions. */ @Test + @DisableFlags(FLAG_REMOVE_DREAM_OVERLAY_HIDE_ON_TOUCH) public void testSessionEndWithTouchInInset() { final HideComplicationTouchHandler touchHandler = new HideComplicationTouchHandler( mVisibilityController, @@ -202,6 +209,7 @@ public class HideComplicationTouchHandlerTest extends SysuiTestCase { * Make sure visibility changes are triggered from session events. */ @Test + @DisableFlags(FLAG_REMOVE_DREAM_OVERLAY_HIDE_ON_TOUCH) public void testSessionLifecycle() { final HideComplicationTouchHandler touchHandler = new HideComplicationTouchHandler( mVisibilityController, @@ -259,4 +267,34 @@ public class HideComplicationTouchHandlerTest extends SysuiTestCase { // Verify session ended. verify(mSession).pop(); } + + @Test + @EnableFlags(FLAG_REMOVE_DREAM_OVERLAY_HIDE_ON_TOUCH) + public void testNoActionWhenDisabledByFlag() { + final HideComplicationTouchHandler touchHandler = new HideComplicationTouchHandler( + mVisibilityController, + RESTORE_TIMEOUT, + HIDE_DELAY, + mTouchInsetManager, + mStatusBarKeyguardViewManager, + mFakeExecutor, + mStateController); + + // Report one session. + when(mSession.getActiveSessionCount()).thenReturn(1); + + // Bouncer is showing. + when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); + + // Start session. + touchHandler.onSessionStart(mSession); + + // Verify session end. + verify(mSession).pop(); + + mClock.advanceTime(HIDE_DELAY); + + // Verify no interaction with visibility controller. + verify(mVisibilityController, never()).setVisibility(anyInt()); + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java index 0f8fc3824e3f..9f52ae9a7406 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java @@ -31,6 +31,8 @@ import android.animation.ValueAnimator; import android.content.pm.UserInfo; import android.graphics.Rect; import android.graphics.Region; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; @@ -41,6 +43,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants; import com.android.systemui.dreams.touch.scrim.ScrimController; @@ -277,6 +280,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { /** * Makes sure swiping up when bouncer initially showing doesn't change the expansion amount. */ + @DisableFlags(Flags.FLAG_DREAM_OVERLAY_BOUNCER_SWIPE_DIRECTION_FILTERING) @Test public void testSwipeUp_whenBouncerInitiallyShowing_doesNotSetExpansion() { when(mCentralSurfaces.isBouncerShowing()).thenReturn(true); @@ -297,8 +301,36 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); - assertThat(gestureListener.onScroll(event1, event2, 0, distanceY)) - .isTrue(); + assertThat(gestureListener.onScroll(event1, event2, 0, distanceY)).isTrue(); + + verify(mScrimController, never()).expand(any()); + } + + /** + * Makes sure swiping up when bouncer initially showing doesn't change the expansion amount. + */ + @Test + @EnableFlags(Flags.FLAG_DREAM_OVERLAY_BOUNCER_SWIPE_DIRECTION_FILTERING) + public void testSwipeUp_whenBouncerInitiallyShowing_doesNotSetExpansion_directionFiltering() { + when(mCentralSurfaces.isBouncerShowing()).thenReturn(true); + + mTouchHandler.onSessionStart(mTouchSession); + ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor = + ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class); + verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture()); + + final OnGestureListener gestureListener = gestureListenerCaptor.getValue(); + + final float percent = .3f; + final float distanceY = SCREEN_HEIGHT_PX * percent; + + // Swiping up near the top of the screen where the touch initiation region is. + final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, + 0, distanceY, 0); + final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, + 0, 0, 0); + + assertThat(gestureListener.onScroll(event1, event2, 0, distanceY)).isFalse(); verify(mScrimController, never()).expand(any()); } @@ -307,6 +339,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { * Makes sure swiping down when bouncer initially hidden doesn't change the expansion amount. */ @Test + @DisableFlags(Flags.FLAG_DREAM_OVERLAY_BOUNCER_SWIPE_DIRECTION_FILTERING) public void testSwipeDown_whenBouncerInitiallyHidden_doesNotSetExpansion() { mTouchHandler.onSessionStart(mTouchSession); ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor = @@ -324,8 +357,34 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, SCREEN_HEIGHT_PX, 0); - assertThat(gestureListener.onScroll(event1, event2, 0, distanceY)) - .isTrue(); + assertThat(gestureListener.onScroll(event1, event2, 0, -distanceY)).isTrue(); + + verify(mScrimController, never()).expand(any()); + } + + /** + * Makes sure swiping down when bouncer initially hidden doesn't change the expansion amount. + */ + @Test + @EnableFlags(Flags.FLAG_DREAM_OVERLAY_BOUNCER_SWIPE_DIRECTION_FILTERING) + public void testSwipeDown_whenBouncerInitiallyHidden_doesNotSetExpansion_directionFiltering() { + mTouchHandler.onSessionStart(mTouchSession); + ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor = + ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class); + verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture()); + + final OnGestureListener gestureListener = gestureListenerCaptor.getValue(); + + final float percent = .15f; + final float distanceY = SCREEN_HEIGHT_PX * percent; + + // Swiping down near the bottom of the screen where the touch initiation region is. + final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, + 0, SCREEN_HEIGHT_PX - distanceY, 0); + final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, + 0, SCREEN_HEIGHT_PX, 0); + + assertThat(gestureListener.onScroll(event1, event2, 0, -distanceY)).isFalse(); verify(mScrimController, never()).expand(any()); } @@ -444,7 +503,8 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { 0, direction == Direction.UP ? SCREEN_HEIGHT_PX - distanceY : distanceY, 0); reset(mScrimController); - assertThat(gestureListener.onScroll(event1, event2, 0, distanceY)) + assertThat(gestureListener.onScroll(event1, event2, 0, + direction == Direction.UP ? distanceY : -distanceY)) .isTrue(); // Ensure only called once @@ -643,7 +703,8 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, direction == Direction.UP ? SCREEN_HEIGHT_PX - distanceY : distanceY, 0); - assertThat(gestureListenerCaptor.getValue().onScroll(event1, event2, 0, distanceY)) + assertThat(gestureListenerCaptor.getValue().onScroll(event1, event2, 0, + direction == Direction.UP ? distanceY : -distanceY)) .isTrue(); final MotionEvent upEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt index 8f03717b42f2..3889703e74c4 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt @@ -26,39 +26,34 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.AnimatorTestRule import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.haptics.vibratorHelper +import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository +import com.android.systemui.keyguard.domain.interactor.keyguardInteractor +import com.android.systemui.kosmos.backgroundCoroutineContext import com.android.systemui.kosmos.testScope -import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.testKosmos -import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.UnconfinedTestDispatcher -import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.any import org.mockito.Mock -import org.mockito.Mockito.never -import org.mockito.Mockito.verify import org.mockito.junit.MockitoJUnit import org.mockito.junit.MockitoRule @SmallTest @RunWith(AndroidJUnit4::class) -@OptIn(ExperimentalCoroutinesApi::class) @RunWithLooper(setAsMainLooper = true) class QSLongPressEffectTest : SysuiTestCase() { @Rule @JvmField val mMockitoRule: MockitoRule = MockitoJUnit.rule() - @Mock private lateinit var vibratorHelper: VibratorHelper @Mock private lateinit var testView: View @get:Rule val animatorTestRule = AnimatorTestRule(this) private val kosmos = testKosmos() + private val vibratorHelper = kosmos.vibratorHelper private val effectDuration = 400 private val lowTickDuration = 12 @@ -68,19 +63,71 @@ class QSLongPressEffectTest : SysuiTestCase() { @Before fun setup() { - whenever( - vibratorHelper.getPrimitiveDurations( - VibrationEffect.Composition.PRIMITIVE_LOW_TICK, - VibrationEffect.Composition.PRIMITIVE_SPIN, - ) - ) - .thenReturn(intArrayOf(lowTickDuration, spinDuration)) + vibratorHelper.primitiveDurations[VibrationEffect.Composition.PRIMITIVE_LOW_TICK] = + lowTickDuration + vibratorHelper.primitiveDurations[VibrationEffect.Composition.PRIMITIVE_SPIN] = spinDuration + + kosmos.fakeKeyguardRepository.setKeyguardDismissible(true) longPressEffect = QSLongPressEffect( vibratorHelper, - effectDuration, + kosmos.keyguardInteractor, + CoroutineScope(kosmos.backgroundCoroutineContext), ) + longPressEffect.initializeEffect(effectDuration) + } + + @Test + fun onReset_whileIdle_resetsEffect() = testWithScope { + // GIVEN a call to reset + longPressEffect.resetEffect() + + // THEN the effect remains idle and has not been initialized + val state by collectLastValue(longPressEffect.state) + assertThat(state).isEqualTo(QSLongPressEffect.State.IDLE) + assertThat(longPressEffect.hasInitialized).isFalse() + } + + @Test + fun onReset_whileRunning_resetsEffect() = testWhileRunning { + // GIVEN a call to reset + longPressEffect.resetEffect() + + // THEN the effect remains idle and has not been initialized + val state by collectLastValue(longPressEffect.state) + assertThat(state).isEqualTo(QSLongPressEffect.State.IDLE) + assertThat(longPressEffect.hasInitialized).isFalse() + } + + @Test + fun onInitialize_withNegativeDuration_doesNotInitialize() = testWithScope { + // GIVEN an effect that has reset + longPressEffect.resetEffect() + + // WHEN attempting to initialize with a negative duration + val couldInitialize = longPressEffect.initializeEffect(-1) + + // THEN the effect can't initialized and remains reset + val state by collectLastValue(longPressEffect.state) + assertThat(couldInitialize).isFalse() + assertThat(state).isEqualTo(QSLongPressEffect.State.IDLE) + assertThat(longPressEffect.hasInitialized).isFalse() + } + + @Test + fun onInitialize_withPositiveDuration_initializes() = testWithScope { + // GIVEN an effect that has reset + longPressEffect.resetEffect() + + // WHEN attempting to initialize with a positive duration + val couldInitialize = longPressEffect.initializeEffect(effectDuration) + + // THEN the effect is initialized + val state by collectLastValue(longPressEffect.state) + assertThat(couldInitialize).isTrue() + assertThat(state).isEqualTo(QSLongPressEffect.State.IDLE) + assertThat(longPressEffect.hasInitialized).isTrue() } @Test @@ -90,7 +137,8 @@ class QSLongPressEffectTest : SysuiTestCase() { longPressEffect.onTouch(testView, downEvent) // THEN the effect moves to the TIMEOUT_WAIT state - assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.TIMEOUT_WAIT) + val state by collectLastValue(longPressEffect.state) + assertThat(state).isEqualTo(QSLongPressEffect.State.TIMEOUT_WAIT) } @Test @@ -100,7 +148,8 @@ class QSLongPressEffectTest : SysuiTestCase() { longPressEffect.onTouch(testView, cancelEvent) // THEN the effect goes back to idle and does not start - assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.IDLE) + val state by collectLastValue(longPressEffect.state) + assertThat(state).isEqualTo(QSLongPressEffect.State.IDLE) assertEffectDidNotStart() } @@ -121,7 +170,7 @@ class QSLongPressEffectTest : SysuiTestCase() { @Test fun onWaitComplete_whileWaiting_beginsEffect() = testWhileWaiting { // GIVEN the pressed timeout is complete - advanceTimeBy(QSLongPressEffect.PRESSED_TIMEOUT + 10L) + longPressEffect.handleTimeoutComplete() // THEN the effect starts assertEffectStarted() @@ -154,15 +203,28 @@ class QSLongPressEffectTest : SysuiTestCase() { } @Test - fun onAnimationComplete_effectEnds() = testWhileRunning { + fun onAnimationComplete_keyguardDismissible_effectEndsWithLongPress() = testWhileRunning { // GIVEN that the animation completes animatorTestRule.advanceTimeBy(effectDuration + 10L) - // THEN the long-press effect completes - assertEffectCompleted() + // THEN the long-press effect completes with a LONG_PRESS + assertEffectCompleted(QSLongPressEffect.ActionType.LONG_PRESS) } @Test + fun onAnimationComplete_keyguardNotDismissible_effectEndsWithResetAndLongPress() = + testWhileRunning { + // GIVEN that the keyguard is not dismissible + kosmos.fakeKeyguardRepository.setKeyguardDismissible(false) + + // GIVEN that the animation completes + animatorTestRule.advanceTimeBy(effectDuration + 10L) + + // THEN the long-press effect completes with RESET_AND_LONG_PRESS + assertEffectCompleted(QSLongPressEffect.ActionType.RESET_AND_LONG_PRESS) + } + + @Test fun onActionDown_whileRunningBackwards_resets() = testWhileRunning { // GIVEN that the effect is at the middle of its completion (progress of 50%) animatorTestRule.advanceTimeBy(effectDuration / 2L) @@ -192,33 +254,21 @@ class QSLongPressEffectTest : SysuiTestCase() { animatorTestRule.advanceTimeBy(effectDuration.toLong()) // THEN the state goes to [QSLongPressEffect.State.IDLE] - assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.IDLE) + val state by collectLastValue(longPressEffect.state) + assertThat(state).isEqualTo(QSLongPressEffect.State.IDLE) } private fun buildMotionEvent(action: Int): MotionEvent = MotionEventBuilder.newBuilder().setAction(action).build() private fun testWithScope(test: suspend TestScope.() -> Unit) = - with(kosmos) { - testScope.runTest { - // GIVEN an effect with a testing scope - longPressEffect.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler)) - - // THEN run the test - test() - } - } + with(kosmos) { testScope.runTest { test() } } private fun testWhileWaiting(test: suspend TestScope.() -> Unit) = with(kosmos) { testScope.runTest { - // GIVEN an effect with a testing scope - longPressEffect.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler)) - // GIVEN the TIMEOUT_WAIT state is entered - val downEvent = - MotionEventBuilder.newBuilder().setAction(MotionEvent.ACTION_DOWN).build() - longPressEffect.onTouch(testView, downEvent) + longPressEffect.setState(QSLongPressEffect.State.TIMEOUT_WAIT) // THEN run the test test() @@ -228,16 +278,9 @@ class QSLongPressEffectTest : SysuiTestCase() { private fun testWhileRunning(test: suspend TestScope.() -> Unit) = with(kosmos) { testScope.runTest { - // GIVEN an effect with a testing scope - longPressEffect.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler)) - - // GIVEN the down event that enters the TIMEOUT_WAIT state - val downEvent = - MotionEventBuilder.newBuilder().setAction(MotionEvent.ACTION_DOWN).build() - longPressEffect.onTouch(testView, downEvent) - - // GIVEN that the timeout completes and the effect starts - advanceTimeBy(QSLongPressEffect.PRESSED_TIMEOUT + 10L) + // GIVEN that the effect starts after the tap timeout is complete + longPressEffect.setState(QSLongPressEffect.State.TIMEOUT_WAIT) + longPressEffect.handleTimeoutComplete() // THEN run the test test() @@ -252,6 +295,7 @@ class QSLongPressEffectTest : SysuiTestCase() { */ private fun TestScope.assertEffectStarted() { val effectProgress by collectLastValue(longPressEffect.effectProgress) + val state by collectLastValue(longPressEffect.state) val longPressHint = LongPressHapticBuilder.createLongPressHint( lowTickDuration, @@ -259,10 +303,10 @@ class QSLongPressEffectTest : SysuiTestCase() { effectDuration, ) - assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.RUNNING_FORWARD) + assertThat(state).isEqualTo(QSLongPressEffect.State.RUNNING_FORWARD) assertThat(effectProgress).isEqualTo(0f) assertThat(longPressHint).isNotNull() - verify(vibratorHelper).vibrate(longPressHint!!) + assertThat(vibratorHelper.hasVibratedWithEffects(longPressHint!!)).isTrue() } /** @@ -274,11 +318,12 @@ class QSLongPressEffectTest : SysuiTestCase() { */ private fun TestScope.assertEffectDidNotStart() { val effectProgress by collectLastValue(longPressEffect.effectProgress) + val state by collectLastValue(longPressEffect.state) - assertThat(longPressEffect.state).isNotEqualTo(QSLongPressEffect.State.RUNNING_FORWARD) - assertThat(longPressEffect.state).isNotEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS) + assertThat(state).isNotEqualTo(QSLongPressEffect.State.RUNNING_FORWARD) + assertThat(state).isNotEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS) assertThat(effectProgress).isNull() - verify(vibratorHelper, never()).vibrate(any(/* type= */ VibrationEffect::class.java)) + assertThat(vibratorHelper.totalVibrations).isEqualTo(0) } /** @@ -286,18 +331,19 @@ class QSLongPressEffectTest : SysuiTestCase() { * 1. The progress is null * 2. The final snap haptics are played * 3. The internal state goes back to [QSLongPressEffect.State.IDLE] - * 4. The action to perform on the tile is the long-press action + * 4. The action to perform on the tile is the action given as a parameter */ - private fun TestScope.assertEffectCompleted() { + private fun TestScope.assertEffectCompleted(expectedAction: QSLongPressEffect.ActionType) { val action by collectLastValue(longPressEffect.actionType) val effectProgress by collectLastValue(longPressEffect.effectProgress) val snapEffect = LongPressHapticBuilder.createSnapEffect() + val state by collectLastValue(longPressEffect.state) assertThat(effectProgress).isNull() assertThat(snapEffect).isNotNull() - verify(vibratorHelper).vibrate(snapEffect!!) - assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.IDLE) - assertThat(action).isEqualTo(QSLongPressEffect.ActionType.LONG_PRESS) + assertThat(vibratorHelper.hasVibratedWithEffects(snapEffect!!)).isTrue() + assertThat(state).isEqualTo(QSLongPressEffect.State.IDLE) + assertThat(action).isEqualTo(expectedAction) } /** @@ -305,17 +351,18 @@ class QSLongPressEffectTest : SysuiTestCase() { * 1. The internal state is [QSLongPressEffect.State.RUNNING_BACKWARDS] * 2. The reverse haptics plays at the point where the animation was paused */ - private fun assertEffectReverses(pausedProgress: Float) { + private fun TestScope.assertEffectReverses(pausedProgress: Float) { val reverseHaptics = LongPressHapticBuilder.createReversedEffect( pausedProgress, lowTickDuration, effectDuration, ) + val state by collectLastValue(longPressEffect.state) - assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS) + assertThat(state).isEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS) assertThat(reverseHaptics).isNotNull() - verify(vibratorHelper).vibrate(reverseHaptics!!) + assertThat(vibratorHelper.hasVibratedWithEffects(reverseHaptics!!)).isTrue() } /** @@ -325,8 +372,9 @@ class QSLongPressEffectTest : SysuiTestCase() { */ private fun TestScope.assertEffectResets() { val effectProgress by collectLastValue(longPressEffect.effectProgress) - assertThat(effectProgress).isEqualTo(0f) + val state by collectLastValue(longPressEffect.state) - assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.TIMEOUT_WAIT) + assertThat(effectProgress).isNull() + assertThat(state).isEqualTo(QSLongPressEffect.State.TIMEOUT_WAIT) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt index 33a17e8c56dd..c88e432d15d2 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt @@ -16,14 +16,13 @@ package com.android.systemui.keyguard.domain.interactor -import android.platform.test.annotations.DisableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardClockSwitch.LARGE import com.android.keyguard.KeyguardClockSwitch.SMALL -import com.android.systemui.Flags as AConfigFlags import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.flags.Flags import com.android.systemui.flags.fakeFeatureFlagsClassic @@ -66,7 +65,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() { } @Test - @DisableFlags(AConfigFlags.FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun clockSize_sceneContainerFlagOff_basedOnRepository() = testScope.runTest { val value by collectLastValue(underTest.clockSize) @@ -78,7 +77,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() { } @Test - @DisableFlags(AConfigFlags.FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun clockShouldBeCentered_sceneContainerFlagOff_basedOnRepository() = testScope.runTest { val value by collectLastValue(underTest.clockShouldBeCentered) @@ -192,7 +191,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() { val value by collectLastValue(underTest.clockShouldBeCentered) kosmos.shadeRepository.setShadeMode(ShadeMode.Split) kosmos.activeNotificationListRepository.setActiveNotifs(1) - kosmos.headsUpNotificationRepository.headsUpAnimatingAway.value = true + kosmos.headsUpNotificationRepository.isHeadsUpAnimatingAway.value = true kosmos.keyguardRepository.setIsDozing(true) assertThat(value).isEqualTo(false) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt index 15c9cf73d51d..412292554e73 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt @@ -55,28 +55,29 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() { val testScope = kosmos.testScope @Test - fun transitionCollectorsReceivesOnlyAppropriateEvents() = runTest { - val lockscreenToAodSteps by collectValues(underTest.lockscreenToAodTransition) - val aodToLockscreenSteps by collectValues(underTest.aodToLockscreenTransition) - - val steps = mutableListOf<TransitionStep>() - steps.add(TransitionStep(AOD, GONE, 0f, STARTED)) - steps.add(TransitionStep(AOD, GONE, 1f, FINISHED)) - steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED)) - steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING)) - steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED)) - steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)) - steps.add(TransitionStep(LOCKSCREEN, AOD, 0.1f, RUNNING)) - steps.add(TransitionStep(LOCKSCREEN, AOD, 0.2f, RUNNING)) + fun transitionCollectorsReceivesOnlyAppropriateEvents() = + testScope.runTest { + val lockscreenToAodSteps by collectValues(underTest.transition(LOCKSCREEN, AOD)) + val aodToLockscreenSteps by collectValues(underTest.transition(AOD, LOCKSCREEN)) - steps.forEach { - repository.sendTransitionStep(it) - runCurrent() - } + val steps = mutableListOf<TransitionStep>() + steps.add(TransitionStep(AOD, GONE, 0f, STARTED)) + steps.add(TransitionStep(AOD, GONE, 1f, FINISHED)) + steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED)) + steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING)) + steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED)) + steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)) + steps.add(TransitionStep(LOCKSCREEN, AOD, 0.1f, RUNNING)) + steps.add(TransitionStep(LOCKSCREEN, AOD, 0.2f, RUNNING)) - assertThat(aodToLockscreenSteps).isEqualTo(steps.subList(2, 5)) - assertThat(lockscreenToAodSteps).isEqualTo(steps.subList(5, 8)) - } + steps.forEach { + repository.sendTransitionStep(it) + runCurrent() + } + + assertThat(aodToLockscreenSteps).isEqualTo(steps.subList(2, 5)) + assertThat(lockscreenToAodSteps).isEqualTo(steps.subList(5, 8)) + } @Test fun dozeAmountTransitionTest_AodToFromLockscreen() = @@ -187,59 +188,60 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() { } @Test - fun finishedKeyguardTransitionStepTests() = runTest { - val finishedSteps by collectValues(underTest.finishedKeyguardTransitionStep) + fun finishedKeyguardTransitionStepTests() = + testScope.runTest { + val finishedSteps by collectValues(underTest.finishedKeyguardTransitionStep) + val steps = mutableListOf<TransitionStep>() - val steps = mutableListOf<TransitionStep>() + steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)) + steps.add(TransitionStep(LOCKSCREEN, AOD, 0.9f, RUNNING)) + steps.add(TransitionStep(LOCKSCREEN, AOD, 1f, FINISHED)) + steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED)) + steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING)) + steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED)) + steps.add(TransitionStep(AOD, GONE, 1f, STARTED)) - steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)) - steps.add(TransitionStep(LOCKSCREEN, AOD, 0.9f, RUNNING)) - steps.add(TransitionStep(LOCKSCREEN, AOD, 1f, FINISHED)) - steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED)) - steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING)) - steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED)) - steps.add(TransitionStep(AOD, GONE, 1f, STARTED)) + steps.forEach { + repository.sendTransitionStep(it) + runCurrent() + } - steps.forEach { - repository.sendTransitionStep(it) - runCurrent() + // Ignore the default state. + assertThat(finishedSteps.subList(1, finishedSteps.size)) + .isEqualTo(listOf(steps[2], steps[5])) } - // Ignore the default state. - assertThat(finishedSteps.subList(1, finishedSteps.size)) - .isEqualTo(listOf(steps[2], steps[5])) - } - @Test - fun startedKeyguardTransitionStepTests() = runTest { - val startedSteps by collectValues(underTest.startedKeyguardTransitionStep) + fun startedKeyguardTransitionStepTests() = + testScope.runTest { + val startedSteps by collectValues(underTest.startedKeyguardTransitionStep) - val steps = mutableListOf<TransitionStep>() + val steps = mutableListOf<TransitionStep>() - steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED)) - steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING)) - steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED)) - steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)) - steps.add(TransitionStep(LOCKSCREEN, AOD, 0.9f, RUNNING)) - steps.add(TransitionStep(LOCKSCREEN, AOD, 1f, FINISHED)) - steps.add(TransitionStep(AOD, GONE, 1f, STARTED)) + steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED)) + steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING)) + steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED)) + steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)) + steps.add(TransitionStep(LOCKSCREEN, AOD, 0.9f, RUNNING)) + steps.add(TransitionStep(LOCKSCREEN, AOD, 1f, FINISHED)) + steps.add(TransitionStep(AOD, GONE, 1f, STARTED)) - steps.forEach { - repository.sendTransitionStep(it) - runCurrent() - } + steps.forEach { + repository.sendTransitionStep(it) + runCurrent() + } - assertThat(startedSteps) - .isEqualTo( - listOf( - // The initial transition will also get sent when collect started - TransitionStep(OFF, LOCKSCREEN, 0f, STARTED), - steps[0], - steps[3], - steps[6] + assertThat(startedSteps) + .isEqualTo( + listOf( + // The initial transition will also get sent when collect started + TransitionStep(OFF, LOCKSCREEN, 0f, STARTED), + steps[0], + steps[3], + steps[6] + ) ) - ) - } + } @Test fun transitionValue() = diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt index f0607f4b70e1..0ac7ff5232a3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt @@ -16,6 +16,7 @@ package com.android.systemui.keyguard.ui +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE import com.android.systemui.SysuiTestCase @@ -35,10 +36,9 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.junit.runners.JUnit4 @SmallTest -@RunWith(JUnit4::class) +@RunWith(AndroidJUnit4::class) class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { val kosmos = testKosmos() val testScope = kosmos.testScope diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt index dddf6485d0f4..4c16a339d696 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt @@ -49,9 +49,7 @@ class OccludedToLockscreenTransitionViewModelTest : SysuiTestCase() { val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository val configurationRepository = kosmos.fakeConfigurationRepository - val underTest by lazy { - kosmos.occludedToLockscreenTransitionViewModel - } + val underTest by lazy { kosmos.occludedToLockscreenTransitionViewModel } @Test fun lockscreenFadeIn() = @@ -164,25 +162,6 @@ class OccludedToLockscreenTransitionViewModelTest : SysuiTestCase() { values.forEach { assertThat(it).isEqualTo(1f) } } - @Test - fun deviceEntryBackgroundView_noUdfpsEnrolled_noUpdates() = - testScope.runTest { - fingerprintPropertyRepository.supportsRearFps() - biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true) - val values by collectValues(underTest.deviceEntryBackgroundViewAlpha) - - keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED)) - keyguardTransitionRepository.sendTransitionStep(step(0.1f)) - keyguardTransitionRepository.sendTransitionStep(step(0.3f)) - keyguardTransitionRepository.sendTransitionStep(step(0.4f)) - keyguardTransitionRepository.sendTransitionStep(step(0.5f)) - keyguardTransitionRepository.sendTransitionStep(step(0.6f)) - keyguardTransitionRepository.sendTransitionStep(step(0.8f)) - keyguardTransitionRepository.sendTransitionStep(step(1f)) - - assertThat(values).isEmpty() // no updates - } - private fun step( value: Float, state: TransitionState = TransitionState.RUNNING diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt index 956ef661d467..33eb90acdcb3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt @@ -26,7 +26,9 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope import com.android.systemui.media.controls.MediaTestHelper import com.android.systemui.media.controls.shared.model.MediaData +import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel import com.android.systemui.media.controls.shared.model.SmartspaceMediaData +import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest @@ -144,6 +146,37 @@ class MediaFilterRepositoryTest : SysuiTestCase() { assertThat(smartspaceMediaData?.isActive).isFalse() } + @Test + fun addMediaDataLoadingState() = + testScope.runTest { + val mediaDataLoadedStates by collectLastValue(underTest.mediaDataLoadedStates) + val instanceId = InstanceId.fakeInstanceId(123) + val mediaLoadedStates = mutableListOf(MediaDataLoadingModel.Loaded(instanceId)) + + underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId)) + + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates) + + mediaLoadedStates.remove(MediaDataLoadingModel.Loaded(instanceId)) + + underTest.addMediaDataLoadingState(MediaDataLoadingModel.Removed(instanceId)) + + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates) + } + + @Test + fun setRecommendationsLoadingState() = + testScope.runTest { + val recommendationsLoadingState by + collectLastValue(underTest.recommendationsLoadingState) + val recommendationsLoadingModel = + SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE) + + underTest.setRecommedationsLoadingState(recommendationsLoadingModel) + + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) + } + companion object { private const val KEY = "KEY" private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID" diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt index d9d84f2d2aac..a0a1eb3a6ca6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt @@ -20,6 +20,7 @@ import android.R import android.graphics.drawable.Icon import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.internal.logging.InstanceId import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.Flags @@ -28,13 +29,20 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.media.controls.MediaTestHelper import com.android.systemui.media.controls.data.repository.MediaFilterRepository import com.android.systemui.media.controls.data.repository.mediaFilterRepository +import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor +import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter import com.android.systemui.media.controls.shared.model.MediaData +import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel import com.android.systemui.media.controls.shared.model.SmartspaceMediaData +import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel +import com.android.systemui.statusbar.notificationLockscreenUserManager import com.android.systemui.testKosmos +import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -45,9 +53,17 @@ class MediaCarouselInteractorTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope + private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter + private val notificationLockscreenUserManager = kosmos.notificationLockscreenUserManager private val mediaFilterRepository: MediaFilterRepository = kosmos.mediaFilterRepository + private val underTest: MediaCarouselInteractor = kosmos.mediaCarouselInteractor + @Before + fun setUp() { + underTest.start() + } + @Test fun addUserMediaEntry_activeThenInactivate() = testScope.runTest { @@ -56,7 +72,7 @@ class MediaCarouselInteractorTest : SysuiTestCase() { val hasActiveMedia by collectLastValue(underTest.hasActiveMedia) val hasAnyMedia by collectLastValue(underTest.hasAnyMedia) - val userMedia = MediaData().copy(active = true) + val userMedia = MediaData(active = true) mediaFilterRepository.addSelectedUserMediaEntry(userMedia) @@ -79,7 +95,7 @@ class MediaCarouselInteractorTest : SysuiTestCase() { val hasActiveMedia by collectLastValue(underTest.hasActiveMedia) val hasAnyMedia by collectLastValue(underTest.hasAnyMedia) - val userMedia = MediaData().copy(active = false) + val userMedia = MediaData(active = false) val instanceId = userMedia.instanceId mediaFilterRepository.addSelectedUserMediaEntry(userMedia) @@ -112,7 +128,7 @@ class MediaCarouselInteractorTest : SysuiTestCase() { isActive = true, recommendations = MediaTestHelper.getValidRecommendationList(icon), ) - val userMedia = MediaData().copy(active = false) + val userMedia = MediaData(active = false) mediaFilterRepository.setRecommendation(userMediaRecommendation) @@ -199,7 +215,80 @@ class MediaCarouselInteractorTest : SysuiTestCase() { fun hasActiveMediaOrRecommendation_nothingSet_returnsFalse() = testScope.runTest { assertThat(underTest.hasActiveMediaOrRecommendation.value).isFalse() } + @Test + fun onMediaDataUpdated_updatesLoadingState() = + testScope.runTest { + whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true) + whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true) + val mediaDataLoadedStates by collectLastValue(underTest.mediaDataLoadedStates) + val instanceId = InstanceId.fakeInstanceId(123) + val mediaLoadedStates: MutableList<MediaDataLoadingModel> = mutableListOf() + + mediaLoadedStates.add(MediaDataLoadingModel.Loaded(instanceId)) + mediaDataFilter.onMediaDataLoaded( + KEY, + KEY, + MediaData(userId = USER_ID, instanceId = instanceId) + ) + + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates) + + val newInstanceId = InstanceId.fakeInstanceId(321) + + mediaLoadedStates.add(MediaDataLoadingModel.Loaded(newInstanceId)) + mediaDataFilter.onMediaDataLoaded( + KEY_2, + KEY_2, + MediaData(userId = USER_ID, instanceId = newInstanceId) + ) + + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates) + + mediaLoadedStates.remove(MediaDataLoadingModel.Loaded(instanceId)) + + mediaDataFilter.onMediaDataRemoved(KEY) + + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates) + + mediaLoadedStates.remove(MediaDataLoadingModel.Loaded(newInstanceId)) + + mediaDataFilter.onMediaDataRemoved(KEY_2) + + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates) + } + + @Test + fun onMediaRecommendationsUpdated_updatesLoadingState() = + testScope.runTest { + whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true) + whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true) + val recommendationsLoadingState by + collectLastValue(underTest.recommendationsLoadingState) + val icon = Icon.createWithResource(context, R.drawable.ic_media_play) + val mediaRecommendations = + SmartspaceMediaData( + targetId = KEY_MEDIA_SMARTSPACE, + isActive = true, + recommendations = MediaTestHelper.getValidRecommendationList(icon), + ) + var recommendationsLoadingModel: SmartspaceMediaLoadingModel = + SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, isPrioritized = true) + + mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, mediaRecommendations) + + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) + + recommendationsLoadingModel = SmartspaceMediaLoadingModel.Removed(KEY_MEDIA_SMARTSPACE) + + mediaDataFilter.onSmartspaceMediaDataRemoved(KEY_MEDIA_SMARTSPACE) + + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) + } + companion object { + private const val KEY = "key" + private const val KEY_2 = "key2" + private const val USER_ID = 0 private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID" } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt index 75e66fb06ce8..61adcd2e2c25 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt @@ -20,13 +20,11 @@ package com.android.systemui.scene.domain.startable import android.app.StatusBarManager import android.os.PowerManager -import android.platform.test.annotations.EnableFlags import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey -import com.android.systemui.Flags as AconfigFlags import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository import com.android.systemui.authentication.domain.interactor.authenticationInteractor @@ -40,6 +38,7 @@ import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepositor import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor +import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository @@ -94,7 +93,7 @@ import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidJUnit4::class) -@EnableFlags(AconfigFlags.FLAG_SCENE_CONTAINER) +@EnableSceneContainer class SceneContainerStartableTest : SysuiTestCase() { @Mock private lateinit var windowController: NotificationShadeWindowController @@ -291,6 +290,38 @@ class SceneContainerStartableTest : SysuiTestCase() { } @Test + fun switchFromBouncerToQuickSettingsWhenDeviceUnlocked() = + testScope.runTest { + val currentSceneKey by collectLastValue(sceneInteractor.currentScene) + + val transitionState = + prepareState( + authenticationMethod = AuthenticationMethodModel.Pin, + isDeviceUnlocked = false, + initialSceneKey = Scenes.Lockscreen, + ) + assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) + underTest.start() + runCurrent() + + sceneInteractor.changeScene(Scenes.QuickSettings, "switching to qs for test") + transitionState.value = ObservableTransitionState.Idle(Scenes.QuickSettings) + runCurrent() + assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings) + + sceneInteractor.changeScene(Scenes.Bouncer, "switching to bouncer for test") + transitionState.value = ObservableTransitionState.Idle(Scenes.Bouncer) + runCurrent() + assertThat(currentSceneKey).isEqualTo(Scenes.Bouncer) + + kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( + SuccessFingerprintAuthenticationStatus(0, true) + ) + + assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings) + } + + @Test fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn() = testScope.runTest { val currentSceneKey by collectLastValue(sceneInteractor.currentScene) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt index e590bae3c53c..2938acf293b3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt @@ -16,11 +16,10 @@ package com.android.systemui.scene.shared.flag -import android.platform.test.annotations.DisableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.Flags.FLAG_SCENE_CONTAINER import com.android.systemui.SysuiTestCase +import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.kosmos.Kosmos import com.google.common.truth.Truth @@ -32,7 +31,7 @@ import org.junit.runner.RunWith internal class SceneContainerFlagsTest : SysuiTestCase() { @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun isNotEnabled_withoutAconfigFlags() { Truth.assertThat(SceneContainerFlag.isEnabled).isEqualTo(false) Truth.assertThat(SceneContainerFlagsImpl().isEnabled()).isEqualTo(false) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt index 757a6c9e5ac6..5b33ecbb28be 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt @@ -641,7 +641,6 @@ class ShadeInteractorImplTest : SysuiTestCase() { ) ) val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) - runCurrent() assertThat(isShadeTouchable).isFalse() } @@ -668,13 +667,17 @@ class ShadeInteractorImplTest : SysuiTestCase() { ) ) val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) - runCurrent() assertThat(isShadeTouchable).isTrue() } @Test fun isShadeTouchable_isFalse_whenStartingToSleepAndNotControlScreenOff() = testScope.runTest { + whenever(dozeParameters.shouldControlScreenOff()).thenReturn(false) + val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) + // Assert the default condition is true + assertThat(isShadeTouchable).isTrue() + powerRepository.updateWakefulness( rawState = WakefulnessState.STARTING_TO_SLEEP, lastWakeReason = WakeSleepReason.POWER_BUTTON, @@ -688,15 +691,17 @@ class ShadeInteractorImplTest : SysuiTestCase() { transitionState = TransitionState.STARTED, ) ) - whenever(dozeParameters.shouldControlScreenOff()).thenReturn(false) - val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) - runCurrent() assertThat(isShadeTouchable).isFalse() } @Test fun isShadeTouchable_isTrue_whenStartingToSleepAndControlScreenOff() = testScope.runTest { + whenever(dozeParameters.shouldControlScreenOff()).thenReturn(true) + val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) + // Assert the default condition is true + assertThat(isShadeTouchable).isTrue() + powerRepository.updateWakefulness( rawState = WakefulnessState.STARTING_TO_SLEEP, lastWakeReason = WakeSleepReason.POWER_BUTTON, @@ -710,9 +715,6 @@ class ShadeInteractorImplTest : SysuiTestCase() { transitionState = TransitionState.STARTED, ) ) - whenever(dozeParameters.shouldControlScreenOff()).thenReturn(true) - val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) - runCurrent() assertThat(isShadeTouchable).isTrue() } @@ -730,7 +732,6 @@ class ShadeInteractorImplTest : SysuiTestCase() { ) ) val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) - runCurrent() assertThat(isShadeTouchable).isTrue() } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt index c8062fb4e724..f0498ded64a5 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt @@ -16,57 +16,20 @@ package com.android.systemui.statusbar.phone -import android.app.ActivityOptions import android.app.PendingIntent import android.content.Intent -import android.os.Bundle -import android.os.RemoteException -import android.os.UserHandle -import android.view.View -import android.widget.FrameLayout -import android.window.SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.ActivityIntentHelper import com.android.systemui.SysuiTestCase -import com.android.systemui.animation.ActivityTransitionAnimator -import com.android.systemui.animation.LaunchableView -import com.android.systemui.assist.AssistManager -import com.android.systemui.keyguard.KeyguardViewMediator -import com.android.systemui.keyguard.WakefulnessLifecycle -import com.android.systemui.plugins.ActivityStarter.OnDismissAction -import com.android.systemui.settings.UserTracker -import com.android.systemui.shade.ShadeController -import com.android.systemui.shade.data.repository.FakeShadeRepository -import com.android.systemui.shade.data.repository.ShadeAnimationRepository -import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractorLegacyImpl -import com.android.systemui.statusbar.CommandQueue -import com.android.systemui.statusbar.NotificationLockscreenUserManager -import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.SysuiStatusBarStateController -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow -import com.android.systemui.statusbar.policy.DeviceProvisionedController -import com.android.systemui.statusbar.policy.KeyguardStateController -import com.android.systemui.statusbar.window.StatusBarWindowController import com.android.systemui.util.concurrency.FakeExecutor -import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.argumentCaptor -import com.android.systemui.util.mockito.eq -import com.android.systemui.util.mockito.nullable -import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat -import dagger.Lazy -import java.util.Optional import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock -import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.mock -import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @@ -74,177 +37,22 @@ import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidJUnit4::class) class ActivityStarterImplTest : SysuiTestCase() { - @Mock private lateinit var centralSurfaces: CentralSurfaces - @Mock private lateinit var assistManager: AssistManager - @Mock private lateinit var dozeServiceHost: DozeServiceHost - @Mock private lateinit var biometricUnlockController: BiometricUnlockController - @Mock private lateinit var keyguardViewMediator: KeyguardViewMediator - @Mock private lateinit var shadeController: ShadeController - @Mock private lateinit var commandQueue: CommandQueue - @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager - @Mock private lateinit var mActivityTransitionAnimator: ActivityTransitionAnimator - @Mock private lateinit var lockScreenUserManager: NotificationLockscreenUserManager - @Mock private lateinit var statusBarWindowController: StatusBarWindowController - @Mock private lateinit var notifShadeWindowController: NotificationShadeWindowController - @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle - @Mock private lateinit var keyguardStateController: KeyguardStateController + @Mock private lateinit var legacyActivityStarterInternal: LegacyActivityStarterInternalImpl + @Mock private lateinit var activityStarterInternal: ActivityStarterInternalImpl @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController - @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor - @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController - @Mock private lateinit var userTracker: UserTracker - @Mock private lateinit var activityIntentHelper: ActivityIntentHelper private lateinit var underTest: ActivityStarterImpl private val mainExecutor = FakeExecutor(FakeSystemClock()) - private val shadeAnimationInteractor = - ShadeAnimationInteractorLegacyImpl(ShadeAnimationRepository(), FakeShadeRepository()) @Before fun setUp() { MockitoAnnotations.initMocks(this) underTest = ActivityStarterImpl( - Lazy { Optional.of(centralSurfaces) }, - Lazy { assistManager }, - Lazy { dozeServiceHost }, - Lazy { biometricUnlockController }, - Lazy { keyguardViewMediator }, - Lazy { shadeController }, - commandQueue, - shadeAnimationInteractor, - Lazy { statusBarKeyguardViewManager }, - Lazy { notifShadeWindowController }, - mActivityTransitionAnimator, - context, - DISPLAY_ID, - lockScreenUserManager, - statusBarWindowController, - wakefulnessLifecycle, - keyguardStateController, - statusBarStateController, - keyguardUpdateMonitor, - deviceProvisionedController, - userTracker, - activityIntentHelper, - mainExecutor, + statusBarStateController = statusBarStateController, + mainExecutor = mainExecutor, + legacyActivityStarter = { legacyActivityStarterInternal }, + activityStarterInternal = { activityStarterInternal }, ) - whenever(userTracker.userHandle).thenReturn(UserHandle.OWNER) - } - - @Test - fun startPendingIntentDismissingKeyguard_keyguardShowing_dismissWithAction() { - val pendingIntent = mock(PendingIntent::class.java) - whenever(pendingIntent.isActivity).thenReturn(true) - whenever(keyguardStateController.isShowing).thenReturn(true) - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) - - underTest.startPendingIntentDismissingKeyguard(pendingIntent) - mainExecutor.runAllReady() - - verify(statusBarKeyguardViewManager) - .dismissWithAction(any(OnDismissAction::class.java), eq(null), anyBoolean(), eq(null)) - } - - @Test - fun startPendingIntentMaybeDismissingKeyguard_keyguardShowing_showOverLs_launchAnimator() { - val pendingIntent = mock(PendingIntent::class.java) - val parent = FrameLayout(context) - val view = - object : View(context), LaunchableView { - override fun setShouldBlockVisibilityChanges(block: Boolean) {} - } - parent.addView(view) - val controller = ActivityTransitionAnimator.Controller.fromView(view) - whenever(pendingIntent.isActivity).thenReturn(true) - whenever(keyguardStateController.isShowing).thenReturn(true) - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) - whenever(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt())) - .thenReturn(true) - - underTest.startPendingIntentMaybeDismissingKeyguard( - intent = pendingIntent, - animationController = controller, - intentSentUiThreadCallback = null, - ) - mainExecutor.runAllReady() - - verify(mActivityTransitionAnimator) - .startPendingIntentWithAnimation( - nullable(), - eq(true), - nullable(), - eq(true), - any(), - ) - } - - fun startPendingIntentDismissingKeyguard_fillInIntentAndExtraOptions_sendAndReturnResult() { - val pendingIntent = mock(PendingIntent::class.java) - val fillInIntent = mock(Intent::class.java) - val parent = FrameLayout(context) - val view = - object : View(context), LaunchableView { - override fun setShouldBlockVisibilityChanges(block: Boolean) {} - } - parent.addView(view) - val controller = ActivityTransitionAnimator.Controller.fromView(view) - whenever(pendingIntent.isActivity).thenReturn(true) - whenever(keyguardStateController.isShowing).thenReturn(true) - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) - whenever(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt())) - .thenReturn(false) - - // extra activity options to set on pending intent - val activityOptions = mock(ActivityOptions::class.java) - activityOptions.splashScreenStyle = SPLASH_SCREEN_STYLE_SOLID_COLOR - activityOptions.isPendingIntentBackgroundActivityLaunchAllowedByPermission = false - val bundleCaptor = argumentCaptor<Bundle>() - - underTest.startPendingIntentMaybeDismissingKeyguard( - intent = pendingIntent, - animationController = controller, - intentSentUiThreadCallback = null, - fillInIntent = fillInIntent, - extraOptions = activityOptions.toBundle(), - ) - mainExecutor.runAllReady() - - // Fill-in intent is passed and options contain extra values specified - verify(pendingIntent) - .sendAndReturnResult( - eq(context), - eq(0), - eq(fillInIntent), - nullable(), - nullable(), - nullable(), - bundleCaptor.capture() - ) - val options = ActivityOptions.fromBundle(bundleCaptor.value) - assertThat(options.isPendingIntentBackgroundActivityLaunchAllowedByPermission).isFalse() - assertThat(options.splashScreenStyle).isEqualTo(SPLASH_SCREEN_STYLE_SOLID_COLOR) - } - - @Test - fun startPendingIntentDismissingKeyguard_associatedView_getAnimatorController() { - val pendingIntent = mock(PendingIntent::class.java) - val associatedView = mock(ExpandableNotificationRow::class.java) - - underTest.startPendingIntentDismissingKeyguard( - intent = pendingIntent, - intentSentUiThreadCallback = null, - associatedView = associatedView, - ) - - verify(centralSurfaces).getAnimatorControllerFromNotification(associatedView) - } - - @Test - fun startActivity_noUserHandleProvided_getUserHandle() { - val intent = mock(Intent::class.java) - - underTest.startActivity(intent, false) - - verify(userTracker).userHandle } @Test @@ -258,115 +66,9 @@ class ActivityStarterImplTest : SysuiTestCase() { @Test fun postStartActivityDismissingKeyguard_intent_postsOnMain() { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) - val intent = mock(Intent::class.java) - - underTest.postStartActivityDismissingKeyguard(intent, 0) + underTest.postStartActivityDismissingKeyguard(mock(Intent::class.java), 0) assertThat(mainExecutor.numPending()).isEqualTo(1) - mainExecutor.runAllReady() - - verify(deviceProvisionedController).isDeviceProvisioned - verify(shadeController).collapseShadeForActivityStart() - } - - @Test - fun postStartActivityDismissingKeyguard_intent_notDeviceProvisioned_doesNotProceed() { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(false) - val intent = mock(Intent::class.java) - - underTest.postStartActivityDismissingKeyguard(intent, 0) - mainExecutor.runAllReady() - - verify(deviceProvisionedController).isDeviceProvisioned - verify(shadeController, never()).collapseShadeForActivityStart() - } - - @Test - fun dismissKeyguardThenExecute_startWakeAndUnlock() { - whenever(wakefulnessLifecycle.wakefulness) - .thenReturn(WakefulnessLifecycle.WAKEFULNESS_ASLEEP) - whenever(keyguardStateController.canDismissLockScreen()).thenReturn(true) - whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false) - whenever(dozeServiceHost.isPulsing).thenReturn(true) - - underTest.dismissKeyguardThenExecute({ true }, {}, false) - - verify(biometricUnlockController) - .startWakeAndUnlock(BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) - } - - @Test - fun dismissKeyguardThenExecute_keyguardIsShowing_dismissWithAction() { - val customMessage = "Enter your pin." - whenever(keyguardStateController.isShowing).thenReturn(true) - - underTest.dismissKeyguardThenExecute({ true }, {}, false, customMessage) - - verify(statusBarKeyguardViewManager) - .dismissWithAction( - any(OnDismissAction::class.java), - any(Runnable::class.java), - eq(false), - eq(customMessage) - ) - } - - @Test - fun dismissKeyguardThenExecute_awakeDreams() { - val customMessage = "Enter your pin." - var dismissActionExecuted = false - whenever(keyguardStateController.isShowing).thenReturn(false) - whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true) - - underTest.dismissKeyguardThenExecute( - { - dismissActionExecuted = true - true - }, - {}, - false, - customMessage - ) - - verify(centralSurfaces).awakenDreams() - assertThat(dismissActionExecuted).isTrue() - } - - @Test - @Throws(RemoteException::class) - fun executeRunnableDismissingKeyguard_dreaming_notShowing_awakenDreams() { - whenever(keyguardStateController.isShowing).thenReturn(false) - whenever(keyguardStateController.isOccluded).thenReturn(false) - whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true) - - underTest.executeRunnableDismissingKeyguard( - runnable = {}, - cancelAction = null, - dismissShade = false, - afterKeyguardGone = false, - deferred = false - ) - - verify(centralSurfaces, times(1)).awakenDreams() - } - - @Test - @Throws(RemoteException::class) - fun executeRunnableDismissingKeyguard_notDreaming_notShowing_doNotAwakenDreams() { - whenever(keyguardStateController.isShowing).thenReturn(false) - whenever(keyguardStateController.isOccluded).thenReturn(false) - whenever(keyguardUpdateMonitor.isDreaming).thenReturn(false) - - underTest.executeRunnableDismissingKeyguard( - runnable = {}, - cancelAction = null, - dismissShade = false, - afterKeyguardGone = false, - deferred = false - ) - - verify(centralSurfaces, never()).awakenDreams() } @Test @@ -377,8 +79,4 @@ class ActivityStarterImplTest : SysuiTestCase() { mainExecutor.runAllReady() verify(statusBarStateController).setLeaveOpenOnKeyguardHide(true) } - - private companion object { - private const val DISPLAY_ID = 0 - } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt new file mode 100644 index 000000000000..b443489f98e2 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt @@ -0,0 +1,358 @@ +/* + * 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.statusbar.phone + +import android.app.ActivityOptions +import android.app.PendingIntent +import android.content.Intent +import android.os.Bundle +import android.os.RemoteException +import android.os.UserHandle +import android.view.View +import android.widget.FrameLayout +import android.window.SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.ActivityIntentHelper +import com.android.systemui.SysuiTestCase +import com.android.systemui.animation.ActivityTransitionAnimator +import com.android.systemui.animation.LaunchableView +import com.android.systemui.assist.AssistManager +import com.android.systemui.keyguard.KeyguardViewMediator +import com.android.systemui.keyguard.WakefulnessLifecycle +import com.android.systemui.plugins.ActivityStarter.OnDismissAction +import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeController +import com.android.systemui.shade.data.repository.FakeShadeRepository +import com.android.systemui.shade.data.repository.ShadeAnimationRepository +import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractorLegacyImpl +import com.android.systemui.statusbar.CommandQueue +import com.android.systemui.statusbar.NotificationLockscreenUserManager +import com.android.systemui.statusbar.NotificationShadeWindowController +import com.android.systemui.statusbar.SysuiStatusBarStateController +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import com.android.systemui.statusbar.policy.DeviceProvisionedController +import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.statusbar.window.StatusBarWindowController +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.eq +import com.android.systemui.util.mockito.nullable +import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.time.FakeSystemClock +import com.google.common.truth.Truth.assertThat +import java.util.Optional +import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.Mock +import org.mockito.Mockito.anyBoolean +import org.mockito.Mockito.mock +import org.mockito.Mockito.never +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@ExperimentalCoroutinesApi +@SmallTest +@RunWith(AndroidJUnit4::class) +class LegacyActivityStarterInternalImplTest : SysuiTestCase() { + @Mock private lateinit var centralSurfaces: CentralSurfaces + @Mock private lateinit var assistManager: AssistManager + @Mock private lateinit var dozeServiceHost: DozeServiceHost + @Mock private lateinit var biometricUnlockController: BiometricUnlockController + @Mock private lateinit var keyguardViewMediator: KeyguardViewMediator + @Mock private lateinit var shadeController: ShadeController + @Mock private lateinit var commandQueue: CommandQueue + @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager + @Mock private lateinit var activityTransitionAnimator: ActivityTransitionAnimator + @Mock private lateinit var lockScreenUserManager: NotificationLockscreenUserManager + @Mock private lateinit var statusBarWindowController: StatusBarWindowController + @Mock private lateinit var notifShadeWindowController: NotificationShadeWindowController + @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle + @Mock private lateinit var keyguardStateController: KeyguardStateController + @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController + @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor + @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController + @Mock private lateinit var userTracker: UserTracker + @Mock private lateinit var activityIntentHelper: ActivityIntentHelper + private lateinit var underTest: LegacyActivityStarterInternalImpl + private val mainExecutor = FakeExecutor(FakeSystemClock()) + private val shadeAnimationInteractor = + ShadeAnimationInteractorLegacyImpl(ShadeAnimationRepository(), FakeShadeRepository()) + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + underTest = + LegacyActivityStarterInternalImpl( + centralSurfacesOptLazy = { Optional.of(centralSurfaces) }, + assistManagerLazy = { assistManager }, + dozeServiceHostLazy = { dozeServiceHost }, + biometricUnlockControllerLazy = { biometricUnlockController }, + keyguardViewMediatorLazy = { keyguardViewMediator }, + shadeControllerLazy = { shadeController }, + commandQueue = commandQueue, + shadeAnimationInteractor = shadeAnimationInteractor, + statusBarKeyguardViewManagerLazy = { statusBarKeyguardViewManager }, + notifShadeWindowControllerLazy = { notifShadeWindowController }, + activityTransitionAnimator = activityTransitionAnimator, + context = context, + displayId = DISPLAY_ID, + lockScreenUserManager = lockScreenUserManager, + statusBarWindowController = statusBarWindowController, + wakefulnessLifecycle = wakefulnessLifecycle, + keyguardStateController = keyguardStateController, + statusBarStateController = statusBarStateController, + keyguardUpdateMonitor = keyguardUpdateMonitor, + deviceProvisionedController = deviceProvisionedController, + userTracker = userTracker, + activityIntentHelper = activityIntentHelper, + mainExecutor = mainExecutor, + ) + whenever(userTracker.userHandle).thenReturn(UserHandle.OWNER) + } + + @Test + fun startPendingIntentDismissingKeyguard_keyguardShowing_dismissWithAction() { + val pendingIntent = mock(PendingIntent::class.java) + whenever(pendingIntent.isActivity).thenReturn(true) + whenever(keyguardStateController.isShowing).thenReturn(true) + whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + + underTest.startPendingIntentDismissingKeyguard(pendingIntent) + mainExecutor.runAllReady() + + verify(statusBarKeyguardViewManager) + .dismissWithAction(any(OnDismissAction::class.java), eq(null), anyBoolean(), eq(null)) + } + + @Test + fun startPendingIntentMaybeDismissingKeyguard_keyguardShowing_showOverLs_launchAnimator() { + val pendingIntent = mock(PendingIntent::class.java) + val parent = FrameLayout(context) + val view = + object : View(context), LaunchableView { + override fun setShouldBlockVisibilityChanges(block: Boolean) {} + } + parent.addView(view) + val controller = ActivityTransitionAnimator.Controller.fromView(view) + whenever(pendingIntent.isActivity).thenReturn(true) + whenever(keyguardStateController.isShowing).thenReturn(true) + whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + whenever(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt())) + .thenReturn(true) + + startPendingIntentMaybeDismissingKeyguard( + intent = pendingIntent, + animationController = controller, + intentSentUiThreadCallback = null, + ) + mainExecutor.runAllReady() + + verify(activityTransitionAnimator) + .startPendingIntentWithAnimation( + nullable(), + eq(true), + nullable(), + eq(true), + any(), + ) + } + + fun startPendingIntentDismissingKeyguard_fillInIntentAndExtraOptions_sendAndReturnResult() { + val pendingIntent = mock(PendingIntent::class.java) + val fillInIntent = mock(Intent::class.java) + val parent = FrameLayout(context) + val view = + object : View(context), LaunchableView { + override fun setShouldBlockVisibilityChanges(block: Boolean) {} + } + parent.addView(view) + val controller = ActivityTransitionAnimator.Controller.fromView(view) + whenever(pendingIntent.isActivity).thenReturn(true) + whenever(keyguardStateController.isShowing).thenReturn(true) + whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + whenever(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt())) + .thenReturn(false) + + // extra activity options to set on pending intent + val activityOptions = mock(ActivityOptions::class.java) + activityOptions.splashScreenStyle = SPLASH_SCREEN_STYLE_SOLID_COLOR + activityOptions.isPendingIntentBackgroundActivityLaunchAllowedByPermission = false + val bundleCaptor = argumentCaptor<Bundle>() + + startPendingIntentMaybeDismissingKeyguard( + intent = pendingIntent, + animationController = controller, + intentSentUiThreadCallback = null, + fillInIntent = fillInIntent, + extraOptions = activityOptions.toBundle(), + ) + mainExecutor.runAllReady() + + // Fill-in intent is passed and options contain extra values specified + verify(pendingIntent) + .sendAndReturnResult( + eq(context), + eq(0), + eq(fillInIntent), + nullable(), + nullable(), + nullable(), + bundleCaptor.capture() + ) + val options = ActivityOptions.fromBundle(bundleCaptor.value) + assertThat(options.isPendingIntentBackgroundActivityLaunchAllowedByPermission).isFalse() + assertThat(options.splashScreenStyle).isEqualTo(SPLASH_SCREEN_STYLE_SOLID_COLOR) + } + + @Test + fun startPendingIntentDismissingKeyguard_associatedView_getAnimatorController() { + val pendingIntent = mock(PendingIntent::class.java) + val associatedView = mock(ExpandableNotificationRow::class.java) + + underTest.startPendingIntentDismissingKeyguard( + intent = pendingIntent, + intentSentUiThreadCallback = null, + associatedView = associatedView, + ) + + verify(centralSurfaces).getAnimatorControllerFromNotification(associatedView) + } + + @Test + fun startActivity_noUserHandleProvided_getUserHandle() { + val intent = mock(Intent::class.java) + + underTest.startActivity(intent, false, null, false, null) + + verify(userTracker).userHandle + } + + @Test + fun dismissKeyguardThenExecute_startWakeAndUnlock() { + whenever(wakefulnessLifecycle.wakefulness) + .thenReturn(WakefulnessLifecycle.WAKEFULNESS_ASLEEP) + whenever(keyguardStateController.canDismissLockScreen()).thenReturn(true) + whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false) + whenever(dozeServiceHost.isPulsing).thenReturn(true) + + underTest.dismissKeyguardThenExecute({ true }, {}, false) + + verify(biometricUnlockController) + .startWakeAndUnlock(BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) + } + + @Test + fun dismissKeyguardThenExecute_keyguardIsShowing_dismissWithAction() { + val customMessage = "Enter your pin." + whenever(keyguardStateController.isShowing).thenReturn(true) + + underTest.dismissKeyguardThenExecute({ true }, {}, false, customMessage) + + verify(statusBarKeyguardViewManager) + .dismissWithAction( + any(OnDismissAction::class.java), + any(Runnable::class.java), + eq(false), + eq(customMessage) + ) + } + + @Test + fun dismissKeyguardThenExecute_awakeDreams() { + val customMessage = "Enter your pin." + var dismissActionExecuted = false + whenever(keyguardStateController.isShowing).thenReturn(false) + whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true) + + underTest.dismissKeyguardThenExecute( + { + dismissActionExecuted = true + true + }, + {}, + false, + customMessage + ) + + verify(centralSurfaces).awakenDreams() + assertThat(dismissActionExecuted).isTrue() + } + + @Test + @Throws(RemoteException::class) + fun executeRunnableDismissingKeyguard_dreaming_notShowing_awakenDreams() { + whenever(keyguardStateController.isShowing).thenReturn(false) + whenever(keyguardStateController.isOccluded).thenReturn(false) + whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true) + + underTest.executeRunnableDismissingKeyguard( + runnable = {}, + cancelAction = null, + dismissShade = false, + afterKeyguardGone = false, + deferred = false + ) + + verify(centralSurfaces, times(1)).awakenDreams() + } + + @Test + @Throws(RemoteException::class) + fun executeRunnableDismissingKeyguard_notDreaming_notShowing_doNotAwakenDreams() { + whenever(keyguardStateController.isShowing).thenReturn(false) + whenever(keyguardStateController.isOccluded).thenReturn(false) + whenever(keyguardUpdateMonitor.isDreaming).thenReturn(false) + + underTest.executeRunnableDismissingKeyguard( + runnable = {}, + cancelAction = null, + dismissShade = false, + afterKeyguardGone = false, + deferred = false + ) + + verify(centralSurfaces, never()).awakenDreams() + } + + private fun startPendingIntentMaybeDismissingKeyguard( + intent: PendingIntent, + intentSentUiThreadCallback: Runnable?, + animationController: ActivityTransitionAnimator.Controller?, + fillInIntent: Intent? = null, + extraOptions: Bundle? = null, + ) { + underTest.startPendingIntentDismissingKeyguard( + intent = intent, + intentSentUiThreadCallback = intentSentUiThreadCallback, + animationController = animationController, + showOverLockscreen = true, + fillInIntent = fillInIntent, + extraOptions = extraOptions, + ) + } + + private companion object { + private const val DISPLAY_ID = 0 + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/TestableHeadsUpManager.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/TestableHeadsUpManager.java index 3c9dc6345d31..69207ba07e6e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/TestableHeadsUpManager.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/TestableHeadsUpManager.java @@ -89,7 +89,7 @@ class TestableHeadsUpManager extends BaseHeadsUpManager { } @Override - public boolean isHeadsUpGoingAway() { + public boolean isHeadsUpAnimatingAwayValue() { throw new UnsupportedOperationException(); } @@ -115,7 +115,7 @@ class TestableHeadsUpManager extends BaseHeadsUpManager { } @Override - public void setHeadsUpGoingAway(boolean headsUpGoingAway) { + public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) { throw new UnsupportedOperationException(); } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/startable/AudioModeLoggerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/startable/AudioModeLoggerStartableTest.kt new file mode 100644 index 000000000000..8bb36724d1d8 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/startable/AudioModeLoggerStartableTest.kt @@ -0,0 +1,93 @@ +/* + * 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.domain.startable + +import android.media.AudioManager +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.internal.logging.uiEventLogger +import com.android.internal.logging.uiEventLoggerFake +import com.android.systemui.SysuiTestCase +import com.android.systemui.kosmos.applicationCoroutineScope +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos +import com.android.systemui.volume.audioModeInteractor +import com.android.systemui.volume.audioRepository +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent +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.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule + +@OptIn(ExperimentalCoroutinesApi::class) +@RunWith(AndroidJUnit4::class) +@SmallTest +class AudioModeLoggerStartableTest : SysuiTestCase() { + @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule() + + private val kosmos = testKosmos() + + private lateinit var underTest: AudioModeLoggerStartable + + @Before + fun setUp() { + with(kosmos) { + underTest = + AudioModeLoggerStartable( + applicationCoroutineScope, + uiEventLogger, + audioModeInteractor + ) + } + } + + @Test + fun audioMode_inCall() { + with(kosmos) { + testScope.runTest { + audioRepository.setMode(AudioManager.MODE_IN_CALL) + + underTest.start() + runCurrent() + + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(VolumePanelUiEvent.VOLUME_PANEL_AUDIO_MODE_CHANGE_TO_CALLING.id) + } + } + } + + @Test + fun audioMode_notInCall() { + with(kosmos) { + testScope.runTest { + audioRepository.setMode(AudioManager.MODE_NORMAL) + + underTest.start() + runCurrent() + + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(VolumePanelUiEvent.VOLUME_PANEL_AUDIO_MODE_CHANGE_TO_NORMAL.id) + } + } + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt index 2cc1ad335535..27a813fb149e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt @@ -21,6 +21,8 @@ import android.content.Intent import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.internal.logging.uiEventLogger +import com.android.internal.logging.uiEventLoggerFake import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope @@ -29,6 +31,7 @@ import com.android.systemui.plugins.activityStarter import com.android.systemui.testKosmos import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import com.android.systemui.volume.panel.volumePanelViewModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -58,7 +61,10 @@ class BottomBarViewModelTest : SysuiTestCase() { private lateinit var underTest: BottomBarViewModel private fun initUnderTest() { - underTest = with(kosmos) { BottomBarViewModel(activityStarter, volumePanelViewModel) } + underTest = + with(kosmos) { + BottomBarViewModel(activityStarter, volumePanelViewModel, uiEventLogger) + } } @Test @@ -96,6 +102,8 @@ class BottomBarViewModelTest : SysuiTestCase() { /* userHandle = */ eq(null), ) assertThat(intentCaptor.value.action).isEqualTo(Settings.ACTION_SOUND_SETTINGS) + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(VolumePanelUiEvent.VOLUME_PANEL_SOUND_SETTINGS_CLICKED.id) activityStartedCaptor.value.onActivityStarted(ActivityManager.START_SUCCESS) val volumePanelState by collectLastValue(volumePanelViewModel.volumePanelState) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModelTest.kt index 610195f5e87e..fdeded8422d6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModelTest.kt @@ -18,6 +18,7 @@ package com.android.systemui.volume.panel.component.captioning.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.internal.logging.uiEventLogger import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope @@ -45,7 +46,12 @@ class CaptioningViewModelTest : SysuiTestCase() { fun setup() { underTest = with(kosmos) { - CaptioningViewModel(context, captioningInteractor, testScope.backgroundScope) + CaptioningViewModel( + context, + captioningInteractor, + testScope.backgroundScope, + uiEventLogger, + ) } } 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 index ec55c75d4ae5..da0a2295143b 100644 --- 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 @@ -46,7 +46,10 @@ class MediaOutputAvailabilityCriteriaTest : SysuiTestCase() { @Before fun setup() { - underTest = MediaOutputAvailabilityCriteria(kosmos.audioModeInteractor) + underTest = + MediaOutputAvailabilityCriteria( + kosmos.audioModeInteractor, + ) } @Test 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 index 462f36d73138..30524d93dc02 100644 --- 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 @@ -22,6 +22,7 @@ import android.media.session.PlaybackState import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.internal.logging.uiEventLogger import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope @@ -64,6 +65,7 @@ class MediaOutputViewModelTest : SysuiTestCase() { mediaOutputActionsInteractor, mediaDeviceSessionInteractor, mediaOutputInteractor, + uiEventLogger, ) with(context.orCreateTestableResources) { diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml index 529d6090a501..b62e684b0105 100644 --- a/packages/SystemUI/res-keyguard/values-am/strings.xml +++ b/packages/SystemUI/res-keyguard/values-am/strings.xml @@ -108,7 +108,7 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"መሣሪያ እንደገና ከጀመረ በኋላ ስርዓተ ጥለት ያስፈልጋል"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"መሣሪያ እንደገና ከጀመረ በኋላ ፒን ያስፈልጋል"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"መሣሪያ እንደገና ከጀመረ በኋላ የይለፍ ቃል ያስፈልጋል"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"ለተጨማሪ ደህንነት በምትኩ ስርዓተ ጥለት ይጠቀሙ"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"ለተጨማሪ ደህንነት በምትኩ ሥርዓተ ጥለት ይጠቀሙ"</string> <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"ለተጨማሪ ደህንነት በምትኩ ፒን ይጠቀሙ"</string> <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"ለተጨማሪ ደህንነት በምትኩ የይለፍ ቃል ይጠቀሙ"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"ፒን ለተጨማሪ ደህንነት ያስፈልጋል"</string> diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml index d07c5b560d44..427373de8bcc 100644 --- a/packages/SystemUI/res-keyguard/values-ar/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml @@ -21,13 +21,13 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"أدخل رقم التعريف الشخصي (PIN)"</string> - <string name="keyguard_enter_pin" msgid="8114529922480276834">"أدخِل رقم التعريف الشخصي."</string> + <string name="keyguard_enter_pin" msgid="8114529922480276834">"أدخِل رقم التعريف الشخصي"</string> <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"أدخل النقش"</string> <string name="keyguard_enter_pattern" msgid="7616595160901084119">"ارسم النقش."</string> <string name="keyguard_enter_your_password" msgid="7225626204122735501">"أدخل كلمة المرور"</string> <string name="keyguard_enter_password" msgid="6483623792371009758">"أدخِل كلمة المرور."</string> <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"بطاقة غير صالحة."</string> - <string name="keyguard_charged" msgid="5478247181205188995">"تم الشحن"</string> + <string name="keyguard_charged" msgid="5478247181205188995">"اكتمل الشحن"</string> <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن لاسلكيًا"</string> <string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن"</string> <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن"</string> @@ -80,9 +80,9 @@ <string name="kg_face_locked_out" msgid="2751559491287575">"يتعذّر فتح القفل بالوجه. أجريت محاولات كثيرة جدًا."</string> <string name="kg_fp_locked_out" msgid="6228277682396768830">"يتعذّر الفتح ببصمة الإصبع. أجريت محاولات كثيرة جدًا."</string> <string name="kg_trust_agent_disabled" msgid="5400691179958727891">"ميزة \"الوكيل المعتمد\" غير متاحة."</string> - <string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"أجريت محاولات كثيرة جدًا بإدخال رقم تعريف شخصي خاطئ."</string> - <string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"أجريت محاولات كثيرة جدًا برسم نقش خاطئ."</string> - <string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"أجريت محاولات كثيرة جدًا بإدخال كلمة مرور خاطئة."</string> + <string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"أجريت محاولات كثيرة جدًا باستخدام رقم تعريف شخصي خاطئ"</string> + <string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"أجريت محاولات كثيرة جدًا باستخدام نقش خاطئ"</string> + <string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"أجريت محاولات كثيرة جدًا باستخدام كلمة مرور خاطئة"</string> <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{أعِد المحاولة خلال ثانية واحدة.}zero{أعِد المحاولة خلال # ثانية.}two{أعِد المحاولة خلال ثانيتين.}few{أعِد المحاولة خلال # ثوانٍ.}many{أعِد المحاولة خلال # ثانية.}other{أعِد المحاولة خلال # ثانية.}}"</string> <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"أدخل رقم التعريف الشخصي لشريحة SIM."</string> <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"أدخل رقم التعريف الشخصي لشريحة SIM التابعة للمشغّل \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string> @@ -108,9 +108,9 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"يجب رسم النقش بعد إعادة تشغيل الجهاز."</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"يجب إدخال رقم التعريف الشخصي بعد إعادة تشغيل الجهاز."</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"يجب إدخال كلمة المرور بعد إعادة تشغيل الجهاز."</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"لمزيد من الأمان، استخدِم النقش بدلاً من ذلك."</string> - <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"لمزيد من الأمان، أدخِل رقم التعريف الشخصي بدلاً من ذلك."</string> - <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"لمزيد من الأمان، أدخِل كلمة المرور بدلاً من ذلك."</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"لمزيد من الأمان، يجب استخدام النقش"</string> + <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"لمزيد من الأمان، يجب إدخال رقم التعريف الشخصي"</string> + <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"لمزيد من الأمان، يجب إدخال كلمة المرور"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"يجب إدخال رقم التعريف الشخصي لمزيد من الأمان"</string> <string name="kg_prompt_added_security_pattern" msgid="1017068086102168544">"يجب رسم النقش لمزيد من الأمان"</string> <string name="kg_prompt_added_security_password" msgid="6053156069765029006">"يجب إدخال كلمة المرور لمزيد من الأمان"</string> diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml index ce8ebd3bf9e7..4ed7e27ff732 100644 --- a/packages/SystemUI/res-keyguard/values-as/strings.xml +++ b/packages/SystemUI/res-keyguard/values-as/strings.xml @@ -108,7 +108,7 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পাছত আৰ্হিৰ আৱশ্যক"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পাছত পিনৰ আৱশ্যক"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পাছত পাছৱৰ্ডৰ আৱশ্যক"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"অতিৰিক্ত সুৰক্ষাৰ বাবে, ইয়াৰ পৰিৱৰ্তে আৰ্হি ব্যৱহাৰ কৰক"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"অতিৰিক্ত সুৰক্ষাৰ বাবে, আৰ্হি ব্যৱহাৰ কৰক"</string> <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"অতিৰিক্ত সুৰক্ষাৰ বাবে, ইয়াৰ পৰিৱৰ্তে পিন ব্যৱহাৰ কৰক"</string> <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"অতিৰিক্ত সুৰক্ষাৰ বাবে, ইয়াৰ পৰিৱৰ্তে পাছৱৰ্ড ব্যৱহাৰ কৰক"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"অতিৰিক্ত সুৰক্ষাৰ বাবে পিন দিয়াটো বাধ্যতামূলক"</string> diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml index 96779450d55e..4a5e789cab8a 100644 --- a/packages/SystemUI/res-keyguard/values-bs/strings.xml +++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml @@ -108,9 +108,9 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"Uzorak je potreban nakon ponovnog pokretanja uređaja"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"PIN je potreban nakon ponovnog pokretanja uređaja"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Lozinka je potrebna nakon pokretanja uređaja"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Radi dodatne zaštite, umjesto toga koristite uzorak"</string> - <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Radi dodatne zaštite, umjesto toga koristite PIN"</string> - <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Radi dodatne zašitite, umjesto toga koristite lozinku"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Za dodatnu sigurnost koristite uzorak"</string> + <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Za dodatnu sigurnost koristite PIN"</string> + <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Za dodatnu sigurnost koristite lozinku"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"PIN je potreban radi dodatne sigurnosti"</string> <string name="kg_prompt_added_security_pattern" msgid="1017068086102168544">"Uzorak je potreban radi dodatne sigurnosti"</string> <string name="kg_prompt_added_security_password" msgid="6053156069765029006">"Lozinka je potrebna radi dodatne sigurnosti"</string> diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml index 8e97e84340d8..5a03cec97ce8 100644 --- a/packages/SystemUI/res-keyguard/values-cs/strings.xml +++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml @@ -83,7 +83,7 @@ <string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"Příliš mnoho pokusů s nesprávným kódem PIN"</string> <string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"Příliš mnoho pokusů s nesprávným gestem"</string> <string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"Příliš mnoho pokusů s nesprávným heslem"</string> - <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Zkuste to znovu za # sekundu.}few{Zkuste to znovu za # sekundy.}many{Zkuste to znovu za # sekundy.}other{Zkuste to znovu za # sekund.}}"</string> + <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Zkuste to znovu za # sekundu}few{Zkuste to znovu za # sekundy}many{Zkuste to znovu za # sekundy}other{Zkuste to znovu za # sekund}}"</string> <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Zadejte kód PIN SIM karty."</string> <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Zadejte kód PIN SIM karty <xliff:g id="CARRIER">%1$s</xliff:g>."</string> <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> eSIM kartu deaktivujte, chcete-li zařízení používat bez mobilních služeb."</string> diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml index 2245710a0a5e..195fdeff3275 100644 --- a/packages/SystemUI/res-keyguard/values-de/strings.xml +++ b/packages/SystemUI/res-keyguard/values-de/strings.xml @@ -20,7 +20,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Gib deine PIN ein"</string> + <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"PIN eingeben"</string> <string name="keyguard_enter_pin" msgid="8114529922480276834">"Gib die PIN ein"</string> <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Muster eingeben"</string> <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Zeichne das Muster"</string> diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml index ea1dd13c6848..c59bdc1604d5 100644 --- a/packages/SystemUI/res-keyguard/values-fi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml @@ -108,9 +108,9 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"Kuvio tarvitaan uudelleenkäynnistyksen jälkeen"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"PIN-koodi tarvitaan uudelleenkäynnistyksen jälkeen"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Salasana tarvitaan uudelleenkäynnistyksen jälkeen"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Lisäsuojaa saat, kun käytät sen sijaan kuviota"</string> - <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Lisäsuojaa saat, kun käytät sen sijaan PIN-koodia"</string> - <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Lisäsuojaa saat, kun käytät sen sijaan salasanaa"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Käytä kuviota, niin saat lisäsuojaa"</string> + <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Käytä PIN-koodia, niin saat lisäsuojaa"</string> + <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Käytä salasanaa, niin saat lisäsuojaa"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"PIN-koodi vaaditaan suojauksen parantamiseksi."</string> <string name="kg_prompt_added_security_pattern" msgid="1017068086102168544">"Kuvio vaaditaan suojauksen parantamiseksi."</string> <string name="kg_prompt_added_security_password" msgid="6053156069765029006">"Salasana vaaditaan suojauksen parantamiseksi."</string> diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml index 6b51ac26cd52..e5cd788200a9 100644 --- a/packages/SystemUI/res-keyguard/values-gl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml @@ -108,9 +108,9 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"Requírese o padrón tras reiniciar o dispositivo"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"Requírese o PIN tras reiniciar o dispositivo"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Requírese o contrasinal tras reiniciar o dispositivo"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Utiliza un padrón para obter maior seguranza"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Utiliza un padrón para unha maior seguranza"</string> <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Utiliza un PIN para obter maior seguranza"</string> - <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Utiliza un contrasinal para obter maior seguranza"</string> + <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Utiliza un contrasinal para unha maior seguranza"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"É necesario poñer o PIN como medida de seguranza adicional"</string> <string name="kg_prompt_added_security_pattern" msgid="1017068086102168544">"É necesario poñer o padrón como medida de seguranza adicional"</string> <string name="kg_prompt_added_security_password" msgid="6053156069765029006">"É necesario poñer o contrasinal como medida de seguranza adicional"</string> diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml index dc5b0b8c8077..e2ac8b65288f 100644 --- a/packages/SystemUI/res-keyguard/values-in/strings.xml +++ b/packages/SystemUI/res-keyguard/values-in/strings.xml @@ -80,10 +80,10 @@ <string name="kg_face_locked_out" msgid="2751559491287575">"Tidak dapat membuka kunci dengan wajah. Terlalu banyak upaya gagal."</string> <string name="kg_fp_locked_out" msgid="6228277682396768830">"Tidak dapat membuka kunci dengan sidik jari. Terlalu banyak upaya gagal."</string> <string name="kg_trust_agent_disabled" msgid="5400691179958727891">"Perangkat tepercaya tidak tersedia"</string> - <string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"Terlalu banyak upaya dengan PIN yang salah"</string> - <string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"Terlalu banyak upaya dengan pola yang salah"</string> - <string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"Terlalu banyak upaya dengan sandi yang salah"</string> - <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Coba lagi dalam # detik.}other{Coba lagi dalam # detik.}}"</string> + <string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"Terlalu banyak pemakaian PIN yang salah"</string> + <string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"Terlalu banyak pemakaian pola yang salah"</string> + <string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"Terlalu banyak pemakaian sandi yang salah"</string> + <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Coba lagi setelah # detik.}other{Coba lagi setelah # detik.}}"</string> <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Masukkan PIN SIM."</string> <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Masukkan PIN SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string> <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Nonaktifkan eSIM untuk menggunakan perangkat tanpa layanan seluler."</string> @@ -108,9 +108,9 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"Pola diperlukan setelah perangkat dimulai ulang"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"PIN diperlukan setelah perangkat dimulai ulang"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Sandi diperlukan setelah perangkat dimulai ulang"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Untuk keamanan tambahan, gunakan pola"</string> - <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Untuk keamanan tambahan, gunakan PIN"</string> - <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Untuk keamanan tambahan, gunakan sandi"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Agar lebih aman, gunakan pola"</string> + <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Agar lebih aman, gunakan PIN"</string> + <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Agar lebih aman, gunakan sandi"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"PIN diperlukan untuk keamanan tambahan"</string> <string name="kg_prompt_added_security_pattern" msgid="1017068086102168544">"Pola diperlukan untuk keamanan tambahan"</string> <string name="kg_prompt_added_security_password" msgid="6053156069765029006">"Sandi diperlukan untuk keamanan tambahan"</string> diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml index 20808dbe4b0a..2deefd0b9643 100644 --- a/packages/SystemUI/res-keyguard/values-is/strings.xml +++ b/packages/SystemUI/res-keyguard/values-is/strings.xml @@ -108,9 +108,9 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"Mynsturs er krafist eftir að tækið er endurræst"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"PIN-númers er krafist eftir að tækið er endurræst"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Aðgangsorðs er krafist eftir að tækið er endurræst"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Fyrir aukið öryggi skaltu nota mynstur í staðinn"</string> - <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Fyrir aukið öryggi skaltu nota PIN-númer í staðinn"</string> - <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Fyrir aukið öryggi skaltu nota aðgangsorð í staðinn"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Til að auka öryggi skaltu nota mynstur í staðinn"</string> + <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Til að auka öryggi skaltu nota PIN-númer í staðinn"</string> + <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Til að auka öryggi skaltu nota aðgangsorð í staðinn"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"PIN-númers er krafist af öryggisástæðum"</string> <string name="kg_prompt_added_security_pattern" msgid="1017068086102168544">"Mynsturs er krafist af öryggisástæðum"</string> <string name="kg_prompt_added_security_password" msgid="6053156069765029006">"Aðgangsorðs er krafist af öryggisástæðum"</string> diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml index 8d86a8df1d69..69154aedd1a0 100644 --- a/packages/SystemUI/res-keyguard/values-ko/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml @@ -108,7 +108,7 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"기기가 다시 시작되어 패턴을 입력해야 합니다."</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"기기가 다시 시작되어 PIN을 입력해야 합니다."</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"기기가 다시 시작되어 비밀번호를 입력해야 합니다."</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"보안 강화를 위해 대신 패턴 사용"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"보안 강화를 위해 패턴 사용"</string> <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"보안 강화를 위해 대신 PIN 사용"</string> <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"보안 강화를 위해 대신 비밀번호 사용"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"보안 강화를 위해 PIN이 필요합니다."</string> diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml index 6bfbd64e5d53..6d2f0e508acf 100644 --- a/packages/SystemUI/res-keyguard/values-ky/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml @@ -49,7 +49,7 @@ <string name="disable_carrier_button_text" msgid="7153361131709275746">"eSIM-картаны өчүрүү"</string> <string name="error_disable_esim_title" msgid="3802652622784813119">"eSIM-картаны өчүрүүгө болбойт"</string> <string name="error_disable_esim_msg" msgid="2441188596467999327">"Катадан улам eSIM-картаны өчүрүүгө болбойт."</string> - <string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Киргизүү"</string> + <string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Enter"</string> <string name="kg_wrong_pattern" msgid="5907301342430102842">"Графикалык ачкыч туура эмес"</string> <string name="kg_wrong_pattern_try_again" msgid="3603524940234151881">"Графклк ачкч тура эмс. Кайтлап крүңз."</string> <string name="kg_wrong_password" msgid="4143127991071670512">"Сырсөз туура эмес"</string> diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml index 3e110b531ab1..6c57d89a36af 100644 --- a/packages/SystemUI/res-keyguard/values-mk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml @@ -49,7 +49,7 @@ <string name="disable_carrier_button_text" msgid="7153361131709275746">"Оневозможи ја eSIM"</string> <string name="error_disable_esim_title" msgid="3802652622784813119">"Не може да се оневозможи eSIM"</string> <string name="error_disable_esim_msg" msgid="2441188596467999327">"eSIM-картичката не може да се оневозможи поради грешка."</string> - <string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Внеси"</string> + <string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Enter"</string> <string name="kg_wrong_pattern" msgid="5907301342430102842">"Погрешна шема"</string> <string name="kg_wrong_pattern_try_again" msgid="3603524940234151881">"Погрешна шема. Обидете се повторно."</string> <string name="kg_wrong_password" msgid="4143127991071670512">"Погрешна лозинка"</string> diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml index 95d638e4c0d3..f74eb6697341 100644 --- a/packages/SystemUI/res-keyguard/values-my/strings.xml +++ b/packages/SystemUI/res-keyguard/values-my/strings.xml @@ -108,7 +108,7 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"စက်ကို ပြန်စပြီးနောက် ပုံဖော်ခြင်းလိုအပ်သည်"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"စက်ကို ပြန်စပြီးနောက် ပင်နံပါတ်လိုအပ်သည်"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"စက်ကို ပြန်စပြီးနောက် စကားဝှက်လိုအပ်သည်"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"ထပ်ဆောင်းလုံခြုံရေးအတွက် ၎င်းအစား ပုံစံသုံးပါ"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"ထပ်ဆောင်းလုံခြုံရေးအတွက် ပုံစံကို အစားထိုးသုံးပါ"</string> <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"ထပ်ဆောင်းလုံခြုံရေးအတွက် ၎င်းအစား ပင်နံပါတ်သုံးပါ"</string> <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"ထပ်ဆောင်းလုံခြုံရေးအတွက် ၎င်းအစား စကားဝှက်သုံးပါ"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"ထပ်ဆောင်း လုံခြုံရေးအတွက် ပင်နံပါတ် လိုအပ်သည်"</string> diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml index 219072b2bbb2..27856d6ba924 100644 --- a/packages/SystemUI/res-keyguard/values-ne/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml @@ -24,7 +24,7 @@ <string name="keyguard_enter_pin" msgid="8114529922480276834">"PIN हाल्नुहोस्"</string> <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"प्याटर्न हाल्नुहोस्"</string> <string name="keyguard_enter_pattern" msgid="7616595160901084119">"प्याटर्न कोर्नुहोस्"</string> - <string name="keyguard_enter_your_password" msgid="7225626204122735501">"पासवर्ड हाल्नुहोस्…"</string> + <string name="keyguard_enter_your_password" msgid="7225626204122735501">"पासवर्ड हाल्नुहोस्"</string> <string name="keyguard_enter_password" msgid="6483623792371009758">"पासवर्ड हाल्नुहोस्"</string> <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"अमान्य कार्ड।"</string> <string name="keyguard_charged" msgid="5478247181205188995">"चार्ज भयो"</string> @@ -108,9 +108,9 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"डिभाइस रिस्टार्ट भएपछि प्याटर्न कोर्नु पर्ने हुन्छ"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"डिभाइस रिस्टार्ट भएपछि PIN हाल्नु पर्ने हुन्छ"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"डिभाइस रिस्टार्ट भएपछि पासवर्ड हाल्नु पर्ने हुन्छ"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"अतिरिक्त सुरक्षाका लागि यो प्रमाणीकरण विधिको साटो प्याटर्न प्रयोग गर्नुहोस्"</string> - <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"अतिरिक्त सुरक्षाका लागि यो प्रमाणीकरण विधिको साटो पिन प्रयोग गर्नुहोस्"</string> - <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"अतिरिक्त सुरक्षाका लागि यो प्रमाणीकरण विधिको साटो पासवर्ड प्रयोग गर्नुहोस्"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"अतिरिक्त सुरक्षाका लागि यसको साटो पासवर्ड प्रयोग गर्नुहोस्"</string> + <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"अतिरिक्त सुरक्षाका लागि यसको साटो पासवर्ड प्रयोग गर्नुहोस्"</string> + <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"अतिरिक्त सुरक्षाका लागि यसको साटो पासवर्ड प्रयोग गर्नुहोस्"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"अतिरिक्त सुरक्षाका लागि PIN चाहिन्छ"</string> <string name="kg_prompt_added_security_pattern" msgid="1017068086102168544">"अतिरिक्त सुरक्षाका लागि प्याटर्न चाहिन्छ"</string> <string name="kg_prompt_added_security_password" msgid="6053156069765029006">"अतिरिक्त सुरक्षाका लागि पासवर्ड चाहिन्छ"</string> diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml index 020640361e7f..9fb9e1bfe8a5 100644 --- a/packages/SystemUI/res-keyguard/values-nl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml @@ -22,7 +22,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Geef je pincode op"</string> <string name="keyguard_enter_pin" msgid="8114529922480276834">"Voer pincode in"</string> - <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Geef je patroon op"</string> + <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Voer je patroon in"</string> <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Teken het patroon"</string> <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Voer je wachtwoord in"</string> <string name="keyguard_enter_password" msgid="6483623792371009758">"Geef het wachtwoord op"</string> @@ -80,9 +80,9 @@ <string name="kg_face_locked_out" msgid="2751559491287575">"Kan niet ontgrendelen met gezicht. Te veel pogingen."</string> <string name="kg_fp_locked_out" msgid="6228277682396768830">"Niet ontgrendeld met vingerafdruk. Te veel pogingen."</string> <string name="kg_trust_agent_disabled" msgid="5400691179958727891">"Trust agent is niet beschikbaar"</string> - <string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"Te veel pogingen met onjuiste pincode"</string> - <string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"Te veel pogingen met onjuist patroon"</string> - <string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"Te veel pogingen met onjuist wachtwoord"</string> + <string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"Pincode te vaak verkeerd ingevoerd"</string> + <string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"Patroon te vaak verkeerd getekend"</string> + <string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"Wachtwoord te vaak verkeerd ingevoerd"</string> <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Probeer het over # seconde opnieuw.}other{Probeer het over # seconden opnieuw.}}"</string> <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Geef de pincode van de simkaart op."</string> <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Geef de pincode voor de simkaart van \'<xliff:g id="CARRIER">%1$s</xliff:g>\' op."</string> @@ -108,9 +108,9 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"Patroon is vereist na opnieuw opstarten apparaat"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"Pincode is vereist na opnieuw opstarten apparaat"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Wachtwoord is vereist na opnieuw opstarten apparaat"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Gebruik in plaats daarvan het patroon voor extra beveiliging"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Gebruik het patroon voor extra beveiliging"</string> <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Gebruik de pincode voor extra beveiliging"</string> - <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Gebruik in plaats daarvan het wachtwoord voor extra beveiliging"</string> + <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Gebruik het wachtwoord voor extra beveiliging"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"Pincode vereist voor extra beveiliging"</string> <string name="kg_prompt_added_security_pattern" msgid="1017068086102168544">"Patroon vereist voor extra beveiliging"</string> <string name="kg_prompt_added_security_password" msgid="6053156069765029006">"Wachtwoord vereist voor extra beveiliging"</string> diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml index 4a8907031cbd..f25e9c5454ed 100644 --- a/packages/SystemUI/res-keyguard/values-pl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml @@ -83,7 +83,7 @@ <string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"Zbyt wiele nieudanych prób wpisania kodu PIN"</string> <string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"Zbyt wiele nieudanych prób narysowania wzoru"</string> <string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"Zbyt wiele nieudanych prób wpisania hasła"</string> - <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Spróbuj ponownie za # sekundę.}few{Spróbuj ponownie za # sekundy.}many{Spróbuj ponownie za # sekund.}other{Spróbuj ponownie za # sekundy.}}"</string> + <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Spróbuj ponownie za # sekundę}few{Spróbuj ponownie za # sekundy}many{Spróbuj ponownie za # sekund}other{Spróbuj ponownie za # sekundy}}"</string> <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Wpisz kod PIN karty SIM."</string> <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Wpisz kod PIN karty SIM „<xliff:g id="CARRIER">%1$s</xliff:g>”."</string> <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Wyłącz kartę eSIM, by używać urządzenia bez usługi sieci komórkowej."</string> diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml index 1ae1aeba90cd..b29220476224 100644 --- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml @@ -24,7 +24,7 @@ <string name="keyguard_enter_pin" msgid="8114529922480276834">"Introduza o PIN"</string> <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Introduza o padrão"</string> <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Desenhe o padrão"</string> - <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Introduza a palavra-passe."</string> + <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Introduza a palavra-passe"</string> <string name="keyguard_enter_password" msgid="6483623792371009758">"Introduza a palavra-passe"</string> <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Cartão inválido."</string> <string name="keyguard_charged" msgid="5478247181205188995">"Carregada"</string> @@ -108,9 +108,9 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"Padrão necessário após reiniciar o dispositivo"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"PIN necessário após reiniciar o dispositivo"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Palavra-passe necessária após reiniciar dispositivo"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Para uma segurança adicional, use antes o padrão"</string> - <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Para uma segurança adicional, use antes o PIN"</string> - <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Para uma segurança adicional, use antes a palavra-passe"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Para segurança adicional, use o padrão"</string> + <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Para segurança adicional, use o PIN"</string> + <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Para segurança adicional, use a palavra-passe"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"Para segurança adicional, é necessária um PIN"</string> <string name="kg_prompt_added_security_pattern" msgid="1017068086102168544">"Para segurança adicional, é necessário um padrão"</string> <string name="kg_prompt_added_security_password" msgid="6053156069765029006">"Para segurança adicional, é necessária uma palavra-passe"</string> diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml index 5725fe0408c7..9b0647afb614 100644 --- a/packages/SystemUI/res-keyguard/values-sk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml @@ -108,7 +108,7 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"Po reštarte zariadenia sa vyžaduje vzor"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"Po reštarte zariadenia sa vyžaduje kód PIN"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Po reštarte zariadenia sa vyžaduje heslo"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"V rámci zvýšenia zabezpečenia použite radšej vzor"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Z bezpečnostných dôvodov použite radšej vzor"</string> <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"V rámci zvýšenia zabezpečenia použite radšej PIN"</string> <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"V rámci zvýšenia zabezpečenia použite radšej heslo"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"Zvýšenie zabezpečenia vyžaduje kód PIN"</string> diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml index bfe5ae09d154..cb17459c84c4 100644 --- a/packages/SystemUI/res-keyguard/values-tl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml @@ -108,7 +108,7 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"Kailangan ang pattern pagka-restart ng device"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"Kailangan ang PIN pagka-restart ng device"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Kailangan ang password pagka-restart ng device"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Para sa karagdagang seguridad, gumamit na lang ng pattern"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Para sa karagdagang seguridad, gumamit ng pattern"</string> <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Para sa karagdagang seguridad, gumamit na lang ng PIN"</string> <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Para sa karagdagang seguridad, gumamit na lang ng password"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"Kinakailangan ang PIN para sa karagdagang seguridad"</string> diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml index bbd319c3988a..72ea8500b746 100644 --- a/packages/SystemUI/res-keyguard/values-vi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml @@ -108,7 +108,7 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"Cần vẽ hình mở khoá sau khi khởi động lại thiết bị"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"Cần nhập mã PIN sau khi khởi động lại thiết bị"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Cần nhập mật khẩu sau khi khởi động lại thiết bị"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Để tăng cường bảo mật, hãy sử dụng hình mở khoá"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Để tăng cường bảo mật, hãy dùng hình mở khoá"</string> <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Để tăng cường bảo mật, hãy sử dụng mã PIN"</string> <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Để tăng cường bảo mật, hãy sử dụng mật khẩu"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"Yêu cầu mã PIN để tăng cường bảo mật"</string> diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml index a316e8cc727f..7d74c9cb8224 100644 --- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml @@ -22,7 +22,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"输入您的 PIN 码"</string> <string name="keyguard_enter_pin" msgid="8114529922480276834">"输入 PIN 码"</string> - <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"绘制您的图案"</string> + <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"绘制解锁图案"</string> <string name="keyguard_enter_pattern" msgid="7616595160901084119">"绘制图案"</string> <string name="keyguard_enter_your_password" msgid="7225626204122735501">"输入您的密码"</string> <string name="keyguard_enter_password" msgid="6483623792371009758">"输入密码"</string> @@ -108,7 +108,7 @@ <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"设备重启后,必须绘制图案才能解锁"</string> <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"设备重启后,必须输入 PIN 码才能解锁"</string> <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"设备重启后,必须输入密码才能解锁"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"为增强安全性,请改用图案"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"为增强安全性,请改用解锁图案"</string> <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"为增强安全性,请改用 PIN 码"</string> <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"为增强安全性,请改用密码"</string> <string name="kg_prompt_added_security_pin" msgid="5487992065995475528">"需要输入 PIN 码以进一步确保安全"</string> diff --git a/packages/SystemUI/res/layout/volume_ringer_drawer.xml b/packages/SystemUI/res/layout/volume_ringer_drawer.xml index 9b1fa23081b4..8f1e0610853f 100644 --- a/packages/SystemUI/res/layout/volume_ringer_drawer.xml +++ b/packages/SystemUI/res/layout/volume_ringer_drawer.xml @@ -67,8 +67,8 @@ android:layout_width="@dimen/volume_ringer_drawer_icon_size" android:layout_height="@dimen/volume_ringer_drawer_icon_size" android:layout_gravity="center" - android:tint="?android:attr/textColorPrimary" - android:src="@drawable/ic_volume_ringer_vibrate" /> + android:src="@drawable/ic_volume_ringer_vibrate" + android:tint="?android:attr/textColorPrimary" /> </FrameLayout> @@ -76,6 +76,7 @@ android:id="@+id/volume_drawer_mute" android:layout_width="@dimen/volume_ringer_drawer_item_size" android:layout_height="@dimen/volume_ringer_drawer_item_size" + android:accessibilityTraversalAfter="@id/volume_drawer_vibrate" android:contentDescription="@string/volume_ringer_hint_mute" android:gravity="center"> @@ -84,8 +85,8 @@ android:layout_width="@dimen/volume_ringer_drawer_icon_size" android:layout_height="@dimen/volume_ringer_drawer_icon_size" android:layout_gravity="center" - android:tint="?android:attr/textColorPrimary" - android:src="@drawable/ic_speaker_mute" /> + android:src="@drawable/ic_speaker_mute" + android:tint="?android:attr/textColorPrimary" /> </FrameLayout> @@ -93,6 +94,7 @@ android:id="@+id/volume_drawer_normal" android:layout_width="@dimen/volume_ringer_drawer_item_size" android:layout_height="@dimen/volume_ringer_drawer_item_size" + android:accessibilityTraversalAfter="@id/volume_drawer_mute" android:contentDescription="@string/volume_ringer_hint_unmute" android:gravity="center"> @@ -101,8 +103,8 @@ android:layout_width="@dimen/volume_ringer_drawer_icon_size" android:layout_height="@dimen/volume_ringer_drawer_icon_size" android:layout_gravity="center" - android:tint="?android:attr/textColorPrimary" - android:src="@drawable/ic_speaker_on" /> + android:src="@drawable/ic_speaker_on" + android:tint="?android:attr/textColorPrimary" /> </FrameLayout> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index af327d2b7791..26fa2b136ed4 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -613,7 +613,7 @@ <dimen name="volume_panel_slice_vertical_padding">8dp</dimen> <dimen name="volume_panel_slice_horizontal_padding">24dp</dimen> - <dimen name="volume_panel_corner_radius">52dp</dimen> + <dimen name="volume_panel_corner_radius">28dp</dimen> <!-- Size of each item in the ringer selector drawer. --> <dimen name="volume_ringer_drawer_item_size">42dp</dimen> diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt index 3b8a268cd5ea..460779c73cda 100644 --- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt +++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt @@ -15,6 +15,7 @@ */ package com.android.keyguard +import android.os.Trace import android.content.BroadcastReceiver import android.content.Context import android.content.Intent @@ -430,6 +431,7 @@ constructor( if (MigrateClocksToBlueprint.isEnabled) { listenForDozeAmountTransition(this) listenForAnyStateToAodTransition(this) + listenForAnyStateToLockscreenTransition(this) } else { listenForDozeAmount(this) } @@ -520,8 +522,12 @@ constructor( private fun handleDoze(doze: Float) { dozeAmount = doze clock?.run { + Trace.beginSection("$TAG#smallClock.animations.doze") smallClock.animations.doze(dozeAmount) + Trace.endSection() + Trace.beginSection("$TAG#largeClock.animations.doze") largeClock.animations.doze(dozeAmount) + Trace.endSection() } smallTimeListener?.update(doze < DOZE_TICKRATE_THRESHOLD) largeTimeListener?.update(doze < DOZE_TICKRATE_THRESHOLD) @@ -536,10 +542,10 @@ constructor( internal fun listenForDozeAmountTransition(scope: CoroutineScope): Job { return scope.launch { merge( - keyguardTransitionInteractor.aodToLockscreenTransition.map { step -> + keyguardTransitionInteractor.transition(AOD, LOCKSCREEN).map { step -> step.copy(value = 1f - step.value) }, - keyguardTransitionInteractor.lockscreenToAodTransition, + keyguardTransitionInteractor.transition(LOCKSCREEN, AOD), ).filter { it.transitionState != TransitionState.FINISHED } @@ -562,6 +568,17 @@ constructor( } @VisibleForTesting + internal fun listenForAnyStateToLockscreenTransition(scope: CoroutineScope): Job { + return scope.launch { + keyguardTransitionInteractor + .transitionStepsToState(LOCKSCREEN) + .filter { it.transitionState == TransitionState.STARTED } + .filter { it.from != AOD } + .collect { handleDoze(0f) } + } + } + + @VisibleForTesting internal fun listenForDozing(scope: CoroutineScope): Job { return scope.launch { combine( @@ -628,7 +645,7 @@ constructor( } companion object { - private val TAG = ClockEventController::class.simpleName!! - private val DOZE_TICKRATE_THRESHOLD = 0.99f + private const val TAG = "ClockEventController" + private const val DOZE_TICKRATE_THRESHOLD = 0.99f } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt index ec54e4ce5e86..9816896e3ea8 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt @@ -282,7 +282,8 @@ open class UdfpsKeyguardViewControllerLegacy( @VisibleForTesting suspend fun listenForGoneToAodTransition(scope: CoroutineScope): Job { return scope.launch { - transitionInteractor.goneToAodTransition.collect { transitionStep -> + transitionInteractor.transition(KeyguardState.GONE, KeyguardState.AOD).collect { + transitionStep -> view.onDozeAmountChanged( transitionStep.value, transitionStep.value, diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt index 7525ce0f98ac..fa19bf478453 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt @@ -27,9 +27,9 @@ import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState -import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.util.kotlin.BooleanFlowOperators.or import com.android.systemui.util.time.SystemClock import dagger.Lazy import javax.inject.Inject @@ -78,15 +78,14 @@ constructor( bouncerRepository.alternateBouncerUIAvailable } private val isDozingOrAod: Flow<Boolean> = - keyguardTransitionInteractor - .get() - .transitions - .map { - it.to == KeyguardState.DOZING || - it.to == KeyguardState.AOD || - ((it.from == KeyguardState.DOZING || it.from == KeyguardState.AOD) && - it.transitionState != TransitionState.FINISHED) - } + or( + keyguardTransitionInteractor.get().transitionValue(KeyguardState.DOZING).map { + it > 0f + }, + keyguardTransitionInteractor.get().transitionValue(KeyguardState.AOD).map { + it > 0f + }, + ) .distinctUntilChanged() /** diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt index aeb564d53195..02a40d93ab65 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt @@ -16,6 +16,7 @@ package com.android.systemui.bouncer.domain.interactor +import com.android.compose.animation.scene.SceneKey import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor import com.android.systemui.authentication.domain.interactor.AuthenticationResult import com.android.systemui.authentication.shared.model.AuthenticationMethodModel.Sim @@ -26,6 +27,8 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.scene.domain.interactor.SceneInteractor +import com.android.systemui.scene.shared.model.Scenes import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async @@ -47,6 +50,7 @@ constructor( private val deviceEntryFaceAuthInteractor: DeviceEntryFaceAuthInteractor, private val falsingInteractor: FalsingInteractor, private val powerInteractor: PowerInteractor, + sceneInteractor: SceneInteractor, ) { private val _onIncorrectBouncerInput = MutableSharedFlow<Unit>() val onIncorrectBouncerInput: SharedFlow<Unit> = _onIncorrectBouncerInput @@ -80,6 +84,10 @@ constructor( } .map {} + /** The scene to show when bouncer is dismissed. */ + val dismissDestination: Flow<SceneKey> = + sceneInteractor.previousScene.map { it ?: Scenes.Lockscreen } + /** Notifies that the user has places down a pointer, not necessarily dragging just yet. */ fun onDown() { falsingInteractor.avoidGesture() diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt index 5c07cc57c620..7c41b75d7105 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt @@ -21,6 +21,12 @@ import android.app.admin.DevicePolicyResources import android.content.Context import android.graphics.Bitmap import androidx.core.graphics.drawable.toBitmap +import com.android.compose.animation.scene.Back +import com.android.compose.animation.scene.SceneKey +import com.android.compose.animation.scene.Swipe +import com.android.compose.animation.scene.SwipeDirection +import com.android.compose.animation.scene.UserAction +import com.android.compose.animation.scene.UserActionResult import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.authentication.shared.model.AuthenticationWipeModel @@ -35,6 +41,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.inputmethod.domain.interactor.InputMethodInteractor +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.user.ui.viewmodel.UserActionViewModel import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel @@ -82,6 +89,15 @@ class BouncerViewModel( initialValue = null, ) + val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> = + bouncerInteractor.dismissDestination + .map(::destinationSceneMap) + .stateIn( + applicationScope, + SharingStarted.WhileSubscribed(), + initialValue = destinationSceneMap(Scenes.Lockscreen), + ) + val message: BouncerMessageViewModel = bouncerMessageViewModel val userSwitcherDropdown: StateFlow<List<UserSwitcherDropdownItemViewModel>> = @@ -310,8 +326,7 @@ class BouncerViewModel( { message }, failedAttempts, remainingAttempts, - ) - ?: message + ) ?: message } else { message } @@ -328,8 +343,7 @@ class BouncerViewModel( .KEYGUARD_DIALOG_FAILED_ATTEMPTS_ERASING_PROFILE, { message }, failedAttempts, - ) - ?: message + ) ?: message } else { message } @@ -357,6 +371,12 @@ class BouncerViewModel( } } + private fun destinationSceneMap(prevScene: SceneKey) = + mapOf( + Back to UserActionResult(prevScene), + Swipe(SwipeDirection.Down) to UserActionResult(prevScene), + ) + data class DialogViewModel( val text: String, @@ -400,13 +420,13 @@ object BouncerViewModelModule { simBouncerInteractor = simBouncerInteractor, authenticationInteractor = authenticationInteractor, selectedUserInteractor = selectedUserInteractor, + devicePolicyManager = devicePolicyManager, + bouncerMessageViewModel = bouncerMessageViewModel, flags = flags, selectedUser = userSwitcherViewModel.selectedUser, users = userSwitcherViewModel.users, userSwitcherMenu = userSwitcherViewModel.menu, actionButton = actionButtonInteractor.actionButton, - devicePolicyManager = devicePolicyManager, - bouncerMessageViewModel = bouncerMessageViewModel, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt index baae986c494d..a8f30297ff07 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt @@ -40,7 +40,6 @@ import com.android.systemui.deviceentry.shared.model.FailedFaceAuthenticationSta import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus import com.android.systemui.dump.DumpManager -import com.android.systemui.keyguard.KeyguardWmStateRefactor import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.data.repository.BiometricType import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository @@ -51,6 +50,7 @@ import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.model.SysUiFaceAuthenticateOptions import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.log.FaceAuthenticationLogger @@ -295,7 +295,8 @@ constructor( } private fun listenForSchedulingWatchdog() { - keyguardTransitionInteractor.anyStateToGoneTransition + keyguardTransitionInteractor + .transition(from = null, to = KeyguardState.GONE) .filter { it.transitionState == TransitionState.FINISHED } .onEach { // We deliberately want to run this in background because scheduleWatchdog does @@ -313,10 +314,16 @@ constructor( // or device starts going to sleep. merge( powerInteractor.isAsleep, - if (KeyguardWmStateRefactor.isEnabled) { - keyguardTransitionInteractor.isInTransitionToState(KeyguardState.GONE) - } else { - keyguardRepository.keyguardDoneAnimationsFinished.map { true } + combine( + keyguardTransitionInteractor.isFinishedInState(KeyguardState.GONE), + keyguardInteractor.statusBarState, + ) { isFinishedInGoneState, statusBarState -> + // When the user is dragging the primary bouncer in (up) by manually scrolling + // up on the lockscreen, the device won't be irreversibly transitioned to GONE + // until the statusBarState updates to SHADE, so we check that here. + // Else, we could reset the face auth state too early and end up in a strange + // state. + isFinishedInGoneState && statusBarState == StatusBarState.SHADE }, userRepository.selectedUser.map { it.selectionStatus == SelectionStatus.SELECTION_IN_PROGRESS diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt index a7266503b7a1..03819ed9e2fe 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt @@ -37,6 +37,10 @@ import com.android.systemui.deviceentry.shared.model.ErrorFaceAuthenticationStat import com.android.systemui.deviceentry.shared.model.FaceAuthenticationStatus import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState.AOD +import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING +import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN +import com.android.systemui.keyguard.shared.model.KeyguardState.OFF import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.log.FaceAuthenticationLogger import com.android.systemui.power.domain.interactor.PowerInteractor @@ -121,9 +125,9 @@ constructor( .launchIn(applicationScope) merge( - keyguardTransitionInteractor.aodToLockscreenTransition, - keyguardTransitionInteractor.offToLockscreenTransition, - keyguardTransitionInteractor.dozingToLockscreenTransition + keyguardTransitionInteractor.transition(AOD, LOCKSCREEN), + keyguardTransitionInteractor.transition(OFF, LOCKSCREEN), + keyguardTransitionInteractor.transition(DOZING, LOCKSCREEN), ) .filter { it.transitionState == TransitionState.STARTED } .sample(powerInteractor.detailedWakefulness) diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/HideComplicationTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/HideComplicationTouchHandler.java index ee48ee5f50fd..d525ce36a061 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/HideComplicationTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/HideComplicationTouchHandler.java @@ -16,6 +16,7 @@ package com.android.systemui.dreams.complication; +import static com.android.systemui.Flags.removeDreamOverlayHideOnTouch; import static com.android.systemui.dreams.complication.dagger.ComplicationModule.COMPLICATIONS_FADE_OUT_DELAY; import static com.android.systemui.dreams.complication.dagger.ComplicationModule.COMPLICATIONS_RESTORE_TIMEOUT; @@ -120,7 +121,7 @@ public class HideComplicationTouchHandler implements DreamTouchHandler { final boolean bouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing(); // If other sessions are interested in this touch, do not fade out elements. - if (session.getActiveSessionCount() > 1 || bouncerShowing + if (removeDreamOverlayHideOnTouch() || session.getActiveSessionCount() > 1 || bouncerShowing || mOverlayStateController.areExitAnimationsRunning()) { if (DEBUG) { Log.d(TAG, "not fading. Active session count: " + session.getActiveSessionCount() diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java index 75c50fd5f586..66d413ab56b8 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java @@ -37,6 +37,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.Flags; import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants; import com.android.systemui.dreams.touch.scrim.ScrimController; import com.android.systemui.dreams.touch.scrim.ScrimManager; @@ -124,13 +125,19 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (mCapture == null) { - // If the user scrolling favors a vertical direction, begin capturing - // scrolls. - mCapture = Math.abs(distanceY) > Math.abs(distanceX); mBouncerInitiallyShowing = mCentralSurfaces .map(CentralSurfaces::isBouncerShowing) .orElse(false); + if (Flags.dreamOverlayBouncerSwipeDirectionFiltering()) { + mCapture = Math.abs(distanceY) > Math.abs(distanceX) + && ((distanceY < 0 && mBouncerInitiallyShowing) + || (distanceY > 0 && !mBouncerInitiallyShowing)); + } else { + // If the user scrolling favors a vertical direction, begin capturing + // scrolls. + mCapture = Math.abs(distanceY) > Math.abs(distanceX); + } if (mCapture) { // reset expanding mExpanded = false; diff --git a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamViewModel.kt b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamViewModel.kt index ac03463da545..04edd252f98f 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamViewModel.kt @@ -23,6 +23,7 @@ import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.ui.viewmodel.DreamingToGlanceableHubTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel @@ -97,7 +98,7 @@ constructor( .distinctUntilChanged() val transitionEnded = - keyguardTransitionInteractor.fromDreamingTransition.filter { step -> + keyguardTransitionInteractor.transition(from = DREAMING, to = null).filter { step -> step.transitionState == TransitionState.FINISHED || step.transitionState == TransitionState.CANCELED } diff --git a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt index f1620d96b159..4327d18da97e 100644 --- a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt +++ b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt @@ -27,40 +27,65 @@ import androidx.annotation.VisibleForTesting import androidx.core.animation.doOnCancel import androidx.core.animation.doOnEnd import androidx.core.animation.doOnStart +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.statusbar.VibratorHelper -import kotlinx.coroutines.CancellationException +import javax.inject.Inject import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn /** * A class that handles the long press visuo-haptic effect for a QS tile. * * The class is also a [View.OnTouchListener] to handle the touch events, clicks and long-press - * gestures of the tile. The class also provides a [State] that can be used to determine the current + * gestures of the tile. The class also provides a [State] tha can be used to determine the current * state of the long press effect. * * @property[vibratorHelper] The [VibratorHelper] to deliver haptic effects. * @property[effectDuration] The duration of the effect in ms. */ -class QSLongPressEffect( +// TODO(b/332902869): In addition from being injectable, we can consider making it a singleton +class QSLongPressEffect +@Inject +constructor( private val vibratorHelper: VibratorHelper?, - private val effectDuration: Int, + val keyguardInteractor: KeyguardInteractor, + @Background bgScope: CoroutineScope, ) : View.OnTouchListener { + private var effectDuration = 0 + /** Current state */ - var state = State.IDLE - @VisibleForTesting set + private var _state = MutableStateFlow(State.IDLE) + val state = _state.stateIn(bgScope, SharingStarted.Lazily, State.IDLE) /** Flows for view control and action */ private val _effectProgress = MutableStateFlow<Float?>(null) - val effectProgress = _effectProgress.asStateFlow() + val effectProgress = _effectProgress.stateIn(bgScope, SharingStarted.Lazily, null) + + // Actions to perform + private val _postedActionType = MutableStateFlow<ActionType?>(null) + val actionType: StateFlow<ActionType?> = + combine( + _postedActionType, + keyguardInteractor.isKeyguardDismissible, + ) { action, isDismissible -> + if (!isDismissible && action == ActionType.LONG_PRESS) { + ActionType.RESET_AND_LONG_PRESS + } else { + action + } + } + .stateIn(bgScope, SharingStarted.Lazily, null) - private val _actionType = MutableStateFlow<ActionType?>(null) - val actionType = _actionType.asStateFlow() + // Should a tap timeout countdown begin + val shouldWaitForTapTimeout: Flow<Boolean> = state.map { it == State.TIMEOUT_WAIT } /** Haptic effects */ private val durations = @@ -69,41 +94,33 @@ class QSLongPressEffect( VibrationEffect.Composition.PRIMITIVE_SPIN ) - private val longPressHint = - LongPressHapticBuilder.createLongPressHint( - durations?.get(0) ?: LongPressHapticBuilder.INVALID_DURATION, - durations?.get(1) ?: LongPressHapticBuilder.INVALID_DURATION, - effectDuration - ) + private var longPressHint: VibrationEffect? = null private val snapEffect = LongPressHapticBuilder.createSnapEffect() - /* A coroutine scope and a timer job that waits for the pressedTimeout */ - var scope: CoroutineScope? = null - private var waitJob: Job? = null + private var effectAnimator: ValueAnimator? = null - private val effectAnimator = - ValueAnimator.ofFloat(0f, 1f).apply { - duration = effectDuration.toLong() - interpolator = AccelerateDecelerateInterpolator() + val hasInitialized: Boolean + get() = longPressHint != null && effectAnimator != null - doOnStart { handleAnimationStart() } - addUpdateListener { _effectProgress.value = animatedValue as Float } - doOnEnd { handleAnimationComplete() } - doOnCancel { handleAnimationCancel() } - } + @VisibleForTesting + fun setState(state: State) { + _state.value = state + } private fun reverse() { - val pausedProgress = effectAnimator.animatedFraction - val effect = - LongPressHapticBuilder.createReversedEffect( - pausedProgress, - durations?.get(0) ?: 0, - effectDuration, - ) - vibratorHelper?.cancel() - vibrate(effect) - effectAnimator.reverse() + effectAnimator?.let { + val pausedProgress = it.animatedFraction + val effect = + LongPressHapticBuilder.createReversedEffect( + pausedProgress, + durations?.get(0) ?: 0, + effectDuration, + ) + vibratorHelper?.cancel() + vibrate(effect) + it.reverse() + } } private fun vibrate(effect: VibrationEffect?) { @@ -129,52 +146,37 @@ class QSLongPressEffect( } private fun handleActionDown() { - when (state) { + when (_state.value) { State.IDLE -> { - startPressedTimeoutWait() - state = State.TIMEOUT_WAIT + setState(State.TIMEOUT_WAIT) } - State.RUNNING_BACKWARDS -> effectAnimator.cancel() + State.RUNNING_BACKWARDS -> effectAnimator?.cancel() else -> {} } } - private fun startPressedTimeoutWait() { - waitJob = - scope?.launch { - try { - delay(PRESSED_TIMEOUT) - handleTimeoutComplete() - } catch (_: CancellationException) { - state = State.IDLE - } - } - } - private fun handleActionUp() { - when (state) { + when (_state.value) { State.TIMEOUT_WAIT -> { - waitJob?.cancel() - _actionType.value = ActionType.CLICK - state = State.IDLE + _postedActionType.value = ActionType.CLICK + setState(State.IDLE) } State.RUNNING_FORWARD -> { reverse() - state = State.RUNNING_BACKWARDS + setState(State.RUNNING_BACKWARDS) } else -> {} } } private fun handleActionCancel() { - when (state) { + when (_state.value) { State.TIMEOUT_WAIT -> { - waitJob?.cancel() - state = State.IDLE + setState(State.IDLE) } State.RUNNING_FORWARD -> { reverse() - state = State.RUNNING_BACKWARDS + setState(State.RUNNING_BACKWARDS) } else -> {} } @@ -182,54 +184,78 @@ class QSLongPressEffect( private fun handleAnimationStart() { vibrate(longPressHint) - state = State.RUNNING_FORWARD + setState(State.RUNNING_FORWARD) } /** This function is called both when an animator completes or gets cancelled */ private fun handleAnimationComplete() { - if (state == State.RUNNING_FORWARD) { + if (_state.value == State.RUNNING_FORWARD) { vibrate(snapEffect) - _actionType.value = ActionType.LONG_PRESS + _postedActionType.value = ActionType.LONG_PRESS _effectProgress.value = null } - if (state != State.TIMEOUT_WAIT) { + if (_state.value != State.TIMEOUT_WAIT) { // This will happen if the animator did not finish by being cancelled - state = State.IDLE + setState(State.IDLE) } } private fun handleAnimationCancel() { - _effectProgress.value = 0f - startPressedTimeoutWait() - state = State.TIMEOUT_WAIT + _effectProgress.value = null + setState(State.TIMEOUT_WAIT) } - private fun handleTimeoutComplete() { - if (state == State.TIMEOUT_WAIT && !effectAnimator.isRunning) { - effectAnimator.start() + fun handleTimeoutComplete() { + if (_state.value == State.TIMEOUT_WAIT && effectAnimator?.isRunning == false) { + effectAnimator?.start() } } fun clearActionType() { - _actionType.value = null + _postedActionType.value = null + } + + /** Reset the effect by going back to a default [IDLE] state */ + fun resetEffect() { + if (effectAnimator?.isRunning == true) { + effectAnimator?.cancel() + } + longPressHint = null + effectAnimator = null + _effectProgress.value = null + _postedActionType.value = null + setState(State.IDLE) } /** * Reset the effect with a new effect duration. * - * The effect will go back to an [IDLE] state where it can begin its logic with a new duration. - * * @param[duration] New duration for the long-press effect + * @return true if the effect initialized correctly */ - fun resetWithDuration(duration: Int) { + fun initializeEffect(duration: Int): Boolean { // The effect can't reset if it is running - if (effectAnimator.isRunning) return + if (duration <= 0) return false + + resetEffect() + effectDuration = duration + effectAnimator = + ValueAnimator.ofFloat(0f, 1f).apply { + this.duration = effectDuration.toLong() + interpolator = AccelerateDecelerateInterpolator() - effectAnimator.duration = duration.toLong() - _effectProgress.value = 0f - _actionType.value = null - waitJob?.cancel() - state = State.IDLE + doOnStart { handleAnimationStart() } + addUpdateListener { _effectProgress.value = animatedValue as Float } + doOnEnd { handleAnimationComplete() } + doOnCancel { handleAnimationCancel() } + } + longPressHint = + LongPressHapticBuilder.createLongPressHint( + durations?.get(0) ?: LongPressHapticBuilder.INVALID_DURATION, + durations?.get(1) ?: LongPressHapticBuilder.INVALID_DURATION, + effectDuration + ) + return true } enum class State { @@ -243,6 +269,7 @@ class QSLongPressEffect( enum class ActionType { CLICK, LONG_PRESS, + RESET_AND_LONG_PRESS, } companion object { diff --git a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt index f4998a7b8789..ddb9f35c74d9 100644 --- a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt @@ -21,56 +21,68 @@ import androidx.lifecycle.repeatOnLifecycle import com.android.app.tracing.coroutines.launch import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.qs.tileimpl.QSTileViewImpl +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.DisposableHandle +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.launch -class QSLongPressEffectViewBinder { - - private var handle: DisposableHandle? = null - val isBound: Boolean - get() = handle != null - +// TODO(b/332903800) +object QSLongPressEffectViewBinder { fun bind( tile: QSTileViewImpl, + qsLongPressEffect: QSLongPressEffect?, tileSpec: String?, - effect: QSLongPressEffect?, - ) { - if (effect == null) return - - handle = - tile.repeatWhenAttached { - repeatOnLifecycle(Lifecycle.State.CREATED) { - effect.scope = this - val tag = "${tileSpec ?: "unknownTileSpec"}#LongPressEffect" + ): DisposableHandle? { + if (qsLongPressEffect == null) return null - launch("$tag#progress") { - effect.effectProgress.collect { progress -> - progress?.let { - if (it == 0f) { - tile.bringToFront() - } + return tile.repeatWhenAttached { + repeatOnLifecycle(Lifecycle.State.CREATED) { + val tag = "${tileSpec ?: "unknownTileSpec"}#LongPressEffect" + // Progress of the effect + launch("$tag#progress") { + qsLongPressEffect.effectProgress.collect { progress -> + progress?.let { + if (it == 0f) { + tile.bringToFront() + } else { tile.updateLongPressEffectProperties(it) } } } + } - launch("$tag#action") { - effect.actionType.collect { action -> - action?.let { - when (it) { - QSLongPressEffect.ActionType.CLICK -> tile.performClick() - QSLongPressEffect.ActionType.LONG_PRESS -> - tile.performLongClick() + // Action to perform + launch("$tag#action") { + qsLongPressEffect.actionType.collect { action -> + action?.let { + when (it) { + QSLongPressEffect.ActionType.CLICK -> tile.performClick() + QSLongPressEffect.ActionType.LONG_PRESS -> tile.performLongClick() + QSLongPressEffect.ActionType.RESET_AND_LONG_PRESS -> { + tile.resetLongPressEffectProperties() + tile.performLongClick() } - effect.clearActionType() } + qsLongPressEffect.clearActionType() } } } - } - } - fun dispose() { - handle?.dispose() - handle = null + // Tap timeout wait + launch("$tag#timeout") { + qsLongPressEffect.shouldWaitForTapTimeout + .filter { it } + .collect { + try { + delay(QSLongPressEffect.PRESSED_TIMEOUT) + qsLongPressEffect.handleTimeoutComplete() + } catch (_: CancellationException) { + qsLongPressEffect.resetEffect() + } + } + } + } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 6b53f4ed554f..a5d7e04bf4d0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -63,6 +63,7 @@ import android.view.SurfaceControl; import android.view.WindowManagerPolicyConstants; import android.window.IRemoteTransition; import android.window.IRemoteTransitionFinishedCallback; +import android.window.RemoteTransitionStub; import android.window.TransitionInfo; import com.android.internal.annotations.GuardedBy; @@ -187,7 +188,7 @@ public class KeyguardService extends Service { // Note: Also used for wrapping occlude by Dream animation. It works (with some redundancy). public static IRemoteTransition wrap(final KeyguardViewMediator keyguardViewMediator, final IRemoteAnimationRunner runner) { - return new IRemoteTransition.Stub() { + return new RemoteTransitionStub() { @GuardedBy("mLeashMap") private final ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = new ArrayMap<>(); @@ -253,11 +254,6 @@ public class KeyguardService extends Service { } } - @Override - public void onTransitionConsumed(IBinder transition, boolean aborted) { - // No-op. - } - private static void initAlphaForAnimationTargets(@NonNull SurfaceControl.Transaction t, @NonNull RemoteAnimationTarget[] targets) { for (RemoteAnimationTarget target : targets) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt index e101b0ab64aa..c835599abfe1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt @@ -29,6 +29,7 @@ import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState.GONE import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.utils.GlobalWindowManager @@ -83,7 +84,7 @@ constructor( applicationScope.launch(bgDispatcher) { // We drop 1 to avoid triggering on initial collect(). - keyguardTransitionInteractor.anyStateToGoneTransition.collect { transition -> + keyguardTransitionInteractor.transition(from = null, to = GONE).collect { transition -> if (transition.transitionState == TransitionState.FINISHED) { onKeyguardGone() } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt index 97081d93892a..d3ad0c2ac7e1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt @@ -20,19 +20,14 @@ package com.android.systemui.keyguard.domain.interactor import android.util.Log 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.data.repository.KeyguardRepository import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository +import com.android.systemui.keyguard.shared.model.Edge import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER import com.android.systemui.keyguard.shared.model.KeyguardState.AOD import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING -import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING -import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING_LOCKSCREEN_HOSTED -import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB -import com.android.systemui.keyguard.shared.model.KeyguardState.GONE import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN -import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED import com.android.systemui.keyguard.shared.model.KeyguardState.OFF import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER import com.android.systemui.keyguard.shared.model.TransitionInfo @@ -40,7 +35,6 @@ import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.util.kotlin.pairwise import javax.inject.Inject -import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.BufferOverflow @@ -53,6 +47,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest +import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch @@ -64,7 +59,6 @@ class KeyguardTransitionInteractor @Inject constructor( @Application val scope: CoroutineScope, - @Main private val mainDispatcher: CoroutineDispatcher, private val keyguardRepository: KeyguardRepository, private val repository: KeyguardTransitionRepository, private val fromLockscreenTransitionInteractor: dagger.Lazy<FromLockscreenTransitionInteractor>, @@ -75,14 +69,13 @@ constructor( dagger.Lazy<FromAlternateBouncerTransitionInteractor>, private val fromDozingTransitionInteractor: dagger.Lazy<FromDozingTransitionInteractor>, ) { - private val TAG = this::class.simpleName - - private val transitionValueCache = mutableMapOf<KeyguardState, MutableSharedFlow<Float>>() + private val transitionMap = mutableMapOf<Edge, MutableSharedFlow<TransitionStep>>() /** * Numerous flows are derived from, or care directly about, the transition value in and out of a * single state. This prevent the redundant filters from running. */ + private val transitionValueCache = mutableMapOf<KeyguardState, MutableSharedFlow<Float>>() private fun getTransitionValueFlow(state: KeyguardState): MutableSharedFlow<Float> { return transitionValueCache.getOrPut(state) { MutableSharedFlow<Float>( @@ -94,6 +87,7 @@ constructor( } } + @Deprecated("Not performant - Use something else in this class") val transitions = repository.transitions /** @@ -106,14 +100,14 @@ constructor( * from when we were canceled. */ val startedStepWithPrecedingStep = - transitions + repository.transitions .pairwise() .filter { it.newValue.transitionState == TransitionState.STARTED } .shareIn(scope, SharingStarted.Eagerly) init { // Collect non-canceled steps and emit transition values. - scope.launch(mainDispatcher) { + scope.launch { repository.transitions .filter { it.transitionState != TransitionState.CANCELED } .collect { step -> @@ -122,11 +116,22 @@ constructor( } } + scope.launch { + repository.transitions.collect { + // FROM->TO + transitionMap[Edge(it.from, it.to)]?.emit(it) + // FROM->(ANY) + transitionMap[Edge(it.from, null)]?.emit(it) + // (ANY)->TO + transitionMap[Edge(null, it.to)]?.emit(it) + } + } + // If a transition from state A -> B is canceled in favor of a transition from B -> C, we // need to ensure we emit transitionValue(A) = 0f, since no further steps will be emitted // where the from or to states are A. This would leave transitionValue(A) stuck at an // arbitrary non-zero value. - scope.launch(mainDispatcher) { + scope.launch { startedStepWithPrecedingStep.collect { (prevStep, startedStep) -> if ( prevStep.transitionState == TransitionState.CANCELED && @@ -138,116 +143,42 @@ constructor( } } - /** (any)->GONE transition information */ - val anyStateToGoneTransition: Flow<TransitionStep> = - repository.transitions.filter { step -> step.to == GONE } - - /** (any)->AOD transition information */ - val anyStateToAodTransition: Flow<TransitionStep> = - repository.transitions.filter { step -> step.to == AOD } - - /** DREAMING->(any) transition information. */ - val fromDreamingTransition: Flow<TransitionStep> = - repository.transitions.filter { step -> step.from == DREAMING } - - /** LOCKSCREEN->(any) transition information. */ - val fromLockscreenTransition: Flow<TransitionStep> = - repository.transitions.filter { step -> step.from == LOCKSCREEN } - - /** (any)->Lockscreen transition information */ - val anyStateToLockscreenTransition: Flow<TransitionStep> = - repository.transitions.filter { step -> step.to == LOCKSCREEN } - - /** (any)->Occluded transition information */ - val anyStateToOccludedTransition: Flow<TransitionStep> = - repository.transitions.filter { step -> step.to == OCCLUDED } - - /** (any)->PrimaryBouncer transition information */ - val anyStateToPrimaryBouncerTransition: Flow<TransitionStep> = - repository.transitions.filter { step -> step.to == PRIMARY_BOUNCER } - - /** (any)->Dreaming transition information */ - val anyStateToDreamingTransition: Flow<TransitionStep> = - repository.transitions.filter { step -> step.to == DREAMING } - - /** (any)->AlternateBouncer transition information */ - val anyStateToAlternateBouncerTransition: Flow<TransitionStep> = - repository.transitions.filter { step -> step.to == ALTERNATE_BOUNCER } - - /** AOD->LOCKSCREEN transition information. */ - val aodToLockscreenTransition: Flow<TransitionStep> = repository.transition(AOD, LOCKSCREEN) - - /** DREAMING->LOCKSCREEN transition information. */ - val dreamingToLockscreenTransition: Flow<TransitionStep> = - repository.transition(DREAMING, LOCKSCREEN) - - /** DREAMING_LOCKSCREEN_HOSTED->LOCKSCREEN transition information. */ - val dreamingLockscreenHostedToLockscreenTransition: Flow<TransitionStep> = - repository.transition(DREAMING_LOCKSCREEN_HOSTED, LOCKSCREEN) - - /** GONE->AOD transition information. */ - val goneToAodTransition: Flow<TransitionStep> = repository.transition(GONE, AOD) - - /** GONE->DREAMING transition information. */ - val goneToDreamingTransition: Flow<TransitionStep> = repository.transition(GONE, DREAMING) - - /** GONE->DREAMING_LOCKSCREEN_HOSTED transition information. */ - val goneToDreamingLockscreenHostedTransition: Flow<TransitionStep> = - repository.transition(GONE, DREAMING_LOCKSCREEN_HOSTED) - - /** GONE->LOCKSCREEN transition information. */ - val goneToLockscreenTransition: Flow<TransitionStep> = repository.transition(GONE, LOCKSCREEN) - - /** LOCKSCREEN->AOD transition information. */ - val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD) - - /** LOCKSCREEN->DOZING transition information. */ - val lockscreenToDozingTransition: Flow<TransitionStep> = - repository.transition(LOCKSCREEN, DOZING) - - /** LOCKSCREEN->DREAMING transition information. */ - val lockscreenToDreamingTransition: Flow<TransitionStep> = - repository.transition(LOCKSCREEN, DREAMING) - - /** LOCKSCREEN->DREAMING_LOCKSCREEN_HOSTED transition information. */ - val lockscreenToDreamingLockscreenHostedTransition: Flow<TransitionStep> = - repository.transition(LOCKSCREEN, DREAMING_LOCKSCREEN_HOSTED) - - /** LOCKSCREEN->GLANCEABLE_HUB transition information. */ - val lockscreenToGlanceableHubTransition: Flow<TransitionStep> = - repository.transition(LOCKSCREEN, GLANCEABLE_HUB) - - /** LOCKSCREEN->OCCLUDED transition information. */ - val lockscreenToOccludedTransition: Flow<TransitionStep> = - repository.transition(LOCKSCREEN, OCCLUDED) - - /** GLANCEABLE_HUB->LOCKSCREEN transition information. */ - val glanceableHubToLockscreenTransition: Flow<TransitionStep> = - repository.transition(GLANCEABLE_HUB, LOCKSCREEN) - - /** OCCLUDED->LOCKSCREEN transition information. */ - val occludedToLockscreenTransition: Flow<TransitionStep> = - repository.transition(OCCLUDED, LOCKSCREEN) - - /** PRIMARY_BOUNCER->GONE transition information. */ - val primaryBouncerToGoneTransition: Flow<TransitionStep> = - repository.transition(PRIMARY_BOUNCER, GONE) - - /** OFF->LOCKSCREEN transition information. */ - val offToLockscreenTransition: Flow<TransitionStep> = repository.transition(OFF, LOCKSCREEN) + /** Given an [edge], return a SharedFlow to collect only relevant [TransitionStep]. */ + fun getOrCreateFlow(edge: Edge): MutableSharedFlow<TransitionStep> { + return transitionMap.getOrPut(edge) { + MutableSharedFlow<TransitionStep>( + extraBufferCapacity = 10, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + } + } - /** DOZING->LOCKSCREEN transition information. */ - val dozingToLockscreenTransition: Flow<TransitionStep> = - repository.transition(DOZING, LOCKSCREEN) + /** + * Receive all [TransitionStep] matching a filter of [from]->[to]. Allow nulls in order to match + * any transition, for instance (any)->GONE. + */ + fun transition(from: KeyguardState?, to: KeyguardState?): Flow<TransitionStep> { + if (from == null && to == null) { + throw IllegalArgumentException("from and to cannot both be null") + } + return getOrCreateFlow(Edge(from = from, to = to)) + } - /** Receive all [TransitionStep] matching a filter of [from]->[to] */ - fun transition(from: KeyguardState, to: KeyguardState): Flow<TransitionStep> { - return repository.transition(from, to) + /** + * The amount of transition into or out of the given [KeyguardState]. + * + * The value will be `0` (or close to `0`, due to float point arithmetic) if not in this step or + * `1` when fully in the given state. + */ + fun transitionValue( + state: KeyguardState, + ): Flow<Float> { + return getTransitionValueFlow(state) } /** - * AOD<->LOCKSCREEN transition information, mapped to dozeAmount range of AOD (1f) <-> - * Lockscreen (0f). + * AOD<->* transition information, mapped to dozeAmount range of AOD (1f) <-> + * * (0f). */ val dozeAmountTransition: Flow<TransitionStep> = repository.transitions @@ -265,13 +196,10 @@ constructor( val startedKeyguardTransitionStep: Flow<TransitionStep> = repository.transitions.filter { step -> step.transitionState == TransitionState.STARTED } - /** The last [TransitionStep] with a [TransitionState] of CANCELED */ - val canceledKeyguardTransitionStep: Flow<TransitionStep> = - repository.transitions.filter { step -> step.transitionState == TransitionState.CANCELED } - /** The last [TransitionStep] with a [TransitionState] of FINISHED */ val finishedKeyguardTransitionStep: Flow<TransitionStep> = - repository.transitions.filter { step -> step.transitionState == TransitionState.FINISHED } + repository.transitions + .filter { step -> step.transitionState == TransitionState.FINISHED } /** The destination state of the last [TransitionState.STARTED] transition. */ val startedKeyguardState: SharedFlow<KeyguardState> = @@ -364,10 +292,6 @@ constructor( * case, the smartspace will never be set to alpha = 1f and you'll have a half-faded smartspace * during the LS -> GONE transition. * - * If you need special-case handling for cancellations (such as conditional handling depending - * on which [KeyguardState] was canceled) you can collect [canceledKeyguardTransitionStep] - * directly. - * * As a helpful footnote, here's the values of [finishedKeyguardState] and * [currentKeyguardState] during a sequence with two cancellations: * 1. We're FINISHED in GONE. currentKeyguardState=GONE; finishedKeyguardState=GONE. @@ -390,7 +314,7 @@ constructor( } } .distinctUntilChanged() - .shareIn(scope, SharingStarted.Eagerly, replay = 1) + .stateIn(scope, SharingStarted.Eagerly, KeyguardState.OFF) /** * The [TransitionInfo] of the most recent call to @@ -420,24 +344,12 @@ constructor( /** Whether we've currently STARTED a transition and haven't yet FINISHED it. */ val isInTransitionToAnyState = isInTransitionWhere({ true }, { true }) - /** - * The amount of transition into or out of the given [KeyguardState]. - * - * The value will be `0` (or close to `0`, due to float point arithmetic) if not in this step or - * `1` when fully in the given state. - */ - fun transitionValue( - state: KeyguardState, - ): Flow<Float> { - return getTransitionValueFlow(state) - } - fun transitionStepsFromState(fromState: KeyguardState): Flow<TransitionStep> { - return repository.transitions.filter { step -> step.from == fromState } + return getOrCreateFlow(Edge(from = fromState, to = null)) } fun transitionStepsToState(toState: KeyguardState): Flow<TransitionStep> { - return repository.transitions.filter { step -> step.to == toState } + return getOrCreateFlow(Edge(from = null, to = toState)) } /** @@ -464,17 +376,24 @@ constructor( fun isInTransitionToState( state: KeyguardState, ): Flow<Boolean> { - return isInTransitionToStateWhere { it == state } + return getOrCreateFlow(Edge(from = null, to = state)) + .mapLatest { it.transitionState.isActive() } + .onStart { emit(false) } + .distinctUntilChanged() } /** - * Whether we're in a transition to a [KeyguardState] that matches the given predicate, but - * haven't yet completed it. + * Whether we're in a transition to and from the given [KeyguardState]s, but haven't yet + * completed it. */ - fun isInTransitionToStateWhere( - stateMatcher: (KeyguardState) -> Boolean, + fun isInTransition( + from: KeyguardState, + to: KeyguardState, ): Flow<Boolean> { - return isInTransitionWhere(fromStatePredicate = { true }, toStatePredicate = stateMatcher) + return getOrCreateFlow(Edge(from = from, to = to)) + .mapLatest { it.transitionState.isActive() } + .onStart { emit(false) } + .distinctUntilChanged() } /** @@ -483,12 +402,29 @@ constructor( fun isInTransitionFromState( state: KeyguardState, ): Flow<Boolean> { - return isInTransitionFromStateWhere { it == state } + return getOrCreateFlow(Edge(from = state, to = null)) + .mapLatest { it.transitionState.isActive() } + .onStart { emit(false) } + .distinctUntilChanged() + } + + /** + * Whether we're in a transition to a [KeyguardState] that matches the given predicate, but + * haven't yet completed it. + * + * If you only care about a single state, instead use the optimized [isInTransitionToState]. + */ + fun isInTransitionToStateWhere( + stateMatcher: (KeyguardState) -> Boolean, + ): Flow<Boolean> { + return isInTransitionWhere(fromStatePredicate = { true }, toStatePredicate = stateMatcher) } /** * Whether we're in a transition out of a [KeyguardState] that matches the given predicate, but * haven't yet completed it. + * + * If you only care about a single state, instead use the optimized [isInTransitionFromState]. */ fun isInTransitionFromStateWhere( stateMatcher: (KeyguardState) -> Boolean, @@ -499,6 +435,9 @@ constructor( /** * Whether we're in a transition between two [KeyguardState]s that match the given predicates, * but haven't yet completed it. + * + * If you only care about a single state for both from and to, instead use the optimized + * [isInTransition]. */ fun isInTransitionWhere( fromStatePredicate: (KeyguardState) -> Boolean, @@ -507,6 +446,13 @@ constructor( return isInTransitionWhere { from, to -> fromStatePredicate(from) && toStatePredicate(to) } } + /** + * Whether we're in a transition between two [KeyguardState]s that match the given predicates, + * but haven't yet completed it. + * + * If you only care about a single state for both from and to, instead use the optimized + * [isInTransition]. + */ fun isInTransitionWhere( fromToStatePredicate: (KeyguardState, KeyguardState) -> Boolean ): Flow<Boolean> { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionState.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionState.kt index 38a93b50ea97..f6567a6ccb53 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionState.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionState.kt @@ -18,11 +18,21 @@ package com.android.systemui.keyguard.shared.model /** Possible states for a running transition between [State] */ enum class TransitionState { /* Transition has begun. */ - STARTED, + STARTED { + override fun isActive() = true + }, /* Transition is actively running. */ - RUNNING, + RUNNING { + override fun isActive() = true + }, /* Transition has completed successfully. */ - FINISHED, + FINISHED { + override fun isActive() = false + }, /* Transition has been interrupted, and not completed successfully. */ - CANCELED, + CANCELED { + override fun isActive() = false + }; + + abstract fun isActive(): Boolean } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt index 5de1a61d61b5..735b10907c73 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt @@ -19,8 +19,6 @@ import android.view.animation.Interpolator import com.android.app.animation.Interpolators.LINEAR import com.android.keyguard.logging.KeyguardTransitionAnimationLogger 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.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.Edge import com.android.systemui.keyguard.shared.model.KeyguardState @@ -35,15 +33,10 @@ import kotlin.math.max import kotlin.math.min import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapNotNull -import kotlinx.coroutines.launch /** * Assists in creating sub-flows for a KeyguardTransition. Call [setup] once for a transition, and @@ -53,35 +46,9 @@ import kotlinx.coroutines.launch class KeyguardTransitionAnimationFlow @Inject constructor( - @Application private val scope: CoroutineScope, - @Main private val mainDispatcher: CoroutineDispatcher, private val transitionInteractor: KeyguardTransitionInteractor, private val logger: KeyguardTransitionAnimationLogger, ) { - private val transitionMap = mutableMapOf<Edge, MutableSharedFlow<TransitionStep>>() - - init { - scope.launch(mainDispatcher) { - transitionInteractor.transitions.collect { - // FROM->TO - transitionMap[Edge(it.from, it.to)]?.emit(it) - // FROM->(ANY) - transitionMap[Edge(it.from, null)]?.emit(it) - // (ANY)->TO - transitionMap[Edge(null, it.to)]?.emit(it) - } - } - } - - private fun getOrCreateFlow(edge: Edge): MutableSharedFlow<TransitionStep> { - return transitionMap.getOrPut(edge) { - MutableSharedFlow<TransitionStep>( - extraBufferCapacity = 10, - onBufferOverflow = BufferOverflow.DROP_OLDEST - ) - } - } - /** Invoke once per transition between FROM->TO states to get access to a shared flow. */ fun setup( duration: Duration, @@ -185,7 +152,8 @@ constructor( }?.let { onStep(interpolator.getInterpolation(it)) } } - return getOrCreateFlow(edge) + return transitionInteractor + .getOrCreateFlow(edge) .map { step -> StateToValue( from = step.from, 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 4d3a78d32b3a..91f76a4df771 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 @@ -169,10 +169,7 @@ class ClockSizeTransition( return@OnPreDrawListener true } - anim.duration = duration - anim.startDelay = startDelay - anim.interpolator = interpolator - anim.addListener( + val listener = object : AnimatorListenerAdapter() { override fun onAnimationStart(anim: Animator) { assignAnimValues("start", 0f, fromVis) @@ -183,8 +180,21 @@ class ClockSizeTransition( if (sendToBack) toView.translationZ = 0f toView.viewTreeObserver.removeOnPreDrawListener(predrawCallback) } + + override fun onAnimationPause(anim: Animator) { + toView.viewTreeObserver.removeOnPreDrawListener(predrawCallback) + } + + override fun onAnimationResume(anim: Animator) { + toView.viewTreeObserver.addOnPreDrawListener(predrawCallback) + } } - ) + + anim.duration = duration + anim.startDelay = startDelay + anim.interpolator = interpolator + anim.addListener(listener) + anim.addPauseListener(listener) assignAnimValues("init", 0f, fromVis) toView.viewTreeObserver.addOnPreDrawListener(predrawCallback) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt index 7814576eff01..5cf100e78e6e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt @@ -19,7 +19,6 @@ package com.android.systemui.keyguard.ui.viewmodel import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState -import com.android.systemui.keyguard.shared.model.TransitionState import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow @@ -38,12 +37,9 @@ constructor( private val deviceSupportsAlternateBouncer: Flow<Boolean> = alternateBouncerInteractor.alternateBouncerSupported private val isTransitioningToOrFromOrShowingAlternateBouncer: Flow<Boolean> = - keyguardTransitionInteractor.transitions - .map { - it.to == KeyguardState.ALTERNATE_BOUNCER || - (it.from == KeyguardState.ALTERNATE_BOUNCER && - it.transitionState != TransitionState.FINISHED) - } + keyguardTransitionInteractor + .transitionValue(KeyguardState.ALTERNATE_BOUNCER) + .map { it > 0f } .distinctUntilChanged() val alternateBouncerWindowRequired: Flow<Boolean> = diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt index 4ddd57110b38..e2177e61d954 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt @@ -29,9 +29,6 @@ import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.BurnInModel -import com.android.systemui.keyguard.shared.model.TransitionState -import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING -import com.android.systemui.keyguard.shared.model.TransitionState.STARTED import com.android.systemui.keyguard.ui.StateToValue import com.android.systemui.res.R import javax.inject.Inject @@ -97,9 +94,9 @@ constructor( occludedToLockscreen, aodToLockscreen -> val translationY = - if (isInTransition(aodToLockscreen.transitionState)) { + if (aodToLockscreen.transitionState.isActive()) { aodToLockscreen.value ?: 0f - } else if (isInTransition(goneToAod.transitionState)) { + } else if (goneToAod.transitionState.isActive()) { (goneToAod.value ?: 0f) + burnInModel.translationY } else { burnInModel.translationY + occludedToLockscreen + keyguardTranslationY @@ -110,10 +107,6 @@ constructor( .distinctUntilChanged() } - private fun isInTransition(state: TransitionState): Boolean { - return state == STARTED || state == RUNNING - } - private fun burnIn( params: BurnInParameters, ): Flow<BurnInModel> { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt index 6d0f96c2f635..24429fae93ac 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt @@ -102,7 +102,7 @@ constructor( to = GONE, ) - return shadeInteractor.shadeExpansion.flatMapLatest { shadeExpansion -> + return shadeInteractor.isAnyExpanded.flatMapLatest { isAnyExpanded -> transitionAnimation .sharedFlow( duration = duration, @@ -110,7 +110,7 @@ constructor( onStart = { leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide() willRunDismissFromKeyguard = willRunAnimationOnKeyguard() - isShadeExpanded = shadeExpansion > 0f + isShadeExpanded = isAnyExpanded }, onStep = { 1f - it }, ) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt index ac67f94fa9cf..24a7c512a6a9 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt @@ -42,6 +42,7 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.phone.ScreenOffAnimationController +import com.android.systemui.util.kotlin.BooleanFlowOperators.or import com.android.systemui.util.kotlin.pairwise import com.android.systemui.util.kotlin.sample import com.android.systemui.util.ui.AnimatableEvent @@ -133,22 +134,18 @@ constructor( private val isOnLockscreen: Flow<Boolean> = combine( keyguardTransitionInteractor.isFinishedInState(LOCKSCREEN).onStart { emit(false) }, - keyguardTransitionInteractor - .isInTransitionWhere { from, to -> from == LOCKSCREEN || to == LOCKSCREEN } - .onStart { emit(false) } + or( + keyguardTransitionInteractor.isInTransitionToState(LOCKSCREEN), + keyguardTransitionInteractor.isInTransitionFromState(LOCKSCREEN), + ), ) { onLockscreen, transitioningToOrFromLockscreen -> onLockscreen || transitioningToOrFromLockscreen } .distinctUntilChanged() - private val lockscreenToGoneTransitionRunning: Flow<Boolean> = - keyguardTransitionInteractor - .isInTransitionWhere { from, to -> from == LOCKSCREEN && to == GONE } - .onStart { emit(false) } - private val alphaOnShadeExpansion: Flow<Float> = combineTransform( - lockscreenToGoneTransitionRunning, + keyguardTransitionInteractor.isInTransition(from = LOCKSCREEN, to = GONE), isOnLockscreen, shadeInteractor.qsExpansion, shadeInteractor.shadeExpansion, diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt index df34169c9a50..9dc5900296c2 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt @@ -19,7 +19,9 @@ package com.android.systemui.media.controls.data.repository import com.android.internal.logging.InstanceId import com.android.systemui.dagger.SysUISingleton import com.android.systemui.media.controls.shared.model.MediaData +import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel import com.android.systemui.media.controls.shared.model.SmartspaceMediaData +import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -46,6 +48,16 @@ class MediaFilterRepository @Inject constructor() { MutableStateFlow(LinkedHashMap()) val allUserEntries: StateFlow<Map<String, MediaData>> = _allUserEntries.asStateFlow() + private val _mediaDataLoadedStates: MutableStateFlow<List<MediaDataLoadingModel>> = + MutableStateFlow(mutableListOf()) + val mediaDataLoadedStates: StateFlow<List<MediaDataLoadingModel>> = + _mediaDataLoadedStates.asStateFlow() + + private val _recommendationsLoadingState: MutableStateFlow<SmartspaceMediaLoadingModel> = + MutableStateFlow(SmartspaceMediaLoadingModel.Unknown) + val recommendationsLoadingState: StateFlow<SmartspaceMediaLoadingModel> = + _recommendationsLoadingState.asStateFlow() + fun addMediaEntry(key: String, data: MediaData) { val entries = LinkedHashMap<String, MediaData>(_allUserEntries.value) entries[key] = data @@ -110,4 +122,25 @@ class MediaFilterRepository @Inject constructor() { fun setReactivatedId(instanceId: InstanceId?) { _reactivatedId.value = instanceId } + + fun addMediaDataLoadingState(mediaDataLoadingModel: MediaDataLoadingModel) { + // Filter out previous loading state that has same [InstanceId]. + val loadedStates = + _mediaDataLoadedStates.value.filter { loadedModel -> + loadedModel !is MediaDataLoadingModel.Loaded || + !loadedModel.equalInstanceIds(mediaDataLoadingModel) + } + + _mediaDataLoadedStates.value = + loadedStates + + if (mediaDataLoadingModel is MediaDataLoadingModel.Loaded) { + listOf(mediaDataLoadingModel) + } else { + emptyList() + } + } + + fun setRecommedationsLoadingState(smartspaceMediaLoadingModel: SmartspaceMediaLoadingModel) { + _recommendationsLoadingState.value = smartspaceMediaLoadingModel + } } diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt index d40069c4b3da..a30e5826529a 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt @@ -28,7 +28,9 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.media.controls.data.repository.MediaFilterRepository import com.android.systemui.media.controls.shared.model.EXTRA_KEY_TRIGGER_RESUME import com.android.systemui.media.controls.shared.model.MediaData +import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel import com.android.systemui.media.controls.shared.model.SmartspaceMediaData +import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel import com.android.systemui.media.controls.util.MediaFlags import com.android.systemui.media.controls.util.MediaUiEventLogger import com.android.systemui.settings.UserTracker @@ -67,9 +69,6 @@ constructor( private val mediaFlags: MediaFlags, private val mediaFilterRepository: MediaFilterRepository, ) : MediaDataManager.Listener { - private val _listeners: MutableSet<Listener> = mutableSetOf() - val listeners: Set<Listener> - get() = _listeners.toSet() lateinit var mediaDataManager: MediaDataManager // Ensure the field (and associated reference) isn't removed during optimization. @@ -111,8 +110,9 @@ constructor( mediaFilterRepository.addSelectedUserMediaEntry(data) - // Notify listeners - listeners.forEach { it.onMediaDataLoaded(data.instanceId) } + mediaFilterRepository.addMediaDataLoadingState( + MediaDataLoadingModel.Loaded(data.instanceId) + ) } override fun onSmartspaceMediaDataLoaded( @@ -159,7 +159,7 @@ constructor( // reactivate. if (shouldReactivate) { val lastActiveId = sorted.lastKey() // most recently active id - // Notify listeners to consider this media active + // Update loading state to consider this media active Log.d(TAG, "reactivating $lastActiveId instead of smartspace") mediaFilterRepository.setReactivatedId(lastActiveId) val mediaData = sorted[lastActiveId]!!.copy(active = true) @@ -168,15 +168,9 @@ constructor( mediaData.packageName, mediaData.instanceId ) - listeners.forEach { - it.onMediaDataLoaded( - lastActiveId, - receivedSmartspaceCardLatency = - (systemClock.currentTimeMillis() - data.headphoneConnectionTimeMillis) - .toInt(), - isSsReactivated = true - ) - } + mediaFilterRepository.addMediaDataLoadingState( + MediaDataLoadingModel.Loaded(lastActiveId) + ) } } else if (data.isActive) { // Mark to prioritize Smartspace card if no recent media. @@ -192,15 +186,18 @@ constructor( smartspaceMediaData.packageName, smartspaceMediaData.instanceId ) - listeners.forEach { it.onSmartspaceMediaDataLoaded(key, shouldPrioritizeMutable) } + mediaFilterRepository.setRecommedationsLoadingState( + SmartspaceMediaLoadingModel.Loaded(key, shouldPrioritizeMutable) + ) } override fun onMediaDataRemoved(key: String) { mediaFilterRepository.removeMediaEntry(key)?.let { mediaData -> val instanceId = mediaData.instanceId mediaFilterRepository.removeSelectedUserMediaEntry(instanceId)?.let { - // Only notify listeners if something actually changed - listeners.forEach { it.onMediaDataRemoved(instanceId) } + mediaFilterRepository.addMediaDataLoadingState( + MediaDataLoadingModel.Removed(instanceId) + ) } } } @@ -210,11 +207,11 @@ constructor( mediaFilterRepository.reactivatedId.value?.let { lastActiveId -> mediaFilterRepository.setReactivatedId(null) Log.d(TAG, "expiring reactivated key $lastActiveId") - // Notify listeners to update with actual active value + // Update loading state with actual active value mediaFilterRepository.selectedUserEntries.value[lastActiveId]?.let { - listeners.forEach { listener -> - listener.onMediaDataLoaded(lastActiveId, immediately) - } + mediaFilterRepository.addMediaDataLoadingState( + MediaDataLoadingModel.Loaded(lastActiveId, immediately) + ) } } @@ -227,7 +224,9 @@ constructor( ) ) } - listeners.forEach { it.onSmartspaceMediaDataRemoved(key, immediately) } + mediaFilterRepository.setRecommedationsLoadingState( + SmartspaceMediaLoadingModel.Removed(key, immediately) + ) } @VisibleForTesting @@ -238,29 +237,37 @@ constructor( // Only remove media when the profile is unavailable. if (DEBUG) Log.d(TAG, "Removing $key after profile change") mediaFilterRepository.removeSelectedUserMediaEntry(data.instanceId, data) - listeners.forEach { listener -> listener.onMediaDataRemoved(data.instanceId) } + mediaFilterRepository.addMediaDataLoadingState( + MediaDataLoadingModel.Removed(data.instanceId) + ) } } } @VisibleForTesting internal fun handleUserSwitched() { - // If the user changes, remove all current MediaData objects and inform listeners - val listenersCopy = listeners + // If the user changes, remove all current MediaData objects. val keyCopy = mediaFilterRepository.selectedUserEntries.value.keys.toMutableList() - // Clear the list first, to make sure callbacks from listeners if we have any entries - // are up to date + // Clear the list first and update loading state to remove media from UI. mediaFilterRepository.clearSelectedUserMedia() keyCopy.forEach { instanceId -> if (DEBUG) Log.d(TAG, "Removing $instanceId after user change") - listenersCopy.forEach { listener -> listener.onMediaDataRemoved(instanceId) } + mediaFilterRepository.addMediaDataLoadingState( + MediaDataLoadingModel.Removed(instanceId) + ) } mediaFilterRepository.allUserEntries.value.forEach { (key, data) -> if (lockscreenUserManager.isCurrentProfile(data.userId)) { - if (DEBUG) Log.d(TAG, "Re-adding $key after user change") + if (DEBUG) + Log.d( + TAG, + "Re-adding $key with instanceId=${data.instanceId} after user change" + ) mediaFilterRepository.addSelectedUserMediaEntry(data) - listenersCopy.forEach { listener -> listener.onMediaDataLoaded(data.instanceId) } + mediaFilterRepository.addMediaDataLoadingState( + MediaDataLoadingModel.Loaded(data.instanceId) + ) } } } @@ -310,12 +317,6 @@ constructor( } } - /** Add a listener for filtered [MediaData] changes */ - fun addListener(listener: Listener) = _listeners.add(listener) - - /** Remove a listener that was registered with addListener */ - fun removeListener(listener: Listener) = _listeners.remove(listener) - /** * Return the time since last active for the most-recent media. * @@ -335,48 +336,6 @@ constructor( return sortedEntries[lastActiveInstanceId]?.let { now - it.lastActive } ?: Long.MAX_VALUE } - interface Listener { - /** - * Called whenever there's new MediaData Loaded for the consumption in views. - * - * @param immediately indicates should apply the UI changes immediately, otherwise wait - * until the next refresh-round before UI becomes visible. True by default to take in - * place immediately. - * @param receivedSmartspaceCardLatency is the latency between headphone connects and sysUI - * displays Smartspace media targets. Will be 0 if the data is not activated by Smartspace - * signal. - * @param isSsReactivated indicates resume media card is reactivated by Smartspace - * recommendation signal - */ - fun onMediaDataLoaded( - instanceId: InstanceId, - immediately: Boolean = true, - receivedSmartspaceCardLatency: Int = 0, - isSsReactivated: Boolean = false, - ) - - /** - * Called whenever there's new Smartspace media data loaded. - * - * @param shouldPrioritize indicates the sorting priority of the Smartspace card. If true, - * it will be prioritized as the first card. Otherwise, it will show up as the last card - * as default. - */ - fun onSmartspaceMediaDataLoaded(key: String, shouldPrioritize: Boolean = false) - - /** Called whenever a previously existing Media notification was removed. */ - fun onMediaDataRemoved(instanceId: InstanceId) - - /** - * Called whenever a previously existing Smartspace media data was removed. - * - * @param immediately indicates should apply the UI changes immediately, otherwise wait - * until the next refresh-round before UI becomes visible. True by default to take in - * place immediately. - */ - fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean = true) - } - companion object { /** * Maximum age of a media control to re-activate on smartspace signal. If there is no media diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt index 7dbca0ae4cda..cdcf3636e148 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt @@ -34,11 +34,14 @@ import com.android.systemui.media.controls.domain.pipeline.MediaDeviceManager import com.android.systemui.media.controls.domain.pipeline.MediaSessionBasedFilter import com.android.systemui.media.controls.domain.pipeline.MediaTimeoutListener import com.android.systemui.media.controls.domain.resume.MediaResumeListener +import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel +import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel import com.android.systemui.media.controls.util.MediaFlags import java.io.PrintWriter import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine @@ -109,6 +112,14 @@ constructor( .distinctUntilChanged() .stateIn(applicationScope, SharingStarted.WhileSubscribed(), false) + /** The most recent list of loaded media controls. */ + val mediaDataLoadedStates: Flow<List<MediaDataLoadingModel>> = + mediaFilterRepository.mediaDataLoadedStates + + /** The most recent change to loaded media recommendations. */ + val recommendationsLoadingState: Flow<SmartspaceMediaLoadingModel> = + mediaFilterRepository.recommendationsLoadingState + override fun start() { if (!mediaFlags.isMediaControlsRefactorEnabled()) { return diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaDataLoadingModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaDataLoadingModel.kt new file mode 100644 index 000000000000..bd42a4df7262 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaDataLoadingModel.kt @@ -0,0 +1,46 @@ +/* + * 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.controls.shared.model + +import com.android.internal.logging.InstanceId + +/** Models media data loading state. */ +sealed class MediaDataLoadingModel { + /** The initial loading state when no media data has yet loaded. */ + data object Unknown : MediaDataLoadingModel() + + /** Media data has been loaded. */ + data class Loaded( + val instanceId: InstanceId, + val immediatelyUpdateUi: Boolean = true, + ) : MediaDataLoadingModel() { + + /** Returns true if [other] has the same instance id, false otherwise. */ + fun equalInstanceIds(other: MediaDataLoadingModel): Boolean { + return when (other) { + is Loaded -> other.instanceId == instanceId + is Removed -> other.instanceId == instanceId + Unknown -> false + } + } + } + + /** Media data has been removed. */ + data class Removed( + val instanceId: InstanceId, + ) : MediaDataLoadingModel() +} diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/SmartspaceMediaLoadingModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/SmartspaceMediaLoadingModel.kt new file mode 100644 index 000000000000..6c1e536f8c02 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/SmartspaceMediaLoadingModel.kt @@ -0,0 +1,35 @@ +/* + * 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.controls.shared.model + +/** Models smartspace media loading state. */ +sealed class SmartspaceMediaLoadingModel { + /** The initial loading state when no smartspace media has yet loaded. */ + data object Unknown : SmartspaceMediaLoadingModel() + + /** Smartspace media has been loaded. */ + data class Loaded( + val key: String, + val isPrioritized: Boolean = false, + ) : SmartspaceMediaLoadingModel() + + /** Smartspace media has been removed. */ + data class Removed( + val key: String, + val immediatelyUpdateUi: Boolean = true, + ) : SmartspaceMediaLoadingModel() +} diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/KeyguardMediaController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/KeyguardMediaController.kt index 963c602b3d1e..c02ce3b0a6c0 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/KeyguardMediaController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/KeyguardMediaController.kt @@ -297,6 +297,7 @@ constructor( } } - private val activeContainer: ViewGroup? = - if (useSplitShade) splitShadeContainer else singlePaneContainer + // This field is only used to log current active container. + private val activeContainer: ViewGroup? + get() = if (useSplitShade) splitShadeContainer else singlePaneContainer } diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt index c3c1e83546df..5b39ed34cb75 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt @@ -46,6 +46,8 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.KeyguardState.GONE +import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.media.controls.domain.pipeline.MediaDataManager @@ -600,7 +602,8 @@ constructor( @VisibleForTesting internal fun listenForAnyStateToGoneKeyguardTransition(scope: CoroutineScope): Job { return scope.launch { - keyguardTransitionInteractor.anyStateToGoneTransition + keyguardTransitionInteractor + .transition(from = null, to = GONE) .filter { it.transitionState == TransitionState.FINISHED } .collect { showMediaCarousel() @@ -612,7 +615,8 @@ constructor( @VisibleForTesting internal fun listenForAnyStateToLockscreenTransition(scope: CoroutineScope): Job { return scope.launch { - keyguardTransitionInteractor.anyStateToLockscreenTransition + keyguardTransitionInteractor + .transition(from = null, to = LOCKSCREEN) .filter { it.transitionState == TransitionState.FINISHED } .collect { if (!allowMediaPlayerOnLockScreen) { diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java index 6e7e0f241dd8..da852348b4e6 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java @@ -18,6 +18,7 @@ package com.android.systemui.media.dialog; import android.annotation.MainThread; import android.content.Context; +import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; @@ -52,8 +53,9 @@ public class MediaOutputSwitcherDialogUI implements CoreStartable, CommandQueue. @Override @MainThread - public void showMediaOutputSwitcher(String packageName) { + public void showMediaOutputSwitcher(String packageName, UserHandle userHandle) { if (!TextUtils.isEmpty(packageName)) { + // TODO: b/279555229 - Pass the userHandle into the output dialog manager. mMediaOutputDialogManager.createAndShow(packageName, false, null); } else { Log.e(TAG, "Unable to launch media output dialog. Package name is empty."); diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java index da9e00ddb6c2..e861ddf69aa6 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java @@ -16,8 +16,11 @@ package com.android.systemui.mediaprojection.permission; +import static android.Manifest.permission.LOG_COMPAT_CHANGE; +import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG; import static android.media.projection.IMediaProjectionManager.EXTRA_PACKAGE_REUSING_GRANTED_CONSENT; import static android.media.projection.IMediaProjectionManager.EXTRA_USER_REVIEW_GRANTED_CONSENT; +import static android.media.projection.MediaProjectionManager.OVERRIDE_DISABLE_MEDIA_PROJECTION_SINGLE_APP_OPTION; import static android.media.projection.ReviewGrantedConsentResult.RECORD_CANCEL; import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_DISPLAY; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; @@ -26,11 +29,13 @@ import static com.android.systemui.mediaprojection.permission.ScreenShareOptionK import static com.android.systemui.mediaprojection.permission.ScreenShareOptionKt.SINGLE_APP; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions.LaunchCookie; import android.app.AlertDialog; import android.app.StatusBarManager; +import android.app.compat.CompatChanges; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -108,6 +113,7 @@ public class MediaProjectionPermissionActivity extends Activity } @Override + @RequiresPermission(allOf = {READ_COMPAT_CHANGE_CONFIG, LOG_COMPAT_CHANGE}) public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -235,6 +241,10 @@ public class MediaProjectionPermissionActivity extends Activity // the correct screen width when in split screen. Context dialogContext = getApplicationContext(); if (isPartialScreenSharingEnabled()) { + final boolean overrideDisableSingleAppOption = + CompatChanges.isChangeEnabled( + OVERRIDE_DISABLE_MEDIA_PROJECTION_SINGLE_APP_OPTION, + mPackageName, getHostUserHandle()); MediaProjectionPermissionDialogDelegate delegate = new MediaProjectionPermissionDialogDelegate( dialogContext, @@ -246,6 +256,7 @@ public class MediaProjectionPermissionActivity extends Activity }, () -> finish(RECORD_CANCEL, /* projection= */ null), appName, + overrideDisableSingleAppOption, mUid, mMediaProjectionMetricsLogger); mDialog = diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt index 0f54e934f3cf..8858041ae529 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt @@ -30,11 +30,12 @@ class MediaProjectionPermissionDialogDelegate( private val onStartRecordingClicked: Consumer<MediaProjectionPermissionDialogDelegate>, private val onCancelClicked: Runnable, private val appName: String?, + private val forceShowPartialScreenshare: Boolean, hostUid: Int, mediaProjectionMetricsLogger: MediaProjectionMetricsLogger, ) : BaseMediaProjectionPermissionDialogDelegate<AlertDialog>( - createOptionList(context, appName, mediaProjectionConfig), + createOptionList(context, appName, mediaProjectionConfig, forceShowPartialScreenshare), appName, hostUid, mediaProjectionMetricsLogger @@ -65,7 +66,8 @@ class MediaProjectionPermissionDialogDelegate( private fun createOptionList( context: Context, appName: String?, - mediaProjectionConfig: MediaProjectionConfig? + mediaProjectionConfig: MediaProjectionConfig?, + overrideDisableSingleAppOption: Boolean = false, ): List<ScreenShareOption> { val singleAppWarningText = if (appName == null) { @@ -80,8 +82,13 @@ class MediaProjectionPermissionDialogDelegate( R.string.media_projection_entry_app_permission_dialog_warning_entire_screen } + // The single app option should only be disabled if there is an app name provided, + // the client has setup a MediaProjection with + // MediaProjectionConfig#createConfigForDefaultDisplay, AND it hasn't been overridden by + // the OVERRIDE_DISABLE_SINGLE_APP_OPTION per-app override. val singleAppOptionDisabled = appName != null && + !overrideDisableSingleAppOption && mediaProjectionConfig?.regionToCapture == MediaProjectionConfig.CAPTURE_REGION_FIXED_DISPLAY diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java index 55dc4859cf90..b8c3c1a2af5f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java @@ -29,6 +29,7 @@ import androidx.annotation.Nullable; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.systemui.dump.DumpManager; +import com.android.systemui.haptics.qs.QSLongPressEffect; import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager; import com.android.systemui.media.controls.ui.view.MediaHost; import com.android.systemui.media.controls.ui.view.MediaHostState; @@ -41,13 +42,13 @@ import com.android.systemui.settings.brightness.BrightnessController; import com.android.systemui.settings.brightness.BrightnessMirrorHandler; import com.android.systemui.settings.brightness.BrightnessSliderController; import com.android.systemui.settings.brightness.MirrorController; -import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.SplitShadeStateController; import com.android.systemui.tuner.TunerService; import javax.inject.Inject; import javax.inject.Named; +import javax.inject.Provider; /** * Controller for {@link QSPanel}. @@ -94,10 +95,10 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { StatusBarKeyguardViewManager statusBarKeyguardViewManager, SplitShadeStateController splitShadeStateController, SceneContainerFlags sceneContainerFlags, - VibratorHelper vibratorHelper) { + Provider<QSLongPressEffect> longPRessEffectProvider) { super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger, uiEventLogger, qsLogger, dumpManager, splitShadeStateController, - vibratorHelper); + longPRessEffectProvider); mTunerService = tunerService; mQsCustomizerController = qsCustomizerController; mQsTileRevealControllerFactory = qsTileRevealControllerFactory; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java index d8e81875bbbf..583cfb9ab47e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java @@ -17,6 +17,7 @@ package com.android.systemui.qs; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import static com.android.systemui.Flags.quickSettingsVisualHapticsLongpress; import android.annotation.NonNull; import android.annotation.Nullable; @@ -32,6 +33,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.systemui.Dumpable; import com.android.systemui.dump.DumpManager; +import com.android.systemui.haptics.qs.QSLongPressEffect; import com.android.systemui.media.controls.ui.view.MediaHost; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTileView; @@ -39,7 +41,6 @@ import com.android.systemui.qs.customize.QSCustomizerController; import com.android.systemui.qs.external.CustomTile; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileViewImpl; -import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.policy.SplitShadeStateController; import com.android.systemui.util.ViewController; import com.android.systemui.util.animation.DisappearParameters; @@ -55,6 +56,8 @@ import java.util.Objects; import java.util.function.Consumer; import java.util.stream.Collectors; +import javax.inject.Provider; + /** * Controller for QSPanel views. * @@ -88,7 +91,7 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr private SplitShadeStateController mSplitShadeStateController; - private final VibratorHelper mVibratorHelper; + private final Provider<QSLongPressEffect> mLongPressEffectProvider; @VisibleForTesting protected final QSPanel.OnConfigurationChangedListener mOnConfigurationChangedListener = @@ -148,7 +151,7 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr QSLogger qsLogger, DumpManager dumpManager, SplitShadeStateController splitShadeStateController, - VibratorHelper vibratorHelper + Provider<QSLongPressEffect> longPressEffectProvider ) { super(view); mHost = host; @@ -162,7 +165,7 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr mSplitShadeStateController = splitShadeStateController; mShouldUseSplitNotificationShade = mSplitShadeStateController.shouldUseSplitNotificationShade(getResources()); - mVibratorHelper = vibratorHelper; + mLongPressEffectProvider = longPressEffectProvider; } @Override @@ -305,8 +308,14 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr } private void addTile(final QSTile tile, boolean collapsedView) { + QSLongPressEffect longPressEffect; + if (quickSettingsVisualHapticsLongpress()) { + longPressEffect = mLongPressEffectProvider.get(); + } else { + longPressEffect = null; + } final QSTileViewImpl tileView = new QSTileViewImpl( - getContext(), collapsedView, mVibratorHelper); + getContext(), collapsedView, longPressEffect); final TileRecord r = new TileRecord(tile, tileView); // TODO(b/250618218): Remove the QSLogger in QSTileViewImpl once we know the root cause of // b/250618218. diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java index 05bb08813cc5..6cda740dd1a8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java @@ -25,6 +25,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.systemui.dump.DumpManager; +import com.android.systemui.haptics.qs.QSLongPressEffect; import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager; import com.android.systemui.media.controls.ui.view.MediaHost; import com.android.systemui.plugins.qs.QSTile; @@ -32,7 +33,6 @@ import com.android.systemui.qs.customize.QSCustomizerController; import com.android.systemui.qs.dagger.QSScope; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.res.R; -import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.policy.SplitShadeStateController; import com.android.systemui.util.leak.RotationUtils; @@ -58,10 +58,11 @@ public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel> Provider<Boolean> usingCollapsedLandscapeMediaProvider, MetricsLogger metricsLogger, UiEventLogger uiEventLogger, QSLogger qsLogger, DumpManager dumpManager, SplitShadeStateController splitShadeStateController, - VibratorHelper vibratorHelper + Provider<QSLongPressEffect> longPressEffectProvider ) { super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger, - uiEventLogger, qsLogger, dumpManager, splitShadeStateController, vibratorHelper); + uiEventLogger, qsLogger, dumpManager, splitShadeStateController, + longPressEffectProvider); mUsingCollapsedLandscapeMediaProvider = usingCollapsedLandscapeMediaProvider; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt index 30044856a7d4..ca71870845e0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt @@ -62,15 +62,15 @@ import com.android.systemui.plugins.qs.QSTileView import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.tileimpl.QSIconViewImpl.QS_ANIM_LENGTH import com.android.systemui.res.R -import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.util.children +import kotlinx.coroutines.DisposableHandle import java.util.Objects private const val TAG = "QSTileViewImpl" open class QSTileViewImpl @JvmOverloads constructor( context: Context, private val collapsed: Boolean = false, - private val vibratorHelper: VibratorHelper? = null, + private val longPressEffect: QSLongPressEffect? = null, ) : QSTileView(context), HeightOverrideable, LaunchableView { companion object { @@ -180,15 +180,13 @@ open class QSTileViewImpl @JvmOverloads constructor( private val locInScreen = IntArray(2) /** Visuo-haptic long-press effects */ - private var longPressEffect: QSLongPressEffect? = null - private val longPressEffectViewBinder = QSLongPressEffectViewBinder() private var initialLongPressProperties: QSLongPressProperties? = null private var finalLongPressProperties: QSLongPressProperties? = null private val colorEvaluator = ArgbEvaluator.getInstance() - val hasLongPressEffect: Boolean - get() = longPressEffect != null - @VisibleForTesting val isLongPressEffectBound: Boolean - get() = longPressEffectViewBinder.isBound + val isLongPressEffectInitialized: Boolean + get() = longPressEffect?.hasInitialized == true + @VisibleForTesting + var longPressEffectHandle: DisposableHandle? = null init { val typedValue = TypedValue() @@ -325,6 +323,13 @@ open class QSTileViewImpl @JvmOverloads constructor( } private fun updateHeight() { + // TODO(b/332900989): Find a more robust way of resetting the tile if not reset by the + // launch animation. + if (scaleX != 1f || scaleY != 1f) { + // The launch animation of a long-press effect did not reset the long-press effect so + // we must do it here + resetLongPressEffectProperties() + } val actualHeight = if (heightOverride != HeightOverrideable.NO_OVERRIDE) { heightOverride } else { @@ -614,25 +619,26 @@ open class QSTileViewImpl @JvmOverloads constructor( lastIconTint = icon.getColor(state) // Long-press effects - if (quickSettingsVisualHapticsLongpress()){ - if (state.handlesLongClick && maybeCreateAndInitializeLongPressEffect()) { - // set the valid long-press effect as the touch listener - showRippleEffect = false + if (state.handlesLongClick && + longPressEffect?.initializeEffect(longPressEffectDuration) == true) { + // set the valid long-press effect as the touch listener + if (longPressEffectHandle == null) { + longPressEffectHandle = + QSLongPressEffectViewBinder.bind(this, longPressEffect, state.spec) setOnTouchListener(longPressEffect) - if (!longPressEffectViewBinder.isBound) { - longPressEffectViewBinder.bind(this, state.spec, longPressEffect) - } - } else { - // Long-press effects might have been enabled before but the new state does not - // handle a long-press. In this case, we go back to the behaviour of a regular tile - // and clean-up the resources - longPressEffectViewBinder.dispose() - showRippleEffect = isClickable - setOnTouchListener(null) - longPressEffect = null - initialLongPressProperties = null - finalLongPressProperties = null } + showRippleEffect = false + initializeLongPressProperties() + } else { + // Long-press effects might have been enabled before but the new state does not + // handle a long-press. In this case, we go back to the behaviour of a regular tile + // and clean-up the resources + setOnTouchListener(null) + longPressEffectHandle?.dispose() + longPressEffectHandle = null + showRippleEffect = isClickable + initialLongPressProperties = null + finalLongPressProperties = null } } @@ -824,7 +830,7 @@ open class QSTileViewImpl @JvmOverloads constructor( private fun interpolateFloat(fraction: Float, start: Float, end: Float): Float = start + fraction * (end - start) - private fun resetLongPressEffectProperties() { + fun resetLongPressEffectProperties() { scaleY = 1f scaleX = 1f for (child in children) { @@ -842,27 +848,6 @@ open class QSTileViewImpl @JvmOverloads constructor( icon.setTint(icon.mIcon as ImageView, lastIconTint) } - private fun maybeCreateAndInitializeLongPressEffect(): Boolean { - // Don't setup the effect if the long-press duration is invalid - val effectDuration = longPressEffectDuration - if (effectDuration <= 0) { - longPressEffect = null - return false - } - - initializeLongPressProperties() - if (longPressEffect == null) { - longPressEffect = - QSLongPressEffect( - vibratorHelper, - effectDuration, - ) - } else { - longPressEffect?.resetWithDuration(effectDuration) - } - return true - } - private fun initializeLongPressProperties() { initialLongPressProperties = QSLongPressProperties( diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt index 1f935f97e771..0e66c28d4b8d 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt @@ -62,6 +62,7 @@ import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged @@ -69,10 +70,12 @@ import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.filterNot import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch /** @@ -246,6 +249,12 @@ constructor( private fun handleDeviceUnlockStatus() { applicationScope.launch { + // Track the previous scene (sans Bouncer), so that we know where to go when the device + // is unlocked whilst on the bouncer. + val previousScene = + sceneInteractor.previousScene + .filterNot { it == Scenes.Bouncer } + .stateIn(this, SharingStarted.Eagerly, initialValue = null) deviceUnlockedInteractor.deviceUnlockStatus .mapNotNull { deviceUnlockStatus -> val renderedScenes = @@ -273,8 +282,15 @@ constructor( when { isOnBouncer -> - // When the device becomes unlocked in Bouncer, go to Gone. - Scenes.Gone to "device was unlocked in Bouncer scene" + // When the device becomes unlocked in Bouncer, go to previous scene, + // or Gone. + if (previousScene.value == Scenes.Lockscreen) { + Scenes.Gone to "device was unlocked in Bouncer scene" + } else { + val prevScene = previousScene.value + (prevScene ?: Scenes.Gone) to + "device was unlocked in Bouncer scene, from sceneKey=$prevScene" + } isOnLockscreen -> // The lockscreen should be dismissed automatically in 2 scenarios: // 1. When face auth bypass is enabled and authentication happens while diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt index 6b9332b39816..254c13367ce2 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt @@ -28,6 +28,7 @@ import android.view.ScrollCaptureResponse import android.view.View import android.view.ViewTreeObserver import android.view.WindowInsets +import android.view.WindowManager import android.window.OnBackInvokedCallback import android.window.OnBackInvokedDispatcher import com.android.internal.logging.UiEventLogger @@ -53,6 +54,7 @@ class ScreenshotShelfViewProxy constructor( private val logger: UiEventLogger, private val viewModel: ScreenshotViewModel, + private val windowManager: WindowManager, @Assisted private val context: Context, @Assisted private val displayId: Int ) : ScreenshotViewProxy { @@ -79,6 +81,16 @@ constructor( addPredictiveBackListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) } setOnKeyListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) } debugLog(DEBUG_WINDOW) { "adding OnComputeInternalInsetsListener" } + view.viewTreeObserver.addOnComputeInternalInsetsListener { info -> + val touchableRegion = + view.getTouchRegion( + windowManager.currentWindowMetrics.windowInsets.getInsets( + WindowInsets.Type.systemGestures() + ) + ) + info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION) + info.touchableRegion.set(touchableRegion) + } screenshotPreview = view.screenshotPreview } @@ -194,6 +206,7 @@ constructor( } ) } + private fun setOnKeyListener(onDismissRequested: (ScreenshotEvent) -> Unit) { view.setOnKeyListener( object : View.OnKeyListener { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/policy/PrivateProfilePolicy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/policy/PrivateProfilePolicy.kt index 6373a58d9d54..d62ab8574799 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/policy/PrivateProfilePolicy.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/policy/PrivateProfilePolicy.kt @@ -26,8 +26,6 @@ import com.android.systemui.screenshot.policy.CapturePolicy.PolicyResult.NotMatc import com.android.systemui.screenshot.policy.CaptureType.FullScreen import javax.inject.Inject -private const val POLICY_NAME = "PrivateProfile" - /** * Condition: When any visible task belongs to a private user. * @@ -41,7 +39,7 @@ constructor( override suspend fun check(content: DisplayContentModel): PolicyResult { // The systemUI notification shade isn't a private profile app, skip. if (content.systemUiState.shadeExpanded) { - return NotMatched(policy = POLICY_NAME, reason = "Notification shade is expanded") + return NotMatched(policy = NAME, reason = "Notification shade is expanded") } // Find the first visible rootTaskInfo with a child task owned by a private user @@ -56,14 +54,11 @@ constructor( } ?.let { root to it } } - ?: return NotMatched( - policy = POLICY_NAME, - reason = "No private profile tasks are visible" - ) + ?: return NotMatched(policy = NAME, reason = "No private profile tasks are visible") // If matched, return parameters needed to modify the request. return Matched( - policy = POLICY_NAME, + policy = NAME, reason = "At least one private profile task is visible", CaptureParameters( type = FullScreen(content.displayId), @@ -72,4 +67,7 @@ constructor( ) ) } + companion object { + const val NAME = "PrivateProfile" + } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/policy/WorkProfilePolicy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/policy/WorkProfilePolicy.kt index 689cc11ac10e..b781ae99a4de 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/policy/WorkProfilePolicy.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/policy/WorkProfilePolicy.kt @@ -27,8 +27,6 @@ import com.android.systemui.screenshot.policy.CaptureType.IsolatedTask import javax.inject.Inject import kotlinx.coroutines.flow.first -private const val POLICY_NAME = "WorkProfile" - /** * Condition: When the top visible task (excluding PIP mode) belongs to a work user. * @@ -39,10 +37,11 @@ class WorkProfilePolicy constructor( private val profileTypes: ProfileTypeRepository, ) : CapturePolicy { + override suspend fun check(content: DisplayContentModel): PolicyResult { // The systemUI notification shade isn't a work app, skip. if (content.systemUiState.shadeExpanded) { - return NotMatched(policy = POLICY_NAME, reason = "Notification shade is expanded") + return NotMatched(policy = NAME, reason = "Notification shade is expanded") } // Find the first non PiP rootTask with a top child task owned by a work user @@ -54,13 +53,13 @@ constructor( profileTypes.getProfileType(child.userId) == ProfileType.WORK } ?: return NotMatched( - policy = POLICY_NAME, + policy = NAME, reason = "The top-most non-PINNED task does not belong to a work profile user" ) // If matched, return parameters needed to modify the request. return PolicyResult.Matched( - policy = POLICY_NAME, + policy = NAME, reason = "The top-most non-PINNED task ($childTask) belongs to a work profile user", CaptureParameters( type = IsolatedTask(taskId = childTask.id, taskBounds = childTask.bounds), @@ -69,4 +68,8 @@ constructor( ) ) } + + companion object { + val NAME = "WorkProfile" + } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt index 747ad4f9e48c..b7a03ef42245 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt @@ -17,17 +17,70 @@ package com.android.systemui.screenshot.ui import android.content.Context +import android.graphics.Insets +import android.graphics.Rect +import android.graphics.Region import android.util.AttributeSet +import android.view.View import android.widget.ImageView import androidx.constraintlayout.widget.ConstraintLayout import com.android.systemui.res.R +import com.android.systemui.screenshot.FloatingWindowUtil class ScreenshotShelfView(context: Context, attrs: AttributeSet? = null) : ConstraintLayout(context, attrs) { lateinit var screenshotPreview: ImageView + private val displayMetrics = context.resources.displayMetrics + private val tmpRect = Rect() + private lateinit var actionsContainerBackground: View + private lateinit var dismissButton: View + override fun onFinishInflate() { super.onFinishInflate() screenshotPreview = requireViewById(R.id.screenshot_preview) + actionsContainerBackground = requireViewById(R.id.actions_container_background) + dismissButton = requireViewById(R.id.screenshot_dismiss_button) + } + + fun getTouchRegion(gestureInsets: Insets): Region { + val region = getSwipeRegion() + + // Receive touches in gesture insets so they don't cause TOUCH_OUTSIDE + // left edge gesture region + val insetRect = Rect(0, 0, gestureInsets.left, displayMetrics.heightPixels) + region.op(insetRect, Region.Op.UNION) + // right edge gesture region + insetRect.set( + displayMetrics.widthPixels - gestureInsets.right, + 0, + displayMetrics.widthPixels, + displayMetrics.heightPixels + ) + region.op(insetRect, Region.Op.UNION) + + return region + } + + private fun getSwipeRegion(): Region { + val swipeRegion = Region() + val padding = FloatingWindowUtil.dpToPx(displayMetrics, -1 * TOUCH_PADDING_DP).toInt() + swipeRegion.addInsetView(screenshotPreview, padding) + swipeRegion.addInsetView(actionsContainerBackground, padding) + swipeRegion.addInsetView(dismissButton, padding) + findViewById<View>(R.id.screenshot_message_container)?.let { + swipeRegion.addInsetView(it, padding) + } + return swipeRegion + } + + private fun Region.addInsetView(view: View, padding: Int = 0) { + view.getBoundsOnScreen(tmpRect) + tmpRect.inset(padding, padding) + this.op(tmpRect, Region.Op.UNION) + } + + companion object { + private const val TOUCH_PADDING_DP = 12f } } diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index 4660831b77af..6b08a9ae52f2 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -30,6 +30,11 @@ import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK; import static com.android.systemui.classifier.Classifier.GENERIC; import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS; import static com.android.systemui.classifier.Classifier.UNLOCK; +import static com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING; +import static com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING_LOCKSCREEN_HOSTED; +import static com.android.systemui.keyguard.shared.model.KeyguardState.GONE; +import static com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN; +import static com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED; import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadScroll; import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadThreeFingerSwipe; import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_CLOSED; @@ -1119,7 +1124,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump controller.setup(mNotificationContainerParent)); // Dreaming->Lockscreen - collectFlow(mView, mKeyguardTransitionInteractor.getDreamingToLockscreenTransition(), + collectFlow(mView, mKeyguardTransitionInteractor.transition(DREAMING, LOCKSCREEN), mDreamingToLockscreenTransition, mMainDispatcher); collectFlow(mView, mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha(), setDreamLockscreenTransitionAlpha(mNotificationStackScrollLayoutController), @@ -1130,7 +1135,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump // Gone -> Dreaming hosted in lockscreen collectFlow(mView, mKeyguardTransitionInteractor - .getGoneToDreamingLockscreenHostedTransition(), + .transition(GONE, DREAMING_LOCKSCREEN_HOSTED), mGoneToDreamingLockscreenHostedTransition, mMainDispatcher); collectFlow(mView, mGoneToDreamingLockscreenHostedTransitionViewModel.getLockscreenAlpha(), setTransitionAlpha(mNotificationStackScrollLayoutController), @@ -1138,16 +1143,16 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump // Lockscreen -> Dreaming hosted in lockscreen collectFlow(mView, mKeyguardTransitionInteractor - .getLockscreenToDreamingLockscreenHostedTransition(), + .transition(LOCKSCREEN, DREAMING_LOCKSCREEN_HOSTED), mLockscreenToDreamingLockscreenHostedTransition, mMainDispatcher); // Dreaming hosted in lockscreen -> Lockscreen collectFlow(mView, mKeyguardTransitionInteractor - .getDreamingLockscreenHostedToLockscreenTransition(), + .transition(DREAMING_LOCKSCREEN_HOSTED, LOCKSCREEN), mDreamingLockscreenHostedToLockscreenTransition, mMainDispatcher); // Occluded->Lockscreen - collectFlow(mView, mKeyguardTransitionInteractor.getOccludedToLockscreenTransition(), + collectFlow(mView, mKeyguardTransitionInteractor.transition(OCCLUDED, LOCKSCREEN), mOccludedToLockscreenTransition, mMainDispatcher); if (!MigrateClocksToBlueprint.isEnabled()) { collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha(), @@ -1158,7 +1163,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } // Lockscreen->Dreaming - collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToDreamingTransition(), + collectFlow(mView, mKeyguardTransitionInteractor.transition(LOCKSCREEN, DREAMING), mLockscreenToDreamingTransition, mMainDispatcher); if (!MigrateClocksToBlueprint.isEnabled()) { collectFlow(mView, mLockscreenToDreamingTransitionViewModel.getLockscreenAlpha(), @@ -1170,7 +1175,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump setTransitionY(mNotificationStackScrollLayoutController), mMainDispatcher); // Gone->Dreaming - collectFlow(mView, mKeyguardTransitionInteractor.getGoneToDreamingTransition(), + collectFlow(mView, mKeyguardTransitionInteractor.transition(GONE, DREAMING), mGoneToDreamingTransition, mMainDispatcher); if (!MigrateClocksToBlueprint.isEnabled()) { collectFlow(mView, mGoneToDreamingTransitionViewModel.getLockscreenAlpha(), @@ -1181,7 +1186,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump setTransitionY(mNotificationStackScrollLayoutController), mMainDispatcher); // Lockscreen->Occluded - collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToOccludedTransition(), + collectFlow(mView, mKeyguardTransitionInteractor.transition(LOCKSCREEN, OCCLUDED), mLockscreenToOccludedTransition, mMainDispatcher); if (!MigrateClocksToBlueprint.isEnabled()) { collectFlow(mView, mLockscreenToOccludedTransitionViewModel.getLockscreenAlpha(), diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java index 6ac81d226eee..b2952dcbcb39 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java @@ -18,6 +18,8 @@ package com.android.systemui.shade; 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.keyguard.shared.model.KeyguardState.DREAMING; +import static com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; @@ -221,7 +223,7 @@ public class NotificationShadeWindowViewController implements Dumpable { mDisableSubpixelTextTransitionListener = new DisableSubpixelTextTransitionListener(mView); bouncerViewBinder.bind(mView.findViewById(R.id.keyguard_bouncer_container)); - collectFlow(mView, keyguardTransitionInteractor.getLockscreenToDreamingTransition(), + collectFlow(mView, keyguardTransitionInteractor.transition(LOCKSCREEN, DREAMING), mLockscreenToDreamingTransition); collectFlow( mView, diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt index d68e28c930f4..0b45c0834245 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt @@ -82,7 +82,7 @@ constructor( override val isShadeTouchable: Flow<Boolean> = combine( powerInteractor.isAsleep, - keyguardTransitionInteractor.isInTransitionToStateWhere { it == KeyguardState.AOD }, + keyguardTransitionInteractor.isInTransitionToState(KeyguardState.AOD), keyguardRepository.dozeTransitionModel.map { it.to == DozeStateModel.DOZE_PULSING }, ) { isAsleep, goingToSleep, isPulsing -> when { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index e7b159a2d057..d955349ffede 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -50,6 +50,7 @@ import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; +import android.os.UserHandle; import android.util.Pair; import android.util.SparseArray; import android.view.KeyEvent; @@ -516,7 +517,7 @@ public class CommandQueue extends IStatusBar.Stub implements /** * @see IStatusBar#showMediaOutputSwitcher */ - default void showMediaOutputSwitcher(String packageName) {} + default void showMediaOutputSwitcher(String packageName, UserHandle userHandle) {} /** * @see IStatusBar#confirmImmersivePrompt @@ -1361,7 +1362,7 @@ public class CommandQueue extends IStatusBar.Stub implements } } @Override - public void showMediaOutputSwitcher(String packageName) { + public void showMediaOutputSwitcher(String packageName, UserHandle userHandle) { int callingUid = Binder.getCallingUid(); if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { throw new SecurityException("Call only allowed from system server."); @@ -1369,6 +1370,7 @@ public class CommandQueue extends IStatusBar.Stub implements synchronized (mLock) { SomeArgs args = SomeArgs.obtain(); args.arg1 = packageName; + args.arg2 = userHandle; mHandler.obtainMessage(MSG_SHOW_MEDIA_OUTPUT_SWITCHER, args).sendToTarget(); } } @@ -1939,8 +1941,10 @@ public class CommandQueue extends IStatusBar.Stub implements case MSG_SHOW_MEDIA_OUTPUT_SWITCHER: args = (SomeArgs) msg.obj; String clientPackageName = (String) args.arg1; + UserHandle clientUserHandle = (UserHandle) args.arg2; for (int i = 0; i < mCallbacks.size(); i++) { - mCallbacks.get(i).showMediaOutputSwitcher(clientPackageName); + mCallbacks.get(i).showMediaOutputSwitcher(clientPackageName, + clientUserHandle); } break; case MSG_CONFIRM_IMMERSIVE_PROMPT: diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 815236e0820c..09985f842185 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -195,20 +195,20 @@ public class KeyguardIndicationController { private boolean mOrganizationOwnedDevice; // these all assume the device is plugged in (wired/wireless/docked) AND chargingOrFull: - private boolean mPowerPluggedIn; - private boolean mPowerPluggedInWired; - private boolean mPowerPluggedInWireless; - private boolean mPowerPluggedInDock; + protected boolean mPowerPluggedIn; + protected boolean mPowerPluggedInWired; + protected boolean mPowerPluggedInWireless; + protected boolean mPowerPluggedInDock; private boolean mPowerCharged; private boolean mBatteryDefender; private boolean mEnableBatteryDefender; private boolean mIncompatibleCharger; - private int mChargingSpeed; + protected int mChargingSpeed; private int mChargingWattage; private int mBatteryLevel; private boolean mBatteryPresent = true; - private long mChargingTimeRemaining; + protected long mChargingTimeRemaining; private Pair<String, BiometricSourceType> mBiometricErrorMessageToShowOnScreenOn; private final Set<Integer> mCoExFaceAcquisitionMsgIdsToShow; private final FaceHelpMessageDeferral mFaceAcquiredMessageDeferral; @@ -1053,20 +1053,24 @@ public class KeyguardIndicationController { * Assumption: device is charging */ protected String computePowerIndication() { - int chargingId; if (mBatteryDefender) { - chargingId = R.string.keyguard_plugged_in_charging_limited; String percentage = NumberFormat.getPercentInstance().format(mBatteryLevel / 100f); - return mContext.getResources().getString(chargingId, percentage); + return mContext.getResources().getString( + R.string.keyguard_plugged_in_charging_limited, percentage); } else if (mPowerPluggedIn && mIncompatibleCharger) { - chargingId = R.string.keyguard_plugged_in_incompatible_charger; String percentage = NumberFormat.getPercentInstance().format(mBatteryLevel / 100f); - return mContext.getResources().getString(chargingId, percentage); + return mContext.getResources().getString( + R.string.keyguard_plugged_in_incompatible_charger, percentage); } else if (mPowerCharged) { return mContext.getResources().getString(R.string.keyguard_charged); } + return computePowerChargingStringIndication(); + } + + protected String computePowerChargingStringIndication() { final boolean hasChargingTime = mChargingTimeRemaining > 0; + int chargingId; if (mPowerPluggedInWired) { switch (mChargingSpeed) { case BatteryStatus.CHARGING_FAST: diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt index ed8c05688a66..77660eb7d864 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt @@ -29,9 +29,9 @@ interface HeadsUpRepository { /** * True if we are exiting the headsUp pinned mode, and some notifications might still be - * animating out. This is used to keep the touchable regions in a reasonable state. + * animating out. This is used to keep their view container visible. */ - val headsUpAnimatingAway: Flow<Boolean> + val isHeadsUpAnimatingAway: Flow<Boolean> /** The heads up row that should be displayed on top. */ val topHeadsUpRow: Flow<HeadsUpRowRepository?> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt index d1dd7b55c11f..7f94da3c8c6a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt @@ -60,7 +60,7 @@ class HeadsUpNotificationInteractor @Inject constructor(repository: HeadsUpRepos } val isHeadsUpOrAnimatingAway: Flow<Boolean> = - combine(hasPinnedRows, repository.headsUpAnimatingAway) { hasPinnedRows, animatingAway -> + combine(hasPinnedRows, repository.isHeadsUpAnimatingAway) { hasPinnedRows, animatingAway -> hasPinnedRows || animatingAway } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt index c4d9ab7a47c2..9619acaed441 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt @@ -27,6 +27,7 @@ import android.database.ContentObserver import android.hardware.display.AmbientDisplayConfiguration import android.os.Handler import android.os.PowerManager +import android.provider.Settings import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED import android.provider.Settings.Global.HEADS_UP_OFF import com.android.systemui.dagger.qualifiers.Main @@ -42,6 +43,7 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.util.settings.GlobalSettings +import com.android.systemui.util.settings.SystemSettings import com.android.systemui.util.time.SystemClock class PeekDisabledSuppressor( @@ -231,6 +233,7 @@ class AlertKeyguardVisibilitySuppressor( class AvalancheSuppressor( private val avalancheProvider: AvalancheProvider, private val systemClock: SystemClock, + private val systemSettings: SystemSettings, ) : VisualInterruptionFilter( types = setOf(PEEK, PULSE), @@ -253,12 +256,23 @@ class AvalancheSuppressor( } override fun shouldSuppress(entry: NotificationEntry): Boolean { - val timeSinceAvalanche = systemClock.currentTimeMillis() - avalancheProvider.startTime - val isActive = timeSinceAvalanche < avalancheProvider.timeoutMs + if (!isCooldownEnabled()) { + reason = "FALSE avalanche cooldown setting DISABLED" + return false + } + val timeSinceAvalancheMs = systemClock.currentTimeMillis() - avalancheProvider.startTime + val timedOut = timeSinceAvalancheMs >= avalancheProvider.timeoutMs + if (timedOut) { + reason = "FALSE avalanche event TIMED OUT. " + + "${timeSinceAvalancheMs/1000} seconds since last avalanche" + return false + } val state = calculateState(entry) - val suppress = isActive && state == State.SUPPRESS - reason = "avalanche suppress=$suppress isActive=$isActive state=$state" - return suppress + if (state != State.SUPPRESS) { + reason = "FALSE avalanche IN ALLOWLIST: $state" + return false + } + return true } private fun calculateState(entry: NotificationEntry): State { @@ -294,4 +308,11 @@ class AvalancheSuppressor( } return State.SUPPRESS } + + private fun isCooldownEnabled(): Boolean { + return systemSettings.getInt( + Settings.System.NOTIFICATION_COOLDOWN_ENABLED, + /* def */ 1 + ) == 1 + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt index 375b6e5cb6a3..e6d97c211dc5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt @@ -40,6 +40,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.EventLog import com.android.systemui.util.settings.GlobalSettings +import com.android.systemui.util.settings.SystemSettings import com.android.systemui.util.time.SystemClock import javax.inject.Inject @@ -61,7 +62,8 @@ constructor( private val systemClock: SystemClock, private val uiEventLogger: UiEventLogger, private val userTracker: UserTracker, - private val avalancheProvider: AvalancheProvider + private val avalancheProvider: AvalancheProvider, + private val systemSettings: SystemSettings ) : VisualInterruptionDecisionProvider { init { @@ -170,7 +172,7 @@ constructor( addFilter(AlertKeyguardVisibilitySuppressor(keyguardNotificationVisibilityProvider)) if (NotificationAvalancheSuppression.isEnabled) { - addFilter(AvalancheSuppressor(avalancheProvider, systemClock)) + addFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) avalancheProvider.register() } started = true diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 5eaccd924344..e980794d23dd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -594,7 +594,11 @@ public class StackScrollAlgorithm { ); if (view instanceof FooterView) { if (FooterViewRefactor.isEnabled()) { - if (((FooterView) view).shouldBeHidden()) { + // TODO(b/333445519): shouldBeHidden should reflect whether the shade is closed + // already, so we shouldn't need to use ambientState here. However, currently it + // doesn't get updated quickly enough and can cause the footer to flash when + // closing the shade. As such, we temporarily also check the ambientState directly. + if (((FooterView) view).shouldBeHidden() || !ambientState.isShadeExpanded()) { viewState.hidden = true; } else { final float footerEnd = algorithmState.mCurrentExpandedYPosition diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt index 13e36d58f6a9..77a0c2e9224c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt @@ -207,9 +207,7 @@ constructor( keyguardTransitionInteractor.finishedKeyguardState.map { statesForConstrainedNotifications.contains(it) }, - keyguardTransitionInteractor - .isInTransitionWhere { from, to -> from == LOCKSCREEN || to == LOCKSCREEN } - .onStart { emit(false) } + keyguardTransitionInteractor.transitionValue(LOCKSCREEN).map { it > 0f }, ) { constrainedNotificationState, transitioningToOrFromLockscreen -> constrainedNotificationState || transitioningToOrFromLockscreen } @@ -241,11 +239,10 @@ constructor( keyguardTransitionInteractor.finishedKeyguardState.map { state -> state == GLANCEABLE_HUB }, - keyguardTransitionInteractor - .isInTransitionWhere { from, to -> - from == GLANCEABLE_HUB || to == GLANCEABLE_HUB - } - .onStart { emit(false) } + or( + keyguardTransitionInteractor.isInTransitionToState(GLANCEABLE_HUB), + keyguardTransitionInteractor.isInTransitionFromState(GLANCEABLE_HUB), + ), ) { isOnGlanceableHub, transitioningToOrFromHub -> isOnGlanceableHub || transitioningToOrFromHub } @@ -290,12 +287,10 @@ constructor( var aodTransitionIsComplete = true return combine( isOnLockscreenWithoutShade, - keyguardTransitionInteractor - .isInTransitionWhere( - fromStatePredicate = { it == LOCKSCREEN }, - toStatePredicate = { it == AOD } - ) - .onStart { emit(false) }, + keyguardTransitionInteractor.isInTransition( + from = LOCKSCREEN, + to = AOD, + ), ::Pair ) .transformWhile { (isOnLockscreenWithoutShade, aodTransitionIsRunning) -> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt index 8ab1eca98cc9..9268d1658b80 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt @@ -14,51 +14,20 @@ package com.android.systemui.statusbar.phone -import android.app.ActivityManager -import android.app.ActivityOptions -import android.app.ActivityTaskManager import android.app.PendingIntent -import android.app.TaskStackBuilder -import android.content.Context import android.content.Intent import android.os.Bundle -import android.os.RemoteException import android.os.UserHandle -import android.provider.Settings -import android.util.Log -import android.view.RemoteAnimationAdapter import android.view.View -import android.view.WindowManager -import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.ActivityIntentHelper import com.android.systemui.animation.ActivityTransitionAnimator -import com.android.systemui.animation.ActivityTransitionAnimator.PendingIntentStarter -import com.android.systemui.animation.DelegateTransitionAnimatorController -import com.android.systemui.assist.AssistManager -import com.android.systemui.camera.CameraIntents.Companion.isInsecureCameraIntent import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.DisplayId import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.keyguard.KeyguardViewMediator -import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter.OnDismissAction -import com.android.systemui.res.R -import com.android.systemui.settings.UserTracker -import com.android.systemui.shade.ShadeController -import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractor -import com.android.systemui.statusbar.CommandQueue -import com.android.systemui.statusbar.NotificationLockscreenUserManager -import com.android.systemui.statusbar.NotificationShadeWindowController +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.statusbar.SysuiStatusBarStateController -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow -import com.android.systemui.statusbar.policy.DeviceProvisionedController -import com.android.systemui.statusbar.policy.KeyguardStateController -import com.android.systemui.statusbar.window.StatusBarWindowController import com.android.systemui.util.concurrency.DelayableExecutor -import com.android.systemui.util.kotlin.getOrNull import dagger.Lazy -import java.util.Optional import javax.inject.Inject /** Handles start activity logic in SystemUI. */ @@ -66,38 +35,18 @@ import javax.inject.Inject class ActivityStarterImpl @Inject constructor( - private val centralSurfacesOptLazy: Lazy<Optional<CentralSurfaces>>, - private val assistManagerLazy: Lazy<AssistManager>, - private val dozeServiceHostLazy: Lazy<DozeServiceHost>, - private val biometricUnlockControllerLazy: Lazy<BiometricUnlockController>, - private val keyguardViewMediatorLazy: Lazy<KeyguardViewMediator>, - private val shadeControllerLazy: Lazy<ShadeController>, - private val commandQueue: CommandQueue, - private val shadeAnimationInteractor: ShadeAnimationInteractor, - private val statusBarKeyguardViewManagerLazy: Lazy<StatusBarKeyguardViewManager>, - private val notifShadeWindowControllerLazy: Lazy<NotificationShadeWindowController>, - private val activityTransitionAnimator: ActivityTransitionAnimator, - private val context: Context, - @DisplayId private val displayId: Int, - private val lockScreenUserManager: NotificationLockscreenUserManager, - private val statusBarWindowController: StatusBarWindowController, - private val wakefulnessLifecycle: WakefulnessLifecycle, - private val keyguardStateController: KeyguardStateController, private val statusBarStateController: SysuiStatusBarStateController, - private val keyguardUpdateMonitor: KeyguardUpdateMonitor, - private val deviceProvisionedController: DeviceProvisionedController, - private val userTracker: UserTracker, - private val activityIntentHelper: ActivityIntentHelper, @Main private val mainExecutor: DelayableExecutor, + legacyActivityStarter: Lazy<LegacyActivityStarterInternalImpl>, + activityStarterInternal: Lazy<ActivityStarterInternalImpl>, ) : ActivityStarter { - companion object { - const val TAG = "ActivityStarterImpl" - } - - private val centralSurfaces: CentralSurfaces? - get() = centralSurfacesOptLazy.get().getOrNull() - private val activityStarterInternal = ActivityStarterInternal() + private val activityStarterInternal: ActivityStarterInternal = + if (SceneContainerFlag.isEnabled) { + activityStarterInternal.get() + } else { + legacyActivityStarter.get() + } override fun startPendingIntentDismissingKeyguard(intent: PendingIntent) { activityStarterInternal.startPendingIntentDismissingKeyguard(intent = intent) @@ -401,575 +350,11 @@ constructor( } } - private fun postOnUiThread(delay: Int = 0, runnable: Runnable) { - mainExecutor.executeDelayed(runnable, delay.toLong()) - } - - /** - * Whether we should animate an activity launch. - * - * Note: This method must be called *before* dismissing the keyguard. - */ - private fun shouldAnimateLaunch( - isActivityIntent: Boolean, - showOverLockscreen: Boolean, - ): Boolean { - // TODO(b/294418322): Support launch animations when occluded. - if (keyguardStateController.isOccluded) { - return false - } - - // Always animate if we are not showing the keyguard or if we animate over the lockscreen - // (without unlocking it). - if (showOverLockscreen || !keyguardStateController.isShowing) { - return true - } - - // We don't animate non-activity launches as they can break the animation. - // TODO(b/184121838): Support non activity launches on the lockscreen. - return isActivityIntent - } - override fun shouldAnimateLaunch(isActivityIntent: Boolean): Boolean { - return shouldAnimateLaunch(isActivityIntent, false) + return activityStarterInternal.shouldAnimateLaunch(isActivityIntent) } - /** - * Encapsulates the activity logic for activity starter. - * - * Logic is duplicated in {@link CentralSurfacesImpl} - */ - private inner class ActivityStarterInternal { - /** Starts an activity after dismissing keyguard. */ - fun startActivityDismissingKeyguard( - intent: Intent, - onlyProvisioned: Boolean = false, - dismissShade: Boolean = false, - disallowEnterPictureInPictureWhileLaunching: Boolean = false, - callback: ActivityStarter.Callback? = null, - flags: Int = 0, - animationController: ActivityTransitionAnimator.Controller? = null, - userHandle: UserHandle? = null, - customMessage: String? = null, - ) { - val userHandle: UserHandle = userHandle ?: getActivityUserHandle(intent) - - if (onlyProvisioned && !deviceProvisionedController.isDeviceProvisioned) return - - val willLaunchResolverActivity: Boolean = - activityIntentHelper.wouldLaunchResolverActivity( - intent, - lockScreenUserManager.currentUserId - ) - - val animate = - animationController != null && - !willLaunchResolverActivity && - shouldAnimateLaunch(isActivityIntent = true) - val animController = - wrapAnimationControllerForShadeOrStatusBar( - animationController = animationController, - dismissShade = dismissShade, - isLaunchForActivity = true, - ) - - // If we animate, we will dismiss the shade only once the animation is done. This is - // taken care of by the StatusBarLaunchAnimationController. - val dismissShadeDirectly = dismissShade && animController == null - - val runnable = Runnable { - assistManagerLazy.get().hideAssist() - intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK - intent.addFlags(flags) - val result = intArrayOf(ActivityManager.START_CANCELED) - activityTransitionAnimator.startIntentWithAnimation( - animController, - animate, - intent.getPackage() - ) { adapter: RemoteAnimationAdapter? -> - val options = - ActivityOptions(CentralSurfaces.getActivityOptions(displayId, adapter)) - - // We know that the intent of the caller is to dismiss the keyguard and - // this runnable is called right after the keyguard is solved, so we tell - // WM that we should dismiss it to avoid flickers when opening an activity - // that can also be shown over the keyguard. - options.setDismissKeyguardIfInsecure() - options.setDisallowEnterPictureInPictureWhileLaunching( - disallowEnterPictureInPictureWhileLaunching - ) - if (isInsecureCameraIntent(intent)) { - // Normally an activity will set it's requested rotation - // animation on its window. However when launching an activity - // causes the orientation to change this is too late. In these cases - // the default animation is used. This doesn't look good for - // the camera (as it rotates the camera contents out of sync - // with physical reality). So, we ask the WindowManager to - // force the cross fade animation if an orientation change - // happens to occur during the launch. - options.rotationAnimationHint = - WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS - } - if (Settings.Panel.ACTION_VOLUME == intent.action) { - // Settings Panel is implemented as activity(not a dialog), so - // underlying app is paused and may enter picture-in-picture mode - // as a result. - // So we need to disable picture-in-picture mode here - // if it is volume panel. - options.setDisallowEnterPictureInPictureWhileLaunching(true) - } - try { - result[0] = - ActivityTaskManager.getService() - .startActivityAsUser( - null, - context.basePackageName, - context.attributionTag, - intent, - intent.resolveTypeIfNeeded(context.contentResolver), - null, - null, - 0, - Intent.FLAG_ACTIVITY_NEW_TASK, - null, - options.toBundle(), - userHandle.identifier, - ) - } catch (e: RemoteException) { - Log.w(TAG, "Unable to start activity", e) - } - result[0] - } - callback?.onActivityStarted(result[0]) - } - val cancelRunnable = Runnable { - callback?.onActivityStarted(ActivityManager.START_CANCELED) - } - // Do not deferKeyguard when occluded because, when keyguard is occluded, - // we do not launch the activity until keyguard is done. - val occluded = (keyguardStateController.isShowing && keyguardStateController.isOccluded) - val deferred = !occluded - executeRunnableDismissingKeyguard( - runnable, - cancelRunnable, - dismissShadeDirectly, - willLaunchResolverActivity, - deferred, - animate, - customMessage, - ) - } - - /** - * Starts a pending intent after dismissing keyguard. - * - * This can be called in a background thread (to prevent calls in [ActivityIntentHelper] in - * the main thread). - */ - fun startPendingIntentDismissingKeyguard( - intent: PendingIntent, - intentSentUiThreadCallback: Runnable? = null, - associatedView: View? = null, - animationController: ActivityTransitionAnimator.Controller? = null, - showOverLockscreen: Boolean = false, - fillInIntent: Intent? = null, - extraOptions: Bundle? = null, - ) { - val animationController = - if (associatedView is ExpandableNotificationRow) { - centralSurfaces?.getAnimatorControllerFromNotification(associatedView) - } else animationController - - val willLaunchResolverActivity = - (intent.isActivity && - activityIntentHelper.wouldPendingLaunchResolverActivity( - intent, - lockScreenUserManager.currentUserId, - )) - - val actuallyShowOverLockscreen = - showOverLockscreen && - intent.isActivity && - activityIntentHelper.wouldPendingShowOverLockscreen( - intent, - lockScreenUserManager.currentUserId - ) - - val animate = - !willLaunchResolverActivity && - animationController != null && - shouldAnimateLaunch(intent.isActivity, actuallyShowOverLockscreen) - - // We wrap animationCallback with a StatusBarLaunchAnimatorController so - // that the shade is collapsed after the animation (or when it is cancelled, - // aborted, etc). - val statusBarController = - wrapAnimationControllerForShadeOrStatusBar( - animationController = animationController, - dismissShade = true, - isLaunchForActivity = intent.isActivity, - ) - val controller = - if (actuallyShowOverLockscreen) { - wrapAnimationControllerForLockscreen(statusBarController) - } else { - statusBarController - } - - // If we animate, don't collapse the shade and defer the keyguard dismiss (in case we - // run the animation on the keyguard). The animation will take care of (instantly) - // collapsing the shade and hiding the keyguard once it is done. - val collapse = !animate - val runnable = Runnable { - try { - activityTransitionAnimator.startPendingIntentWithAnimation( - controller, - animate, - intent.creatorPackage, - actuallyShowOverLockscreen, - object : PendingIntentStarter { - override fun startPendingIntent( - animationAdapter: RemoteAnimationAdapter? - ): Int { - val options = - ActivityOptions( - CentralSurfaces.getActivityOptions( - displayId, - animationAdapter - ) - .apply { extraOptions?.let { putAll(it) } } - ) - // TODO b/221255671: restrict this to only be set for - // notifications - options.isEligibleForLegacyPermissionPrompt = true - options.setPendingIntentBackgroundActivityStartMode( - ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED - ) - return intent.sendAndReturnResult( - context, - 0, - fillInIntent, - null, - null, - null, - options.toBundle() - ) - } - }, - ) - } catch (e: PendingIntent.CanceledException) { - // the stack trace isn't very helpful here. - // Just log the exception message. - Log.w(TAG, "Sending intent failed: $e") - if (!collapse) { - // executeRunnableDismissingKeyguard did not collapse for us already. - shadeControllerLazy.get().collapseOnMainThread() - } - // TODO: Dismiss Keyguard. - } - if (intent.isActivity) { - assistManagerLazy.get().hideAssist() - // This activity could have started while the device is dreaming, in which case - // the dream would occlude the activity. In order to show the newly started - // activity, we wake from the dream. - keyguardUpdateMonitor.awakenFromDream() - } - intentSentUiThreadCallback?.let { postOnUiThread(runnable = it) } - } - - if (!actuallyShowOverLockscreen) { - postOnUiThread(delay = 0) { - executeRunnableDismissingKeyguard( - runnable = runnable, - afterKeyguardGone = willLaunchResolverActivity, - dismissShade = collapse, - willAnimateOnKeyguard = animate, - ) - } - } else { - postOnUiThread(delay = 0, runnable) - } - } - - /** Starts an Activity. */ - fun startActivity( - intent: Intent, - dismissShade: Boolean = false, - animationController: ActivityTransitionAnimator.Controller? = null, - showOverLockscreenWhenLocked: Boolean = false, - userHandle: UserHandle? = null, - ) { - val userHandle = userHandle ?: getActivityUserHandle(intent) - // Make sure that we dismiss the keyguard if it is directly dismissible or when we don't - // want to show the activity above it. - if (keyguardStateController.isUnlocked || !showOverLockscreenWhenLocked) { - startActivityDismissingKeyguard( - intent = intent, - onlyProvisioned = false, - dismissShade = dismissShade, - disallowEnterPictureInPictureWhileLaunching = false, - callback = null, - flags = 0, - animationController = animationController, - userHandle = userHandle, - ) - return - } - - val animate = - animationController != null && - shouldAnimateLaunch( - /* isActivityIntent= */ true, - showOverLockscreenWhenLocked - ) == true - - var controller: ActivityTransitionAnimator.Controller? = null - if (animate) { - // Wrap the animation controller to dismiss the shade and set - // mIsLaunchingActivityOverLockscreen during the animation. - val delegate = - wrapAnimationControllerForShadeOrStatusBar( - animationController = animationController, - dismissShade = dismissShade, - isLaunchForActivity = true, - ) - controller = wrapAnimationControllerForLockscreen(delegate) - } else if (dismissShade) { - // The animation will take care of dismissing the shade at the end of the animation. - // If we don't animate, collapse it directly. - shadeControllerLazy.get().cancelExpansionAndCollapseShade() - } - - // We should exit the dream to prevent the activity from starting below the - // dream. - if (keyguardUpdateMonitor.isDreaming) { - centralSurfaces?.awakenDreams() - } - - activityTransitionAnimator.startIntentWithAnimation( - controller, - animate, - intent.getPackage(), - showOverLockscreenWhenLocked - ) { adapter: RemoteAnimationAdapter? -> - TaskStackBuilder.create(context) - .addNextIntent(intent) - .startActivities( - CentralSurfaces.getActivityOptions(displayId, adapter), - userHandle - ) - } - } - - /** Executes an action after dismissing keyguard. */ - fun dismissKeyguardThenExecute( - action: OnDismissAction, - cancel: Runnable? = null, - afterKeyguardGone: Boolean = false, - customMessage: String? = null, - ) { - if ( - !action.willRunAnimationOnKeyguard() && - wakefulnessLifecycle.wakefulness == WakefulnessLifecycle.WAKEFULNESS_ASLEEP && - keyguardStateController.canDismissLockScreen() && - !statusBarStateController.leaveOpenOnKeyguardHide() && - dozeServiceHostLazy.get().isPulsing - ) { - // Reuse the biometric wake-and-unlock transition if we dismiss keyguard from a - // pulse. - // TODO: Factor this transition out of BiometricUnlockController. - biometricUnlockControllerLazy - .get() - .startWakeAndUnlock(BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) - } - if (keyguardStateController.isShowing) { - statusBarKeyguardViewManagerLazy - .get() - .dismissWithAction(action, cancel, afterKeyguardGone, customMessage) - } else { - // If the keyguard isn't showing but the device is dreaming, we should exit the - // dream. - if (keyguardUpdateMonitor.isDreaming) { - centralSurfaces?.awakenDreams() - } - action.onDismiss() - } - } - - /** Executes an action after dismissing keyguard. */ - fun executeRunnableDismissingKeyguard( - runnable: Runnable? = null, - cancelAction: Runnable? = null, - dismissShade: Boolean = false, - afterKeyguardGone: Boolean = false, - deferred: Boolean = false, - willAnimateOnKeyguard: Boolean = false, - customMessage: String? = null, - ) { - val onDismissAction: OnDismissAction = - object : OnDismissAction { - override fun onDismiss(): Boolean { - if (runnable != null) { - if ( - keyguardStateController.isShowing && - keyguardStateController.isOccluded - ) { - statusBarKeyguardViewManagerLazy - .get() - .addAfterKeyguardGoneRunnable(runnable) - } else { - mainExecutor.execute(runnable) - } - } - if (dismissShade) { - shadeControllerLazy.get().collapseShadeForActivityStart() - } - return deferred - } - - override fun willRunAnimationOnKeyguard(): Boolean { - return willAnimateOnKeyguard - } - } - dismissKeyguardThenExecute( - onDismissAction, - cancelAction, - afterKeyguardGone, - customMessage, - ) - } - - /** - * Return a [ActivityTransitionAnimator.Controller] wrapping `animationController` so that: - * - if it launches in the notification shade window and `dismissShade` is true, then the - * shade will be instantly dismissed at the end of the animation. - * - if it launches in status bar window, it will make the status bar window match the - * device size during the animation (that way, the animation won't be clipped by the - * status bar size). - * - * @param animationController the controller that is wrapped and will drive the main - * animation. - * @param dismissShade whether the notification shade will be dismissed at the end of the - * animation. This is ignored if `animationController` is not animating in the shade - * window. - * @param isLaunchForActivity whether the launch is for an activity. - */ - private fun wrapAnimationControllerForShadeOrStatusBar( - animationController: ActivityTransitionAnimator.Controller?, - dismissShade: Boolean, - isLaunchForActivity: Boolean, - ): ActivityTransitionAnimator.Controller? { - if (animationController == null) { - return null - } - val rootView = animationController.transitionContainer.rootView - val controllerFromStatusBar: Optional<ActivityTransitionAnimator.Controller> = - statusBarWindowController.wrapAnimationControllerIfInStatusBar( - rootView, - animationController - ) - if (controllerFromStatusBar.isPresent) { - return controllerFromStatusBar.get() - } - - centralSurfaces?.let { - // If the view is not in the status bar, then we are animating a view in the shade. - // We have to make sure that we collapse it when the animation ends or is cancelled. - if (dismissShade) { - return StatusBarTransitionAnimatorController( - animationController, - shadeAnimationInteractor, - shadeControllerLazy.get(), - notifShadeWindowControllerLazy.get(), - commandQueue, - displayId, - isLaunchForActivity - ) - } - } - - return animationController - } - - /** - * Wraps an animation controller so that if an activity would be launched on top of the - * lockscreen, the correct flags are set for it to be occluded. - */ - private fun wrapAnimationControllerForLockscreen( - animationController: ActivityTransitionAnimator.Controller? - ): ActivityTransitionAnimator.Controller? { - return animationController?.let { - object : DelegateTransitionAnimatorController(it) { - override fun onIntentStarted(willAnimate: Boolean) { - delegate.onIntentStarted(willAnimate) - if (willAnimate) { - centralSurfaces?.setIsLaunchingActivityOverLockscreen(true) - } - } - - override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) { - super.onTransitionAnimationStart(isExpandingFullyAbove) - - // Double check that the keyguard is still showing and not going - // away, but if so set the keyguard occluded. Typically, WM will let - // KeyguardViewMediator know directly, but we're overriding that to - // play the custom launch animation, so we need to take care of that - // here. The unocclude animation is not overridden, so WM will call - // KeyguardViewMediator's unocclude animation runner when the - // activity is exited. - if ( - keyguardStateController.isShowing && - !keyguardStateController.isKeyguardGoingAway - ) { - Log.d(TAG, "Setting occluded = true in #startActivity.") - keyguardViewMediatorLazy - .get() - .setOccluded(true /* isOccluded */, true /* animate */) - } - } - - override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) { - // Set mIsLaunchingActivityOverLockscreen to false before actually - // finishing the animation so that we can assume that - // mIsLaunchingActivityOverLockscreen being true means that we will - // collapse the shade (or at least run the post collapse runnables) - // later on. - centralSurfaces?.setIsLaunchingActivityOverLockscreen(false) - delegate.onTransitionAnimationEnd(isExpandingFullyAbove) - } - - override fun onTransitionAnimationCancelled( - newKeyguardOccludedState: Boolean? - ) { - if (newKeyguardOccludedState != null) { - keyguardViewMediatorLazy - .get() - .setOccluded(newKeyguardOccludedState, false /* animate */) - } - - // Set mIsLaunchingActivityOverLockscreen to false before actually - // finishing the animation so that we can assume that - // mIsLaunchingActivityOverLockscreen being true means that we will - // collapse the shade (or at least run the // post collapse - // runnables) later on. - centralSurfaces?.setIsLaunchingActivityOverLockscreen(false) - delegate.onTransitionAnimationCancelled(newKeyguardOccludedState) - } - } - } - } - - /** Retrieves the current user handle to start the Activity. */ - private fun getActivityUserHandle(intent: Intent): UserHandle { - val packages: Array<String> = - context.resources.getStringArray(R.array.system_ui_packages) - for (pkg in packages) { - val componentName = intent.component ?: break - if (pkg == componentName.packageName) { - return UserHandle(UserHandle.myUserId()) - } - } - return userTracker.userHandle - } + private fun postOnUiThread(delay: Int = 0, runnable: Runnable) { + mainExecutor.executeDelayed(runnable, delay.toLong()) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt new file mode 100644 index 000000000000..e8443982d560 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt @@ -0,0 +1,88 @@ +/* + * 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.statusbar.phone + +import android.app.PendingIntent +import android.content.Intent +import android.os.Bundle +import android.os.UserHandle +import android.view.View +import com.android.systemui.ActivityIntentHelper +import com.android.systemui.animation.ActivityTransitionAnimator +import com.android.systemui.plugins.ActivityStarter + +interface ActivityStarterInternal { + /** + * Starts a pending intent after dismissing keyguard. + * + * This can be called in a background thread (to prevent calls in [ActivityIntentHelper] in the + * main thread). + */ + fun startPendingIntentDismissingKeyguard( + intent: PendingIntent, + intentSentUiThreadCallback: Runnable? = null, + associatedView: View? = null, + animationController: ActivityTransitionAnimator.Controller? = null, + showOverLockscreen: Boolean = false, + fillInIntent: Intent? = null, + extraOptions: Bundle? = null, + ) + + /** Starts an activity after dismissing keyguard. */ + fun startActivityDismissingKeyguard( + intent: Intent, + dismissShade: Boolean, + onlyProvisioned: Boolean = false, + callback: ActivityStarter.Callback? = null, + flags: Int = 0, + animationController: ActivityTransitionAnimator.Controller? = null, + customMessage: String? = null, + disallowEnterPictureInPictureWhileLaunching: Boolean = false, + userHandle: UserHandle? = null, + ) + + /** Starts an Activity. */ + fun startActivity( + intent: Intent, + dismissShade: Boolean, + animationController: ActivityTransitionAnimator.Controller?, + showOverLockscreenWhenLocked: Boolean, + userHandle: UserHandle? = null, + ) + + /** Executes an action after dismissing keyguard. */ + fun dismissKeyguardThenExecute( + action: ActivityStarter.OnDismissAction, + cancel: Runnable?, + afterKeyguardGone: Boolean, + customMessage: String? = null, + ) + + /** Executes an action after dismissing keyguard. */ + fun executeRunnableDismissingKeyguard( + runnable: Runnable?, + cancelAction: Runnable? = null, + dismissShade: Boolean = false, + afterKeyguardGone: Boolean = false, + deferred: Boolean = false, + willAnimateOnKeyguard: Boolean = false, + customMessage: String? = null, + ) + + /** Whether we should animate an activity launch. */ + fun shouldAnimateLaunch(isActivityIntent: Boolean): Boolean +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt new file mode 100644 index 000000000000..c101755bcf38 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt @@ -0,0 +1,96 @@ +/* + * 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.statusbar.phone + +import android.app.PendingIntent +import android.content.Intent +import android.os.Bundle +import android.os.UserHandle +import android.view.View +import com.android.systemui.animation.ActivityTransitionAnimator +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.plugins.ActivityStarter +import javax.inject.Inject + +/** + * Encapsulates the activity logic for activity starter when flexiglass is enabled. + * + * TODO: b/308819693 + */ +@SysUISingleton +class ActivityStarterInternalImpl @Inject constructor() : ActivityStarterInternal { + override fun startPendingIntentDismissingKeyguard( + intent: PendingIntent, + intentSentUiThreadCallback: Runnable?, + associatedView: View?, + animationController: ActivityTransitionAnimator.Controller?, + showOverLockscreen: Boolean, + fillInIntent: Intent?, + extraOptions: Bundle? + ) { + TODO("Not yet implemented b/308819693") + } + + override fun startActivityDismissingKeyguard( + intent: Intent, + dismissShade: Boolean, + onlyProvisioned: Boolean, + callback: ActivityStarter.Callback?, + flags: Int, + animationController: ActivityTransitionAnimator.Controller?, + customMessage: String?, + disallowEnterPictureInPictureWhileLaunching: Boolean, + userHandle: UserHandle? + ) { + TODO("Not yet implemented b/308819693") + } + + override fun startActivity( + intent: Intent, + dismissShade: Boolean, + animationController: ActivityTransitionAnimator.Controller?, + showOverLockscreenWhenLocked: Boolean, + userHandle: UserHandle? + ) { + TODO("Not yet implemented b/308819693") + } + + override fun dismissKeyguardThenExecute( + action: ActivityStarter.OnDismissAction, + cancel: Runnable?, + afterKeyguardGone: Boolean, + customMessage: String? + ) { + TODO("Not yet implemented b/308819693") + } + + override fun executeRunnableDismissingKeyguard( + runnable: Runnable?, + cancelAction: Runnable?, + dismissShade: Boolean, + afterKeyguardGone: Boolean, + deferred: Boolean, + willAnimateOnKeyguard: Boolean, + customMessage: String? + ) { + TODO("Not yet implemented b/308819693") + } + + override fun shouldAnimateLaunch(isActivityIntent: Boolean): Boolean { + TODO("Not yet implemented b/308819693") + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java index 3f200d578261..0ddf37db6078 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java @@ -91,7 +91,8 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements StateFlowKt.MutableStateFlow(null); private final MutableStateFlow<Set<HeadsUpRowRepository>> mHeadsUpNotificationRows = StateFlowKt.MutableStateFlow(new HashSet<>()); - private final MutableStateFlow<Boolean> mHeadsUpGoingAway = StateFlowKt.MutableStateFlow(false); + private final MutableStateFlow<Boolean> mHeadsUpAnimatingAway = + StateFlowKt.MutableStateFlow(false); private boolean mReleaseOnExpandFinish; private boolean mTrackingHeadsUp; private final HashSet<String> mSwipedOutKeys = new HashSet<>(); @@ -184,7 +185,7 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements // Public methods: /** - * Add a listener to receive callbacks onHeadsUpGoingAway + * Add a listener to receive callbacks {@link #setHeadsUpAnimatingAway(boolean)} */ @Override public void addHeadsUpPhoneListener(OnHeadsUpPhoneListenerChange listener) { @@ -264,7 +265,7 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements if (isExpanded != mIsExpanded) { mIsExpanded = isExpanded; if (isExpanded) { - mHeadsUpGoingAway.setValue(false); + mHeadsUpAnimatingAway.setValue(false); } } } @@ -274,20 +275,15 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements * animating out. This is used to keep the touchable regions in a reasonable state. */ @Override - public void setHeadsUpGoingAway(boolean headsUpGoingAway) { - if (headsUpGoingAway != mHeadsUpGoingAway.getValue()) { + public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) { + if (headsUpAnimatingAway != mHeadsUpAnimatingAway.getValue()) { for (OnHeadsUpPhoneListenerChange listener : mHeadsUpPhoneListeners) { - listener.onHeadsUpGoingAwayStateChanged(headsUpGoingAway); + listener.onHeadsUpAnimatingAwayStateChanged(headsUpAnimatingAway); } - mHeadsUpGoingAway.setValue(headsUpGoingAway); + mHeadsUpAnimatingAway.setValue(headsUpAnimatingAway); } } - @Override - public boolean isHeadsUpGoingAway() { - return mHeadsUpGoingAway.getValue(); - } - /** * Notifies that a remote input textbox in notification gets active or inactive. * @@ -504,8 +500,13 @@ public class HeadsUpManagerPhone extends BaseHeadsUpManager implements @Override @NonNull - public Flow<Boolean> getHeadsUpAnimatingAway() { - return mHeadsUpGoingAway; + public Flow<Boolean> isHeadsUpAnimatingAway() { + return mHeadsUpAnimatingAway; + } + + @Override + public boolean isHeadsUpAnimatingAwayValue() { + return mHeadsUpAnimatingAway.getValue(); } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt new file mode 100644 index 000000000000..ebaeb39efe31 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt @@ -0,0 +1,639 @@ +/* + * 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.statusbar.phone + +import android.app.ActivityManager +import android.app.ActivityOptions +import android.app.ActivityTaskManager +import android.app.PendingIntent +import android.app.TaskStackBuilder +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.os.RemoteException +import android.os.UserHandle +import android.provider.Settings +import android.util.Log +import android.view.RemoteAnimationAdapter +import android.view.View +import android.view.WindowManager +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.ActivityIntentHelper +import com.android.systemui.animation.ActivityTransitionAnimator +import com.android.systemui.animation.DelegateTransitionAnimatorController +import com.android.systemui.assist.AssistManager +import com.android.systemui.camera.CameraIntents +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.DisplayId +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.keyguard.KeyguardViewMediator +import com.android.systemui.keyguard.WakefulnessLifecycle +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.res.R +import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeController +import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractor +import com.android.systemui.statusbar.CommandQueue +import com.android.systemui.statusbar.NotificationLockscreenUserManager +import com.android.systemui.statusbar.NotificationShadeWindowController +import com.android.systemui.statusbar.SysuiStatusBarStateController +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import com.android.systemui.statusbar.policy.DeviceProvisionedController +import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.statusbar.window.StatusBarWindowController +import com.android.systemui.util.concurrency.DelayableExecutor +import com.android.systemui.util.kotlin.getOrNull +import dagger.Lazy +import java.util.Optional +import javax.inject.Inject + +/** Encapsulates the activity logic for activity starter. */ +@SysUISingleton +class LegacyActivityStarterInternalImpl +@Inject +constructor( + private val centralSurfacesOptLazy: Lazy<Optional<CentralSurfaces>>, + private val keyguardStateController: KeyguardStateController, + private val statusBarStateController: SysuiStatusBarStateController, + private val assistManagerLazy: Lazy<AssistManager>, + private val dozeServiceHostLazy: Lazy<DozeServiceHost>, + private val biometricUnlockControllerLazy: Lazy<BiometricUnlockController>, + private val keyguardViewMediatorLazy: Lazy<KeyguardViewMediator>, + private val shadeControllerLazy: Lazy<ShadeController>, + private val commandQueue: CommandQueue, + private val shadeAnimationInteractor: ShadeAnimationInteractor, + private val statusBarKeyguardViewManagerLazy: Lazy<StatusBarKeyguardViewManager>, + private val notifShadeWindowControllerLazy: Lazy<NotificationShadeWindowController>, + private val activityTransitionAnimator: ActivityTransitionAnimator, + private val context: Context, + @DisplayId private val displayId: Int, + private val lockScreenUserManager: NotificationLockscreenUserManager, + private val statusBarWindowController: StatusBarWindowController, + private val wakefulnessLifecycle: WakefulnessLifecycle, + private val keyguardUpdateMonitor: KeyguardUpdateMonitor, + private val deviceProvisionedController: DeviceProvisionedController, + private val userTracker: UserTracker, + private val activityIntentHelper: ActivityIntentHelper, + @Main private val mainExecutor: DelayableExecutor, +) : ActivityStarterInternal { + private val centralSurfaces: CentralSurfaces? + get() = centralSurfacesOptLazy.get().getOrNull() + + override fun startActivityDismissingKeyguard( + intent: Intent, + dismissShade: Boolean, + onlyProvisioned: Boolean, + callback: ActivityStarter.Callback?, + flags: Int, + animationController: ActivityTransitionAnimator.Controller?, + customMessage: String?, + disallowEnterPictureInPictureWhileLaunching: Boolean, + userHandle: UserHandle?, + ) { + val userHandle: UserHandle = userHandle ?: getActivityUserHandle(intent) + + if (onlyProvisioned && !deviceProvisionedController.isDeviceProvisioned) return + + val willLaunchResolverActivity: Boolean = + activityIntentHelper.wouldLaunchResolverActivity( + intent, + lockScreenUserManager.currentUserId + ) + + val animate = + animationController != null && + !willLaunchResolverActivity && + shouldAnimateLaunch(isActivityIntent = true) + val animController = + wrapAnimationControllerForShadeOrStatusBar( + animationController = animationController, + dismissShade = dismissShade, + isLaunchForActivity = true, + ) + + // If we animate, we will dismiss the shade only once the animation is done. This is + // taken care of by the StatusBarLaunchAnimationController. + val dismissShadeDirectly = dismissShade && animController == null + + val runnable = Runnable { + assistManagerLazy.get().hideAssist() + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + intent.addFlags(flags) + val result = intArrayOf(ActivityManager.START_CANCELED) + activityTransitionAnimator.startIntentWithAnimation( + animController, + animate, + intent.getPackage() + ) { adapter: RemoteAnimationAdapter? -> + val options = + ActivityOptions(CentralSurfaces.getActivityOptions(displayId, adapter)) + + // We know that the intent of the caller is to dismiss the keyguard and + // this runnable is called right after the keyguard is solved, so we tell + // WM that we should dismiss it to avoid flickers when opening an activity + // that can also be shown over the keyguard. + options.setDismissKeyguardIfInsecure() + options.setDisallowEnterPictureInPictureWhileLaunching( + disallowEnterPictureInPictureWhileLaunching + ) + if (CameraIntents.isInsecureCameraIntent(intent)) { + // Normally an activity will set it's requested rotation + // animation on its window. However when launching an activity + // causes the orientation to change this is too late. In these cases + // the default animation is used. This doesn't look good for + // the camera (as it rotates the camera contents out of sync + // with physical reality). So, we ask the WindowManager to + // force the cross fade animation if an orientation change + // happens to occur during the launch. + options.rotationAnimationHint = + WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS + } + if (Settings.Panel.ACTION_VOLUME == intent.action) { + // Settings Panel is implemented as activity(not a dialog), so + // underlying app is paused and may enter picture-in-picture mode + // as a result. + // So we need to disable picture-in-picture mode here + // if it is volume panel. + options.setDisallowEnterPictureInPictureWhileLaunching(true) + } + try { + result[0] = + ActivityTaskManager.getService() + .startActivityAsUser( + null, + context.basePackageName, + context.attributionTag, + intent, + intent.resolveTypeIfNeeded(context.contentResolver), + null, + null, + 0, + Intent.FLAG_ACTIVITY_NEW_TASK, + null, + options.toBundle(), + userHandle.identifier, + ) + } catch (e: RemoteException) { + Log.w(TAG, "Unable to start activity", e) + } + result[0] + } + callback?.onActivityStarted(result[0]) + } + val cancelRunnable = Runnable { + callback?.onActivityStarted(ActivityManager.START_CANCELED) + } + // Do not deferKeyguard when occluded because, when keyguard is occluded, + // we do not launch the activity until keyguard is done. + val occluded = (keyguardStateController.isShowing && keyguardStateController.isOccluded) + val deferred = !occluded + executeRunnableDismissingKeyguard( + runnable, + cancelRunnable, + dismissShadeDirectly, + willLaunchResolverActivity, + deferred, + animate, + customMessage, + ) + } + + override fun startPendingIntentDismissingKeyguard( + intent: PendingIntent, + intentSentUiThreadCallback: Runnable?, + associatedView: View?, + animationController: ActivityTransitionAnimator.Controller?, + showOverLockscreen: Boolean, + fillInIntent: Intent?, + extraOptions: Bundle?, + ) { + val animationController = + if (associatedView is ExpandableNotificationRow) { + centralSurfaces?.getAnimatorControllerFromNotification(associatedView) + } else animationController + + val willLaunchResolverActivity = + (intent.isActivity && + activityIntentHelper.wouldPendingLaunchResolverActivity( + intent, + lockScreenUserManager.currentUserId, + )) + + val actuallyShowOverLockscreen = + showOverLockscreen && + intent.isActivity && + activityIntentHelper.wouldPendingShowOverLockscreen( + intent, + lockScreenUserManager.currentUserId + ) + + val animate = + !willLaunchResolverActivity && + animationController != null && + shouldAnimateLaunch(intent.isActivity, actuallyShowOverLockscreen) + + // We wrap animationCallback with a StatusBarLaunchAnimatorController so + // that the shade is collapsed after the animation (or when it is cancelled, + // aborted, etc). + val statusBarController = + wrapAnimationControllerForShadeOrStatusBar( + animationController = animationController, + dismissShade = true, + isLaunchForActivity = intent.isActivity, + ) + val controller = + if (actuallyShowOverLockscreen) { + wrapAnimationControllerForLockscreen(statusBarController) + } else { + statusBarController + } + + // If we animate, don't collapse the shade and defer the keyguard dismiss (in case we + // run the animation on the keyguard). The animation will take care of (instantly) + // collapsing the shade and hiding the keyguard once it is done. + val collapse = !animate + val runnable = Runnable { + try { + activityTransitionAnimator.startPendingIntentWithAnimation( + controller, + animate, + intent.creatorPackage, + actuallyShowOverLockscreen, + object : ActivityTransitionAnimator.PendingIntentStarter { + override fun startPendingIntent( + animationAdapter: RemoteAnimationAdapter? + ): Int { + val options = + ActivityOptions( + CentralSurfaces.getActivityOptions(displayId, animationAdapter) + .apply { extraOptions?.let { putAll(it) } } + ) + // TODO b/221255671: restrict this to only be set for + // notifications + options.isEligibleForLegacyPermissionPrompt = true + options.setPendingIntentBackgroundActivityStartMode( + ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED + ) + return intent.sendAndReturnResult( + context, + 0, + fillInIntent, + null, + null, + null, + options.toBundle() + ) + } + }, + ) + } catch (e: PendingIntent.CanceledException) { + // the stack trace isn't very helpful here. + // Just log the exception message. + Log.w(TAG, "Sending intent failed: $e") + if (!collapse) { + // executeRunnableDismissingKeyguard did not collapse for us already. + shadeControllerLazy.get().collapseOnMainThread() + } + // TODO: Dismiss Keyguard. + } + if (intent.isActivity) { + assistManagerLazy.get().hideAssist() + // This activity could have started while the device is dreaming, in which case + // the dream would occlude the activity. In order to show the newly started + // activity, we wake from the dream. + keyguardUpdateMonitor.awakenFromDream() + } + intentSentUiThreadCallback?.let { postOnUiThread(runnable = it) } + } + + if (!actuallyShowOverLockscreen) { + postOnUiThread(delay = 0) { + executeRunnableDismissingKeyguard( + runnable = runnable, + afterKeyguardGone = willLaunchResolverActivity, + dismissShade = collapse, + willAnimateOnKeyguard = animate, + ) + } + } else { + postOnUiThread(delay = 0, runnable) + } + } + + override fun startActivity( + intent: Intent, + dismissShade: Boolean, + animationController: ActivityTransitionAnimator.Controller?, + showOverLockscreenWhenLocked: Boolean, + userHandle: UserHandle?, + ) { + val userHandle = userHandle ?: getActivityUserHandle(intent) + // Make sure that we dismiss the keyguard if it is directly dismissible or when we don't + // want to show the activity above it. + if (keyguardStateController.isUnlocked || !showOverLockscreenWhenLocked) { + startActivityDismissingKeyguard( + intent = intent, + onlyProvisioned = false, + dismissShade = dismissShade, + disallowEnterPictureInPictureWhileLaunching = false, + callback = null, + flags = 0, + animationController = animationController, + userHandle = userHandle, + ) + return + } + + val animate = + animationController != null && + shouldAnimateLaunch(/* isActivityIntent= */ true, showOverLockscreenWhenLocked) + + var controller: ActivityTransitionAnimator.Controller? = null + if (animate) { + // Wrap the animation controller to dismiss the shade and set + // mIsLaunchingActivityOverLockscreen during the animation. + val delegate = + wrapAnimationControllerForShadeOrStatusBar( + animationController = animationController, + dismissShade = dismissShade, + isLaunchForActivity = true, + ) + controller = wrapAnimationControllerForLockscreen(delegate) + } else if (dismissShade) { + // The animation will take care of dismissing the shade at the end of the animation. + // If we don't animate, collapse it directly. + shadeControllerLazy.get().cancelExpansionAndCollapseShade() + } + + // We should exit the dream to prevent the activity from starting below the + // dream. + if (keyguardUpdateMonitor.isDreaming) { + centralSurfaces?.awakenDreams() + } + + activityTransitionAnimator.startIntentWithAnimation( + controller, + animate, + intent.getPackage(), + showOverLockscreenWhenLocked + ) { adapter: RemoteAnimationAdapter? -> + TaskStackBuilder.create(context) + .addNextIntent(intent) + .startActivities(CentralSurfaces.getActivityOptions(displayId, adapter), userHandle) + } + } + + override fun dismissKeyguardThenExecute( + action: ActivityStarter.OnDismissAction, + cancel: Runnable?, + afterKeyguardGone: Boolean, + customMessage: String?, + ) { + if ( + !action.willRunAnimationOnKeyguard() && + wakefulnessLifecycle.wakefulness == WakefulnessLifecycle.WAKEFULNESS_ASLEEP && + keyguardStateController.canDismissLockScreen() && + !statusBarStateController.leaveOpenOnKeyguardHide() && + dozeServiceHostLazy.get().isPulsing + ) { + // Reuse the biometric wake-and-unlock transition if we dismiss keyguard from a + // pulse. + // TODO: Factor this transition out of BiometricUnlockController. + biometricUnlockControllerLazy + .get() + .startWakeAndUnlock(BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) + } + if (keyguardStateController.isShowing) { + statusBarKeyguardViewManagerLazy + .get() + .dismissWithAction(action, cancel, afterKeyguardGone, customMessage) + } else { + // If the keyguard isn't showing but the device is dreaming, we should exit the + // dream. + if (keyguardUpdateMonitor.isDreaming) { + centralSurfaces?.awakenDreams() + } + action.onDismiss() + } + } + + override fun executeRunnableDismissingKeyguard( + runnable: Runnable?, + cancelAction: Runnable?, + dismissShade: Boolean, + afterKeyguardGone: Boolean, + deferred: Boolean, + willAnimateOnKeyguard: Boolean, + customMessage: String?, + ) { + val onDismissAction: ActivityStarter.OnDismissAction = + object : ActivityStarter.OnDismissAction { + override fun onDismiss(): Boolean { + if (runnable != null) { + if ( + keyguardStateController.isShowing && keyguardStateController.isOccluded + ) { + statusBarKeyguardViewManagerLazy + .get() + .addAfterKeyguardGoneRunnable(runnable) + } else { + mainExecutor.execute(runnable) + } + } + if (dismissShade) { + shadeControllerLazy.get().collapseShadeForActivityStart() + } + return deferred + } + + override fun willRunAnimationOnKeyguard(): Boolean { + return willAnimateOnKeyguard + } + } + dismissKeyguardThenExecute( + onDismissAction, + cancelAction, + afterKeyguardGone, + customMessage, + ) + } + + /** + * Return a [ActivityTransitionAnimator.Controller] wrapping `animationController` so that: + * - if it launches in the notification shade window and `dismissShade` is true, then the shade + * will be instantly dismissed at the end of the animation. + * - if it launches in status bar window, it will make the status bar window match the device + * size during the animation (that way, the animation won't be clipped by the status bar + * size). + * + * @param animationController the controller that is wrapped and will drive the main animation. + * @param dismissShade whether the notification shade will be dismissed at the end of the + * animation. This is ignored if `animationController` is not animating in the shade window. + * @param isLaunchForActivity whether the launch is for an activity. + */ + private fun wrapAnimationControllerForShadeOrStatusBar( + animationController: ActivityTransitionAnimator.Controller?, + dismissShade: Boolean, + isLaunchForActivity: Boolean, + ): ActivityTransitionAnimator.Controller? { + if (animationController == null) { + return null + } + val rootView = animationController.transitionContainer.rootView + val controllerFromStatusBar: Optional<ActivityTransitionAnimator.Controller> = + statusBarWindowController.wrapAnimationControllerIfInStatusBar( + rootView, + animationController + ) + if (controllerFromStatusBar.isPresent) { + return controllerFromStatusBar.get() + } + + centralSurfaces?.let { + // If the view is not in the status bar, then we are animating a view in the shade. + // We have to make sure that we collapse it when the animation ends or is cancelled. + if (dismissShade) { + return StatusBarTransitionAnimatorController( + animationController, + shadeAnimationInteractor, + shadeControllerLazy.get(), + notifShadeWindowControllerLazy.get(), + commandQueue, + displayId, + isLaunchForActivity + ) + } + } + + return animationController + } + + /** + * Wraps an animation controller so that if an activity would be launched on top of the + * lockscreen, the correct flags are set for it to be occluded. + */ + private fun wrapAnimationControllerForLockscreen( + animationController: ActivityTransitionAnimator.Controller? + ): ActivityTransitionAnimator.Controller? { + return animationController?.let { + object : DelegateTransitionAnimatorController(it) { + override fun onIntentStarted(willAnimate: Boolean) { + delegate.onIntentStarted(willAnimate) + if (willAnimate) { + centralSurfaces?.setIsLaunchingActivityOverLockscreen(true) + } + } + + override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) { + super.onTransitionAnimationStart(isExpandingFullyAbove) + + // Double check that the keyguard is still showing and not going + // away, but if so set the keyguard occluded. Typically, WM will let + // KeyguardViewMediator know directly, but we're overriding that to + // play the custom launch animation, so we need to take care of that + // here. The unocclude animation is not overridden, so WM will call + // KeyguardViewMediator's unocclude animation runner when the + // activity is exited. + if ( + keyguardStateController.isShowing && + !keyguardStateController.isKeyguardGoingAway + ) { + Log.d(TAG, "Setting occluded = true in #startActivity.") + keyguardViewMediatorLazy + .get() + .setOccluded(true /* isOccluded */, true /* animate */) + } + } + + override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) { + // Set mIsLaunchingActivityOverLockscreen to false before actually + // finishing the animation so that we can assume that + // mIsLaunchingActivityOverLockscreen being true means that we will + // collapse the shade (or at least run the post collapse runnables) + // later on. + centralSurfaces?.setIsLaunchingActivityOverLockscreen(false) + delegate.onTransitionAnimationEnd(isExpandingFullyAbove) + } + + override fun onTransitionAnimationCancelled(newKeyguardOccludedState: Boolean?) { + if (newKeyguardOccludedState != null) { + keyguardViewMediatorLazy + .get() + .setOccluded(newKeyguardOccludedState, false /* animate */) + } + + // Set mIsLaunchingActivityOverLockscreen to false before actually + // finishing the animation so that we can assume that + // mIsLaunchingActivityOverLockscreen being true means that we will + // collapse the shade (or at least run the // post collapse + // runnables) later on. + centralSurfaces?.setIsLaunchingActivityOverLockscreen(false) + delegate.onTransitionAnimationCancelled(newKeyguardOccludedState) + } + } + } + } + + /** Retrieves the current user handle to start the Activity. */ + private fun getActivityUserHandle(intent: Intent): UserHandle { + val packages: Array<String> = context.resources.getStringArray(R.array.system_ui_packages) + for (pkg in packages) { + val componentName = intent.component ?: break + if (pkg == componentName.packageName) { + return UserHandle(UserHandle.myUserId()) + } + } + return userTracker.userHandle + } + + /** + * Whether we should animate an activity launch. + * + * Note: This method must be called *before* dismissing the keyguard. + */ + private fun shouldAnimateLaunch( + isActivityIntent: Boolean, + showOverLockscreen: Boolean, + ): Boolean { + // TODO(b/294418322): Support launch animations when occluded. + if (keyguardStateController.isOccluded) { + return false + } + + // Always animate if we are not showing the keyguard or if we animate over the lockscreen + // (without unlocking it). + if (showOverLockscreen || !keyguardStateController.isShowing) { + return true + } + + // We don't animate non-activity launches as they can break the animation. + // TODO(b/184121838): Support non activity launches on the lockscreen. + return isActivityIntent + } + + override fun shouldAnimateLaunch(isActivityIntent: Boolean): Boolean { + return shouldAnimateLaunch(isActivityIntent, false) + } + + private fun postOnUiThread(delay: Int = 0, runnable: Runnable) { + mainExecutor.executeDelayed(runnable, delay.toLong()) + } + + companion object { + private const val TAG = "LegacyActivityStarterInternalImpl" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java index ed1f6ff7e513..87139ac0cada 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java @@ -98,11 +98,11 @@ public class StatusBarHeadsUpChangeListener implements OnHeadsUpChangedListener, // we need to keep the panel open artificially, let's wait until the //animation // is finished. - mHeadsUpManager.setHeadsUpGoingAway(true); + mHeadsUpManager.setHeadsUpAnimatingAway(true); mNsslController.runAfterAnimationFinished(() -> { if (!mHeadsUpManager.hasPinnedHeadsUp()) { mNotificationShadeWindowController.setHeadsUpShowing(false); - mHeadsUpManager.setHeadsUpGoingAway(false); + mHeadsUpManager.setHeadsUpAnimatingAway(false); } mNotificationRemoteInputManager.onPanelCollapsed(); }); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java index c615887d5c25..8e8de46957ed 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java @@ -121,7 +121,7 @@ public final class StatusBarTouchableRegionManager implements Dumpable { updateTouchableRegion(); } }); - mHeadsUpManager.addHeadsUpPhoneListener(this::onHeadsUpGoingAwayStateChanged); + mHeadsUpManager.addHeadsUpPhoneListener(this::onHeadsUpAnimatingAwayStateChanged); mNotificationShadeWindowController = notificationShadeWindowController; mNotificationShadeWindowController.setForcePluginOpenListener((forceOpen) -> { @@ -214,7 +214,7 @@ public final class StatusBarTouchableRegionManager implements Dumpable { && (mNotificationShadeWindowView.getRootWindowInsets() != null) && (mNotificationShadeWindowView.getRootWindowInsets().getDisplayCutout() != null); boolean shouldObserve = mHeadsUpManager.hasPinnedHeadsUp() - || mHeadsUpManager.isHeadsUpGoingAway() + || mHeadsUpManager.isHeadsUpAnimatingAwayValue() || mForceCollapsedUntilLayout || hasCutoutInset || mNotificationShadeWindowController.getForcePluginOpen(); @@ -288,8 +288,8 @@ public final class StatusBarTouchableRegionManager implements Dumpable { || mUnlockedScreenOffAnimationController.isAnimationPlaying(); } - private void onHeadsUpGoingAwayStateChanged(boolean headsUpGoingAway) { - if (!headsUpGoingAway) { + private void onHeadsUpAnimatingAwayStateChanged(boolean headsUpAnimatingAway) { + if (!headsUpAnimatingAway) { updateTouchableRegionAfterLayout(); } else { updateTouchableRegion(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt index 52a6d8cf0952..cc87e8a45d13 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt @@ -19,6 +19,9 @@ package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING +import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN +import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor @@ -77,15 +80,13 @@ constructor( @Application coroutineScope: CoroutineScope, ) : CollapsedStatusBarViewModel { override val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean> = - keyguardTransitionInteractor.lockscreenToOccludedTransition - .map { - it.transitionState == TransitionState.STARTED || - it.transitionState == TransitionState.RUNNING - } + keyguardTransitionInteractor + .isInTransition(LOCKSCREEN, OCCLUDED) .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false) override val transitionFromLockscreenToDreamStartedEvent: Flow<Unit> = - keyguardTransitionInteractor.lockscreenToDreamingTransition + keyguardTransitionInteractor + .transition(LOCKSCREEN, DREAMING) .filter { it.transitionState == TransitionState.STARTED } .map {} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt index 9cdecef3f6e8..1b56702f3907 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt @@ -115,13 +115,16 @@ class AvalancheController @Inject constructor( * Run or ignore Runnable for given HeadsUpEntry. If entry was never shown, ignore and delete * all Runnables associated with that entry. */ - fun delete(entry: HeadsUpEntry, runnable: Runnable, label: String) { + fun delete(entry: HeadsUpEntry?, runnable: Runnable, label: String) { if (!NotificationThrottleHun.isEnabled) { runnable.run() return } val fn = "[$label] => AvalancheController.delete " + getKey(entry) - + if (entry == null) { + log { "$fn => cannot remove NULL entry" } + return + } if (entry in nextMap) { log { "$fn => [remove from next]" } if (entry in nextMap) nextMap.remove(entry) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java index d99af2ddb95d..b8318a7dfb61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java @@ -256,10 +256,15 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { // A copy is necessary here as we are changing the underlying map. This would cause // undefined behavior if we iterated over the key set directly. ArraySet<String> keysToRemove = new ArraySet<>(mHeadsUpEntryMap.keySet()); + + // Must get waiting keys before calling removeEntry, which clears waiting entries in + // AvalancheController + List<String> waitingKeysToRemove = mAvalancheController.getWaitingKeys(); + for (String key : keysToRemove) { removeEntry(key); } - for (String key : mAvalancheController.getWaitingKeys()) { + for (String key : waitingKeysToRemove) { removeEntry(key); } } @@ -903,8 +908,12 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { mLogger.logAutoRemoveCanceled(mEntry, reason); } }; - mAvalancheController.update(this, runnable, - reason + " removeAutoRemovalCallbacks"); + if (isHeadsUpEntry(this.mEntry.getKey())) { + mAvalancheController.update(this, runnable, reason + " cancelAutoRemovalCallbacks"); + } else { + // Just removed + runnable.run(); + } } public void scheduleAutoRemovalCallback(FinishTimeUpdater finishTimeCalculator, 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 52a2e9ccc163..28a2a1f49bf6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt @@ -73,7 +73,8 @@ interface HeadsUpManager : Dumpable { /** Returns whether or not the given notification is managed by this manager. */ fun isHeadsUpEntry(key: String): Boolean - fun isHeadsUpGoingAway(): Boolean + /** @see setHeadsUpAnimatingAway */ + fun isHeadsUpAnimatingAwayValue(): Boolean /** Returns if the given notification is snoozed or not. */ fun isSnoozed(packageName: String): Boolean @@ -130,7 +131,7 @@ interface HeadsUpManager : Dumpable { * Set that we are exiting the headsUp pinned mode, but some notifications might still be * animating out. This is used to keep the touchable regions in a reasonable state. */ - fun setHeadsUpGoingAway(headsUpGoingAway: Boolean) + fun setHeadsUpAnimatingAway(headsUpAnimatingAway: Boolean) /** * Notifies that a remote input textbox in notification gets active or inactive. @@ -194,10 +195,10 @@ interface AnimationStateHandler { interface OnHeadsUpPhoneListenerChange { /** * Called when a heads up notification is 'going away' or no longer 'going away'. See - * [HeadsUpManager.setHeadsUpGoingAway]. + * [HeadsUpManager.setHeadsUpAnimatingAway]. */ // TODO(b/325936094) delete this callback, and listen to the flow instead - fun onHeadsUpGoingAwayStateChanged(headsUpGoingAway: Boolean) + fun onHeadsUpAnimatingAwayStateChanged(headsUpAnimatingAway: Boolean) } /* No op impl of HeadsUpManager. */ @@ -215,7 +216,7 @@ class HeadsUpManagerEmptyImpl @Inject constructor() : HeadsUpManager { override fun getTopEntry() = null override fun hasPinnedHeadsUp() = false override fun isHeadsUpEntry(key: String) = false - override fun isHeadsUpGoingAway() = false + override fun isHeadsUpAnimatingAwayValue() = false override fun isSnoozed(packageName: String) = false override fun isSticky(key: String?) = false override fun isTrackingHeadsUp() = false @@ -228,7 +229,7 @@ class HeadsUpManagerEmptyImpl @Inject constructor() : HeadsUpManager { override fun setAnimationStateHandler(handler: AnimationStateHandler) {} override fun setExpanded(entry: NotificationEntry, expanded: Boolean) {} override fun setGutsShown(entry: NotificationEntry, gutsShown: Boolean) {} - override fun setHeadsUpGoingAway(headsUpGoingAway: Boolean) {} + override fun setHeadsUpAnimatingAway(headsUpAnimatingAway: Boolean) {} override fun setRemoteInputActive(entry: NotificationEntry, remoteInputActive: Boolean) {} override fun setTrackingHeadsUp(tracking: Boolean) {} override fun setUser(user: Int) {} diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index 27a708a00cb7..1688b0b51b41 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -1129,7 +1129,9 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, } updateSelectedRingerContainerDescription(true); - + mSelectedRingerContainer.setImportantForAccessibility( + View.IMPORTANT_FOR_ACCESSIBILITY_NO); + mSelectedRingerContainer.clearFocus(); mIsRingerDrawerOpen = true; } @@ -1175,7 +1177,8 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, .start(); updateSelectedRingerContainerDescription(false); - + mSelectedRingerContainer.setImportantForAccessibility( + View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); mIsRingerDrawerOpen = false; } @@ -1746,7 +1749,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, boolean isZenMuted = mState.zenMode == Global.ZEN_MODE_ALARMS || mState.zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS || (mState.zenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS - && mState.disallowRinger); + && mState.disallowRinger); enableRingerViewsH(!isZenMuted); switch (mState.ringerModeInternal) { case AudioManager.RINGER_MODE_VIBRATE: @@ -1796,7 +1799,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(host, info); info.addAction(new AccessibilityNodeInfo.AccessibilityAction( - AccessibilityNodeInfo.ACTION_CLICK, hintLabel)); + AccessibilityNodeInfo.ACTION_CLICK, hintLabel)); } }); } diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/UiEventLoggerStartableModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/UiEventLoggerStartableModule.kt new file mode 100644 index 000000000000..9b84090d72cd --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/UiEventLoggerStartableModule.kt @@ -0,0 +1,33 @@ +/* + * 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.dagger + +import com.android.systemui.volume.domain.startable.AudioModeLoggerStartable +import com.android.systemui.volume.panel.domain.VolumePanelStartable +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoSet + +@Module +interface UiEventLoggerStartableModule { + + @Binds + @IntoSet + fun bindAudioModeLoggerStartable( + audioModeLoggerStartable: AudioModeLoggerStartable, + ): VolumePanelStartable +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/domain/startable/AudioModeLoggerStartable.kt b/packages/SystemUI/src/com/android/systemui/volume/domain/startable/AudioModeLoggerStartable.kt new file mode 100644 index 000000000000..12447577e945 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/domain/startable/AudioModeLoggerStartable.kt @@ -0,0 +1,49 @@ +/* + * 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.domain.startable + +import com.android.internal.logging.UiEventLogger +import com.android.settingslib.volume.domain.interactor.AudioModeInteractor +import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope +import com.android.systemui.volume.panel.domain.VolumePanelStartable +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.launch + +/** Logger for audio mode */ +@VolumePanelScope +class AudioModeLoggerStartable +@Inject +constructor( + @VolumePanelScope private val scope: CoroutineScope, + private val uiEventLogger: UiEventLogger, + private val audioModeInteractor: AudioModeInteractor, +) : VolumePanelStartable { + + override fun start() { + scope.launch { + audioModeInteractor.isOngoingCall.distinctUntilChanged().collect { ongoingCall -> + uiEventLogger.log( + if (ongoingCall) VolumePanelUiEvent.VOLUME_PANEL_AUDIO_MODE_CHANGE_TO_CALLING + else VolumePanelUiEvent.VOLUME_PANEL_AUDIO_MODE_CHANGE_TO_NORMAL + ) + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModel.kt index 04d7b1fa6532..3ca9cdfe285c 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModel.kt @@ -18,8 +18,10 @@ package com.android.systemui.volume.panel.component.bottombar.ui.viewmodel import android.content.Intent import android.provider.Settings +import com.android.internal.logging.UiEventLogger import com.android.systemui.plugins.ActivityStarter import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel import javax.inject.Inject @@ -29,6 +31,7 @@ class BottomBarViewModel constructor( private val activityStarter: ActivityStarter, private val volumePanelViewModel: VolumePanelViewModel, + private val uiEventLogger: UiEventLogger, ) { fun onDoneClicked() { @@ -36,6 +39,7 @@ constructor( } fun onSettingsClicked() { + uiEventLogger.log(VolumePanelUiEvent.VOLUME_PANEL_SOUND_SETTINGS_CLICKED) activityStarter.startActivityDismissingKeyguard( /* intent = */ Intent(Settings.ACTION_SOUND_SETTINGS), /* onlyProvisioned = */ false, diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/captioning/domain/CaptioningAvailabilityCriteria.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/captioning/domain/CaptioningAvailabilityCriteria.kt index aab825fb9f5e..85da1d0efe3a 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/captioning/domain/CaptioningAvailabilityCriteria.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/captioning/domain/CaptioningAvailabilityCriteria.kt @@ -16,18 +16,36 @@ package com.android.systemui.volume.panel.component.captioning.domain +import com.android.internal.logging.UiEventLogger import com.android.settingslib.view.accessibility.domain.interactor.CaptioningInteractor import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.shareIn @VolumePanelScope class CaptioningAvailabilityCriteria @Inject -constructor(private val captioningInteractor: CaptioningInteractor) : - ComponentAvailabilityCriteria { +constructor( + captioningInteractor: CaptioningInteractor, + @VolumePanelScope private val scope: CoroutineScope, + private val uiEventLogger: UiEventLogger, +) : ComponentAvailabilityCriteria { - override fun isAvailable(): Flow<Boolean> = + private val availability = captioningInteractor.isSystemAudioCaptioningUiEnabled + .onEach { visible -> + uiEventLogger.log( + if (visible) VolumePanelUiEvent.VOLUME_PANEL_LIVE_CAPTION_TOGGLE_SHOWN + else VolumePanelUiEvent.VOLUME_PANEL_LIVE_CAPTION_TOGGLE_GONE + ) + } + .shareIn(scope, SharingStarted.WhileSubscribed(), replay = 1) + + override fun isAvailable(): Flow<Boolean> = availability } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModel.kt index 92f8f221d918..01421f86311f 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModel.kt @@ -17,11 +17,13 @@ package com.android.systemui.volume.panel.component.captioning.ui.viewmodel import android.content.Context +import com.android.internal.logging.UiEventLogger import com.android.settingslib.view.accessibility.domain.interactor.CaptioningInteractor import com.android.systemui.common.shared.model.Icon import com.android.systemui.res.R import com.android.systemui.volume.panel.component.button.ui.viewmodel.ToggleButtonViewModel import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted @@ -38,6 +40,7 @@ constructor( private val context: Context, private val captioningInteractor: CaptioningInteractor, @VolumePanelScope private val coroutineScope: CoroutineScope, + private val uiEventLogger: UiEventLogger, ) { val buttonViewModel: StateFlow<ToggleButtonViewModel?> = @@ -57,6 +60,13 @@ constructor( .stateIn(coroutineScope, SharingStarted.Eagerly, null) fun setIsSystemAudioCaptioningEnabled(enabled: Boolean) { + uiEventLogger.logWithPosition( + VolumePanelUiEvent.VOLUME_PANEL_LIVE_CAPTION_TOGGLE_CLICKED, + 0, + null, + if (enabled) VolumePanelUiEvent.LIVE_CAPTION_TOGGLE_ENABLED + else VolumePanelUiEvent.LIVE_CAPTION_TOGGLE_DISABLED + ) coroutineScope.launch { captioningInteractor.setIsSystemAudioCaptioningEnabled(enabled) } } } 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 index fc9602e6017f..6b237f8e329b 100644 --- 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 @@ -17,6 +17,7 @@ package com.android.systemui.volume.panel.component.mediaoutput.ui.viewmodel import android.content.Context +import com.android.internal.logging.UiEventLogger import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Color import com.android.systemui.common.shared.model.Icon @@ -26,6 +27,7 @@ import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor import com.android.systemui.volume.panel.component.mediaoutput.shared.model.SessionWithPlayback import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -48,6 +50,7 @@ constructor( private val actionsInteractor: MediaOutputActionsInteractor, private val mediaDeviceSessionInteractor: MediaDeviceSessionInteractor, interactor: MediaOutputInteractor, + private val uiEventLogger: UiEventLogger, ) { private val sessionWithPlayback: StateFlow<SessionWithPlayback?> = @@ -126,6 +129,7 @@ constructor( ) fun onBarClick(expandable: Expandable) { + uiEventLogger.log(VolumePanelUiEvent.VOLUME_PANEL_MEDIA_OUTPUT_CLICKED) actionsInteractor.onBarClick(sessionWithPlayback.value, expandable) } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt index f022039e9cde..4ecdd46163f9 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt @@ -17,6 +17,7 @@ package com.android.systemui.volume.panel.component.spatial.ui.viewmodel import android.content.Context +import com.android.internal.logging.UiEventLogger import com.android.systemui.common.shared.model.Color import com.android.systemui.common.shared.model.Icon import com.android.systemui.dagger.qualifiers.Application @@ -29,6 +30,7 @@ import com.android.systemui.volume.panel.component.spatial.domain.interactor.Spa import com.android.systemui.volume.panel.component.spatial.domain.model.SpatialAudioAvailabilityModel import com.android.systemui.volume.panel.component.spatial.domain.model.SpatialAudioEnabledModel import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted @@ -46,6 +48,7 @@ constructor( @VolumePanelScope private val scope: CoroutineScope, availabilityCriteria: SpatialAudioAvailabilityCriteria, private val interactor: SpatialAudioComponentInteractor, + private val uiEventLogger: UiEventLogger, ) { val spatialAudioButton: StateFlow<ButtonViewModel?> = @@ -101,6 +104,19 @@ constructor( .stateIn(scope, SharingStarted.Eagerly, emptyList()) fun setEnabled(model: SpatialAudioEnabledModel) { + uiEventLogger.logWithPosition( + VolumePanelUiEvent.VOLUME_PANEL_SPATIAL_AUDIO_TOGGLE_CLICKED, + 0, + null, + when (model) { + SpatialAudioEnabledModel.Disabled -> 0 + SpatialAudioEnabledModel.SpatialAudioEnabled -> 1 + SpatialAudioEnabledModel.HeadTrackingEnabled -> 2 + else -> { + -1 + } + } + ) scope.launch { interactor.setEnabled(model) } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt index 1ae1ebb99f8b..c8cd6fdbea70 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt @@ -18,12 +18,14 @@ package com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel import android.content.Context import android.media.AudioManager +import com.android.internal.logging.UiEventLogger import com.android.settingslib.volume.domain.interactor.AudioVolumeInteractor import com.android.settingslib.volume.shared.model.AudioStream import com.android.settingslib.volume.shared.model.AudioStreamModel import com.android.settingslib.volume.shared.model.RingerMode import com.android.systemui.common.shared.model.Icon import com.android.systemui.res.R +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -43,6 +45,7 @@ constructor( @Assisted private val coroutineScope: CoroutineScope, private val context: Context, private val audioVolumeInteractor: AudioVolumeInteractor, + private val uiEventLogger: UiEventLogger, ) : SliderViewModel { private val audioStream = audioStreamWrapper.audioStream @@ -69,6 +72,19 @@ constructor( AudioStream(AudioManager.STREAM_ALARM) to R.string.stream_alarm_unavailable, AudioStream(AudioManager.STREAM_MUSIC) to R.string.stream_media_unavailable, ) + private val uiEventByStream = + mapOf( + AudioStream(AudioManager.STREAM_MUSIC) to + VolumePanelUiEvent.VOLUME_PANEL_MUSIC_SLIDER_TOUCHED, + AudioStream(AudioManager.STREAM_VOICE_CALL) to + VolumePanelUiEvent.VOLUME_PANEL_VOICE_CALL_SLIDER_TOUCHED, + AudioStream(AudioManager.STREAM_RING) to + VolumePanelUiEvent.VOLUME_PANEL_RING_SLIDER_TOUCHED, + AudioStream(AudioManager.STREAM_NOTIFICATION) to + VolumePanelUiEvent.VOLUME_PANEL_NOTIFICATION_SLIDER_TOUCHED, + AudioStream(AudioManager.STREAM_ALARM) to + VolumePanelUiEvent.VOLUME_PANEL_ALARM_SLIDER_TOUCHED, + ) override val slider: StateFlow<SliderState> = combine( @@ -88,6 +104,10 @@ constructor( } } + override fun onValueChangeFinished() { + uiEventByStream[audioStream]?.let { uiEventLogger.log(it) } + } + override fun toggleMuted(state: SliderState) { val audioViewModel = state as? State audioViewModel ?: return diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt index 3689303ab28d..956ab66ac0c3 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt @@ -54,6 +54,8 @@ constructor( } } + override fun onValueChangeFinished() {} + override fun toggleMuted(state: SliderState) { // do nothing because this action isn't supported for Cast sliders. } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderViewModel.kt index 74aee559194b..7ded8c5c9fc1 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderViewModel.kt @@ -25,5 +25,7 @@ interface SliderViewModel { fun onValueChanged(state: SliderState, newValue: Float) + fun onValueChangeFinished() + fun toggleMuted(state: SliderState) } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/DefaultMultibindsModule.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/DefaultMultibindsModule.kt index d1d539003f93..f889ed6e06be 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/DefaultMultibindsModule.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/DefaultMultibindsModule.kt @@ -17,6 +17,7 @@ package com.android.systemui.volume.panel.dagger import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria +import com.android.systemui.volume.panel.domain.VolumePanelStartable import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey import com.android.systemui.volume.panel.shared.model.VolumePanelUiComponent import dagger.Module @@ -31,4 +32,6 @@ interface DefaultMultibindsModule { @Multibinds fun criteriaMap(): Map<VolumePanelComponentKey, ComponentAvailabilityCriteria> @Multibinds fun components(): Map<VolumePanelComponentKey, VolumePanelUiComponent> + + @Multibinds fun startables(): Set<VolumePanelStartable> } 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 d868c33d0887..ec64f3d93012 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 @@ -16,6 +16,7 @@ package com.android.systemui.volume.panel.dagger +import com.android.systemui.volume.dagger.UiEventLoggerStartableModule import com.android.systemui.volume.panel.component.anc.AncModule import com.android.systemui.volume.panel.component.bottombar.BottomBarModule import com.android.systemui.volume.panel.component.captioning.CaptioningModule @@ -25,6 +26,7 @@ import com.android.systemui.volume.panel.component.volume.VolumeSlidersModule 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 +import com.android.systemui.volume.panel.domain.VolumePanelStartable import com.android.systemui.volume.panel.domain.interactor.ComponentsInteractor import com.android.systemui.volume.panel.ui.UiModule import com.android.systemui.volume.panel.ui.composable.ComponentsFactory @@ -47,6 +49,7 @@ import kotlinx.coroutines.CoroutineScope DefaultMultibindsModule::class, DomainModule::class, UiModule::class, + UiEventLoggerStartableModule::class, // Components modules BottomBarModule::class, AncModule::class, @@ -66,6 +69,8 @@ interface VolumePanelComponent { fun componentsLayoutManager(): ComponentsLayoutManager + fun volumePanelStartables(): Set<VolumePanelStartable> + @Subcomponent.Factory interface Factory : VolumePanelComponentFactory { diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/domain/VolumePanelStartable.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/domain/VolumePanelStartable.kt new file mode 100644 index 000000000000..9c39f5e75f88 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/domain/VolumePanelStartable.kt @@ -0,0 +1,22 @@ +/* + * 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.domain + +/** Code that needs to be run when Volume Panel is started.. */ +interface VolumePanelStartable { + fun start() +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/VolumePanelUiEvent.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/VolumePanelUiEvent.kt new file mode 100644 index 000000000000..8b8714fcca8c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/VolumePanelUiEvent.kt @@ -0,0 +1,56 @@ +/* + * 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.ui + +import com.android.internal.logging.UiEvent +import com.android.internal.logging.UiEventLogger + +/** UI events for Volume Panel. */ +enum class VolumePanelUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum { + @UiEvent(doc = "The volume panel is shown") VOLUME_PANEL_SHOWN(1634), + @UiEvent(doc = "The volume panel is gone") VOLUME_PANEL_GONE(1635), + @UiEvent(doc = "Media output is clicked") VOLUME_PANEL_MEDIA_OUTPUT_CLICKED(1636), + @UiEvent(doc = "Audio mode changed to normal") VOLUME_PANEL_AUDIO_MODE_CHANGE_TO_NORMAL(1680), + @UiEvent(doc = "Audio mode changed to calling") VOLUME_PANEL_AUDIO_MODE_CHANGE_TO_CALLING(1681), + @UiEvent(doc = "Sound settings is clicked") VOLUME_PANEL_SOUND_SETTINGS_CLICKED(1638), + @UiEvent(doc = "The music volume slider is touched") VOLUME_PANEL_MUSIC_SLIDER_TOUCHED(1639), + @UiEvent(doc = "The voice call volume slider is touched") + VOLUME_PANEL_VOICE_CALL_SLIDER_TOUCHED(1640), + @UiEvent(doc = "The ring volume slider is touched") VOLUME_PANEL_RING_SLIDER_TOUCHED(1641), + @UiEvent(doc = "The notification volume slider is touched") + VOLUME_PANEL_NOTIFICATION_SLIDER_TOUCHED(1642), + @UiEvent(doc = "The alarm volume slider is touched") VOLUME_PANEL_ALARM_SLIDER_TOUCHED(1643), + @UiEvent(doc = "Live caption toggle is shown") VOLUME_PANEL_LIVE_CAPTION_TOGGLE_SHOWN(1644), + @UiEvent(doc = "Live caption toggle is gone") VOLUME_PANEL_LIVE_CAPTION_TOGGLE_GONE(1645), + @UiEvent(doc = "Live caption toggle is clicked") VOLUME_PANEL_LIVE_CAPTION_TOGGLE_CLICKED(1646), + @UiEvent(doc = "Spatial audio button is shown") VOLUME_PANEL_SPATIAL_AUDIO_BUTTON_SHOWN(1647), + @UiEvent(doc = "Spatial audio button is gone") VOLUME_PANEL_SPATIAL_AUDIO_BUTTON_GONE(1648), + @UiEvent(doc = "Spatial audio popup is shown") VOLUME_PANEL_SPATIAL_AUDIO_POP_UP_SHOWN(1649), + @UiEvent(doc = "Spatial audio toggle is clicked") + VOLUME_PANEL_SPATIAL_AUDIO_TOGGLE_CLICKED(1650), + @UiEvent(doc = "ANC button is shown") VOLUME_PANEL_ANC_BUTTON_SHOWN(1651), + @UiEvent(doc = "ANC button is gone") VOLUME_PANEL_ANC_BUTTON_GONE(1652), + @UiEvent(doc = "ANC popup is shown") VOLUME_PANEL_ANC_POPUP_SHOWN(1653), + @UiEvent(doc = "ANC toggle is clicked") VOLUME_PANEL_ANC_TOGGLE_CLICKED(1654); + + override fun getId() = metricId + + companion object { + const val LIVE_CAPTION_TOGGLE_DISABLED = 0 + const val LIVE_CAPTION_TOGGLE_ENABLED = 1 + } +} 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 c728fefa77e6..ccb91ac79b6a 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 @@ -21,8 +21,10 @@ import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels +import com.android.internal.logging.UiEventLogger import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import com.android.systemui.volume.panel.ui.composable.VolumePanelRoot import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel import javax.inject.Inject @@ -34,6 +36,7 @@ constructor( private val volumePanelViewModelFactory: Provider<VolumePanelViewModel.Factory>, private val volumePanelFlag: VolumePanelFlag, private val configurationController: ConfigurationController, + private val uiEventLogger: UiEventLogger, ) : ComponentActivity() { private val viewModel: VolumePanelViewModel by @@ -43,8 +46,16 @@ constructor( enableEdgeToEdge() super.onCreate(savedInstanceState) volumePanelFlag.assertNewVolumePanel() - - setContent { VolumePanelRoot(viewModel = viewModel, onDismiss = ::finish) } + uiEventLogger.log(VolumePanelUiEvent.VOLUME_PANEL_SHOWN) + setContent { + VolumePanelRoot( + viewModel = viewModel, + onDismiss = { + uiEventLogger.log(VolumePanelUiEvent.VOLUME_PANEL_GONE) + finish() + } + ) + } } override fun onContentChanged() { 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 5ae827ff4e3d..1de4fd1f9593 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 @@ -26,6 +26,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.onConfigChanged import com.android.systemui.volume.panel.dagger.VolumePanelComponent import com.android.systemui.volume.panel.dagger.factory.VolumePanelComponentFactory +import com.android.systemui.volume.panel.domain.VolumePanelStartable import com.android.systemui.volume.panel.domain.interactor.ComponentsInteractor import com.android.systemui.volume.panel.ui.composable.ComponentsFactory import com.android.systemui.volume.panel.ui.layout.ComponentsLayout @@ -109,6 +110,10 @@ class VolumePanelViewModel( replay = 1, ) + init { + volumePanelComponent.volumePanelStartables().onEach(VolumePanelStartable::start) + } + fun dismissPanel() { mutablePanelVisibility.update { false } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt index f32d5b8838b7..e72027a921b7 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt @@ -319,9 +319,19 @@ class ClockEventControllerTest : SysuiTestCase() { fun listenForDozeAmountTransition_updatesClockDozeAmount() = runBlocking(IMMEDIATE) { val transitionStep = MutableStateFlow(TransitionStep()) - whenever(keyguardTransitionInteractor.lockscreenToAodTransition) + whenever( + keyguardTransitionInteractor.transition( + KeyguardState.LOCKSCREEN, + KeyguardState.AOD + ) + ) .thenReturn(transitionStep) - whenever(keyguardTransitionInteractor.aodToLockscreenTransition) + whenever( + keyguardTransitionInteractor.transition( + KeyguardState.AOD, + KeyguardState.LOCKSCREEN + ) + ) .thenReturn(transitionStep) val job = underTest.listenForDozeAmountTransition(this) @@ -361,6 +371,27 @@ class ClockEventControllerTest : SysuiTestCase() { } @Test + fun listenForTransitionToLSFromOccluded_updatesClockDozeAmountToOne() = + runBlocking(IMMEDIATE) { + val transitionStep = MutableStateFlow(TransitionStep()) + whenever(keyguardTransitionInteractor.transitionStepsToState(KeyguardState.LOCKSCREEN)) + .thenReturn(transitionStep) + + val job = underTest.listenForAnyStateToLockscreenTransition(this) + transitionStep.value = + TransitionStep( + from = KeyguardState.OCCLUDED, + to = KeyguardState.LOCKSCREEN, + transitionState = TransitionState.STARTED, + ) + yield() + + verify(animations, times(2)).doze(0f) + + job.cancel() + } + + @Test fun listenForTransitionToAodFromLockscreen_neverUpdatesClockDozeAmount() = runBlocking(IMMEDIATE) { val transitionStep = MutableStateFlow(TransitionStep()) @@ -378,6 +409,27 @@ class ClockEventControllerTest : SysuiTestCase() { verify(animations, never()).doze(1f) + job.cancel() + } + + @Test + fun listenForAnyStateToLockscreenTransition_neverUpdatesClockDozeAmount() = + runBlocking(IMMEDIATE) { + val transitionStep = MutableStateFlow(TransitionStep()) + whenever(keyguardTransitionInteractor.transitionStepsToState(KeyguardState.LOCKSCREEN)) + .thenReturn(transitionStep) + + val job = underTest.listenForAnyStateToLockscreenTransition(this) + transitionStep.value = + TransitionStep( + from = KeyguardState.AOD, + to = KeyguardState.LOCKSCREEN, + transitionState = TransitionState.STARTED, + ) + yield() + + verify(animations, never()).doze(0f) + job.cancel() } diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt index dac88a340cb1..e06134bdf982 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt @@ -119,6 +119,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { fun faceAuthIsRequestedWhenLockscreenBecomesVisibleFromOffState() = testScope.runTest { underTest.start() + runCurrent() powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_LID) faceWakeUpTriggersConfig.setTriggerFaceAuthOnWakeUpFrom( @@ -160,6 +161,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { fun faceAuthIsRequestedWhenLockscreenBecomesVisibleFromAodState() = testScope.runTest { underTest.start() + runCurrent() powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_LID) faceWakeUpTriggersConfig.setTriggerFaceAuthOnWakeUpFrom( @@ -207,6 +209,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { fun faceAuthIsRequestedWhenLockscreenBecomesVisibleFromDozingState() = testScope.runTest { underTest.start() + runCurrent() powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_LID) faceWakeUpTriggersConfig.setTriggerFaceAuthOnWakeUpFrom( diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt index 2b51863117e9..b0aace6f650e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt @@ -15,6 +15,8 @@ import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepos import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.kosmos.testScope import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.testKosmos @@ -22,7 +24,6 @@ import com.android.systemui.util.mockito.any import com.android.systemui.utils.GlobalWindowManager import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before @@ -42,8 +43,7 @@ import org.mockito.MockitoAnnotations class ResourceTrimmerTest : SysuiTestCase() { val kosmos = testKosmos() - private val testDispatcher = UnconfinedTestDispatcher() - private val testScope = TestScope(testDispatcher) + private val testScope = kosmos.testScope private val keyguardRepository = kosmos.fakeKeyguardRepository private val featureFlags = kosmos.fakeFeatureFlagsClassic private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository @@ -74,7 +74,7 @@ class ResourceTrimmerTest : SysuiTestCase() { kosmos.keyguardTransitionInteractor, globalWindowManager, testScope.backgroundScope, - testDispatcher, + kosmos.testDispatcher, featureFlags ) resourceTrimmer.start() diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt index 6d605a564022..b1a8dd1d3fdc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt @@ -281,6 +281,14 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { // Oh no, we're still surfaceBehindAnimating=true, but no longer transitioning to GONE. transitionRepository.sendTransitionStep( TransitionStep( + transitionState = TransitionState.CANCELED, + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + ) + ) + runCurrent() + transitionRepository.sendTransitionStep( + TransitionStep( transitionState = TransitionState.STARTED, from = KeyguardState.LOCKSCREEN, to = KeyguardState.AOD, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt index 143c4dacb6be..1396b20a800d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt @@ -57,11 +57,18 @@ class AlternateBouncerWindowViewModelTest : SysuiTestCase() { stepFromAlternateBouncer(0f, TransitionState.STARTED), stepFromAlternateBouncer(.4f), stepFromAlternateBouncer(.6f), - stepFromAlternateBouncer(1f), ), testScope, ) assertThat(alternateBouncerWindowRequired).isTrue() + + transitionRepository.sendTransitionSteps( + listOf( + stepFromAlternateBouncer(1.0f, TransitionState.FINISHED), + ), + testScope, + ) + assertThat(alternateBouncerWindowRequired).isFalse() } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt index 85a20e22818f..01754c4b5598 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt @@ -23,6 +23,7 @@ import com.android.keyguard.KeyguardClockSwitch import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository import com.android.systemui.keyguard.data.repository.keyguardClockRepository import com.android.systemui.keyguard.data.repository.keyguardRepository @@ -49,6 +50,7 @@ import org.mockito.Mockito.mock @SmallTest @RunWith(JUnit4::class) +@DisableSceneContainer class KeyguardClockViewModelTest : SysuiTestCase() { private lateinit var kosmos: Kosmos private lateinit var underTest: KeyguardClockViewModel @@ -71,7 +73,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun currentClockLayout_splitShadeOn_clockCentered_largeClock() = testScope.runTest { with(kosmos) { @@ -84,7 +85,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun currentClockLayout_splitShadeOn_clockNotCentered_largeClock_splitShadeLargeClock() = testScope.runTest { with(kosmos) { @@ -98,7 +98,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun currentClockLayout_splitShadeOn_clockNotCentered_smallClock_splitShadeSmallClock() = testScope.runTest { with(kosmos) { @@ -112,7 +111,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun currentClockLayout_singleShade_smallClock_smallClock() = testScope.runTest { with(kosmos) { @@ -124,7 +122,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun currentClockLayout_singleShade_largeClock_largeClock() = testScope.runTest { with(kosmos) { @@ -136,7 +133,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun hasCustomPositionUpdatedAnimation_withConfigTrue_isTrue() = testScope.runTest { with(kosmos) { @@ -151,7 +147,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun hasCustomPositionUpdatedAnimation_withConfigFalse_isFalse() = testScope.runTest { with(kosmos) { @@ -167,7 +162,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun testClockSize_alwaysSmallClockSize() = testScope.runTest { kosmos.fakeKeyguardClockRepository.setSelectedClockSize(SettingsClockSize.SMALL) @@ -178,7 +172,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun testClockSize_dynamicClockSize() = testScope.runTest { kosmos.keyguardClockRepository.setClockSize(KeyguardClockSwitch.SMALL) @@ -191,7 +184,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun isLargeClockVisible_whenLargeClockSize_isTrue() = testScope.runTest { kosmos.keyguardClockRepository.setClockSize(KeyguardClockSwitch.LARGE) @@ -200,7 +192,6 @@ class KeyguardClockViewModelTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) fun isLargeClockVisible_whenSmallClockSize_isFalse() = testScope.runTest { kosmos.keyguardClockRepository.setClockSize(KeyguardClockSwitch.SMALL) diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt index b70cc30eb3e1..fe8fdc042ae4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt @@ -29,7 +29,9 @@ import com.android.systemui.media.controls.MediaTestUtils import com.android.systemui.media.controls.data.repository.MediaFilterRepository import com.android.systemui.media.controls.shared.model.EXTRA_KEY_TRIGGER_RESUME import com.android.systemui.media.controls.shared.model.MediaData +import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel import com.android.systemui.media.controls.shared.model.SmartspaceMediaData +import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel import com.android.systemui.media.controls.ui.controller.MediaPlayerData import com.android.systemui.media.controls.util.MediaFlags import com.android.systemui.media.controls.util.MediaUiEventLogger @@ -48,12 +50,10 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyLong import org.mockito.Mock import org.mockito.Mockito.never -import org.mockito.Mockito.reset import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @@ -76,7 +76,6 @@ private val SMARTSPACE_INSTANCE_ID = InstanceId.fakeInstanceId(456)!! @TestableLooper.RunWithLooper class MediaDataFilterImplTest : SysuiTestCase() { - @Mock private lateinit var listener: MediaDataFilterImpl.Listener @Mock private lateinit var userTracker: UserTracker @Mock private lateinit var broadcastSender: BroadcastSender @Mock private lateinit var mediaDataManager: MediaDataManager @@ -89,7 +88,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Mock private lateinit var cardAction: SmartspaceAction private lateinit var mediaDataFilter: MediaDataFilterImpl - private lateinit var mediaFilterRepository: MediaFilterRepository + private lateinit var repository: MediaFilterRepository private lateinit var testScope: TestScope private lateinit var dataMain: MediaData private lateinit var dataGuest: MediaData @@ -102,7 +101,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { MediaPlayerData.clear() whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(false) testScope = TestScope() - mediaFilterRepository = MediaFilterRepository() + repository = MediaFilterRepository() mediaDataFilter = MediaDataFilterImpl( context, @@ -113,10 +112,9 @@ class MediaDataFilterImplTest : SysuiTestCase() { clock, logger, mediaFlags, - mediaFilterRepository, + repository, ) mediaDataFilter.mediaDataManager = mediaDataManager - mediaDataFilter.addListener(listener) // Start all tests as main user setUser(USER_MAIN) @@ -162,91 +160,114 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnDataLoadedForCurrentUser_callsListener() { - // GIVEN a media for main user - mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) + fun onDataLoadedForCurrentUser_updatesLoadedStates() = + testScope.runTest { + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) + val mediaDataLoadingModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) - // THEN we should tell the listener - verify(listener).onMediaDataLoaded(eq(dataMain.instanceId), eq(true), eq(0), eq(false)) - } + mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) + + assertThat(mediaDataLoadedStates).isEqualTo(mediaDataLoadingModel) + } @Test - fun testOnDataLoadedForGuest_doesNotCallListener() { - // GIVEN a media for guest user - mediaDataFilter.onMediaDataLoaded(KEY, null, dataGuest) + fun onDataLoadedForGuest_doesNotUpdateLoadedStates() = + testScope.runTest { + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) + val mediaLoadedStatesModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) - // THEN we should NOT tell the listener - verify(listener, never()).onMediaDataLoaded(any(), anyBoolean(), anyInt(), anyBoolean()) - } + mediaDataFilter.onMediaDataLoaded(KEY, null, dataGuest) + + assertThat(mediaDataLoadedStates).isNotEqualTo(mediaLoadedStatesModel) + } @Test - fun testOnRemovedForCurrent_callsListener() { - // GIVEN a media was removed for main user - mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) - mediaDataFilter.onMediaDataRemoved(KEY) + fun onRemovedForCurrent_updatesLoadedStates() = + testScope.runTest { + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) + val mediaLoadedStatesModel = + mutableListOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) - // THEN we should tell the listener - verify(listener).onMediaDataRemoved(eq(dataMain.instanceId)) - } + // GIVEN a media was removed for main user + mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) + + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) + + mediaLoadedStatesModel.remove(MediaDataLoadingModel.Loaded(dataMain.instanceId)) + mediaDataFilter.onMediaDataRemoved(KEY) + + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) + } @Test - fun testOnRemovedForGuest_doesNotCallListener() { - // GIVEN a media was removed for guest user - mediaDataFilter.onMediaDataLoaded(KEY, null, dataGuest) - mediaDataFilter.onMediaDataRemoved(KEY) + fun onRemovedForGuest_doesNotUpdateLoadedStates() = + testScope.runTest { + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) - // THEN we should NOT tell the listener - verify(listener, never()).onMediaDataRemoved(eq(dataGuest.instanceId)) - } + // GIVEN a media was removed for guest user + mediaDataFilter.onMediaDataLoaded(KEY, null, dataGuest) + mediaDataFilter.onMediaDataRemoved(KEY) + + assertThat(mediaDataLoadedStates).isEmpty() + } @Test - fun testOnUserSwitched_removesOldUserControls() { - // GIVEN that we have a media loaded for main user - mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) + fun onUserSwitched_removesOldUserControls() = + testScope.runTest { + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) + val mediaLoadedStatesModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) - // and we switch to guest user - setUser(USER_GUEST) + // GIVEN that we have a media loaded for main user + mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) - // THEN we should remove the main user's media - verify(listener).onMediaDataRemoved(eq(dataMain.instanceId)) - } + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) + + // and we switch to guest user + setUser(USER_GUEST) + + // THEN we should remove the main user's media + assertThat(mediaDataLoadedStates).isEmpty() + } @Test - fun testOnUserSwitched_addsNewUserControls() { - // GIVEN that we had some media for both users - mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) - mediaDataFilter.onMediaDataLoaded(KEY_ALT, null, dataGuest) - reset(listener) + fun onUserSwitched_addsNewUserControls() = + testScope.runTest { + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) + val guestLoadedStatesModel = listOf(MediaDataLoadingModel.Loaded(dataGuest.instanceId)) + val mainLoadedStatesModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) - // and we switch to guest user - setUser(USER_GUEST) + // GIVEN that we had some media for both users + mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) + mediaDataFilter.onMediaDataLoaded(KEY_ALT, null, dataGuest) - // THEN we should add back the guest user media - verify(listener).onMediaDataLoaded(eq(dataGuest.instanceId), eq(true), eq(0), eq(false)) + // and we switch to guest user + setUser(USER_GUEST) - // but not the main user's - verify(listener, never()) - .onMediaDataLoaded(eq(dataMain.instanceId), anyBoolean(), anyInt(), anyBoolean()) - } + assertThat(mediaDataLoadedStates).isEqualTo(guestLoadedStatesModel) + assertThat(mediaDataLoadedStates).isNotEqualTo(mainLoadedStatesModel) + } @Test - fun testOnProfileChanged_profileUnavailable_loadControls() { - // GIVEN that we had some media for both profiles - mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) - mediaDataFilter.onMediaDataLoaded(KEY_ALT, null, dataPrivateProfile) - reset(listener) + fun onProfileChanged_profileUnavailable_updateStates() = + testScope.runTest { + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) - // and we change profile status - setPrivateProfileUnavailable() + // GIVEN that we had some media for both profiles + mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) + mediaDataFilter.onMediaDataLoaded(KEY_ALT, null, dataPrivateProfile) - // THEN we should add the private profile media - verify(listener).onMediaDataRemoved(eq(dataPrivateProfile.instanceId)) - } + // and we change profile status + setPrivateProfileUnavailable() + + val mediaLoadedStatesModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) + // THEN we should remove the private profile media + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) + } @Test fun hasAnyMedia_mediaSet_returnsTrue() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = dataMain) assertThat(hasAnyMedia(selectedUserEntries)).isTrue() @@ -255,7 +276,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun hasAnyMedia_recommendationSet_returnsFalse() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) assertThat(hasAnyMedia(selectedUserEntries)).isFalse() @@ -264,8 +285,8 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun hasAnyMediaOrRecommendation_mediaSet_returnsTrue() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = dataMain) assertThat(hasAnyMediaOrRecommendation(selectedUserEntries, smartspaceMediaData)) @@ -275,8 +296,8 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun hasAnyMediaOrRecommendation_recommendationSet_returnsTrue() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) assertThat(hasAnyMediaOrRecommendation(selectedUserEntries, smartspaceMediaData)) @@ -286,7 +307,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun hasActiveMedia_inactiveMediaSet_returnsFalse() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val data = dataMain.copy(active = false) mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data) @@ -297,7 +318,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun hasActiveMedia_activeMediaSet_returnsTrue() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) val data = dataMain.copy(active = true) mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data) @@ -307,9 +328,9 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun hasActiveMediaOrRecommendation_inactiveMediaSet_returnsFalse() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) val data = dataMain.copy(active = false) mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data) @@ -326,9 +347,9 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun hasActiveMediaOrRecommendation_activeMediaSet_returnsTrue() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) val data = dataMain.copy(active = true) mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data) @@ -345,9 +366,9 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun hasActiveMediaOrRecommendation_inactiveRecommendationSet_returnsFalse() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) whenever(smartspaceData.isActive).thenReturn(false) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) @@ -364,9 +385,9 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun hasActiveMediaOrRecommendation_invalidRecommendationSet_returnsFalse() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) whenever(smartspaceData.isValid()).thenReturn(false) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) @@ -383,9 +404,9 @@ class MediaDataFilterImplTest : SysuiTestCase() { @Test fun hasActiveMediaOrRecommendation_activeAndValidRecommendationSet_returnsTrue() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) whenever(smartspaceData.isActive).thenReturn(true) whenever(smartspaceData.isValid()).thenReturn(true) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) @@ -401,10 +422,10 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testHasAnyMediaOrRecommendation_onlyCurrentUser() = + fun hasAnyMediaOrRecommendation_onlyCurrentUser() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) assertThat(hasAnyMediaOrRecommendation(selectedUserEntries, smartspaceMediaData)) .isFalse() @@ -415,11 +436,11 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testHasActiveMediaOrRecommendation_onlyCurrentUser() = + fun hasActiveMediaOrRecommendation_onlyCurrentUser() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -443,10 +464,10 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnNotificationRemoved_doesNotHaveMedia() = + fun onNotificationRemoved_doesNotHaveMedia() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = dataMain) mediaDataFilter.onMediaDataRemoved(KEY) @@ -456,7 +477,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnSwipeToDismiss_setsTimedOut() { + fun onSwipeToDismiss_setsTimedOut() { mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain) mediaDataFilter.onSwipeToDismiss() @@ -464,15 +485,19 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnSmartspaceMediaDataLoaded_noMedia_activeValidRec_prioritizesSmartspace() = + fun onSmartspaceMediaDataLoaded_noMedia_activeValidRec_prioritizesSmartspace() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) + val recommendationsLoadingModel = + SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY, isPrioritized = true) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(true)) + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -487,18 +512,19 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnSmartspaceMediaDataLoaded_noMedia_inactiveRec_showsNothing() = + fun onSmartspaceMediaDataLoaded_noMedia_inactiveRec_showsNothing() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) whenever(smartspaceData.isActive).thenReturn(false) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - verify(listener, never()).onMediaDataLoaded(any(), anyBoolean(), anyInt(), anyBoolean()) - verify(listener, never()).onSmartspaceMediaDataLoaded(any(), anyBoolean()) + assertThat(recommendationsLoadingState).isEqualTo(SmartspaceMediaLoadingModel.Unknown) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -513,17 +539,21 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnSmartspaceMediaDataLoaded_noRecentMedia_activeValidRec_prioritizesSmartspace() = + fun onSmartspaceMediaDataLoaded_noRecentMedia_activeValidRec_prioritizesSmartspace() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) + val recommendationsLoadingModel = + SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY, isPrioritized = true) val dataOld = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) mediaDataFilter.onMediaDataLoaded(KEY, null, dataOld) clock.advanceTime(MediaDataFilterImpl.SMARTSPACE_MAX_AGE + 100) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(true)) + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -538,11 +568,13 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnSmartspaceMediaDataLoaded_noRecentMedia_inactiveRec_showsNothing() = + fun onSmartspaceMediaDataLoaded_noRecentMedia_inactiveRec_showsNothing() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) whenever(smartspaceData.isActive).thenReturn(false) val dataOld = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) @@ -550,7 +582,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { clock.advanceTime(MediaDataFilterImpl.SMARTSPACE_MAX_AGE + 100) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - verify(listener, never()).onSmartspaceMediaDataLoaded(any(), anyBoolean()) + assertThat(recommendationsLoadingState).isEqualTo(SmartspaceMediaLoadingModel.Unknown) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -565,27 +597,29 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnSmartspaceMediaDataLoaded_hasRecentMedia_inactiveRec_showsNothing() = + fun onSmartspaceMediaDataLoaded_hasRecentMedia_inactiveRec_showsNothing() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) whenever(smartspaceData.isActive).thenReturn(false) // WHEN we have media that was recently played, but not currently active val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) + val mediaLoadedStatesModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - verify(listener) - .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false)) - reset(listener) + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) + // AND we get a smartspace signal mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - // THEN we should tell listeners to treat the media as not active instead - verify(listener, never()).onMediaDataLoaded(any(), anyBoolean(), anyInt(), anyBoolean()) - verify(listener, never()).onSmartspaceMediaDataLoaded(any(), anyBoolean()) + // THEN we should treat the media as not active instead + assertThat(recommendationsLoadingState).isEqualTo(SmartspaceMediaLoadingModel.Unknown) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -600,27 +634,28 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnSmartspaceMediaDataLoaded_hasRecentMedia_activeInvalidRec_usesMedia() = + fun onSmartspaceMediaDataLoaded_hasRecentMedia_activeInvalidRec_usesMedia() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) whenever(smartspaceData.isValid()).thenReturn(false) // WHEN we have media that was recently played, but not currently active val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) + val mediaLoadedStatesModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - verify(listener) - .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false)) + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) // AND we get a smartspace signal runCurrent() mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - // THEN we should tell listeners to treat the media as active instead - val dataCurrentAndActive = dataCurrent.copy(active = true) - verify(listener) - .onMediaDataLoaded(eq(dataCurrentAndActive.instanceId), eq(true), eq(100), eq(true)) + // THEN we should treat the media as active instead + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -630,31 +665,35 @@ class MediaDataFilterImplTest : SysuiTestCase() { ) .isTrue() // Smartspace update shouldn't be propagated for the empty rec list. - verify(listener, never()).onSmartspaceMediaDataLoaded(any(), anyBoolean()) + assertThat(recommendationsLoadingState).isEqualTo(SmartspaceMediaLoadingModel.Unknown) verify(logger, never()).logRecommendationAdded(any(), any()) verify(logger).logRecommendationActivated(eq(APP_UID), eq(PACKAGE), eq(INSTANCE_ID)) } @Test - fun testOnSmartspaceMediaDataLoaded_hasRecentMedia_activeValidRec_usesBoth() = + fun onSmartspaceMediaDataLoaded_hasRecentMedia_activeValidRec_usesBoth() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) // WHEN we have media that was recently played, but not currently active val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) + val mediaDataLoadingModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) + val recommendationsLoadingModel = SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY) + mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - verify(listener) - .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false)) + + assertThat(mediaDataLoadedStates).isEqualTo(mediaDataLoadingModel) // AND we get a smartspace signal runCurrent() mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - // THEN we should tell listeners to treat the media as active instead - val dataCurrentAndActive = dataCurrent.copy(active = true) - verify(listener) - .onMediaDataLoaded(eq(dataCurrentAndActive.instanceId), eq(true), eq(100), eq(true)) + // THEN we should treat the media as active instead + assertThat(mediaDataLoadedStates).isEqualTo(mediaDataLoadingModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -664,22 +703,25 @@ class MediaDataFilterImplTest : SysuiTestCase() { ) .isTrue() // Smartspace update should also be propagated but not prioritized. - verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(false)) + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) verify(logger).logRecommendationAdded(SMARTSPACE_PACKAGE, SMARTSPACE_INSTANCE_ID) verify(logger).logRecommendationActivated(eq(APP_UID), eq(PACKAGE), eq(INSTANCE_ID)) } @Test - fun testOnSmartspaceMediaDataRemoved_usedSmartspace_clearsSmartspace() = + fun onSmartspaceMediaDataRemoved_usedSmartspace_clearsSmartspace() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) + val recommendationsLoadingModel = SmartspaceMediaLoadingModel.Removed(SMARTSPACE_KEY) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY) - verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY) + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -692,26 +734,28 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnSmartspaceMediaDataRemoved_usedMediaAndSmartspace_clearsBoth() = + fun onSmartspaceMediaDataRemoved_usedMediaAndSmartspace_clearsBoth() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) + val recommendationsLoadingModel = SmartspaceMediaLoadingModel.Removed(SMARTSPACE_KEY) + val mediaLoadedStatesModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - verify(listener) - .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false)) + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) runCurrent() mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - val dataCurrentAndActive = dataCurrent.copy(active = true) - verify(listener) - .onMediaDataLoaded(eq(dataCurrentAndActive.instanceId), eq(true), eq(100), eq(true)) + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY) - verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY) + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -724,17 +768,20 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnSmartspaceLoaded_persistentEnabled_isInactive_notifiesListeners() = + fun onSmartspaceLoaded_persistentEnabled_isInactive() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) + val recommendationsLoadingModel = SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY) whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(true) whenever(smartspaceData.isActive).thenReturn(false) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(false)) + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -748,11 +795,16 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnSmartspaceLoaded_persistentEnabled_inactive_hasRecentMedia_staysInactive() = + fun onSmartspaceLoaded_persistentEnabled_inactive_hasRecentMedia_staysInactive() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) + val recommendationsLoadingModel = SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY) + val mediaLoadedStatesModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(true) whenever(smartspaceData.isActive).thenReturn(false) @@ -760,16 +812,14 @@ class MediaDataFilterImplTest : SysuiTestCase() { // If there is media that was recently played but inactive val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - verify(listener) - .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false)) - reset(listener) + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) + // And an inactive recommendation is loaded mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) // Smartspace is loaded but the media stays inactive - verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(false)) - verify(listener, never()).onMediaDataLoaded(any(), anyBoolean(), anyInt(), anyBoolean()) + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -783,7 +833,7 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testOnSwipeToDismiss_persistentEnabled_recommendationSetInactive() { + fun onSwipeToDismiss_persistentEnabled_recommendationSetInactive() { whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(true) val data = @@ -802,16 +852,21 @@ class MediaDataFilterImplTest : SysuiTestCase() { } @Test - fun testSmartspaceLoaded_shouldTriggerResume_doesTrigger() = + fun smartspaceLoaded_shouldTriggerResume_doesTrigger() = testScope.runTest { - val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries) - val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData) - val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId) + val selectedUserEntries by collectLastValue(repository.selectedUserEntries) + val smartspaceMediaData by collectLastValue(repository.smartspaceMediaData) + val reactivatedKey by collectLastValue(repository.reactivatedId) + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) + val recommendationsLoadingModel = SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY) + val mediaLoadedStatesModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) // WHEN we have media that was recently played, but not currently active val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - verify(listener) - .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false)) + + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) // AND we get a smartspace signal with extra to trigger resume runCurrent() @@ -819,10 +874,8 @@ class MediaDataFilterImplTest : SysuiTestCase() { whenever(cardAction.extras).thenReturn(extras) mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) - // THEN we should tell listeners to treat the media as active instead - val dataCurrentAndActive = dataCurrent.copy(active = true) - verify(listener) - .onMediaDataLoaded(eq(dataCurrentAndActive.instanceId), eq(true), eq(100), eq(true)) + // THEN we should treat the media as active instead + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) assertThat( hasActiveMediaOrRecommendation( selectedUserEntries, @@ -831,27 +884,33 @@ class MediaDataFilterImplTest : SysuiTestCase() { ) ) .isTrue() - // And send the smartspace data, but not prioritized - verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(false)) + // And update the smartspace data state, but not prioritized + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) } @Test - fun testSmartspaceLoaded_notShouldTriggerResume_doesNotTrigger() { - // WHEN we have media that was recently played, but not currently active - val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) - mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - verify(listener).onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false)) + fun smartspaceLoaded_notShouldTriggerResume_doesNotTrigger() = + testScope.runTest { + val mediaDataLoadedStates by collectLastValue(repository.mediaDataLoadedStates) + val recommendationsLoadingState by + collectLastValue(repository.recommendationsLoadingState) + val recommendationsLoadingModel = SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY) + val mediaLoadedStatesModel = listOf(MediaDataLoadingModel.Loaded(dataMain.instanceId)) - // AND we get a smartspace signal with extra to not trigger resume - val extras = Bundle().apply { putBoolean(EXTRA_KEY_TRIGGER_RESUME, false) } - whenever(cardAction.extras).thenReturn(extras) - mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) + // WHEN we have media that was recently played, but not currently active + val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime()) + mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent) - // THEN listeners are not updated to show media - verify(listener, never()).onMediaDataLoaded(any(), eq(true), eq(100), eq(true)) - // But the smartspace update is still propagated - verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(false)) - } + assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStatesModel) + + // AND we get a smartspace signal with extra to not trigger resume + val extras = Bundle().apply { putBoolean(EXTRA_KEY_TRIGGER_RESUME, false) } + whenever(cardAction.extras).thenReturn(extras) + mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData) + + // But the smartspace update is still propagated + assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel) + } private fun hasActiveMediaOrRecommendation( entries: Map<InstanceId, MediaData>?, diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt new file mode 100644 index 000000000000..e044eeca8303 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2022 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.mediaprojection.permission + +import android.app.AlertDialog +import android.media.projection.MediaProjectionConfig +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.view.WindowManager +import android.widget.Spinner +import android.widget.TextView +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.flags.FeatureFlagsClassic +import com.android.systemui.flags.Flags +import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger +import com.android.systemui.res.R +import com.android.systemui.statusbar.phone.AlertDialogWithDelegate +import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.util.mockito.mock +import junit.framework.Assert.assertEquals +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.`when` as whenever + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class MediaProjectionPermissionDialogDelegateTest : SysuiTestCase() { + + private lateinit var dialog: AlertDialog + + private val flags = mock<FeatureFlagsClassic>() + private val onStartRecordingClicked = mock<Runnable>() + private val mediaProjectionMetricsLogger = mock<MediaProjectionMetricsLogger>() + + private val mediaProjectionConfig: MediaProjectionConfig = + MediaProjectionConfig.createConfigForDefaultDisplay() + private val appName: String = "testApp" + private val hostUid: Int = 12345 + + private val resIdSingleApp = R.string.screen_share_permission_dialog_option_single_app + private val resIdFullScreen = R.string.screen_share_permission_dialog_option_entire_screen + private val resIdSingleAppDisabled = + R.string.media_projection_entry_app_permission_dialog_single_app_disabled + + @Before + fun setUp() { + whenever(flags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING)).thenReturn(true) + } + + @After + fun teardown() { + if (::dialog.isInitialized) { + dialog.dismiss() + } + } + + @Test + fun showDialog_forceShowPartialScreenShareFalse() { + // Set up dialog with MediaProjectionConfig.createConfigForDefaultDisplay() and + // overrideDisableSingleAppOption = false + val overrideDisableSingleAppOption = false + setUpAndShowDialog(overrideDisableSingleAppOption) + + val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner) + val secondOptionText = + spinner.adapter + .getDropDownView(1, null, spinner) + .findViewById<TextView>(android.R.id.text2) + ?.text + + // check that the first option is full screen and enabled + assertEquals(context.getString(resIdFullScreen), spinner.selectedItem) + + // check that the second option is single app and disabled + assertEquals(context.getString(resIdSingleAppDisabled, appName), secondOptionText) + } + + @Test + fun showDialog_forceShowPartialScreenShareTrue() { + // Set up dialog with MediaProjectionConfig.createConfigForDefaultDisplay() and + // overrideDisableSingleAppOption = true + val overrideDisableSingleAppOption = true + setUpAndShowDialog(overrideDisableSingleAppOption) + + val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner) + val secondOptionText = + spinner.adapter + .getDropDownView(1, null, spinner) + .findViewById<TextView>(android.R.id.text1) + ?.text + + // check that the first option is single app and enabled + assertEquals(context.getString(resIdSingleApp), spinner.selectedItem) + + // check that the second option is full screen and enabled + assertEquals(context.getString(resIdFullScreen), secondOptionText) + } + + private fun setUpAndShowDialog(overrideDisableSingleAppOption: Boolean) { + val delegate = + MediaProjectionPermissionDialogDelegate( + context, + mediaProjectionConfig, + {}, + onStartRecordingClicked, + appName, + overrideDisableSingleAppOption, + hostUid, + mediaProjectionMetricsLogger + ) + + dialog = AlertDialogWithDelegate(context, R.style.Theme_SystemUI_Dialog, delegate) + SystemUIDialog.applyFlags(dialog) + SystemUIDialog.setDialogSize(dialog) + + dialog.window?.addSystemFlags( + WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS + ) + + delegate.onCreate(dialog, savedInstanceState = null) + dialog.show() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java index 0101741a9242..542bfaaa8484 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java @@ -16,6 +16,8 @@ package com.android.systemui.qs; +import static com.android.systemui.Flags.FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS; + import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; @@ -33,6 +35,8 @@ import static org.mockito.Mockito.when; import android.content.res.Configuration; import android.content.res.Resources; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; import android.view.ContextThemeWrapper; @@ -45,13 +49,14 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.testing.UiEventLoggerFake; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; +import com.android.systemui.haptics.qs.QSLongPressEffect; +import com.android.systemui.kosmos.KosmosJavaAdapter; import com.android.systemui.media.controls.ui.view.MediaHost; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.customize.QSCustomizerController; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.res.R; -import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController; import com.android.systemui.util.animation.DisappearParameters; @@ -66,11 +71,14 @@ import java.io.StringWriter; import java.util.Collections; import java.util.List; +import javax.inject.Provider; + @RunWith(AndroidTestingRunner.class) @RunWithLooper @SmallTest public class QSPanelControllerBaseTest extends SysuiTestCase { + private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this); @Mock private QSPanel mQSPanel; @Mock @@ -101,8 +109,8 @@ public class QSPanelControllerBaseTest extends SysuiTestCase { Configuration mConfiguration; @Mock Runnable mHorizontalLayoutListener; - @Mock - VibratorHelper mVibratorHelper; + private TestableLongPressEffectProvider mLongPressEffectProvider = + new TestableLongPressEffectProvider(); private QSPanelControllerBase<QSPanel> mController; @@ -114,7 +122,7 @@ public class QSPanelControllerBaseTest extends SysuiTestCase { DumpManager dumpManager) { super(view, host, qsCustomizerController, true, mediaHost, metricsLogger, uiEventLogger, qsLogger, dumpManager, new ResourcesSplitShadeStateController(), - mVibratorHelper); + mLongPressEffectProvider); } @Override @@ -123,6 +131,17 @@ public class QSPanelControllerBaseTest extends SysuiTestCase { } } + private class TestableLongPressEffectProvider implements Provider<QSLongPressEffect> { + + private int mEffectsProvided = 0; + + @Override + public QSLongPressEffect get() { + mEffectsProvided++; + return mKosmos.getQsLongPressEffect(); + } + } + @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); @@ -421,6 +440,27 @@ public class QSPanelControllerBaseTest extends SysuiTestCase { } @Test + @EnableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS) + public void setTiles_longPressEffectEnabled_nonNullLongPressEffectsAreProvided() { + mLongPressEffectProvider.mEffectsProvided = 0; + when(mQSHost.getTiles()).thenReturn(List.of(mQSTile, mOtherTile)); + mController.setTiles(); + + // There is one non-null effect provided for each tile in the host + assertThat(mLongPressEffectProvider.mEffectsProvided).isEqualTo(2); + } + + @Test + @DisableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS) + public void setTiles_longPressEffectDisabled_noLongPressEffectsAreProvided() { + mLongPressEffectProvider.mEffectsProvided = 0; + when(mQSHost.getTiles()).thenReturn(List.of(mQSTile, mOtherTile)); + mController.setTiles(); + + assertThat(mLongPressEffectProvider.mEffectsProvided).isEqualTo(0); + } + + @Test public void setTiles_differentTiles_extraTileRemoved() { when(mQSHost.getTiles()).thenReturn(List.of(mQSTile, mOtherTile)); mController.setTiles(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt index 916e8ddb6e8a..a60494f87fb4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt @@ -7,19 +7,19 @@ import android.testing.TestableResources import android.view.ContextThemeWrapper import com.android.internal.logging.MetricsLogger import com.android.internal.logging.UiEventLogger -import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager +import com.android.systemui.haptics.qs.QSLongPressEffect import com.android.systemui.media.controls.ui.view.MediaHost import com.android.systemui.media.controls.ui.view.MediaHostState import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.customize.QSCustomizerController import com.android.systemui.qs.logging.QSLogger +import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags import com.android.systemui.settings.brightness.BrightnessController import com.android.systemui.settings.brightness.BrightnessSliderController -import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController import com.android.systemui.tuner.TunerService @@ -36,6 +36,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.reset import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations +import javax.inject.Provider import org.mockito.Mockito.`when` as whenever @SmallTest @@ -62,7 +63,7 @@ class QSPanelControllerTest : SysuiTestCase() { @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager @Mock private lateinit var configuration: Configuration @Mock private lateinit var pagedTileLayout: PagedTileLayout - @Mock private lateinit var vibratorHelper: VibratorHelper + @Mock private lateinit var longPressEffectProvider: Provider<QSLongPressEffect> private val sceneContainerFlags = FakeSceneContainerFlags() @@ -103,7 +104,7 @@ class QSPanelControllerTest : SysuiTestCase() { statusBarKeyguardViewManager, ResourcesSplitShadeStateController(), sceneContainerFlags, - vibratorHelper, + longPressEffectProvider, ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt index 71a9a8b3318f..1eb0a51bcaf6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt @@ -22,15 +22,15 @@ import android.view.ContextThemeWrapper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger import com.android.internal.logging.testing.UiEventLoggerFake -import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager +import com.android.systemui.haptics.qs.QSLongPressEffect import com.android.systemui.media.controls.ui.view.MediaHost import com.android.systemui.media.controls.ui.view.MediaHostState import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.customize.QSCustomizerController import com.android.systemui.qs.logging.QSLogger -import com.android.systemui.statusbar.VibratorHelper +import com.android.systemui.res.R import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController import com.android.systemui.util.leak.RotationUtils import org.junit.After @@ -45,6 +45,7 @@ import org.mockito.Mockito.reset import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations +import javax.inject.Provider import org.mockito.Mockito.`when` as whenever @SmallTest @@ -60,7 +61,7 @@ class QuickQSPanelControllerTest : SysuiTestCase() { @Mock private lateinit var tile: QSTile @Mock private lateinit var tileLayout: TileLayout @Captor private lateinit var captor: ArgumentCaptor<QSPanel.OnConfigurationChangedListener> - @Mock private lateinit var vibratorHelper: VibratorHelper + @Mock private lateinit var longPressEffectProvider: Provider<QSLongPressEffect> private val uiEventLogger = UiEventLoggerFake() private val dumpManager = DumpManager() @@ -92,7 +93,7 @@ class QuickQSPanelControllerTest : SysuiTestCase() { uiEventLogger, qsLogger, dumpManager, - vibratorHelper, + longPressEffectProvider, ) controller.init() @@ -161,7 +162,7 @@ class QuickQSPanelControllerTest : SysuiTestCase() { uiEventLogger: UiEventLoggerFake, qsLogger: QSLogger, dumpManager: DumpManager, - vibratorHelper: VibratorHelper, + longPressEffectProvider: Provider<QSLongPressEffect>, ) : QuickQSPanelController( view, @@ -175,7 +176,7 @@ class QuickQSPanelControllerTest : SysuiTestCase() { qsLogger, dumpManager, ResourcesSplitShadeStateController(), - vibratorHelper, + longPressEffectProvider, ) { private var rotation = RotationUtils.ROTATION_NONE diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt index 2b1ac915f430..512ca5315530 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.qs.tileimpl import android.content.Context import android.graphics.drawable.Drawable -import android.platform.test.annotations.EnableFlags import android.service.quicksettings.Tile import android.testing.AndroidTestingRunner import android.testing.TestableLooper @@ -28,10 +27,12 @@ import android.view.View import android.view.accessibility.AccessibilityNodeInfo import android.widget.TextView import androidx.test.filters.SmallTest -import com.android.systemui.Flags.FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS import com.android.systemui.res.R import com.android.systemui.SysuiTestCase +import com.android.systemui.haptics.qs.QSLongPressEffect +import com.android.systemui.haptics.qs.qsLongPressEffect import com.android.systemui.plugins.qs.QSTile +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test @@ -50,13 +51,14 @@ class QSTileViewImplTest : SysuiTestCase() { private lateinit var tileView: FakeTileView private lateinit var customDrawableView: View private lateinit var chevronView: View + private val kosmos = testKosmos() @Before fun setUp() { MockitoAnnotations.initMocks(this) context.ensureTestableResources() - tileView = FakeTileView(context, false) + tileView = FakeTileView(context, false, kosmos.qsLongPressEffect) customDrawableView = tileView.requireViewById(R.id.customDrawable) chevronView = tileView.requireViewById(R.id.chevron) } @@ -383,7 +385,6 @@ class QSTileViewImplTest : SysuiTestCase() { } @Test - @EnableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS) fun onStateChange_longPressEffectActive_withInvalidDuration_doesNotCreateEffect() { val state = QSTile.State() // A state that handles longPress @@ -393,12 +394,11 @@ class QSTileViewImplTest : SysuiTestCase() { // WHEN the state changes tileView.changeState(state) - // THEN the long-press effect is not created - assertThat(tileView.hasLongPressEffect).isFalse() + // THEN the long-press effect is not initialized + assertThat(tileView.isLongPressEffectInitialized).isFalse() } @Test - @EnableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS) fun onStateChange_longPressEffectActive_withValidDuration_createsEffect() { // GIVEN a test state that handles long-press and a valid long-press effect duration val state = QSTile.State() @@ -406,12 +406,11 @@ class QSTileViewImplTest : SysuiTestCase() { // WHEN the state changes tileView.changeState(state) - // THEN the long-press effect created - assertThat(tileView.hasLongPressEffect).isTrue() + // THEN the long-press effect is initialized + assertThat(tileView.isLongPressEffectInitialized).isTrue() } @Test - @EnableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS) fun onStateChange_fromLongPress_to_noLongPress_unBoundsTile() { // GIVEN a state that no longer handles long-press val state = QSTile.State() @@ -421,11 +420,10 @@ class QSTileViewImplTest : SysuiTestCase() { tileView.changeState(state) // THEN the view binder no longer binds the view to the long-press effect - assertThat(tileView.isLongPressEffectBound).isFalse() + assertThat(tileView.longPressEffectHandle).isNull() } @Test - @EnableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS) fun onStateChange_fromNoLongPress_to_longPress_bindsTile() { // GIVEN that the tile has changed to a state that does not handle long-press val state = QSTile.State() @@ -437,15 +435,53 @@ class QSTileViewImplTest : SysuiTestCase() { tileView.changeState(state) // THEN the view is bounded to the long-press effect - assertThat(tileView.isLongPressEffectBound).isTrue() + assertThat(tileView.longPressEffectHandle).isNotNull() + } + + @Test + fun onStateChange_withoutLongPressEffect_fromLongPress_to_noLongPress_neverBindsEffect() { + // GIVEN a tile where the long-press effect is null + tileView = FakeTileView(context, false, null) + + // GIVEN a state that no longer handles long-press + val state = QSTile.State() + state.handlesLongClick = false + + // WHEN the state changes + tileView.changeState(state) + + // THEN the view binder does not bind the view and no effect is initialized + assertThat(tileView.longPressEffectHandle).isNull() + assertThat(tileView.isLongPressEffectInitialized).isFalse() + } + + @Test + fun onStateChange_withoutLongPressEffect_fromNoLongPress_to_longPress_neverBindsEffect() { + // GIVEN a tile where the long-press effect is null + tileView = FakeTileView(context, false, null) + + // GIVEN that the tile has changed to a state that does not handle long-press + val state = QSTile.State() + state.handlesLongClick = false + tileView.changeState(state) + + // WHEN the state changes back to handling long-press + state.handlesLongClick = true + tileView.changeState(state) + + // THEN the view binder does not bind the view and no effect is initialized + assertThat(tileView.longPressEffectHandle).isNull() + assertThat(tileView.isLongPressEffectInitialized).isFalse() } class FakeTileView( context: Context, - collapsed: Boolean + collapsed: Boolean, + longPressEffect: QSLongPressEffect?, ) : QSTileViewImpl( ContextThemeWrapper(context, R.style.Theme_SystemUI_QuickSettings), - collapsed + collapsed, + longPressEffect, ) { var constantLongPressEffectDuration = 500 diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt index 587da2d5d677..b051df21389e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt @@ -18,11 +18,6 @@ package com.android.systemui.screenshot import android.app.ActivityTaskManager.RootTaskInfo import android.app.IActivityTaskManager -import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME -import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD -import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED -import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN -import android.app.WindowConfiguration.WINDOWING_MODE_PINNED import android.content.ComponentName import android.content.Context import android.graphics.Rect @@ -31,6 +26,12 @@ import android.os.UserManager import android.testing.AndroidTestingRunner import com.android.systemui.SysuiTestCase import com.android.systemui.screenshot.ScreenshotPolicy.DisplayContentInfo +import com.android.systemui.screenshot.policy.ActivityType.Home +import com.android.systemui.screenshot.policy.ActivityType.Undefined +import com.android.systemui.screenshot.policy.WindowingMode.FullScreen +import com.android.systemui.screenshot.policy.WindowingMode.PictureInPicture +import com.android.systemui.screenshot.policy.newChildTask +import com.android.systemui.screenshot.policy.newRootTaskInfo import com.android.systemui.settings.FakeDisplayTracker import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat @@ -58,20 +59,19 @@ class ScreenshotPolicyImplTest : SysuiTestCase() { ), Rect(0, 0, 1080, 2400), UserHandle.of(MANAGED_PROFILE_USER), - 65)) + 65 + ) + ) } @Test fun findPrimaryContent_ignoresPipTask() = runBlocking { - val policy = fakeTasksPolicyImpl( - mContext, - shadeExpanded = false, - tasks = listOf( - pipTask, - fullScreenWorkProfileTask, - launcherTask, - emptyTask) - ) + val policy = + fakeTasksPolicyImpl( + mContext, + shadeExpanded = false, + tasks = listOf(pipTask, fullScreenWorkProfileTask, launcherTask, emptyTask) + ) val info = policy.findPrimaryContent(DISPLAY_ID) assertThat(info).isEqualTo(fullScreenWorkProfileTask.toDisplayContentInfo()) @@ -79,14 +79,12 @@ class ScreenshotPolicyImplTest : SysuiTestCase() { @Test fun findPrimaryContent_shadeExpanded_ignoresTopTask() = runBlocking { - val policy = fakeTasksPolicyImpl( - mContext, - shadeExpanded = true, - tasks = listOf( - fullScreenWorkProfileTask, - launcherTask, - emptyTask) - ) + val policy = + fakeTasksPolicyImpl( + mContext, + shadeExpanded = true, + tasks = listOf(fullScreenWorkProfileTask, launcherTask, emptyTask) + ) val info = policy.findPrimaryContent(DISPLAY_ID) assertThat(info).isEqualTo(policy.systemUiContent) @@ -94,11 +92,7 @@ class ScreenshotPolicyImplTest : SysuiTestCase() { @Test fun findPrimaryContent_emptyTaskList() = runBlocking { - val policy = fakeTasksPolicyImpl( - mContext, - shadeExpanded = false, - tasks = listOf() - ) + val policy = fakeTasksPolicyImpl(mContext, shadeExpanded = false, tasks = listOf()) val info = policy.findPrimaryContent(DISPLAY_ID) assertThat(info).isEqualTo(policy.systemUiContent) @@ -106,14 +100,12 @@ class ScreenshotPolicyImplTest : SysuiTestCase() { @Test fun findPrimaryContent_workProfileNotOnTop() = runBlocking { - val policy = fakeTasksPolicyImpl( - mContext, - shadeExpanded = false, - tasks = listOf( - launcherTask, - fullScreenWorkProfileTask, - emptyTask) - ) + val policy = + fakeTasksPolicyImpl( + mContext, + shadeExpanded = false, + tasks = listOf(launcherTask, fullScreenWorkProfileTask, emptyTask) + ) val info = policy.findPrimaryContent(DISPLAY_ID) assertThat(info).isEqualTo(launcherTask.toDisplayContentInfo()) @@ -129,102 +121,80 @@ class ScreenshotPolicyImplTest : SysuiTestCase() { val dispatcher = Dispatchers.Unconfined val displayTracker = FakeDisplayTracker(context) - return object : ScreenshotPolicyImpl(context, userManager, atmService, dispatcher, - displayTracker) { + return object : + ScreenshotPolicyImpl(context, userManager, atmService, dispatcher, displayTracker) { override suspend fun isManagedProfile(userId: Int) = (userId == MANAGED_PROFILE_USER) override suspend fun getAllRootTaskInfosOnDisplay(displayId: Int) = tasks override suspend fun isNotificationShadeExpanded() = shadeExpanded } } - private val pipTask = RootTaskInfo().apply { - configuration.windowConfiguration.apply { - windowingMode = WINDOWING_MODE_PINNED - setBounds(Rect(628, 1885, 1038, 2295)) - activityType = ACTIVITY_TYPE_STANDARD + private val pipTask = + newRootTaskInfo( + taskId = 66, + userId = PRIMARY_USER, + displayId = DISPLAY_ID, + bounds = Rect(628, 1885, 1038, 2295), + windowingMode = PictureInPicture, + topActivity = ComponentName.unflattenFromString(YOUTUBE_PIP_ACTIVITY), + ) { + listOf(newChildTask(taskId = 66, userId = 0, name = YOUTUBE_HOME_ACTIVITY)) } - displayId = DISPLAY_ID - userId = PRIMARY_USER - taskId = 66 - visible = true - isVisible = true - isRunning = true - numActivities = 1 - topActivity = ComponentName( - "com.google.android.youtube", - "com.google.android.apps.youtube.app.watchwhile.WatchWhileActivity" - ) - childTaskIds = intArrayOf(66) - childTaskNames = arrayOf("com.google.android.youtube/" + - "com.google.android.youtube.app.honeycomb.Shell\$HomeActivity") - childTaskUserIds = intArrayOf(0) - childTaskBounds = arrayOf(Rect(628, 1885, 1038, 2295)) - } - private val fullScreenWorkProfileTask = RootTaskInfo().apply { - configuration.windowConfiguration.apply { - windowingMode = WINDOWING_MODE_FULLSCREEN - setBounds(Rect(0, 0, 1080, 2400)) - activityType = ACTIVITY_TYPE_STANDARD + private val fullScreenWorkProfileTask = + newRootTaskInfo( + taskId = 65, + userId = MANAGED_PROFILE_USER, + displayId = DISPLAY_ID, + bounds = Rect(0, 0, 1080, 2400), + windowingMode = FullScreen, + topActivity = ComponentName.unflattenFromString(FILES_HOME_ACTIVITY), + ) { + listOf( + newChildTask(taskId = 65, userId = MANAGED_PROFILE_USER, name = FILES_HOME_ACTIVITY) + ) } - displayId = DISPLAY_ID - userId = MANAGED_PROFILE_USER - taskId = 65 - visible = true - isVisible = true - isRunning = true - numActivities = 1 - topActivity = ComponentName( - "com.google.android.apps.nbu.files", - "com.google.android.apps.nbu.files.home.HomeActivity" - ) - childTaskIds = intArrayOf(65) - childTaskNames = arrayOf("com.google.android.apps.nbu.files/" + - "com.google.android.apps.nbu.files.home.HomeActivity") - childTaskUserIds = intArrayOf(MANAGED_PROFILE_USER) - childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400)) - } - - private val launcherTask = RootTaskInfo().apply { - configuration.windowConfiguration.apply { - windowingMode = WINDOWING_MODE_FULLSCREEN - setBounds(Rect(0, 0, 1080, 2400)) - activityType = ACTIVITY_TYPE_HOME + private val launcherTask = + newRootTaskInfo( + taskId = 1, + userId = PRIMARY_USER, + displayId = DISPLAY_ID, + activityType = Home, + windowingMode = FullScreen, + bounds = Rect(0, 0, 1080, 2400), + topActivity = ComponentName.unflattenFromString(LAUNCHER_ACTIVITY), + ) { + listOf(newChildTask(taskId = 1, userId = 0, name = LAUNCHER_ACTIVITY)) } - displayId = DISPLAY_ID - taskId = 1 - userId = PRIMARY_USER - visible = true - isVisible = true - isRunning = true - numActivities = 1 - topActivity = ComponentName( - "com.google.android.apps.nexuslauncher", - "com.google.android.apps.nexuslauncher.NexusLauncherActivity", - ) - childTaskIds = intArrayOf(1) - childTaskNames = arrayOf("com.google.android.apps.nexuslauncher/" + - "com.google.android.apps.nexuslauncher.NexusLauncherActivity") - childTaskUserIds = intArrayOf(0) - childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400)) - } - private val emptyTask = RootTaskInfo().apply { - configuration.windowConfiguration.apply { - windowingMode = WINDOWING_MODE_FULLSCREEN - setBounds(Rect(0, 0, 1080, 2400)) - activityType = ACTIVITY_TYPE_UNDEFINED + private val emptyTask = + newRootTaskInfo( + taskId = 2, + userId = PRIMARY_USER, + displayId = DISPLAY_ID, + visible = false, + running = false, + numActivities = 0, + activityType = Undefined, + bounds = Rect(0, 0, 1080, 2400), + ) { + listOf( + newChildTask(taskId = 3, name = ""), + newChildTask(taskId = 4, name = ""), + ) } - displayId = DISPLAY_ID - taskId = 2 - userId = PRIMARY_USER - visible = false - isVisible = false - isRunning = false - numActivities = 0 - childTaskIds = intArrayOf(3, 4) - childTaskNames = arrayOf("", "") - childTaskUserIds = intArrayOf(0, 0) - childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400), Rect(0, 2400, 1080, 4800)) - } } + +const val YOUTUBE_HOME_ACTIVITY = + "com.google.android.youtube/" + "com.google.android.youtube.app.honeycomb.Shell\$HomeActivity" + +const val FILES_HOME_ACTIVITY = + "com.google.android.apps.nbu.files/" + "com.google.android.apps.nbu.files.home.HomeActivity" + +const val YOUTUBE_PIP_ACTIVITY = + "com.google.android.youtube/" + + "com.google.android.apps.youtube.app.watchwhile.WatchWhileActivity" + +const val LAUNCHER_ACTIVITY = + "com.google.android.apps.nexuslauncher/" + + "com.google.android.apps.nexuslauncher.NexusLauncherActivity" diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/NewRootTaskInfo.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/NewRootTaskInfo.kt new file mode 100644 index 000000000000..6c35b233ffec --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/NewRootTaskInfo.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.screenshot.policy + +import android.app.ActivityTaskManager.RootTaskInfo +import android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT +import android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM +import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME +import android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS +import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD +import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED +import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM +import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN +import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW +import android.app.WindowConfiguration.WINDOWING_MODE_PINNED +import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED +import android.content.ComponentName +import android.graphics.Rect +import android.os.UserHandle +import android.view.Display +import com.android.systemui.screenshot.data.model.ChildTaskModel +import com.android.systemui.screenshot.policy.ActivityType.Standard +import com.android.systemui.screenshot.policy.WindowingMode.FullScreen + +/** An enum mapping to [android.app.WindowConfiguration] constants via [toInt]. */ +enum class ActivityType(private val intValue: Int) { + Undefined(ACTIVITY_TYPE_UNDEFINED), + Standard(ACTIVITY_TYPE_STANDARD), + Home(ACTIVITY_TYPE_HOME), + Recents(ACTIVITY_TYPE_RECENTS), + Assistant(ACTIVITY_TYPE_ASSISTANT), + Dream(ACTIVITY_TYPE_DREAM); + + /** Returns the [android.app.WindowConfiguration] int constant for the type. */ + fun toInt() = intValue +} + +/** An enum mapping to [android.app.WindowConfiguration] constants via [toInt]. */ +enum class WindowingMode(private val intValue: Int) { + Undefined(WINDOWING_MODE_UNDEFINED), + FullScreen(WINDOWING_MODE_FULLSCREEN), + PictureInPicture(WINDOWING_MODE_PINNED), + Freeform(WINDOWING_MODE_FREEFORM), + MultiWindow(WINDOWING_MODE_MULTI_WINDOW); + + /** Returns the [android.app.WindowConfiguration] int constant for the mode. */ + fun toInt() = intValue +} + +/** + * Constructs a child task for a [RootTaskInfo], copying [RootTaskInfo.bounds] and + * [RootTaskInfo.userId] from the parent by default. + */ +fun RootTaskInfo.newChildTask( + taskId: Int, + name: String, + bounds: Rect? = null, + userId: Int? = null +): ChildTaskModel { + return ChildTaskModel(taskId, name, bounds ?: this.bounds, userId ?: this.userId) +} + +/** Constructs a new [RootTaskInfo]. */ +fun newRootTaskInfo( + taskId: Int, + userId: Int = UserHandle.USER_SYSTEM, + displayId: Int = Display.DEFAULT_DISPLAY, + visible: Boolean = true, + running: Boolean = true, + activityType: ActivityType = Standard, + windowingMode: WindowingMode = FullScreen, + bounds: Rect? = null, + topActivity: ComponentName? = null, + topActivityType: ActivityType = Standard, + numActivities: Int? = null, + childTaskListBuilder: RootTaskInfo.() -> List<ChildTaskModel>, +): RootTaskInfo { + return RootTaskInfo().apply { + configuration.windowConfiguration.apply { + setWindowingMode(windowingMode.toInt()) + setActivityType(activityType.toInt()) + setBounds(bounds) + } + this.bounds = bounds + this.displayId = displayId + this.userId = userId + this.taskId = taskId + this.visible = visible + this.isVisible = visible + this.isRunning = running + this.topActivity = topActivity + this.topActivityType = topActivityType.toInt() + // NOTE: topActivityInfo is _not_ populated by this code + + val childTasks = childTaskListBuilder(this) + this.numActivities = numActivities ?: childTasks.size + + childTaskNames = childTasks.map { it.name }.toTypedArray() + childTaskIds = childTasks.map { it.id }.toIntArray() + childTaskBounds = childTasks.map { it.bounds }.toTypedArray() + childTaskUserIds = childTasks.map { it.userId }.toIntArray() + } +} 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 e7b29d826a0c..0a8e470f8a7c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java @@ -410,6 +410,8 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { mock(DeviceEntryUdfpsInteractor.class); when(deviceEntryUdfpsInteractor.isUdfpsSupported()).thenReturn(MutableStateFlow(false)); + when(mKeyguardTransitionInteractor.isInTransitionToState(any())).thenReturn(emptyFlow()); + mShadeInteractor = new ShadeInteractorImpl( mTestScope.getBackgroundScope(), mKosmos.getDeviceProvisioningInteractor(), @@ -539,7 +541,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { }).when(mView).setOnTouchListener(any(NotificationPanelViewController.TouchHandler.class)); // Dreaming->Lockscreen - when(mKeyguardTransitionInteractor.getDreamingToLockscreenTransition()) + when(mKeyguardTransitionInteractor.transition(any(), any())) .thenReturn(emptyFlow()); when(mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha()) .thenReturn(emptyFlow()); @@ -547,46 +549,28 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { .thenReturn(emptyFlow()); // Occluded->Lockscreen - when(mKeyguardTransitionInteractor.getOccludedToLockscreenTransition()) - .thenReturn(emptyFlow()); when(mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha()) .thenReturn(emptyFlow()); when(mOccludedToLockscreenTransitionViewModel.getLockscreenTranslationY()) .thenReturn(emptyFlow()); // Lockscreen->Dreaming - when(mKeyguardTransitionInteractor.getLockscreenToDreamingTransition()) - .thenReturn(emptyFlow()); when(mLockscreenToDreamingTransitionViewModel.getLockscreenAlpha()) .thenReturn(emptyFlow()); when(mLockscreenToDreamingTransitionViewModel.lockscreenTranslationY(anyInt())) .thenReturn(emptyFlow()); // Gone->Dreaming - when(mKeyguardTransitionInteractor.getGoneToDreamingTransition()) - .thenReturn(emptyFlow()); when(mGoneToDreamingTransitionViewModel.getLockscreenAlpha()) .thenReturn(emptyFlow()); when(mGoneToDreamingTransitionViewModel.lockscreenTranslationY(anyInt())) .thenReturn(emptyFlow()); // Gone->Dreaming lockscreen hosted - when(mKeyguardTransitionInteractor.getGoneToDreamingLockscreenHostedTransition()) - .thenReturn(emptyFlow()); when(mGoneToDreamingLockscreenHostedTransitionViewModel.getLockscreenAlpha()) .thenReturn(emptyFlow()); - // Dreaming lockscreen hosted->Lockscreen - when(mKeyguardTransitionInteractor.getDreamingLockscreenHostedToLockscreenTransition()) - .thenReturn(emptyFlow()); - - // Lockscreen->Dreaming lockscreen hosted - when(mKeyguardTransitionInteractor.getLockscreenToDreamingLockscreenHostedTransition()) - .thenReturn(emptyFlow()); - // Lockscreen->Occluded - when(mKeyguardTransitionInteractor.getLockscreenToOccludedTransition()) - .thenReturn(emptyFlow()); when(mLockscreenToOccludedTransitionViewModel.getLockscreenAlpha()) .thenReturn(emptyFlow()); when(mLockscreenToOccludedTransitionViewModel.getLockscreenTranslationY()) 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 2c0a15dd4e5a..b04503b8e031 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt @@ -43,6 +43,8 @@ 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.model.KeyguardState.DREAMING +import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.res.R import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler @@ -160,7 +162,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { .thenReturn(keyguardBouncerComponent) whenever(keyguardBouncerComponent.securityContainerController) .thenReturn(keyguardSecurityContainerController) - whenever(keyguardTransitionInteractor.lockscreenToDreamingTransition) + whenever(keyguardTransitionInteractor.transition(LOCKSCREEN, DREAMING)) .thenReturn(emptyFlow<TransitionStep>()) featureFlagsClassic = FakeFeatureFlagsClassic() diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt index 98a815cabe83..ba8eb6f4ba36 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt @@ -36,6 +36,8 @@ 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.model.KeyguardState.DREAMING +import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.res.R import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor @@ -149,7 +151,7 @@ class NotificationShadeWindowViewTest : SysuiTestCase() { whenever(statusBarStateController.isDozing).thenReturn(false) mDependency.injectTestDependency(ShadeController::class.java, shadeController) whenever(dockManager.isDocked).thenReturn(false) - whenever(keyguardTransitionInteractor.lockscreenToDreamingTransition) + whenever(keyguardTransitionInteractor.transition(LOCKSCREEN, DREAMING)) .thenReturn(emptyFlow()) val featureFlags = FakeFeatureFlags() diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt index f2abb909e004..7c33648e08a3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt @@ -1,15 +1,14 @@ package com.android.systemui.shade.transition -import android.platform.test.annotations.DisableFlags import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest -import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.dump.DumpManager +import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testScope import com.android.systemui.scene.domain.interactor.SceneInteractor @@ -70,7 +69,7 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun onPanelExpansionChanged_setsFractionEqualToEventFraction() { underTest.onPanelExpansionChanged(DEFAULT_EXPANSION_EVENT) @@ -78,7 +77,7 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() { } @Test - @DisableFlags(Flags.FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun onPanelStateChanged_forwardsToScrimTransitionController() { startLegacyPanelExpansion() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt index de6108632153..d2fc087e44bd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt @@ -19,12 +19,10 @@ package com.android.systemui.statusbar import android.animation.ObjectAnimator -import android.platform.test.annotations.DisableFlags import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.internal.logging.testing.UiEventLoggerFake -import com.android.systemui.Flags.FLAG_SCENE_CONTAINER import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository import com.android.systemui.authentication.shared.model.AuthenticationMethodModel @@ -35,6 +33,7 @@ import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor +import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.jank.interactionJankMonitor @@ -187,7 +186,7 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun testChangeState_logged() { TestableLooper.get(this).runWithLooper { underTest.state = StatusBarState.KEYGUARD @@ -214,7 +213,7 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun testSetState_appliesState_sameStateButDifferentUpcomingState() { underTest.state = StatusBarState.SHADE underTest.setUpcomingState(StatusBarState.KEYGUARD) @@ -227,7 +226,7 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun testSetState_appliesState_differentStateEqualToUpcomingState() { underTest.state = StatusBarState.SHADE underTest.setUpcomingState(StatusBarState.KEYGUARD) @@ -239,7 +238,7 @@ class StatusBarStateControllerImplTest : SysuiTestCase() { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun testSetState_doesNotApplyState_currentAndUpcomingStatesSame() { underTest.state = StatusBarState.SHADE underTest.setUpcomingState(StatusBarState.SHADE) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt index 4eb7daa1eac7..894e02e80997 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt @@ -188,6 +188,9 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() { @Test fun animationsEnabled_isTrue_whenStartingToSleepAndControlScreenOff() = testComponent.runTest { + val animationsEnabled by collectLastValue(underTest.areContainerChangesAnimated) + assertThat(animationsEnabled).isTrue() + powerRepository.updateWakefulness( rawState = WakefulnessState.STARTING_TO_SLEEP, lastWakeReason = WakeSleepReason.POWER_BUTTON, @@ -201,8 +204,6 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() { ) ) whenever(dozeParams.shouldControlScreenOff()).thenReturn(true) - val animationsEnabled by collectLastValue(underTest.areContainerChangesAnimated) - runCurrent() assertThat(animationsEnabled).isTrue() } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt index 35b84939b05d..78b76151e7e6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt @@ -195,6 +195,9 @@ class NotificationIconContainerStatusBarViewModelTest : SysuiTestCase() { @Test fun animationsEnabled_isTrue_whenStartingToSleepAndControlScreenOff() = testComponent.runTest { + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + assertThat(animationsEnabled).isTrue() + powerRepository.updateWakefulness( rawState = WakefulnessState.STARTING_TO_SLEEP, lastWakeReason = WakeSleepReason.POWER_BUTTON, @@ -208,7 +211,7 @@ class NotificationIconContainerStatusBarViewModelTest : SysuiTestCase() { ) ) whenever(dozeParams.shouldControlScreenOff()).thenReturn(true) - val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() assertThat(animationsEnabled).isTrue() } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt index 54108642385f..edab9d9f7fdf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt @@ -50,7 +50,8 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro systemClock, uiEventLogger, userTracker, - avalancheProvider + avalancheProvider, + systemSettings ) } @@ -82,7 +83,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowConversationFromAfterEvent() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH @@ -97,7 +98,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_suppressConversationFromBeforeEvent() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldNotHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_DEFAULT @@ -112,7 +113,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowHighPriorityConversation() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH @@ -125,7 +126,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowCall() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH @@ -138,7 +139,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowCategoryReminder() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH @@ -151,7 +152,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowCategoryEvent() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH @@ -164,7 +165,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowFsi() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { assertFsiNotSuppressed() } } @@ -173,7 +174,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro fun testAvalancheFilter_duringAvalanche_allowColorized() { avalancheProvider.startTime = whenAgo(10) - withFilter(AvalancheSuppressor(avalancheProvider, systemClock)) { + withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) { ensurePeekState() assertShouldHeadsUp(buildEntry { importance = NotificationManager.IMPORTANCE_HIGH diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt index 24f670831193..3b979a7c1386 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt @@ -77,6 +77,8 @@ import com.android.systemui.util.FakeEventLog import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.settings.FakeGlobalSettings +import com.android.systemui.util.settings.FakeSettings +import com.android.systemui.util.settings.SystemSettings import com.android.systemui.util.time.FakeSystemClock import com.android.systemui.utils.leaks.FakeBatteryController import com.android.systemui.utils.leaks.FakeKeyguardStateController @@ -126,6 +128,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() { protected val uiEventLogger = UiEventLoggerFake() protected val userTracker = FakeUserTracker() protected val avalancheProvider: AvalancheProvider = mock() + lateinit var systemSettings: SystemSettings protected abstract val provider: VisualInterruptionDecisionProvider @@ -153,6 +156,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() { deviceProvisionedController.currentUser = userId userTracker.set(listOf(user), /* currentUserIndex = */ 0) + systemSettings = FakeSettings() provider.start() } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt index 620ad9c19bfa..60aaa646fced 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt @@ -30,6 +30,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.EventLog import com.android.systemui.util.settings.GlobalSettings +import com.android.systemui.util.settings.SystemSettings import com.android.systemui.util.time.SystemClock object VisualInterruptionDecisionProviderTestUtil { @@ -51,7 +52,8 @@ object VisualInterruptionDecisionProviderTestUtil { systemClock: SystemClock, uiEventLogger: UiEventLogger, userTracker: UserTracker, - avalancheProvider: AvalancheProvider + avalancheProvider: AvalancheProvider, + systemSettings: SystemSettings ): VisualInterruptionDecisionProvider { return if (VisualInterruptionRefactor.isEnabled) { VisualInterruptionDecisionProviderImpl( @@ -70,7 +72,8 @@ object VisualInterruptionDecisionProviderTestUtil { systemClock, uiEventLogger, userTracker, - avalancheProvider + avalancheProvider, + systemSettings ) } else { NotificationInterruptStateProviderWrapper( diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java index 06a4d0820386..01492f629fe8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java @@ -398,7 +398,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { } @Test - public void testAboveShelfChangedListenerCalledHeadsUpGoingAway() throws Exception { + public void testAboveShelfChangedListenerCalledHeadsUpAnimatingAway() throws Exception { ExpandableNotificationRow row = mNotificationTestHelper.createRow(); AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class); row.setAboveShelfChangedListener(listener); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index abb9432425bc..1e058cac8001 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -20,7 +20,6 @@ import static android.view.View.GONE; import static android.view.WindowInsets.Type.ime; import static com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION; -import static com.android.systemui.Flags.FLAG_SCENE_CONTAINER; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.RUBBER_BAND_FACTOR_NORMAL; @@ -72,6 +71,7 @@ import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.systemui.ExpandHelper; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; +import com.android.systemui.flags.DisableSceneContainer; import com.android.systemui.flags.EnableSceneContainer; import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.flags.FeatureFlags; @@ -227,7 +227,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test + @DisableSceneContainer // TODO(b/312473478): address disabled test public void testUpdateStackHeight_qsExpansionZero() { final float expansionFraction = 0.2f; final float overExpansion = 50f; @@ -726,7 +726,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address lack of QS Header + @DisableSceneContainer // TODO(b/312473478): address lack of QS Header public void testInsideQSHeader_noOffset() { ViewGroup qsHeader = mock(ViewGroup.class); Rect boundsOnScreen = new Rect(0, 0, 1000, 1000); @@ -743,7 +743,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address lack of QS Header + @DisableSceneContainer // TODO(b/312473478): address lack of QS Header public void testInsideQSHeader_Offset() { ViewGroup qsHeader = mock(ViewGroup.class); Rect boundsOnScreen = new Rect(100, 100, 1000, 1000); @@ -763,14 +763,14 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test + @DisableSceneContainer // TODO(b/312473478): address disabled test public void setFractionToShade_recomputesStackHeight() { mStackScroller.setFractionToShade(1f); verify(mNotificationStackSizeCalculator).computeHeight(any(), anyInt(), anyFloat()); } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test + @DisableSceneContainer // TODO(b/312473478): address disabled test public void testSetOwnScrollY_shadeNotClosing_scrollYChanges() { // Given: shade is not closing, scrollY is 0 mAmbientState.setScrollY(0); @@ -869,7 +869,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test + @DisableSceneContainer // TODO(b/312473478): address disabled test public void testSplitShade_hasTopOverscroll() { mTestableResources .addOverride(R.bool.config_use_split_notification_shade, /* value= */ true); @@ -942,7 +942,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test + @DisableSceneContainer // TODO(b/312473478): address disabled test public void testSetMaxDisplayedNotifications_notifiesListeners() { ExpandableView.OnHeightChangedListener listener = mock(ExpandableView.OnHeightChangedListener.class); @@ -957,7 +957,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer public void testDispatchTouchEvent_sceneContainerDisabled() { MotionEvent event = MotionEvent.obtain( SystemClock.uptimeMillis(), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index 2f153d8b7003..25e4728725e9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -181,7 +181,9 @@ import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.concurrency.MessageRouterImpl; import com.android.systemui.util.kotlin.JavaAdapter; import com.android.systemui.util.settings.FakeGlobalSettings; +import com.android.systemui.util.settings.FakeSettings; import com.android.systemui.util.settings.GlobalSettings; +import com.android.systemui.util.settings.SystemSettings; import com.android.systemui.util.time.FakeSystemClock; import com.android.systemui.util.time.SystemClock; import com.android.systemui.volume.VolumeComponent; @@ -325,6 +327,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { private ShadeController mShadeController; private final FakeSystemClock mFakeSystemClock = new FakeSystemClock(); private final FakeGlobalSettings mFakeGlobalSettings = new FakeGlobalSettings(); + private final SystemSettings mSystemSettings = new FakeSettings(); private final FakeEventLog mFakeEventLog = new FakeEventLog(); private final FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock); private final FakeExecutor mUiBgExecutor = new FakeExecutor(mFakeSystemClock); @@ -375,7 +378,8 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mFakeSystemClock, mock(UiEventLogger.class), mUserTracker, - mAvalancheProvider); + mAvalancheProvider, + mSystemSettings); mVisualInterruptionDecisionProvider.start(); mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class)); 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 11a53f753b2a..ed2fb2c0cfc9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java @@ -65,6 +65,7 @@ import android.widget.ImageButton; import android.widget.SeekBar; import androidx.test.core.view.MotionEventBuilder; +import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import com.android.internal.jank.InteractionJankMonitor; @@ -293,7 +294,7 @@ public class VolumeDialogImplTest extends SysuiTestCase { mTestableLooper.processAllMessages(); } - @Test + @Test @FlakyTest(bugId = 329099861) @EnableFlags(FLAG_HAPTIC_VOLUME_SLIDER) public void testVolumeChange_withSliderHaptics_deliversOnProgressChangedHapticsEagerly() { // create haptic plugins on the rows with the flag enabled diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index aabd4e9e79be..c24c86c8cb2a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -174,6 +174,7 @@ import com.android.systemui.user.domain.interactor.SelectedUserInteractor; import com.android.systemui.user.domain.interactor.UserSwitcherInteractor; import com.android.systemui.util.FakeEventLog; import com.android.systemui.util.settings.FakeGlobalSettings; +import com.android.systemui.util.settings.SystemSettings; import com.android.systemui.util.time.SystemClock; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; @@ -554,7 +555,8 @@ public class BubblesTest extends SysuiTestCase { mock(SystemClock.class), mock(UiEventLogger.class), mock(UserTracker.class), - mock(AvalancheProvider.class) + mock(AvalancheProvider.class), + mock(SystemSettings.class) ); interruptionDecisionProvider.start(); diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorKosmos.kt index c06554573bd7..9ce9ff2faf21 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorKosmos.kt @@ -24,6 +24,7 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.testScope import com.android.systemui.power.domain.interactor.powerInteractor +import com.android.systemui.scene.domain.interactor.sceneInteractor val Kosmos.bouncerInteractor by Fixture { BouncerInteractor( @@ -33,5 +34,6 @@ val Kosmos.bouncerInteractor by Fixture { deviceEntryFaceAuthInteractor = deviceEntryFaceAuthInteractor, falsingInteractor = falsingInteractor, powerInteractor = powerInteractor, + sceneInteractor = sceneInteractor, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt index 0f6c7cf13211..c3dad748064d 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt @@ -18,6 +18,7 @@ package com.android.systemui.bouncer.ui.viewmodel +import android.app.admin.devicePolicyManager import android.content.applicationContext import com.android.systemui.authentication.domain.interactor.authenticationInteractor import com.android.systemui.bouncer.domain.interactor.bouncerActionButtonInteractor @@ -31,7 +32,6 @@ import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.user.domain.interactor.selectedUserInteractor import com.android.systemui.user.ui.viewmodel.userSwitcherViewModel -import com.android.systemui.util.mockito.mock import kotlinx.coroutines.ExperimentalCoroutinesApi val Kosmos.bouncerViewModel by Fixture { @@ -44,12 +44,12 @@ val Kosmos.bouncerViewModel by Fixture { simBouncerInteractor = simBouncerInteractor, authenticationInteractor = authenticationInteractor, selectedUserInteractor = selectedUserInteractor, + devicePolicyManager = devicePolicyManager, + bouncerMessageViewModel = bouncerMessageViewModel, flags = composeBouncerFlags, selectedUser = userSwitcherViewModel.selectedUser, users = userSwitcherViewModel.users, userSwitcherMenu = userSwitcherViewModel.menu, actionButton = bouncerActionButtonInteractor.actionButton, - devicePolicyManager = mock(), - bouncerMessageViewModel = bouncerMessageViewModel, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/DisableSceneContainer.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/DisableSceneContainer.kt new file mode 100644 index 000000000000..09f34308bdb9 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/DisableSceneContainer.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.flags + +import android.platform.test.annotations.DisableFlags +import com.android.systemui.Flags.FLAG_SCENE_CONTAINER + +/** + * This includes @[DisableFlags] to work with [SetFlagsRule] to disable all aconfig flags required + * by that feature. + */ +@DisableFlags( + FLAG_SCENE_CONTAINER, +) +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) +annotation class DisableSceneContainer diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/qs/QSLongPressEffectKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/qs/QSLongPressEffectKosmos.kt new file mode 100644 index 000000000000..636d509663a2 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/qs/QSLongPressEffectKosmos.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.haptics.qs + +import com.android.systemui.haptics.vibratorHelper +import com.android.systemui.keyguard.domain.interactor.keyguardInteractor +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testScope + +val Kosmos.qsLongPressEffect by + Kosmos.Fixture { QSLongPressEffect(vibratorHelper, keyguardInteractor, testScope) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt index 185deda950c6..6cc1e8eba73d 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt @@ -20,13 +20,11 @@ import com.android.systemui.keyguard.data.repository.keyguardRepository import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope -import com.android.systemui.kosmos.testDispatcher val Kosmos.keyguardTransitionInteractor: KeyguardTransitionInteractor by Kosmos.Fixture { KeyguardTransitionInteractor( scope = applicationCoroutineScope, - mainDispatcher = testDispatcher, repository = keyguardTransitionRepository, keyguardRepository = keyguardRepository, fromLockscreenTransitionInteractor = { fromLockscreenTransitionInteractor }, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt index f7de5a4c20c7..1a05d21cc30a 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowKosmos.kt @@ -22,14 +22,10 @@ import com.android.keyguard.logging.keyguardTransitionAnimationLogger import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture -import com.android.systemui.kosmos.applicationCoroutineScope -import com.android.systemui.kosmos.testDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi val Kosmos.keyguardTransitionAnimationFlow by Fixture { KeyguardTransitionAnimationFlow( - scope = applicationCoroutineScope, - mainDispatcher = testDispatcher, transitionInteractor = keyguardTransitionInteractor, logger = keyguardTransitionAnimationLogger, ) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt index a46d35842cf3..fdc3e0a22627 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt @@ -33,6 +33,7 @@ import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.globalactions.domain.interactor.globalActionsInteractor +import com.android.systemui.haptics.qs.qsLongPressEffect import com.android.systemui.jank.interactionJankMonitor import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository @@ -110,6 +111,7 @@ class KosmosJavaAdapter( kosmos.sharedNotificationContainerInteractor } val brightnessMirrorShowingInteractor by lazy { kosmos.brightnessMirrorShowingInteractor } + val qsLongPressEffect by lazy { kosmos.qsLongPressEffect } init { kosmos.applicationContext = testCase.context diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt index 165c9429c917..dc1b9feea88f 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt @@ -26,7 +26,7 @@ import kotlinx.coroutines.flow.MutableStateFlow val Kosmos.headsUpNotificationRepository by Fixture { FakeHeadsUpNotificationRepository() } class FakeHeadsUpNotificationRepository : HeadsUpRepository { - override val headsUpAnimatingAway: MutableStateFlow<Boolean> = MutableStateFlow(false) + override val isHeadsUpAnimatingAway: MutableStateFlow<Boolean> = MutableStateFlow(false) override val topHeadsUpRow: Flow<HeadsUpRowRepository?> = MutableStateFlow(null) override val activeHeadsUpRows: MutableStateFlow<Set<HeadsUpRowRepository>> = MutableStateFlow(emptySet()) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/truth/TruthUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/truth/TruthUtils.kt new file mode 100644 index 000000000000..64fed689d7a9 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/truth/TruthUtils.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.truth + +import com.google.common.truth.MapSubject +import com.google.common.truth.Ordered + +fun MapSubject.containsEntriesExactly(entry: Pair<*, *>, vararg entries: Pair<*, *>): Ordered = + containsExactly( + entry.first, + entry.second, + *entries + .asSequence() + .flatMap { (key, value) -> sequenceOf(key, value) } + .toList() + .toTypedArray() + ) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/VolumePanelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/VolumePanelKosmos.kt index d3410737a432..348a02e1da04 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/VolumePanelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/VolumePanelKosmos.kt @@ -24,6 +24,7 @@ import com.android.systemui.util.mockito.mock import com.android.systemui.volume.panel.dagger.factory.KosmosVolumePanelComponentFactory import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria import com.android.systemui.volume.panel.domain.TestComponentAvailabilityCriteria +import com.android.systemui.volume.panel.domain.VolumePanelStartable import com.android.systemui.volume.panel.domain.interactor.ComponentsInteractor import com.android.systemui.volume.panel.domain.interactor.ComponentsInteractorImpl import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey @@ -44,6 +45,8 @@ val Kosmos.componentsFactory: ComponentsFactory by var Kosmos.componentsLayoutManager: ComponentsLayoutManager by Kosmos.Fixture() var Kosmos.enabledComponents: Collection<VolumePanelComponentKey> by Kosmos.Fixture { componentByKey.keys } +var Kosmos.volumePanelStartables: Set<VolumePanelStartable> by + Kosmos.Fixture { emptySet<VolumePanelStartable>() } val Kosmos.unavailableCriteria: Provider<ComponentAvailabilityCriteria> by Kosmos.Fixture { Provider { TestComponentAvailabilityCriteria(false) } } val Kosmos.availableCriteria: Provider<ComponentAvailabilityCriteria> by diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt index 49041ed0d652..e5f5d4e389f1 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt @@ -22,10 +22,12 @@ import com.android.systemui.volume.panel.componentsFactory import com.android.systemui.volume.panel.componentsInteractor import com.android.systemui.volume.panel.componentsLayoutManager import com.android.systemui.volume.panel.dagger.VolumePanelComponent +import com.android.systemui.volume.panel.domain.VolumePanelStartable import com.android.systemui.volume.panel.domain.interactor.ComponentsInteractor import com.android.systemui.volume.panel.ui.composable.ComponentsFactory import com.android.systemui.volume.panel.ui.layout.ComponentsLayoutManager import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel +import com.android.systemui.volume.panel.volumePanelStartables import kotlinx.coroutines.CoroutineScope class KosmosVolumePanelComponentFactory(private val kosmos: Kosmos) : VolumePanelComponentFactory { @@ -41,5 +43,8 @@ class KosmosVolumePanelComponentFactory(private val kosmos: Kosmos) : VolumePane override fun componentsLayoutManager(): ComponentsLayoutManager = kosmos.componentsLayoutManager + + override fun volumePanelStartables(): Set<VolumePanelStartable> = + kosmos.volumePanelStartables } } diff --git a/packages/overlays/NoCutoutOverlay/res/values-ne/strings.xml b/packages/overlays/NoCutoutOverlay/res/values-ne/strings.xml index ff920b290dbb..97559b4feda8 100644 --- a/packages/overlays/NoCutoutOverlay/res/values-ne/strings.xml +++ b/packages/overlays/NoCutoutOverlay/res/values-ne/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay" msgid="9031691255599853162">"लुकाइयोस्"</string> + <string name="display_cutout_emulation_overlay" msgid="9031691255599853162">"लुकाउनुहोस्"</string> </resources> diff --git a/services/Android.bp b/services/Android.bp index 623519521a5a..cd974c5f562d 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -324,34 +324,34 @@ non_updatable_exportable_droidstubs { baseline_file: "api/lint-baseline.txt", }, }, - dists: [ - { - targets: ["sdk"], - dir: "apistubs/android/system-server/api", - dest: "android-non-updatable.txt", - }, - { - targets: ["sdk"], - dir: "apistubs/android/system-server/api", - dest: "android-non-updatable-removed.txt", - }, - ], soong_config_variables: { release_hidden_api_exportable_stubs: { dists: [ { + targets: ["sdk"], + dir: "apistubs/android/system-server/api", + dest: "android-non-updatable.txt", tag: ".exportable.api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/system-server/api", + dest: "android-non-updatable-removed.txt", tag: ".exportable.removed-api.txt", }, ], conditions_default: { dists: [ { + targets: ["sdk"], + dir: "apistubs/android/system-server/api", + dest: "android-non-updatable.txt", tag: ".api.txt", }, { + targets: ["sdk"], + dir: "apistubs/android/system-server/api", + dest: "android-non-updatable-removed.txt", tag: ".removed-api.txt", }, ], diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java index 20816a1b22c8..32c7dde7a555 100644 --- a/services/core/java/com/android/server/SystemServiceManager.java +++ b/services/core/java/com/android/server/SystemServiceManager.java @@ -44,6 +44,9 @@ import com.android.server.am.EventLogTags; import com.android.server.pm.ApexManager; import com.android.server.pm.UserManagerInternal; import com.android.server.utils.TimingsTraceAndSlog; +import com.android.tools.r8.keepanno.annotations.KeepTarget; +import com.android.tools.r8.keepanno.annotations.TypePattern; +import com.android.tools.r8.keepanno.annotations.UsesReflection; import dalvik.system.PathClassLoader; @@ -135,7 +138,13 @@ public final class SystemServiceManager implements Dumpable { } /** - * Starts a service by class name. + * Starts a service by class name from the current {@code SYSTEMSERVERCLASSPATH}. + * + * In general, this should only be used for services in the classpath that cannot + * be resolved by {@code services.jar} at build time, e.g., those defined in an apex jar from + * {@code PRODUCT_APEX_SYSTEM_SERVER_JARS} or a downstream jar in + * {@code PRODUCT_SYSTEM_SERVER_JARS}. Otherwise prefer the explicit type variant + * {@link #startService(Class)}. * * @return The service instance. */ @@ -147,7 +156,11 @@ public final class SystemServiceManager implements Dumpable { } /** - * Starts a service by class name and a path that specifies the jar where the service lives. + * Starts a service by class name and standalone jar path where the service lives. + * + * In general, this should only be used for services in {@code STANDALONE_SYSTEMSERVER_JARS}, + * which in turn derives from {@code PRODUCT_STANDALONE_SYSTEM_SERVER_JARS} and + * {@code PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS}. * * @return The service instance. */ @@ -207,6 +220,11 @@ public final class SystemServiceManager implements Dumpable { * @throws RuntimeException if the service fails to start. */ @android.ravenwood.annotation.RavenwoodKeep + @UsesReflection( + @KeepTarget( + instanceOfClassConstantExclusive = SystemService.class, + methodName = "<init>", + methodParameterTypePatterns = {@TypePattern(constant = Context.class)})) public <T extends SystemService> T startService(Class<T> serviceClass) { try { final String name = serviceClass.getName(); diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 603a95c31e5b..1015ad9fe1da 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -880,6 +880,14 @@ public class AccountManagerService packagesToVisibility = Collections.emptyMap(); accountRemovedReceivers = Collections.emptyList(); } + if (notify) { + Integer oldVisibility = + accounts.accountsDb.findAccountVisibility(account, packageName); + if (oldVisibility != null && oldVisibility == newVisibility) { + // Database will not be updated - skip LOGIN_ACCOUNTS_CHANGED broadcast. + notify = false; + } + } if (!updateAccountVisibilityLocked(account, packageName, newVisibility, accounts)) { return false; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index ad15ea90c45c..8022eb37fce7 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -497,6 +497,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -629,6 +631,9 @@ public class ActivityManagerService extends IActivityManager.Stub private static final int MAX_BUGREPORT_TITLE_SIZE = 100; private static final int MAX_BUGREPORT_DESCRIPTION_SIZE = 150; + private static final DateTimeFormatter DROPBOX_TIME_FORMATTER = + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); + OomAdjuster mOomAdjuster; static final String EXTRA_TITLE = "android.intent.extra.TITLE"; @@ -2167,22 +2172,25 @@ public class ActivityManagerService extends IActivityManager.Stub */ static class VolatileDropboxEntryStates { private final Boolean mIsProcessFrozen; + private final ZonedDateTime mTimestamp; - private VolatileDropboxEntryStates(Boolean frozenState) { + private VolatileDropboxEntryStates(Boolean frozenState, ZonedDateTime timestamp) { this.mIsProcessFrozen = frozenState; + this.mTimestamp = timestamp; } - public static VolatileDropboxEntryStates withProcessFrozenState(boolean frozenState) { - return new VolatileDropboxEntryStates(frozenState); - } - - public static VolatileDropboxEntryStates emptyVolatileDropboxEnytyStates() { - return new VolatileDropboxEntryStates(null); + public static VolatileDropboxEntryStates withProcessFrozenStateAndTimestamp( + boolean frozenState, ZonedDateTime timestamp) { + return new VolatileDropboxEntryStates(frozenState, timestamp); } public Boolean isProcessFrozen() { return mIsProcessFrozen; } + + public ZonedDateTime getTimestamp() { + return mTimestamp; + } } static class MemBinder extends Binder { @@ -9678,6 +9686,11 @@ public class ActivityManagerService extends IActivityManager.Stub ? volatileStates.isProcessFrozen() : process.mOptRecord.isFrozen() ).append("\n"); } + if (volatileStates != null && volatileStates.getTimestamp() != null) { + String formattedTime = DROPBOX_TIME_FORMATTER.format( + volatileStates.getTimestamp()); + sb.append("Timestamp: ").append(formattedTime).append("\n"); + } int flags = process.info.flags; final IPackageManager pm = AppGlobals.getPackageManager(); sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n"); diff --git a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java index 0aa1a69334d7..76c59520d4ea 100644 --- a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java +++ b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java @@ -66,7 +66,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.time.Instant; import java.time.ZoneId; -import java.time.format.DateTimeFormatter; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.UUID; import java.util.concurrent.ExecutionException; @@ -79,9 +79,6 @@ import java.util.concurrent.atomic.AtomicLong; * The error state of the process, such as if it's crashing/ANR etc. */ class ProcessErrorStateRecord { - private static final DateTimeFormatter DROPBOX_TIME_FORMATTER = - DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"); - final ProcessRecord mApp; private final ActivityManagerService mService; @@ -355,9 +352,18 @@ class ProcessErrorStateRecord { synchronized (mProcLock) { latencyTracker.waitingOnProcLockEnded(); setNotResponding(true); + + ZonedDateTime timestamp = null; + if (timeoutRecord != null && timeoutRecord.mEndUptimeMillis > 0) { + long millisSinceEndUptimeMs = anrTime - timeoutRecord.mEndUptimeMillis; + timestamp = Instant.now().minusMillis(millisSinceEndUptimeMs) + .atZone(ZoneId.systemDefault()); + } + volatileDropboxEntriyStates = ActivityManagerService.VolatileDropboxEntryStates - .withProcessFrozenState(mApp.mOptRecord.isFrozen()); + .withProcessFrozenStateAndTimestamp( + mApp.mOptRecord.isFrozen(), timestamp); } // Log the ANR to the event log. @@ -450,13 +456,6 @@ class ProcessErrorStateRecord { info.append("ErrorId: ").append(errorId.toString()).append("\n"); } info.append("Frozen: ").append(mApp.mOptRecord.isFrozen()).append("\n"); - if (timeoutRecord != null && timeoutRecord.mEndUptimeMillis > 0) { - long millisSinceEndUptimeMs = anrTime - timeoutRecord.mEndUptimeMillis; - String formattedTime = DROPBOX_TIME_FORMATTER.format( - Instant.now().minusMillis(millisSinceEndUptimeMs) - .atZone(ZoneId.systemDefault())); - info.append("Timestamp: ").append(formattedTime).append("\n"); - } // Retrieve controller with max ANR delay from AnrControllers // Note that we retrieve the controller before dumping stacks because dumping stacks can diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index 3e3ec17eb0e0..1f89ca70ce8d 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -170,6 +170,7 @@ public class SettingsToPropertiesMapper { "pixel_biometrics_face", "pixel_bluetooth", "pixel_connectivity_gps", + "pixel_continuity", "pixel_sensors", "pixel_system_sw_video", "pixel_watch", diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index debd9d0f0c83..be39778372ca 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -1364,6 +1364,9 @@ public class AppOpsService extends IAppOpsService.Stub { @GuardedBy("this") private void packageRemovedLocked(int uid, String packageName) { + mHandler.post(PooledLambda.obtainRunnable(HistoricalRegistry::clearHistory, + mHistoricalRegistry, uid, packageName)); + UidState uidState = mUidStates.get(uid); if (uidState == null) { return; @@ -1398,9 +1401,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } - - mHandler.post(PooledLambda.obtainRunnable(HistoricalRegistry::clearHistory, - mHistoricalRegistry, uid, packageName)); } public void uidRemoved(int uid) { diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java index 16514fa813dc..e6de14bcf9aa 100644 --- a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java +++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java @@ -29,7 +29,6 @@ import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; -import android.util.IndentingPrintWriter; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; @@ -122,7 +121,8 @@ final class IRadioServiceAidlImpl extends IRadioService.Stub { + " without permission " + Manifest.permission.DUMP); return; } - IndentingPrintWriter radioPrintWriter = new IndentingPrintWriter(printWriter); + android.util.IndentingPrintWriter radioPrintWriter = + new android.util.IndentingPrintWriter(printWriter); radioPrintWriter.printf("BroadcastRadioService\n"); radioPrintWriter.increaseIndent(); diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java index ab083429a200..93fb7b2525fb 100644 --- a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java +++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java @@ -26,7 +26,6 @@ import android.hardware.radio.ITunerCallback; import android.hardware.radio.RadioManager; import android.os.Binder; import android.os.RemoteException; -import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Slog; @@ -139,7 +138,7 @@ final class IRadioServiceHidlImpl extends IRadioService.Stub { + " without permission " + Manifest.permission.DUMP); return; } - IndentingPrintWriter radioPw = new IndentingPrintWriter(pw); + android.util.IndentingPrintWriter radioPw = new android.util.IndentingPrintWriter(pw); radioPw.printf("BroadcastRadioService\n"); radioPw.increaseIndent(); diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioLogger.java b/services/core/java/com/android/server/broadcastradio/RadioEventLogger.java index cca351bc0d73..2c8f499c619b 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/RadioLogger.java +++ b/services/core/java/com/android/server/broadcastradio/RadioEventLogger.java @@ -14,31 +14,35 @@ * limitations under the License. */ -package com.android.server.broadcastradio.aidl; +package com.android.server.broadcastradio; import android.text.TextUtils; -import android.util.IndentingPrintWriter; import android.util.LocalLog; import android.util.Log; import com.android.server.utils.Slogf; /** - * Event logger to log and dump events of radio module and tuner session - * for AIDL broadcast radio HAL + * Event logger to log and dump events of broadcast radio service client for HIDL and AIDL + * broadcast HAL. */ -final class RadioLogger { +public final class RadioEventLogger { private final String mTag; private final boolean mDebug; private final LocalLog mEventLogger; - RadioLogger(String tag, int loggerQueueSize) { + public RadioEventLogger(String tag, int loggerQueueSize) { mTag = tag; mDebug = Log.isLoggable(mTag, Log.DEBUG); mEventLogger = new LocalLog(loggerQueueSize); } - void logRadioEvent(String logFormat, Object... args) { + /** + * Log broadcast radio service event + * @param logFormat String format of log message + * @param args Arguments of log message + */ + public void logRadioEvent(String logFormat, Object... args) { String log = TextUtils.formatSimple(logFormat, args); mEventLogger.log(log); if (mDebug) { @@ -46,7 +50,11 @@ final class RadioLogger { } } - void dump(IndentingPrintWriter pw) { + /** + * Dump broadcast radio service event + * @param pw Indenting print writer for dump + */ + public void dump(android.util.IndentingPrintWriter pw) { mEventLogger.dump(pw); } } diff --git a/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java b/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java index b618aa3d65dc..9654a93d2036 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java @@ -22,7 +22,6 @@ import android.hardware.radio.IAnnouncementListener; import android.hardware.radio.ICloseHandle; import android.os.IBinder; import android.os.RemoteException; -import android.util.IndentingPrintWriter; import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -94,7 +93,7 @@ public final class AnnouncementAggregator extends ICloseHandle.Stub { if (mCloseHandle != null) mCloseHandle.close(); } - public void dumpInfo(IndentingPrintWriter pw) { + public void dumpInfo(android.util.IndentingPrintWriter pw) { pw.printf("ModuleWatcher:\n"); pw.increaseIndent(); @@ -192,7 +191,8 @@ public final class AnnouncementAggregator extends ICloseHandle.Stub { @Override protected void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { - IndentingPrintWriter announcementPrintWriter = new IndentingPrintWriter(printWriter); + android.util.IndentingPrintWriter announcementPrintWriter = + new android.util.IndentingPrintWriter(printWriter); announcementPrintWriter.printf("AnnouncementAggregator\n"); announcementPrintWriter.increaseIndent(); diff --git a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java index 086f3aa8ad65..1c421614599d 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java @@ -29,7 +29,6 @@ import android.os.IServiceCallback; import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; -import android.util.IndentingPrintWriter; import android.util.Log; import android.util.SparseArray; @@ -261,7 +260,7 @@ public final class BroadcastRadioServiceImpl { * * @param pw The file to which {@link BroadcastRadioServiceImpl} state is dumped. */ - public void dumpInfo(IndentingPrintWriter pw) { + public void dumpInfo(android.util.IndentingPrintWriter pw) { synchronized (mLock) { pw.printf("Next module id available: %d\n", mNextModuleId); pw.printf("ServiceName to module id map:\n"); diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java index cd865105c48e..0cac35641ed0 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java @@ -38,10 +38,10 @@ import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArraySet; -import android.util.IndentingPrintWriter; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.broadcastradio.RadioEventLogger; import com.android.server.broadcastradio.RadioServiceUserController; import com.android.server.utils.Slogf; @@ -59,7 +59,7 @@ final class RadioModule { private final Object mLock = new Object(); private final Handler mHandler; - private final RadioLogger mLogger; + private final RadioEventLogger mLogger; private final RadioManager.ModuleProperties mProperties; /** @@ -197,7 +197,7 @@ final class RadioModule { mProperties = Objects.requireNonNull(properties, "properties cannot be null"); mService = Objects.requireNonNull(service, "service cannot be null"); mHandler = new Handler(Looper.getMainLooper()); - mLogger = new RadioLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE); + mLogger = new RadioEventLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE); } @Nullable @@ -524,7 +524,7 @@ final class RadioModule { return BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length); } - void dumpInfo(IndentingPrintWriter pw) { + void dumpInfo(android.util.IndentingPrintWriter pw) { pw.printf("RadioModule\n"); pw.increaseIndent(); diff --git a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java index 4ed36ec9878c..925f149b12cf 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java @@ -29,9 +29,9 @@ import android.os.Binder; import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.IndentingPrintWriter; import com.android.internal.annotations.GuardedBy; +import com.android.server.broadcastradio.RadioEventLogger; import com.android.server.broadcastradio.RadioServiceUserController; import com.android.server.utils.Slogf; @@ -45,7 +45,7 @@ final class TunerSession extends ITuner.Stub { private final Object mLock = new Object(); - private final RadioLogger mLogger; + private final RadioEventLogger mLogger; private final RadioModule mModule; final int mUserId; final android.hardware.radio.ITunerCallback mCallback; @@ -70,7 +70,7 @@ final class TunerSession extends ITuner.Stub { mUserId = Binder.getCallingUserHandle().getIdentifier(); mCallback = Objects.requireNonNull(callback, "callback cannot be null"); mUid = Binder.getCallingUid(); - mLogger = new RadioLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE); + mLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE); } @Override @@ -434,7 +434,7 @@ final class TunerSession extends ITuner.Stub { } } - void dumpInfo(IndentingPrintWriter pw) { + void dumpInfo(android.util.IndentingPrintWriter pw) { pw.printf("TunerSession\n"); pw.increaseIndent(); diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java index 3198842c1ff3..e1650c227266 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java @@ -30,7 +30,6 @@ import android.hidl.manager.V1_0.IServiceNotification; import android.os.IHwBinder.DeathRecipient; import android.os.RemoteException; import android.util.ArrayMap; -import android.util.IndentingPrintWriter; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -222,7 +221,7 @@ public final class BroadcastRadioService { * * @param pw The file to which BroadcastRadioService state is dumped. */ - public void dumpInfo(IndentingPrintWriter pw) { + public void dumpInfo(android.util.IndentingPrintWriter pw) { synchronized (mLock) { pw.printf("Next module id available: %d\n", mNextModuleId); pw.printf("ServiceName to module id map:\n"); diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioEventLogger.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioEventLogger.java deleted file mode 100644 index b8d12280ac05..000000000000 --- a/services/core/java/com/android/server/broadcastradio/hal2/RadioEventLogger.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (C) 2022 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.broadcastradio.hal2; - -import android.util.IndentingPrintWriter; -import android.util.LocalLog; -import android.util.Log; - -import com.android.server.utils.Slogf; - -final class RadioEventLogger { - private final String mTag; - private final LocalLog mEventLogger; - - RadioEventLogger(String tag, int loggerQueueSize) { - mTag = tag; - mEventLogger = new LocalLog(loggerQueueSize); - } - - @SuppressWarnings("AnnotateFormatMethod") - void logRadioEvent(String logFormat, Object... args) { - String log = String.format(logFormat, args); - mEventLogger.log(log); - if (Log.isLoggable(mTag, Log.DEBUG)) { - Slogf.d(mTag, log); - } - } - - void dump(IndentingPrintWriter pw) { - mEventLogger.dump(pw); - } -} diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java index 0e11df8282a7..7269f24fc4b1 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java @@ -40,11 +40,11 @@ import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArraySet; -import android.util.IndentingPrintWriter; import android.util.MutableInt; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.broadcastradio.RadioEventLogger; import com.android.server.broadcastradio.RadioServiceUserController; import com.android.server.utils.Slogf; @@ -453,7 +453,7 @@ final class RadioModule { return BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length); } - void dumpInfo(IndentingPrintWriter pw) { + void dumpInfo(android.util.IndentingPrintWriter pw) { pw.printf("RadioModule\n"); pw.increaseIndent(); pw.printf("BroadcastRadioService: %s\n", mService); diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java index 6d435e38117f..b1b5d3488a5b 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java @@ -31,11 +31,11 @@ import android.os.Binder; import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.IndentingPrintWriter; import android.util.MutableBoolean; import android.util.MutableInt; import com.android.internal.annotations.GuardedBy; +import com.android.server.broadcastradio.RadioEventLogger; import com.android.server.broadcastradio.RadioServiceUserController; import com.android.server.utils.Slogf; @@ -389,7 +389,7 @@ final class TunerSession extends ITuner.Stub { } } - void dumpInfo(IndentingPrintWriter pw) { + void dumpInfo(android.util.IndentingPrintWriter pw) { pw.printf("TunerSession\n"); pw.increaseIndent(); pw.printf("HIDL HAL Session: %s\n", mHwSession); diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java index f3836794c32e..47f73f1b819a 100644 --- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java +++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java @@ -167,7 +167,8 @@ public final class FontManagerService extends IFontManager.Stub { public void onBootPhase(int phase) { final int latestFontLoadBootPhase = (Flags.completeFontLoadInSystemServicesReady()) - ? SystemService.PHASE_SYSTEM_SERVICES_READY + // Complete font load in the phase before PHASE_SYSTEM_SERVICES_READY + ? SystemService.PHASE_LOCK_SETTINGS_READY : SystemService.PHASE_ACTIVITY_MANAGER_READY; if (phase == latestFontLoadBootPhase) { // Wait for FontManagerService to start since it will be needed after this point. diff --git a/services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java b/services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java new file mode 100644 index 000000000000..7890fe0ed461 --- /dev/null +++ b/services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java @@ -0,0 +1,464 @@ +/* + * 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.inputmethod; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import android.Manifest; +import android.annotation.BinderThread; +import android.annotation.EnforcePermission; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.UserIdInt; +import android.os.Binder; +import android.os.IBinder; +import android.os.ResultReceiver; +import android.os.ShellCallback; +import android.view.MotionEvent; +import android.view.WindowManager; +import android.view.inputmethod.CursorAnchorInfo; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.ImeTracker; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; +import android.view.inputmethod.InputMethodSubtype; +import android.window.ImeOnBackInvokedDispatcher; + +import com.android.internal.inputmethod.DirectBootAwareness; +import com.android.internal.inputmethod.IBooleanListener; +import com.android.internal.inputmethod.IConnectionlessHandwritingCallback; +import com.android.internal.inputmethod.IImeTracker; +import com.android.internal.inputmethod.IInputMethodClient; +import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection; +import com.android.internal.inputmethod.IRemoteInputConnection; +import com.android.internal.inputmethod.InputBindResult; +import com.android.internal.inputmethod.SoftInputShowHideReason; +import com.android.internal.inputmethod.StartInputFlags; +import com.android.internal.inputmethod.StartInputReason; +import com.android.internal.view.IInputMethodManager; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.List; + +/** + * An actual implementation class of {@link IInputMethodManager.Stub} to allow other classes to + * focus on handling IPC callbacks. + */ +final class IInputMethodManagerImpl extends IInputMethodManager.Stub { + + /** + * Tells that the given permission is already verified before the annotated method gets called. + */ + @Retention(SOURCE) + @Target({METHOD}) + @interface PermissionVerified { + String value() default ""; + } + + @BinderThread + interface Callback { + void addClient(IInputMethodClient client, IRemoteInputConnection inputConnection, + int selfReportedDisplayId); + + InputMethodInfo getCurrentInputMethodInfoAsUser(@UserIdInt int userId); + + List<InputMethodInfo> getInputMethodList(@UserIdInt int userId, + @DirectBootAwareness int directBootAwareness); + + List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId); + + List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId, + boolean allowsImplicitlyEnabledSubtypes, @UserIdInt int userId); + + InputMethodSubtype getLastInputMethodSubtype(@UserIdInt int userId); + + boolean showSoftInput(IInputMethodClient client, IBinder windowToken, + @Nullable ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags, + @MotionEvent.ToolType int lastClickToolType, ResultReceiver resultReceiver, + @SoftInputShowHideReason int reason); + + boolean hideSoftInput(IInputMethodClient client, IBinder windowToken, + @Nullable ImeTracker.Token statsToken, @InputMethodManager.HideFlags int flags, + ResultReceiver resultReceiver, @SoftInputShowHideReason int reason); + + @PermissionVerified(Manifest.permission.TEST_INPUT_METHOD) + void hideSoftInputFromServerForTest(); + + void startInputOrWindowGainedFocusAsync( + @StartInputReason int startInputReason, IInputMethodClient client, + IBinder windowToken, @StartInputFlags int startInputFlags, + @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode, int windowFlags, + @Nullable EditorInfo editorInfo, IRemoteInputConnection inputConnection, + IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection, + int unverifiedTargetSdkVersion, @UserIdInt int userId, + @NonNull ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq); + + InputBindResult startInputOrWindowGainedFocus( + @StartInputReason int startInputReason, IInputMethodClient client, + IBinder windowToken, @StartInputFlags int startInputFlags, + @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode, int windowFlags, + @Nullable EditorInfo editorInfo, IRemoteInputConnection inputConnection, + IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection, + int unverifiedTargetSdkVersion, @UserIdInt int userId, + @NonNull ImeOnBackInvokedDispatcher imeDispatcher); + + void showInputMethodPickerFromClient(IInputMethodClient client, int auxiliarySubtypeMode); + + @PermissionVerified(Manifest.permission.WRITE_SECURE_SETTINGS) + void showInputMethodPickerFromSystem(int auxiliarySubtypeMode, int displayId); + + @PermissionVerified(Manifest.permission.TEST_INPUT_METHOD) + boolean isInputMethodPickerShownForTest(); + + InputMethodSubtype getCurrentInputMethodSubtype(@UserIdInt int userId); + + void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes, + @UserIdInt int userId); + + void setExplicitlyEnabledInputMethodSubtypes(String imeId, + @NonNull int[] subtypeHashCodes, @UserIdInt int userId); + + int getInputMethodWindowVisibleHeight(IInputMethodClient client); + + void reportPerceptibleAsync(IBinder windowToken, boolean perceptible); + + @PermissionVerified(Manifest.permission.INTERNAL_SYSTEM_WINDOW) + void removeImeSurface(); + + void removeImeSurfaceFromWindowAsync(IBinder windowToken); + + void startProtoDump(byte[] bytes, int i, String s); + + boolean isImeTraceEnabled(); + + @PermissionVerified(Manifest.permission.CONTROL_UI_TRACING) + void startImeTrace(); + + @PermissionVerified(Manifest.permission.CONTROL_UI_TRACING) + void stopImeTrace(); + + void startStylusHandwriting(IInputMethodClient client); + + void startConnectionlessStylusHandwriting(IInputMethodClient client, @UserIdInt int userId, + @Nullable CursorAnchorInfo cursorAnchorInfo, @Nullable String delegatePackageName, + @Nullable String delegatorPackageName, + @NonNull IConnectionlessHandwritingCallback callback); + + boolean acceptStylusHandwritingDelegation(@NonNull IInputMethodClient client, + @UserIdInt int userId, @NonNull String delegatePackageName, + @NonNull String delegatorPackageName, + @InputMethodManager.HandwritingDelegateFlags int flags); + + void acceptStylusHandwritingDelegationAsync(@NonNull IInputMethodClient client, + @UserIdInt int userId, @NonNull String delegatePackageName, + @NonNull String delegatorPackageName, + @InputMethodManager.HandwritingDelegateFlags int flags, IBooleanListener callback); + + void prepareStylusHandwritingDelegation(@NonNull IInputMethodClient client, + @UserIdInt int userId, @NonNull String delegatePackageName, + @NonNull String delegatorPackageName); + + boolean isStylusHandwritingAvailableAsUser(@UserIdInt int userId, boolean connectionless); + + @PermissionVerified(Manifest.permission.TEST_INPUT_METHOD) + void addVirtualStylusIdForTestSession(IInputMethodClient client); + + @PermissionVerified(Manifest.permission.TEST_INPUT_METHOD) + void setStylusWindowIdleTimeoutForTest(IInputMethodClient client, long timeout); + + IImeTracker getImeTrackerService(); + + void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out, + @Nullable FileDescriptor err, @NonNull String[] args, + @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver, + @NonNull Binder self); + + void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, @Nullable String[] args); + } + + @NonNull + private final Callback mCallback; + + private IInputMethodManagerImpl(@NonNull Callback callback) { + mCallback = callback; + } + + static IInputMethodManagerImpl create(@NonNull Callback callback) { + return new IInputMethodManagerImpl(callback); + } + + @Override + public void addClient(IInputMethodClient client, IRemoteInputConnection inputmethod, + int untrustedDisplayId) { + mCallback.addClient(client, inputmethod, untrustedDisplayId); + } + + @Override + public InputMethodInfo getCurrentInputMethodInfoAsUser(@UserIdInt int userId) { + return mCallback.getCurrentInputMethodInfoAsUser(userId); + } + + @Override + public List<InputMethodInfo> getInputMethodList(@UserIdInt int userId, + int directBootAwareness) { + return mCallback.getInputMethodList(userId, directBootAwareness); + } + + @Override + public List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId) { + return mCallback.getEnabledInputMethodList(userId); + } + + @Override + public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId, + boolean allowsImplicitlyEnabledSubtypes, @UserIdInt int userId) { + return mCallback.getEnabledInputMethodSubtypeList(imiId, allowsImplicitlyEnabledSubtypes, + userId); + } + + @Override + public InputMethodSubtype getLastInputMethodSubtype(@UserIdInt int userId) { + return mCallback.getLastInputMethodSubtype(userId); + } + + @Override + public boolean showSoftInput(IInputMethodClient client, IBinder windowToken, + @NonNull ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags, + @MotionEvent.ToolType int lastClickToolType, ResultReceiver resultReceiver, + @SoftInputShowHideReason int reason) { + return mCallback.showSoftInput(client, windowToken, statsToken, flags, lastClickToolType, + resultReceiver, reason); + } + + @Override + public boolean hideSoftInput(IInputMethodClient client, IBinder windowToken, + @NonNull ImeTracker.Token statsToken, @InputMethodManager.HideFlags int flags, + ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { + return mCallback.hideSoftInput(client, windowToken, statsToken, flags, resultReceiver, + reason); + } + + @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD) + @Override + public void hideSoftInputFromServerForTest() { + super.hideSoftInputFromServerForTest_enforcePermission(); + + mCallback.hideSoftInputFromServerForTest(); + } + + @Override + public InputBindResult startInputOrWindowGainedFocus( + @StartInputReason int startInputReason, IInputMethodClient client, IBinder windowToken, + @StartInputFlags int startInputFlags, + @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode, + int windowFlags, @Nullable EditorInfo editorInfo, + IRemoteInputConnection inputConnection, + IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection, + int unverifiedTargetSdkVersion, @UserIdInt int userId, + @NonNull ImeOnBackInvokedDispatcher imeDispatcher) { + return mCallback.startInputOrWindowGainedFocus( + startInputReason, client, windowToken, startInputFlags, softInputMode, + windowFlags, editorInfo, inputConnection, remoteAccessibilityInputConnection, + unverifiedTargetSdkVersion, userId, imeDispatcher); + } + + @Override + public void startInputOrWindowGainedFocusAsync(@StartInputReason int startInputReason, + IInputMethodClient client, IBinder windowToken, + @StartInputFlags int startInputFlags, + @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode, + int windowFlags, @Nullable EditorInfo editorInfo, + IRemoteInputConnection inputConnection, + IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection, + int unverifiedTargetSdkVersion, @UserIdInt int userId, + @NonNull ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq) { + mCallback.startInputOrWindowGainedFocusAsync( + startInputReason, client, windowToken, startInputFlags, softInputMode, + windowFlags, editorInfo, inputConnection, remoteAccessibilityInputConnection, + unverifiedTargetSdkVersion, userId, imeDispatcher, startInputSeq); + } + + @Override + public void showInputMethodPickerFromClient(IInputMethodClient client, + int auxiliarySubtypeMode) { + mCallback.showInputMethodPickerFromClient(client, auxiliarySubtypeMode); + } + + @EnforcePermission(Manifest.permission.WRITE_SECURE_SETTINGS) + @Override + public void showInputMethodPickerFromSystem(int auxiliarySubtypeMode, int displayId) { + super.showInputMethodPickerFromSystem_enforcePermission(); + + mCallback.showInputMethodPickerFromSystem(auxiliarySubtypeMode, displayId); + + } + + @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD) + @Override + public boolean isInputMethodPickerShownForTest() { + super.isInputMethodPickerShownForTest_enforcePermission(); + + return mCallback.isInputMethodPickerShownForTest(); + } + + @Override + public InputMethodSubtype getCurrentInputMethodSubtype(@UserIdInt int userId) { + return mCallback.getCurrentInputMethodSubtype(userId); + } + + @Override + public void setAdditionalInputMethodSubtypes(String id, InputMethodSubtype[] subtypes, + @UserIdInt int userId) { + mCallback.setAdditionalInputMethodSubtypes(id, subtypes, userId); + } + + @Override + public void setExplicitlyEnabledInputMethodSubtypes(String imeId, int[] subtypeHashCodes, + @UserIdInt int userId) { + mCallback.setExplicitlyEnabledInputMethodSubtypes(imeId, subtypeHashCodes, userId); + } + + @Override + public int getInputMethodWindowVisibleHeight(IInputMethodClient client) { + return mCallback.getInputMethodWindowVisibleHeight(client); + } + + @Override + public void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) { + mCallback.reportPerceptibleAsync(windowToken, perceptible); + } + + @EnforcePermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW) + @Override + public void removeImeSurface() { + super.removeImeSurface_enforcePermission(); + + mCallback.removeImeSurface(); + } + + @Override + public void removeImeSurfaceFromWindowAsync(IBinder windowToken) { + mCallback.removeImeSurfaceFromWindowAsync(windowToken); + } + + @Override + public void startProtoDump(byte[] protoDump, int source, String where) { + mCallback.startProtoDump(protoDump, source, where); + } + + @Override + public boolean isImeTraceEnabled() { + return mCallback.isImeTraceEnabled(); + } + + @EnforcePermission(Manifest.permission.CONTROL_UI_TRACING) + @Override + public void startImeTrace() { + super.startImeTrace_enforcePermission(); + + mCallback.startImeTrace(); + } + + @EnforcePermission(Manifest.permission.CONTROL_UI_TRACING) + @Override + public void stopImeTrace() { + super.stopImeTrace_enforcePermission(); + + mCallback.stopImeTrace(); + } + + @Override + public void startStylusHandwriting(IInputMethodClient client) { + mCallback.startStylusHandwriting(client); + } + + @Override + public void startConnectionlessStylusHandwriting(IInputMethodClient client, + @UserIdInt int userId, CursorAnchorInfo cursorAnchorInfo, + String delegatePackageName, String delegatorPackageName, + IConnectionlessHandwritingCallback callback) { + mCallback.startConnectionlessStylusHandwriting(client, userId, cursorAnchorInfo, + delegatePackageName, delegatorPackageName, callback); + } + + @Override + public void prepareStylusHandwritingDelegation(IInputMethodClient client, @UserIdInt int userId, + String delegatePackageName, String delegatorPackageName) { + mCallback.prepareStylusHandwritingDelegation(client, userId, + delegatePackageName, delegatorPackageName); + } + + @Override + public boolean acceptStylusHandwritingDelegation(IInputMethodClient client, + @UserIdInt int userId, String delegatePackageName, String delegatorPackageName, + @InputMethodManager.HandwritingDelegateFlags int flags) { + return mCallback.acceptStylusHandwritingDelegation(client, userId, + delegatePackageName, delegatorPackageName, flags); + } + + @Override + public void acceptStylusHandwritingDelegationAsync(IInputMethodClient client, + @UserIdInt int userId, String delegatePackageName, String delegatorPackageName, + @InputMethodManager.HandwritingDelegateFlags int flags, + IBooleanListener callback) { + mCallback.acceptStylusHandwritingDelegationAsync(client, userId, + delegatePackageName, delegatorPackageName, flags, callback); + } + + @Override + public boolean isStylusHandwritingAvailableAsUser(@UserIdInt int userId, + boolean connectionless) { + return mCallback.isStylusHandwritingAvailableAsUser(userId, connectionless); + } + + @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD) + @Override + public void addVirtualStylusIdForTestSession(IInputMethodClient client) { + super.addVirtualStylusIdForTestSession_enforcePermission(); + + mCallback.addVirtualStylusIdForTestSession(client); + } + + @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD) + @Override + public void setStylusWindowIdleTimeoutForTest(IInputMethodClient client, long timeout) { + super.setStylusWindowIdleTimeoutForTest_enforcePermission(); + + mCallback.setStylusWindowIdleTimeoutForTest(client, timeout); + } + + @Override + public IImeTracker getImeTrackerService() { + return mCallback.getImeTrackerService(); + } + + @Override + public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out, + @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, + @NonNull ResultReceiver resultReceiver) { + mCallback.onShellCommand(in, out, err, args, callback, resultReceiver, this); + } + + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + mCallback.dump(fd, pw, args); + } +} diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 1d07eee927b2..03a85c40ef31 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -61,7 +61,6 @@ import android.annotation.AnyThread; import android.annotation.BinderThread; import android.annotation.DrawableRes; import android.annotation.DurationMillisLong; -import android.annotation.EnforcePermission; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -172,7 +171,6 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; -import com.android.internal.view.IInputMethodManager; import com.android.server.AccessibilityManagerInternal; import com.android.server.EventLogTags; import com.android.server.LocalServices; @@ -211,8 +209,9 @@ import java.util.function.IntConsumer; /** * This class provides a system service that manages input methods. */ -public final class InputMethodManagerService extends IInputMethodManager.Stub - implements Handler.Callback { +public final class InputMethodManagerService implements IInputMethodManagerImpl.Callback, + ZeroJankProxy.Callback, Handler.Callback { + // Virtual device id for test. private static final Integer VIRTUAL_STYLUS_ID_FOR_TEST = 999999; static final boolean DEBUG = false; @@ -1236,21 +1235,14 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @Override public void onStart() { mService.publishLocalService(); - IInputMethodManager.Stub service; + IInputMethodManagerImpl.Callback service; if (Flags.useZeroJankProxy()) { - service = - new ZeroJankProxy( - mService.mHandler::post, - mService, - () -> { - synchronized (ImfLock.class) { - return mService.isInputShown(); - } - }); + service = new ZeroJankProxy(mService.mHandler::post, mService); } else { service = mService; } - publishBinderService(Context.INPUT_METHOD_SERVICE, service, false /*allowIsolated*/, + publishBinderService(Context.INPUT_METHOD_SERVICE, + IInputMethodManagerImpl.create(service), false /*allowIsolated*/, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO); } @@ -1935,10 +1927,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } @Nullable - ClientState getClientState(IInputMethodClient client) { - synchronized (ImfLock.class) { - return mClientController.getClient(client.asBinder()); - } + @GuardedBy("ImfLock.class") + @Override + public ClientState getClientStateLocked(IInputMethodClient client) { + return mClientController.getClient(client.asBinder()); } // TODO(b/314150112): Move this to ClientController. @@ -2017,7 +2009,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } @GuardedBy("ImfLock.class") - private boolean isInputShown() { + @Override + public boolean isInputShownLocked() { return mVisibilityStateComputer.isInputShown(); } @@ -3133,11 +3126,16 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub public void startConnectionlessStylusHandwriting(IInputMethodClient client, int userId, @Nullable CursorAnchorInfo cursorAnchorInfo, @Nullable String delegatePackageName, @Nullable String delegatorPackageName, - @NonNull IConnectionlessHandwritingCallback callback) throws RemoteException { + @NonNull IConnectionlessHandwritingCallback callback) { synchronized (ImfLock.class) { if (!mBindingController.supportsConnectionlessStylusHandwriting()) { Slog.w(TAG, "Connectionless stylus handwriting mode unsupported by IME."); - callback.onError(CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED); + try { + callback.onError(CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to report CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED", e); + e.rethrowAsRuntimeException(); + } return; } } @@ -3148,7 +3146,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub synchronized (ImfLock.class) { if (!mClientController.verifyClientAndPackageMatch(client, delegatorPackageName)) { Slog.w(TAG, "startConnectionlessStylusHandwriting() fail"); - callback.onError(CONNECTIONLESS_HANDWRITING_ERROR_OTHER); + try { + callback.onError(CONNECTIONLESS_HANDWRITING_ERROR_OTHER); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to report CONNECTIONLESS_HANDWRITING_ERROR_OTHER", e); + e.rethrowAsRuntimeException(); + } throw new IllegalArgumentException("Delegator doesn't match UID"); } } @@ -3172,7 +3175,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub if (!startStylusHandwriting( client, false, immsCallback, cursorAnchorInfo, isForDelegation)) { - callback.onError(CONNECTIONLESS_HANDWRITING_ERROR_OTHER); + try { + callback.onError(CONNECTIONLESS_HANDWRITING_ERROR_OTHER); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to report CONNECTIONLESS_HANDWRITING_ERROR_OTHER", e); + e.rethrowAsRuntimeException(); + } } } @@ -3272,11 +3280,15 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @UserIdInt int userId, @NonNull String delegatePackageName, @NonNull String delegatorPackageName, - @InputMethodManager.HandwritingDelegateFlags int flags, IBooleanListener callback) - throws RemoteException { + @InputMethodManager.HandwritingDelegateFlags int flags, IBooleanListener callback) { boolean result = acceptStylusHandwritingDelegation( client, userId, delegatePackageName, delegatorPackageName, flags); - callback.onResult(result); + try { + callback.onResult(result); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to report result=" + result, e); + e.rethrowAsRuntimeException(); + } } @Override @@ -3367,7 +3379,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") boolean showCurrentInputLocked(IBinder windowToken, @NonNull ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags, - int lastClickToolType, @Nullable ResultReceiver resultReceiver, + @MotionEvent.ToolType int lastClickToolType, @Nullable ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { if (!mVisibilityStateComputer.onImeShowFlags(statsToken, flags)) { return false; @@ -3413,7 +3425,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub "InputMethodManagerService#hideSoftInput"); synchronized (ImfLock.class) { if (!canInteractWithImeLocked(uid, client, "hideSoftInput", statsToken)) { - if (isInputShown()) { + if (isInputShownLocked()) { ImeTracker.forLogging().onFailed( statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED); } else { @@ -3436,10 +3448,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } @Override - @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD) public void hideSoftInputFromServerForTest() { - super.hideSoftInputFromServerForTest_enforcePermission(); - synchronized (ImfLock.class) { hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */, SoftInputShowHideReason.HIDE_SOFT_INPUT); @@ -3472,7 +3482,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // TODO(b/246309664): Clean up IMMS#mImeWindowVis IInputMethodInvoker curMethod = getCurMethodLocked(); final boolean shouldHideSoftInput = curMethod != null - && (isInputShown() || (mImeWindowVis & InputMethodService.IME_ACTIVE) != 0); + && (isInputShownLocked() || (mImeWindowVis & InputMethodService.IME_ACTIVE) != 0); mVisibilityStateComputer.requestImeVisibility(windowToken, false); if (shouldHideSoftInput) { @@ -3845,13 +3855,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } } - @EnforcePermission(Manifest.permission.WRITE_SECURE_SETTINGS) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.WRITE_SECURE_SETTINGS) @Override public void showInputMethodPickerFromSystem(int auxiliarySubtypeMode, int displayId) { // Always call subtype picker, because subtype picker is a superset of input method // picker. - super.showInputMethodPickerFromSystem_enforcePermission(); - mHandler.obtainMessage(MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId) .sendToTarget(); } @@ -3859,10 +3867,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub /** * A test API for CTS to make sure that the input method menu is showing. */ - @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD) public boolean isInputMethodPickerShownForTest() { - super.isInputMethodPickerShownForTest_enforcePermission(); - synchronized (ImfLock.class) { return mMenuController.isisInputMethodPickerShownForTestLocked(); } @@ -4162,11 +4168,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub }); } - @EnforcePermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.INTERNAL_SYSTEM_WINDOW) @Override public void removeImeSurface() { - super.removeImeSurface_enforcePermission(); - mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE).sendToTarget(); } @@ -4275,11 +4279,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub * a stylus deviceId is not already registered on device. */ @BinderThread - @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD) @Override public void addVirtualStylusIdForTestSession(IInputMethodClient client) { - super.addVirtualStylusIdForTestSession_enforcePermission(); - int uid = Binder.getCallingUid(); synchronized (ImfLock.class) { if (!canInteractWithImeLocked(uid, client, "addVirtualStylusIdForTestSession", @@ -4302,12 +4304,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub * @param timeout to set in milliseconds. To reset to default, use a value <= zero. */ @BinderThread - @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD) @Override public void setStylusWindowIdleTimeoutForTest( IInputMethodClient client, @DurationMillisLong long timeout) { - super.setStylusWindowIdleTimeoutForTest_enforcePermission(); - int uid = Binder.getCallingUid(); synchronized (ImfLock.class) { if (!canInteractWithImeLocked(uid, client, "setStylusWindowIdleTimeoutForTest", @@ -4403,10 +4403,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } @BinderThread - @EnforcePermission(Manifest.permission.CONTROL_UI_TRACING) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.CONTROL_UI_TRACING) @Override public void startImeTrace() { - super.startImeTrace_enforcePermission(); ImeTracing.getInstance().startTrace(null /* printwriter */); synchronized (ImfLock.class) { mClientController.forAllClients(c -> c.mClient.setImeTraceEnabled(true /* enabled */)); @@ -4414,11 +4413,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } @BinderThread - @EnforcePermission(Manifest.permission.CONTROL_UI_TRACING) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.CONTROL_UI_TRACING) @Override public void stopImeTrace() { - super.stopImeTrace_enforcePermission(); - ImeTracing.getInstance().stopTrace(null /* printwriter */); synchronized (ImfLock.class) { mClientController.forAllClients(c -> c.mClient.setImeTraceEnabled(false /* enabled */)); @@ -4698,7 +4695,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // implemented so that auxiliary subtypes will be excluded when the soft // keyboard is invisible. synchronized (ImfLock.class) { - showAuxSubtypes = isInputShown(); + showAuxSubtypes = isInputShownLocked(); } break; case InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES: @@ -5845,7 +5842,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @BinderThread @Override - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; PriorityDump.dump(mPriorityDumper, fd, pw, args); @@ -5975,7 +5972,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, - @NonNull ResultReceiver resultReceiver) throws RemoteException { + @NonNull ResultReceiver resultReceiver, @NonNull Binder self) { final int callingUid = Binder.getCallingUid(); // Reject any incoming calls from non-shell users, including ones from the system user. if (callingUid != Process.ROOT_UID && callingUid != Process.SHELL_UID) { @@ -5996,7 +5993,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub throw new SecurityException(errorMsg); } new ShellCommandImpl(this).exec( - this, in, out, err, args, callback, resultReceiver); + self, in, out, err, args, callback, resultReceiver); } private static final class ShellCommandImpl extends ShellCommand { diff --git a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java index ffc2319b60af..1cd1ddce78fd 100644 --- a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java +++ b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java @@ -36,17 +36,16 @@ import static com.android.server.inputmethod.InputMethodManagerService.TAG; import android.Manifest; import android.annotation.BinderThread; -import android.annotation.EnforcePermission; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.UserIdInt; import android.os.Binder; import android.os.IBinder; -import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ShellCallback; import android.util.Slog; +import android.view.MotionEvent; import android.view.WindowManager; import android.view.inputmethod.CursorAnchorInfo; import android.view.inputmethod.EditorInfo; @@ -56,6 +55,7 @@ import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import android.window.ImeOnBackInvokedDispatcher; +import com.android.internal.annotations.GuardedBy; import com.android.internal.inputmethod.DirectBootAwareness; import com.android.internal.inputmethod.IBooleanListener; import com.android.internal.inputmethod.IConnectionlessHandwritingCallback; @@ -76,22 +76,25 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; -import java.util.function.BooleanSupplier; /** * A proxy that processes all {@link IInputMethodManager} calls asynchronously. - * @hide */ -public class ZeroJankProxy extends IInputMethodManager.Stub { +final class ZeroJankProxy implements IInputMethodManagerImpl.Callback { - private final IInputMethodManager mInner; + interface Callback extends IInputMethodManagerImpl.Callback { + @GuardedBy("ImfLock.class") + ClientState getClientStateLocked(IInputMethodClient client); + @GuardedBy("ImfLock.class") + boolean isInputShownLocked(); + } + + private final Callback mInner; private final Executor mExecutor; - private final BooleanSupplier mIsInputShown; - ZeroJankProxy(Executor executor, IInputMethodManager inner, BooleanSupplier isInputShown) { + ZeroJankProxy(Executor executor, Callback inner) { mInner = inner; mExecutor = executor; - mIsInputShown = isInputShown; } private void offload(ThrowingRunnable r) { @@ -126,45 +129,43 @@ public class ZeroJankProxy extends IInputMethodManager.Stub { @Override public void addClient(IInputMethodClient client, IRemoteInputConnection inputConnection, - int selfReportedDisplayId) throws RemoteException { + int selfReportedDisplayId) { offload(() -> mInner.addClient(client, inputConnection, selfReportedDisplayId)); } @Override - public InputMethodInfo getCurrentInputMethodInfoAsUser(int userId) throws RemoteException { + public InputMethodInfo getCurrentInputMethodInfoAsUser(int userId) { return mInner.getCurrentInputMethodInfoAsUser(userId); } @Override public List<InputMethodInfo> getInputMethodList( - int userId, @DirectBootAwareness int directBootAwareness) throws RemoteException { + int userId, @DirectBootAwareness int directBootAwareness) { return mInner.getInputMethodList(userId, directBootAwareness); } @Override - public List<InputMethodInfo> getEnabledInputMethodList(int userId) throws RemoteException { + public List<InputMethodInfo> getEnabledInputMethodList(int userId) { return mInner.getEnabledInputMethodList(userId); } @Override public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId, - boolean allowsImplicitlyEnabledSubtypes, int userId) - throws RemoteException { + boolean allowsImplicitlyEnabledSubtypes, int userId) { return mInner.getEnabledInputMethodSubtypeList(imiId, allowsImplicitlyEnabledSubtypes, userId); } @Override - public InputMethodSubtype getLastInputMethodSubtype(int userId) throws RemoteException { + public InputMethodSubtype getLastInputMethodSubtype(int userId) { return mInner.getLastInputMethodSubtype(userId); } @Override public boolean showSoftInput(IInputMethodClient client, IBinder windowToken, @Nullable ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags, - int lastClickTooType, ResultReceiver resultReceiver, - @SoftInputShowHideReason int reason) - throws RemoteException { + @MotionEvent.ToolType int lastClickToolType, ResultReceiver resultReceiver, + @SoftInputShowHideReason int reason) { offload( () -> { if (!mInner.showSoftInput( @@ -172,7 +173,7 @@ public class ZeroJankProxy extends IInputMethodManager.Stub { windowToken, statsToken, flags, - lastClickTooType, + lastClickToolType, resultReceiver, reason)) { sendResultReceiverFailure(resultReceiver); @@ -184,8 +185,7 @@ public class ZeroJankProxy extends IInputMethodManager.Stub { @Override public boolean hideSoftInput(IInputMethodClient client, IBinder windowToken, @Nullable ImeTracker.Token statsToken, @InputMethodManager.HideFlags int flags, - ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) - throws RemoteException { + ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { offload( () -> { if (!mInner.hideSoftInput( @@ -200,17 +200,19 @@ public class ZeroJankProxy extends IInputMethodManager.Stub { if (resultReceiver == null) { return; } - resultReceiver.send( - mIsInputShown.getAsBoolean() + final boolean isInputShown; + synchronized (ImfLock.class) { + isInputShown = mInner.isInputShownLocked(); + } + resultReceiver.send(isInputShown ? InputMethodManager.RESULT_UNCHANGED_SHOWN : InputMethodManager.RESULT_UNCHANGED_HIDDEN, null); } @Override - @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD) - public void hideSoftInputFromServerForTest() throws RemoteException { - super.hideSoftInputFromServerForTest_enforcePermission(); + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD) + public void hideSoftInputFromServerForTest() { mInner.hideSoftInputFromServerForTest(); } @@ -225,8 +227,7 @@ public class ZeroJankProxy extends IInputMethodManager.Stub { IRemoteInputConnection inputConnection, IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection, int unverifiedTargetSdkVersion, @UserIdInt int userId, - @NonNull ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq) - throws RemoteException { + @NonNull ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq) { offload(() -> { InputBindResult result = mInner.startInputOrWindowGainedFocus(startInputReason, client, windowToken, startInputFlags, softInputMode, windowFlags, @@ -249,99 +250,92 @@ public class ZeroJankProxy extends IInputMethodManager.Stub { IRemoteInputConnection inputConnection, IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection, int unverifiedTargetSdkVersion, @UserIdInt int userId, - @NonNull ImeOnBackInvokedDispatcher imeDispatcher) - throws RemoteException { + @NonNull ImeOnBackInvokedDispatcher imeDispatcher) { // Should never be called when flag is enabled i.e. when this proxy is used. return null; } @Override public void showInputMethodPickerFromClient(IInputMethodClient client, - int auxiliarySubtypeMode) - throws RemoteException { + int auxiliarySubtypeMode) { offload(() -> mInner.showInputMethodPickerFromClient(client, auxiliarySubtypeMode)); } - @EnforcePermission(Manifest.permission.WRITE_SECURE_SETTINGS) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.WRITE_SECURE_SETTINGS) @Override - public void showInputMethodPickerFromSystem(int auxiliarySubtypeMode, int displayId) - throws RemoteException { + public void showInputMethodPickerFromSystem(int auxiliarySubtypeMode, int displayId) { mInner.showInputMethodPickerFromSystem(auxiliarySubtypeMode, displayId); } - @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD) @Override - public boolean isInputMethodPickerShownForTest() throws RemoteException { - super.isInputMethodPickerShownForTest_enforcePermission(); + public boolean isInputMethodPickerShownForTest() { return mInner.isInputMethodPickerShownForTest(); } @Override - public InputMethodSubtype getCurrentInputMethodSubtype(int userId) throws RemoteException { + public InputMethodSubtype getCurrentInputMethodSubtype(int userId) { return mInner.getCurrentInputMethodSubtype(userId); } @Override public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes, - @UserIdInt int userId) throws RemoteException { + @UserIdInt int userId) { mInner.setAdditionalInputMethodSubtypes(imiId, subtypes, userId); } @Override public void setExplicitlyEnabledInputMethodSubtypes(String imeId, - @NonNull int[] subtypeHashCodes, @UserIdInt int userId) throws RemoteException { + @NonNull int[] subtypeHashCodes, @UserIdInt int userId) { mInner.setExplicitlyEnabledInputMethodSubtypes(imeId, subtypeHashCodes, userId); } @Override - public int getInputMethodWindowVisibleHeight(IInputMethodClient client) - throws RemoteException { + public int getInputMethodWindowVisibleHeight(IInputMethodClient client) { return mInner.getInputMethodWindowVisibleHeight(client); } @Override - public void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) - throws RemoteException { + public void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) { // Already async TODO(b/293640003): ordering issues? mInner.reportPerceptibleAsync(windowToken, perceptible); } - @EnforcePermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.INTERNAL_SYSTEM_WINDOW) @Override - public void removeImeSurface() throws RemoteException { + public void removeImeSurface() { mInner.removeImeSurface(); } @Override - public void removeImeSurfaceFromWindowAsync(IBinder windowToken) throws RemoteException { + public void removeImeSurfaceFromWindowAsync(IBinder windowToken) { mInner.removeImeSurfaceFromWindowAsync(windowToken); } @Override - public void startProtoDump(byte[] bytes, int i, String s) throws RemoteException { + public void startProtoDump(byte[] bytes, int i, String s) { mInner.startProtoDump(bytes, i, s); } @Override - public boolean isImeTraceEnabled() throws RemoteException { + public boolean isImeTraceEnabled() { return mInner.isImeTraceEnabled(); } - @EnforcePermission(Manifest.permission.CONTROL_UI_TRACING) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.CONTROL_UI_TRACING) @Override - public void startImeTrace() throws RemoteException { + public void startImeTrace() { mInner.startImeTrace(); } - @EnforcePermission(Manifest.permission.CONTROL_UI_TRACING) + @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.CONTROL_UI_TRACING) @Override - public void stopImeTrace() throws RemoteException { + public void stopImeTrace() { mInner.stopImeTrace(); } @Override - public void startStylusHandwriting(IInputMethodClient client) - throws RemoteException { + public void startStylusHandwriting(IInputMethodClient client) { offload(() -> mInner.startStylusHandwriting(client)); } @@ -349,7 +343,7 @@ public class ZeroJankProxy extends IInputMethodManager.Stub { public void startConnectionlessStylusHandwriting(IInputMethodClient client, int userId, @Nullable CursorAnchorInfo cursorAnchorInfo, @Nullable String delegatePackageName, @Nullable String delegatorPackageName, - @NonNull IConnectionlessHandwritingCallback callback) throws RemoteException { + @NonNull IConnectionlessHandwritingCallback callback) { offload(() -> mInner.startConnectionlessStylusHandwriting( client, userId, cursorAnchorInfo, delegatePackageName, delegatorPackageName, callback)); @@ -363,14 +357,11 @@ public class ZeroJankProxy extends IInputMethodManager.Stub { @NonNull String delegatorPackageName, @InputMethodManager.HandwritingDelegateFlags int flags) { try { - return CompletableFuture.supplyAsync(() -> { - try { - return mInner.acceptStylusHandwritingDelegation( - client, userId, delegatePackageName, delegatorPackageName, flags); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - }, this::offload).get(); + return CompletableFuture.supplyAsync(() -> + mInner.acceptStylusHandwritingDelegation( + client, userId, delegatePackageName, delegatorPackageName, + flags), + this::offload).get(); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { @@ -384,8 +375,7 @@ public class ZeroJankProxy extends IInputMethodManager.Stub { @UserIdInt int userId, @NonNull String delegatePackageName, @NonNull String delegatorPackageName, - @InputMethodManager.HandwritingDelegateFlags int flags, IBooleanListener callback) - throws RemoteException { + @InputMethodManager.HandwritingDelegateFlags int flags, IBooleanListener callback) { offload(() -> mInner.acceptStylusHandwritingDelegationAsync( client, userId, delegatePackageName, delegatorPackageName, flags, callback)); } @@ -401,52 +391,45 @@ public class ZeroJankProxy extends IInputMethodManager.Stub { } @Override - public boolean isStylusHandwritingAvailableAsUser(int userId, boolean connectionless) - throws RemoteException { + public boolean isStylusHandwritingAvailableAsUser(int userId, boolean connectionless) { return mInner.isStylusHandwritingAvailableAsUser(userId, connectionless); } - @EnforcePermission("android.permission.TEST_INPUT_METHOD") + @IInputMethodManagerImpl.PermissionVerified("android.permission.TEST_INPUT_METHOD") @Override - public void addVirtualStylusIdForTestSession(IInputMethodClient client) - throws RemoteException { + public void addVirtualStylusIdForTestSession(IInputMethodClient client) { mInner.addVirtualStylusIdForTestSession(client); } - @EnforcePermission("android.permission.TEST_INPUT_METHOD") + @IInputMethodManagerImpl.PermissionVerified("android.permission.TEST_INPUT_METHOD") @Override - public void setStylusWindowIdleTimeoutForTest(IInputMethodClient client, long timeout) - throws RemoteException { + public void setStylusWindowIdleTimeoutForTest(IInputMethodClient client, long timeout) { mInner.setStylusWindowIdleTimeoutForTest(client, timeout); } @Override - public IImeTracker getImeTrackerService() throws RemoteException { + public IImeTracker getImeTrackerService() { return mInner.getImeTrackerService(); } @BinderThread @Override public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out, - @Nullable FileDescriptor err, - @NonNull String[] args, @Nullable ShellCallback callback, - @NonNull ResultReceiver resultReceiver) throws RemoteException { - ((InputMethodManagerService) mInner).onShellCommand( - in, out, err, args, callback, resultReceiver); + @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, + @NonNull ResultReceiver resultReceiver, @NonNull Binder self) { + mInner.onShellCommand(in, out, err, args, callback, resultReceiver, self); } @Override - protected void dump(@NonNull FileDescriptor fd, - @NonNull PrintWriter fout, + public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, @Nullable String[] args) { - ((InputMethodManagerService) mInner).dump(fd, fout, args); + mInner.dump(fd, fout, args); } private void sendOnStartInputResult( IInputMethodClient client, InputBindResult res, int startInputSeq) { synchronized (ImfLock.class) { - InputMethodManagerService service = (InputMethodManagerService) mInner; - final ClientState cs = service.getClientState(client); + final ClientState cs = mInner.getClientStateLocked(client); if (cs != null && cs.mClient != null) { cs.mClient.onStartInputResult(res, startInputSeq); } else { diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 19562ef79fbb..dbdb155eb2e3 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -950,13 +950,18 @@ public class LockSettingsService extends ILockSettings.Stub { && android.multiuser.Flags.enablePrivateSpaceFeatures() && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()) { mHandler.post(() -> { - UserProperties userProperties = - mUserManager.getUserProperties(UserHandle.of(userId)); - if (userProperties != null - && userProperties.getAllowStoppingUserWithDelayedLocking()) { - int strongAuthRequired = LockPatternUtils.StrongAuthTracker - .getDefaultFlags(mContext); - requireStrongAuth(strongAuthRequired, userId); + try { + UserProperties userProperties = + mUserManager.getUserProperties(UserHandle.of(userId)); + if (userProperties != null && userProperties + .getAllowStoppingUserWithDelayedLocking()) { + int strongAuthRequired = LockPatternUtils.StrongAuthTracker + .getDefaultFlags(mContext); + requireStrongAuth(strongAuthRequired, userId); + } + } catch (IllegalArgumentException e) { + Slogf.d(TAG, "User %d does not exist or has been removed", + userId); } }); } diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java index 1a129cb080a8..064443ce7d10 100644 --- a/services/core/java/com/android/server/media/MediaRouterService.java +++ b/services/core/java/com/android/server/media/MediaRouterService.java @@ -267,9 +267,11 @@ public final class MediaRouterService extends IMediaRouterService.Stub // Binder call @Override public boolean showMediaOutputSwitcher(String packageName) { - if (!validatePackageName(Binder.getCallingUid(), packageName)) { + int uid = Binder.getCallingUid(); + if (!validatePackageName(uid, packageName)) { throw new SecurityException("packageName must match the calling identity"); } + UserHandle userHandle = UserHandle.getUserHandleForUid(uid); final long token = Binder.clearCallingIdentity(); try { if (mContext.getSystemService(ActivityManager.class).getPackageImportance(packageName) @@ -280,7 +282,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub synchronized (mLock) { StatusBarManagerInternal statusBar = LocalServices.getService(StatusBarManagerInternal.class); - statusBar.showMediaOutputSwitcher(packageName); + statusBar.showMediaOutputSwitcher(packageName, userHandle); } } finally { Binder.restoreCallingIdentity(token); diff --git a/services/core/java/com/android/server/media/MediaSession2Record.java b/services/core/java/com/android/server/media/MediaSession2Record.java index 0cd7654f70ea..dfb2b0a750e3 100644 --- a/services/core/java/com/android/server/media/MediaSession2Record.java +++ b/services/core/java/com/android/server/media/MediaSession2Record.java @@ -157,6 +157,11 @@ public class MediaSession2Record extends MediaSessionRecordImpl { } @Override + public void expireTempEngaged() { + // NA as MediaSession2 doesn't support UserEngagementStates for FGS. + } + + @Override public boolean sendMediaButton(String packageName, int pid, int uid, boolean asSystemService, KeyEvent ke, int sequenceId, ResultReceiver cb) { // TODO(jaewan): Implement. diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 93f68a831705..194ab04817ec 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -24,6 +24,7 @@ import static android.media.session.MediaController.PlaybackInfo.PLAYBACK_TYPE_L import static android.media.session.MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE; import android.Manifest; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -85,6 +86,8 @@ import com.android.server.LocalServices; import com.android.server.uri.UriGrantsManagerInternal; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -225,6 +228,49 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde private int mPolicies; + private @UserEngagementState int mUserEngagementState = USER_DISENGAGED; + + @IntDef({USER_PERMANENTLY_ENGAGED, USER_TEMPORARY_ENGAGED, USER_DISENGAGED}) + @Retention(RetentionPolicy.SOURCE) + private @interface UserEngagementState {} + + /** + * Indicates that the session is active and in one of the user engaged states. + * + * @see #updateUserEngagedStateIfNeededLocked(boolean) () + */ + private static final int USER_PERMANENTLY_ENGAGED = 0; + + /** + * Indicates that the session is active and in {@link PlaybackState#STATE_PAUSED} state. + * + * @see #updateUserEngagedStateIfNeededLocked(boolean) () + */ + private static final int USER_TEMPORARY_ENGAGED = 1; + + /** + * Indicates that the session is either not active or in one of the user disengaged states + * + * @see #updateUserEngagedStateIfNeededLocked(boolean) () + */ + private static final int USER_DISENGAGED = 2; + + /** + * Indicates the duration of the temporary engaged states. + * + * <p>Some {@link MediaSession} states like {@link PlaybackState#STATE_PAUSED} are temporarily + * engaged, meaning the corresponding session is only considered in an engaged state for the + * duration of this timeout, and only if coming from an engaged state. + * + * <p>For example, if a session is transitioning from a user-engaged state {@link + * PlaybackState#STATE_PLAYING} to a temporary user-engaged state {@link + * PlaybackState#STATE_PAUSED}, then the session will be considered in a user-engaged state for + * the duration of this timeout, starting at the transition instant. However, a temporary + * user-engaged state is not considered user-engaged when transitioning from a non-user engaged + * state {@link PlaybackState#STATE_STOPPED}. + */ + private static final int TEMP_USER_ENGAGED_TIMEOUT = 600000; + public MediaSessionRecord( int ownerPid, int ownerUid, @@ -548,6 +594,7 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde mSessionCb.mCb.asBinder().unlinkToDeath(this, 0); mDestroyed = true; mPlaybackState = null; + updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ true); mHandler.post(MessageHandler.MSG_DESTROYED); } } @@ -559,6 +606,12 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde } } + @Override + public void expireTempEngaged() { + mHandler.removeCallbacks(mHandleTempEngagedSessionTimeout); + updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ true); + } + /** * Sends media button. * @@ -1129,6 +1182,11 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde } }; + private final Runnable mHandleTempEngagedSessionTimeout = + () -> { + updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ true); + }; + @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS) private static boolean componentNameExists( @NonNull ComponentName componentName, @NonNull Context context, int userId) { @@ -1145,6 +1203,40 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde return !resolveInfos.isEmpty(); } + private void updateUserEngagedStateIfNeededLocked(boolean isTimeoutExpired) { + int oldUserEngagedState = mUserEngagementState; + int newUserEngagedState; + if (!isActive() || mPlaybackState == null) { + newUserEngagedState = USER_DISENGAGED; + } else if (isActive() && mPlaybackState.isActive()) { + newUserEngagedState = USER_PERMANENTLY_ENGAGED; + } else if (mPlaybackState.getState() == PlaybackState.STATE_PAUSED) { + newUserEngagedState = + oldUserEngagedState == USER_PERMANENTLY_ENGAGED || !isTimeoutExpired + ? USER_TEMPORARY_ENGAGED + : USER_DISENGAGED; + } else { + newUserEngagedState = USER_DISENGAGED; + } + if (oldUserEngagedState == newUserEngagedState) { + return; + } + + if (newUserEngagedState == USER_TEMPORARY_ENGAGED) { + mHandler.postDelayed(mHandleTempEngagedSessionTimeout, TEMP_USER_ENGAGED_TIMEOUT); + } else if (oldUserEngagedState == USER_TEMPORARY_ENGAGED) { + mHandler.removeCallbacks(mHandleTempEngagedSessionTimeout); + } + + boolean wasUserEngaged = oldUserEngagedState != USER_DISENGAGED; + boolean isNowUserEngaged = newUserEngagedState != USER_DISENGAGED; + mUserEngagementState = newUserEngagedState; + if (wasUserEngaged != isNowUserEngaged) { + mService.onSessionUserEngagementStateChange( + /* mediaSessionRecord= */ this, /* isUserEngaged= */ isNowUserEngaged); + } + } + private final class SessionStub extends ISession.Stub { @Override public void destroySession() throws RemoteException { @@ -1182,8 +1274,10 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde .logFgsApiEnd(ActivityManager.FOREGROUND_SERVICE_API_TYPE_MEDIA_PLAYBACK, callingUid, callingPid); } - - mIsActive = active; + synchronized (mLock) { + mIsActive = active; + updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ false); + } long token = Binder.clearCallingIdentity(); try { mService.onSessionActiveStateChanged(MediaSessionRecord.this, mPlaybackState); @@ -1341,6 +1435,7 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde && TRANSITION_PRIORITY_STATES.contains(newState)); synchronized (mLock) { mPlaybackState = state; + updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ false); } final long token = Binder.clearCallingIdentity(); try { diff --git a/services/core/java/com/android/server/media/MediaSessionRecordImpl.java b/services/core/java/com/android/server/media/MediaSessionRecordImpl.java index 09991995099e..b57b14835987 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecordImpl.java +++ b/services/core/java/com/android/server/media/MediaSessionRecordImpl.java @@ -196,6 +196,12 @@ public abstract class MediaSessionRecordImpl { */ public abstract boolean isClosed(); + /** + * Note: This method is only used for testing purposes If the session is temporary engaged, the + * timeout will expire and it will become disengaged. + */ + public abstract void expireTempEngaged(); + @Override public final boolean equals(Object o) { if (this == o) return true; diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 53c32cf31d21..74adf5e0d52c 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -367,11 +367,13 @@ public class MediaSessionService extends SystemService implements Monitor { } boolean isUserEngaged = isUserEngaged(record, playbackState); - Log.d(TAG, "onSessionActiveStateChanged: " - + "record=" + record - + "playbackState=" + playbackState - + "allowRunningInForeground=" + isUserEngaged); - setForegroundServiceAllowance(record, /* allowRunningInForeground= */ isUserEngaged); + Log.d( + TAG, + "onSessionActiveStateChanged:" + + " record=" + + record + + " playbackState=" + + playbackState); reportMediaInteractionEvent(record, isUserEngaged); mHandler.postSessionsChanged(record); } @@ -479,11 +481,13 @@ public class MediaSessionService extends SystemService implements Monitor { } user.mPriorityStack.onPlaybackStateChanged(record, shouldUpdatePriority); boolean isUserEngaged = isUserEngaged(record, playbackState); - Log.d(TAG, "onSessionPlaybackStateChanged: " - + "record=" + record - + "playbackState=" + playbackState - + "allowRunningInForeground=" + isUserEngaged); - setForegroundServiceAllowance(record, /* allowRunningInForeground= */ isUserEngaged); + Log.d( + TAG, + "onSessionPlaybackStateChanged:" + + " record=" + + record + + " playbackState=" + + playbackState); reportMediaInteractionEvent(record, isUserEngaged); } } @@ -650,68 +654,112 @@ public class MediaSessionService extends SystemService implements Monitor { session.close(); Log.d(TAG, "destroySessionLocked: record=" + session); - setForegroundServiceAllowance(session, /* allowRunningInForeground= */ false); + reportMediaInteractionEvent(session, /* userEngaged= */ false); mHandler.postSessionsChanged(session); } - private void setForegroundServiceAllowance( - MediaSessionRecordImpl record, boolean allowRunningInForeground) { - if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) { - return; - } - ForegroundServiceDelegationOptions foregroundServiceDelegationOptions = - record.getForegroundServiceDelegationOptions(); - if (foregroundServiceDelegationOptions == null) { - return; - } - if (allowRunningInForeground) { - onUserSessionEngaged(record); + void onSessionUserEngagementStateChange( + MediaSessionRecordImpl mediaSessionRecord, boolean isUserEngaged) { + if (isUserEngaged) { + addUserEngagedSession(mediaSessionRecord); + startFgsIfSessionIsLinkedToNotification(mediaSessionRecord); } else { - onUserDisengaged(record); + removeUserEngagedSession(mediaSessionRecord); + stopFgsIfNoSessionIsLinkedToNotification(mediaSessionRecord); } } - private void onUserSessionEngaged(MediaSessionRecordImpl mediaSessionRecord) { + private void addUserEngagedSession(MediaSessionRecordImpl mediaSessionRecord) { synchronized (mLock) { int uid = mediaSessionRecord.getUid(); mUserEngagedSessionsForFgs.putIfAbsent(uid, new HashSet<>()); mUserEngagedSessionsForFgs.get(uid).add(mediaSessionRecord); + } + } + + private void removeUserEngagedSession(MediaSessionRecordImpl mediaSessionRecord) { + synchronized (mLock) { + int uid = mediaSessionRecord.getUid(); + Set<MediaSessionRecordImpl> mUidUserEngagedSessionsForFgs = + mUserEngagedSessionsForFgs.get(uid); + if (mUidUserEngagedSessionsForFgs == null) { + return; + } + + mUidUserEngagedSessionsForFgs.remove(mediaSessionRecord); + if (mUidUserEngagedSessionsForFgs.isEmpty()) { + mUserEngagedSessionsForFgs.remove(uid); + } + } + } + + private void startFgsIfSessionIsLinkedToNotification( + MediaSessionRecordImpl mediaSessionRecord) { + Log.d(TAG, "startFgsIfSessionIsLinkedToNotification: record=" + mediaSessionRecord); + if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) { + return; + } + synchronized (mLock) { + int uid = mediaSessionRecord.getUid(); for (Notification mediaNotification : mMediaNotifications.getOrDefault(uid, Set.of())) { if (mediaSessionRecord.isLinkedToNotification(mediaNotification)) { - mActivityManagerInternal.startForegroundServiceDelegate( - mediaSessionRecord.getForegroundServiceDelegationOptions(), - /* connection= */ null); + startFgsDelegate(mediaSessionRecord.getForegroundServiceDelegationOptions()); return; } } } } - private void onUserDisengaged(MediaSessionRecordImpl mediaSessionRecord) { + private void startFgsDelegate( + ForegroundServiceDelegationOptions foregroundServiceDelegationOptions) { + final long token = Binder.clearCallingIdentity(); + try { + mActivityManagerInternal.startForegroundServiceDelegate( + foregroundServiceDelegationOptions, /* connection= */ null); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private void stopFgsIfNoSessionIsLinkedToNotification( + MediaSessionRecordImpl mediaSessionRecord) { + Log.d(TAG, "stopFgsIfNoSessionIsLinkedToNotification: record=" + mediaSessionRecord); + if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) { + return; + } synchronized (mLock) { int uid = mediaSessionRecord.getUid(); - if (mUserEngagedSessionsForFgs.containsKey(uid)) { - mUserEngagedSessionsForFgs.get(uid).remove(mediaSessionRecord); - if (mUserEngagedSessionsForFgs.get(uid).isEmpty()) { - mUserEngagedSessionsForFgs.remove(uid); - } + ForegroundServiceDelegationOptions foregroundServiceDelegationOptions = + mediaSessionRecord.getForegroundServiceDelegationOptions(); + if (foregroundServiceDelegationOptions == null) { + return; } - boolean shouldStopFgs = true; - for (MediaSessionRecordImpl sessionRecord : + for (MediaSessionRecordImpl record : mUserEngagedSessionsForFgs.getOrDefault(uid, Set.of())) { - for (Notification mediaNotification : mMediaNotifications.getOrDefault(uid, - Set.of())) { - if (sessionRecord.isLinkedToNotification(mediaNotification)) { - shouldStopFgs = false; + for (Notification mediaNotification : + mMediaNotifications.getOrDefault(uid, Set.of())) { + if (record.isLinkedToNotification(mediaNotification)) { + // A user engaged session linked with a media notification is found. + // We shouldn't call stop FGS in this case. + return; } } } - if (shouldStopFgs) { - mActivityManagerInternal.stopForegroundServiceDelegate( - mediaSessionRecord.getForegroundServiceDelegationOptions()); - } + + stopFgsDelegate(foregroundServiceDelegationOptions); + } + } + + private void stopFgsDelegate( + ForegroundServiceDelegationOptions foregroundServiceDelegationOptions) { + final long token = Binder.clearCallingIdentity(); + try { + mActivityManagerInternal.stopForegroundServiceDelegate( + foregroundServiceDelegationOptions); + } finally { + Binder.restoreCallingIdentity(token); } } @@ -2502,7 +2550,6 @@ public class MediaSessionService extends SystemService implements Monitor { } MediaSessionRecord session = null; MediaButtonReceiverHolder mediaButtonReceiverHolder = null; - if (mCustomMediaKeyDispatcher != null) { MediaSession.Token token = mCustomMediaKeyDispatcher.getMediaSession( keyEvent, uid, asSystemService); @@ -2630,6 +2677,18 @@ public class MediaSessionService extends SystemService implements Monitor { && streamType <= AudioManager.STREAM_NOTIFICATION; } + @Override + public void expireTempEngagedSessions() { + synchronized (mLock) { + for (Set<MediaSessionRecordImpl> uidSessions : + mUserEngagedSessionsForFgs.values()) { + for (MediaSessionRecordImpl sessionRecord : uidSessions) { + sessionRecord.expireTempEngaged(); + } + } + } + } + private class MediaKeyListenerResultReceiver extends ResultReceiver implements Runnable { private final String mPackageName; private final int mPid; @@ -3127,7 +3186,6 @@ public class MediaSessionService extends SystemService implements Monitor { super.onNotificationPosted(sbn); Notification postedNotification = sbn.getNotification(); int uid = sbn.getUid(); - if (!postedNotification.isMediaNotification()) { return; } @@ -3138,11 +3196,9 @@ public class MediaSessionService extends SystemService implements Monitor { mUserEngagedSessionsForFgs.getOrDefault(uid, Set.of())) { ForegroundServiceDelegationOptions foregroundServiceDelegationOptions = mediaSessionRecord.getForegroundServiceDelegationOptions(); - if (mediaSessionRecord.isLinkedToNotification(postedNotification) - && foregroundServiceDelegationOptions != null) { - mActivityManagerInternal.startForegroundServiceDelegate( - foregroundServiceDelegationOptions, - /* connection= */ null); + if (foregroundServiceDelegationOptions != null + && mediaSessionRecord.isLinkedToNotification(postedNotification)) { + startFgsDelegate(foregroundServiceDelegationOptions); return; } } @@ -3173,21 +3229,7 @@ public class MediaSessionService extends SystemService implements Monitor { return; } - boolean shouldStopFgs = true; - for (MediaSessionRecordImpl mediaSessionRecord : - mUserEngagedSessionsForFgs.getOrDefault(uid, Set.of())) { - for (Notification mediaNotification : - mMediaNotifications.getOrDefault(uid, Set.of())) { - if (mediaSessionRecord.isLinkedToNotification(mediaNotification)) { - shouldStopFgs = false; - } - } - } - if (shouldStopFgs - && notificationRecord.getForegroundServiceDelegationOptions() != null) { - mActivityManagerInternal.stopForegroundServiceDelegate( - notificationRecord.getForegroundServiceDelegationOptions()); - } + stopFgsIfNoSessionIsLinkedToNotification(notificationRecord); } } diff --git a/services/core/java/com/android/server/media/MediaShellCommand.java b/services/core/java/com/android/server/media/MediaShellCommand.java index a56380827f2c..a20de3198d2c 100644 --- a/services/core/java/com/android/server/media/MediaShellCommand.java +++ b/services/core/java/com/android/server/media/MediaShellCommand.java @@ -92,6 +92,8 @@ public class MediaShellCommand extends ShellCommand { runMonitor(); } else if (cmd.equals("volume")) { runVolume(); + } else if (cmd.equals("expire-temp-engaged-sessions")) { + expireTempEngagedSessions(); } else { showError("Error: unknown command '" + cmd + "'"); return -1; @@ -367,4 +369,8 @@ public class MediaShellCommand extends ShellCommand { private void runVolume() throws Exception { VolumeCtrl.run(this); } + + private void expireTempEngagedSessions() throws Exception { + mSessionService.expireTempEngagedSessions(); + } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index ebc1a2a45579..b14242ef8e08 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -22,6 +22,7 @@ import static android.Manifest.permission.STATUS_BAR_SERVICE; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.app.ActivityManagerInternal.ServiceNotificationPolicy.NOT_FOREGROUND_SERVICE; import static android.app.AppOpsManager.MODE_ALLOWED; +import static android.app.AppOpsManager.MODE_DEFAULT; import static android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR; import static android.app.Flags.lifetimeExtensionRefactor; import static android.app.Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION; @@ -701,7 +702,7 @@ public class NotificationManagerService extends SystemService { private static final int MY_UID = Process.myUid(); private static final int MY_PID = Process.myPid(); - private static final IBinder ALLOWLIST_TOKEN = new Binder(); + static final IBinder ALLOWLIST_TOKEN = new Binder(); protected RankingHandler mRankingHandler; private long mLastOverRateLogTime; private float mMaxPackageEnqueueRate = DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE; @@ -3598,8 +3599,8 @@ public class NotificationManagerService extends SystemService { } } - @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING) @Override + @EnforcePermission(android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING) public void setToastRateLimitingEnabled(boolean enable) { super.setToastRateLimitingEnabled_enforcePermission(); @@ -4524,7 +4525,6 @@ public class NotificationManagerService extends SystemService { return getActiveNotificationsWithAttribution(callingPkg, null); } - @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_NOTIFICATIONS) /** * System-only API for getting a list of current (i.e. not cleared) notifications. * @@ -4532,6 +4532,7 @@ public class NotificationManagerService extends SystemService { * @returns A list of all the notifications, in natural order. */ @Override + @EnforcePermission(android.Manifest.permission.ACCESS_NOTIFICATIONS) public StatusBarNotification[] getActiveNotificationsWithAttribution(String callingPkg, String callingAttributionTag) { // enforce() will ensure the calling uid has the correct permission @@ -4549,9 +4550,9 @@ public class NotificationManagerService extends SystemService { }); // noteOp will check to make sure the callingPkg matches the uid - if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, - callingAttributionTag, null) - == MODE_ALLOWED) { + int mode = mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, + callingAttributionTag, null); + if (mode == MODE_ALLOWED || mode == MODE_DEFAULT) { synchronized (mNotificationLock) { final int N = mNotificationList.size(); for (int i = 0; i < N; i++) { @@ -4627,7 +4628,7 @@ public class NotificationManagerService extends SystemService { // Remove background token before returning notification to untrusted app, this // ensures the app isn't able to perform background operations that are // associated with notification interactions. - notification.clearAllowlistToken(); + notification.overrideAllowlistToken(null); return new StatusBarNotification( sbn.getPackageName(), sbn.getOpPkg(), @@ -4651,12 +4652,12 @@ public class NotificationManagerService extends SystemService { includeSnoozed); } - @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_NOTIFICATIONS) /** * System-only API for getting a list of recent (cleared, no longer shown) notifications. */ @Override @RequiresPermission(android.Manifest.permission.ACCESS_NOTIFICATIONS) + @EnforcePermission(android.Manifest.permission.ACCESS_NOTIFICATIONS) public StatusBarNotification[] getHistoricalNotificationsWithAttribution(String callingPkg, String callingAttributionTag, int count, boolean includeSnoozed) { // enforce() will ensure the calling uid has the correct permission @@ -4666,9 +4667,9 @@ public class NotificationManagerService extends SystemService { int uid = Binder.getCallingUid(); // noteOp will check to make sure the callingPkg matches the uid - if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, - callingAttributionTag, null) - == MODE_ALLOWED) { + int mode = mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, + callingAttributionTag, null); + if (mode == MODE_ALLOWED || mode == MODE_DEFAULT) { synchronized (mArchive) { tmp = mArchive.getArray(mUm, count, includeSnoozed); } @@ -4676,7 +4677,6 @@ public class NotificationManagerService extends SystemService { return tmp; } - @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_NOTIFICATIONS) /** * System-only API for getting a list of historical notifications. May contain multiple days * of notifications. @@ -4684,6 +4684,7 @@ public class NotificationManagerService extends SystemService { @Override @WorkerThread @RequiresPermission(android.Manifest.permission.ACCESS_NOTIFICATIONS) + @EnforcePermission(android.Manifest.permission.ACCESS_NOTIFICATIONS) public NotificationHistory getNotificationHistory(String callingPkg, String callingAttributionTag) { // enforce() will ensure the calling uid has the correct permission @@ -4691,9 +4692,9 @@ public class NotificationManagerService extends SystemService { int uid = Binder.getCallingUid(); // noteOp will check to make sure the callingPkg matches the uid - if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, - callingAttributionTag, null) - == MODE_ALLOWED) { + int mode = mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, + callingAttributionTag, null); + if (mode == MODE_ALLOWED || mode == MODE_DEFAULT) { IntArray currentUserIds = mUserProfiles.getCurrentProfileIds(); Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "notifHistoryReadHistory"); try { @@ -7214,6 +7215,17 @@ public class NotificationManagerService extends SystemService { + " trying to post for invalid pkg " + pkg + " in user " + incomingUserId); } + if (android.app.Flags.secureAllowlistToken()) { + IBinder allowlistToken = notification.getAllowlistToken(); + if (allowlistToken != null && allowlistToken != ALLOWLIST_TOKEN) { + throw new SecurityException( + "Unexpected allowlist token received from " + callingUid); + } + // allowlistToken is populated by unparceling, so it can be null if the notification was + // posted from inside system_server. Ensure it's the expected value. + notification.overrideAllowlistToken(ALLOWLIST_TOKEN); + } + checkRestrictedCategories(notification); // Notifications passed to setForegroundService() have FLAG_FOREGROUND_SERVICE, diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index b5d49b36affe..53863aa83ab4 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -622,6 +622,7 @@ public final class PowerManagerService extends SystemService // Value we store for tracking face down behavior. @VisibleForTesting boolean mIsFaceDown = false; + private boolean mUseFaceDownDetector = true; private long mLastFlipTime = 0L; // The screen brightness setting override from the window manager @@ -3253,7 +3254,7 @@ public final class PowerManagerService extends SystemService mScreenTimeoutOverridePolicy.getScreenTimeoutOverrideLocked( mWakeLockSummary, screenOffTimeout); } - if (mIsFaceDown) { + if (mIsFaceDown && mUseFaceDownDetector) { shortestScreenOffTimeout = Math.min(screenDimDuration, shortestScreenOffTimeout); } @@ -4701,6 +4702,7 @@ public final class PowerManagerService extends SystemService pw.println(" mHoldingDisplaySuspendBlocker=" + mHoldingDisplaySuspendBlocker); pw.println(" mLastFlipTime=" + mLastFlipTime); pw.println(" mIsFaceDown=" + mIsFaceDown); + pw.println(" mUseFaceDownDetector=" + mUseFaceDownDetector); pw.println(); pw.println("Settings and Configuration:"); @@ -6921,6 +6923,16 @@ public final class PowerManagerService extends SystemService Binder.restoreCallingIdentity(ident); } } + + public void setUseFaceDownDetector(boolean enable) { + final long ident = Binder.clearCallingIdentity(); + try { + mUseFaceDownDetector = enable; + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } @VisibleForTesting diff --git a/services/core/java/com/android/server/power/PowerManagerShellCommand.java b/services/core/java/com/android/server/power/PowerManagerShellCommand.java index 9439b762fde0..20184e9fd1a7 100644 --- a/services/core/java/com/android/server/power/PowerManagerShellCommand.java +++ b/services/core/java/com/android/server/power/PowerManagerShellCommand.java @@ -63,6 +63,8 @@ class PowerManagerShellCommand extends ShellCommand { return runListAmbientDisplaySuppressionTokens(); case "set-prox": return runSetProx(); + case "set-face-down-detector": + return runSetFaceDownDetector(); default: return handleDefaultCommands(cmd); } @@ -178,6 +180,20 @@ class PowerManagerShellCommand extends ShellCommand { return 0; } + /** + * To be used for testing - allowing us to disable the usage of face down detector. + */ + private int runSetFaceDownDetector() { + try { + mService.setUseFaceDownDetector(Boolean.parseBoolean(getNextArgRequired())); + } catch (Exception e) { + PrintWriter pw = getOutPrintWriter(); + pw.println("Error: " + e); + return -1; + } + return 0; + } + @Override public void onHelp() { final PrintWriter pw = getOutPrintWriter(); @@ -203,6 +219,8 @@ class PowerManagerShellCommand extends ShellCommand { pw.println(" Acquires the proximity sensor wakelock. Wakelock is associated with"); pw.println(" a specific display if specified. 'list' lists wakelocks previously"); pw.println(" created by set-prox including their held status."); + pw.println(" set-face-down-detector [true|false]"); + pw.println(" sets whether we use face down detector timeouts or not"); pw.println(); Intent.printIntentArgsHelp(pw , ""); diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java index fc2df578c6e3..d060c7ca3034 100644 --- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java +++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java @@ -290,8 +290,8 @@ public class BatteryStatsImpl extends BatteryStats { private KernelMemoryBandwidthStats mKernelMemoryBandwidthStats; private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>(); private int[] mCpuPowerBracketMap; - private CpuPowerStatsCollector mCpuPowerStatsCollector; - private MobileRadioPowerStatsCollector mMobileRadioPowerStatsCollector; + private final CpuPowerStatsCollector mCpuPowerStatsCollector; + private final MobileRadioPowerStatsCollector mMobileRadioPowerStatsCollector; private final SparseBooleanArray mPowerStatsCollectorEnabled = new SparseBooleanArray(); public LongSparseArray<SamplingTimer> getKernelMemoryStats() { @@ -1777,7 +1777,7 @@ public class BatteryStatsImpl extends BatteryStats { return mMaxLearnedBatteryCapacityUah; } - public class FrameworkStatsLogger { + public static class FrameworkStatsLogger { public void uidProcessStateChanged(int uid, int state) { // TODO(b/155216561): It is possible for isolated uids to be in a higher // state than its parent uid. We should track the highest state within the union of host @@ -1786,25 +1786,24 @@ public class BatteryStatsImpl extends BatteryStats { ActivityManager.processStateAmToProto(state)); } - public void wakelockStateChanged(int uid, WorkChain wc, String name, int type, - int procState, boolean acquired) { + public void wakelockStateChanged(int uid, WorkChain wc, String name, + int procState, boolean acquired, int powerManagerWakeLockLevel) { int event = acquired ? FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE : FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE; if (wc != null) { FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), - wc.getTags(), getPowerManagerWakeLockLevel(type), name, - event, procState); + wc.getTags(), powerManagerWakeLockLevel, name, event, procState); } else { - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, - mapIsolatedUid(uid), null, getPowerManagerWakeLockLevel(type), name, - event, procState); + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, uid, + null, powerManagerWakeLockLevel, name, event, procState); } } - public void kernelWakeupReported(long deltaUptimeUs) { - FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, - /* duration_usec */ deltaUptimeUs, mLastWakeupElapsedTimeMs); + public void kernelWakeupReported(long deltaUptimeUs, String lastWakeupReason, + long lastWakeupElapsedTimeMs) { + FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, lastWakeupReason, + /* duration_usec */ deltaUptimeUs, lastWakeupElapsedTimeMs); } public void gpsScanStateChanged(int uid, WorkChain workChain, boolean stateOn) { @@ -1868,41 +1867,6 @@ public class BatteryStatsImpl extends BatteryStats { private final FrameworkStatsLogger mFrameworkStatsLogger; - @VisibleForTesting - public BatteryStatsImpl(@NonNull BatteryStatsConfig config, Clock clock, File historyDirectory, - @NonNull Handler handler, - @NonNull PowerStatsUidResolver powerStatsUidResolver, - @NonNull FrameworkStatsLogger frameworkStatsLogger, - @NonNull BatteryStatsHistory.TraceDelegate traceDelegate, - @NonNull BatteryStatsHistory.EventLogger eventLogger) { - mBatteryStatsConfig = config; - mClock = clock; - initKernelStatsReaders(); - mHandler = handler; - mPowerStatsUidResolver = powerStatsUidResolver; - mFrameworkStatsLogger = frameworkStatsLogger; - mConstants = new Constants(mHandler); - mStartClockTimeMs = clock.currentTimeMillis(); - mDailyFile = null; - mMonotonicClock = new MonotonicClock(0, mClock); - if (historyDirectory == null) { - mCheckinFile = null; - mStatsFile = null; - mHistory = new BatteryStatsHistory(mConstants.MAX_HISTORY_BUFFER, - mStepDetailsCalculator, mClock, mMonotonicClock, traceDelegate, eventLogger); - } else { - mCheckinFile = new AtomicFile(new File(historyDirectory, "batterystats-checkin.bin")); - mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin")); - mHistory = new BatteryStatsHistory(historyDirectory, mConstants.MAX_HISTORY_FILES, - mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, mMonotonicClock, - traceDelegate, eventLogger); - } - mPlatformIdleStateCallback = null; - mEnergyConsumerRetriever = null; - mUserInfoProvider = null; - initPowerStatsCollectors(); - } - private void initKernelStatsReaders() { if (!isKernelStatsAvailable()) { return; @@ -2006,19 +1970,6 @@ public class BatteryStatsImpl extends BatteryStats { private final PowerStatsCollectorInjector mPowerStatsCollectorInjector = new PowerStatsCollectorInjector(); - @SuppressWarnings("GuardedBy") // Accessed from constructor only - private void initPowerStatsCollectors() { - mCpuPowerStatsCollector = new CpuPowerStatsCollector(mPowerStatsCollectorInjector, - mBatteryStatsConfig.getPowerStatsThrottlePeriod( - BatteryConsumer.POWER_COMPONENT_CPU)); - mCpuPowerStatsCollector.addConsumer(this::recordPowerStats); - - mMobileRadioPowerStatsCollector = new MobileRadioPowerStatsCollector( - mPowerStatsCollectorInjector, mBatteryStatsConfig.getPowerStatsThrottlePeriod( - BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)); - mMobileRadioPowerStatsCollector.addConsumer(this::recordPowerStats); - } - /** * TimeBase observer. */ @@ -4975,8 +4926,9 @@ public class BatteryStatsImpl extends BatteryStats { Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs); uidStats.noteStartWakeLocked(pid, name, type, elapsedRealtimeMs); - mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name, type, - uidStats.mProcessState, true /* acquired */); + mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name, + uidStats.mProcessState, true /* acquired */, + getPowerManagerWakeLockLevel(type)); } } @@ -5019,8 +4971,9 @@ public class BatteryStatsImpl extends BatteryStats { Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs); uidStats.noteStopWakeLocked(pid, name, type, elapsedRealtimeMs); - mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name, type, - uidStats.mProcessState, false /* acquired */); + mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name, + uidStats.mProcessState, false/* acquired */, + getPowerManagerWakeLockLevel(type)); if (mappedUid != uid) { // Decrement the ref count for the isolated uid and delete the mapping if uneeded. @@ -5036,8 +4989,8 @@ public class BatteryStatsImpl extends BatteryStats { * TODO: Delete this. Instead, FrameworkStatsLog.write should be called from * PowerManager's Notifier. */ - private int getPowerManagerWakeLockLevel(int battertStatsWakelockType) { - switch (battertStatsWakelockType) { + private int getPowerManagerWakeLockLevel(int batteryStatsWakelockType) { + switch (batteryStatsWakelockType) { // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK case BatteryStats.WAKE_TYPE_PARTIAL: return PowerManager.PARTIAL_WAKE_LOCK; @@ -5055,7 +5008,7 @@ public class BatteryStatsImpl extends BatteryStats { return -1; default: - Slog.e(TAG, "Illegal wakelock type in batterystats: " + battertStatsWakelockType); + Slog.e(TAG, "Illegal wakelock type in batterystats: " + batteryStatsWakelockType); return -1; } } @@ -5257,7 +5210,8 @@ public class BatteryStatsImpl extends BatteryStats { long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs; SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds - mFrameworkStatsLogger.kernelWakeupReported(deltaUptimeMs * 1000); + mFrameworkStatsLogger.kernelWakeupReported(deltaUptimeMs * 1000, mLastWakeupReason, + mLastWakeupElapsedTimeMs); mLastWakeupReason = null; } } @@ -11094,11 +11048,27 @@ public class BatteryStatsImpl extends BatteryStats { public BatteryStatsImpl(@NonNull BatteryStatsConfig config, @NonNull Clock clock, @NonNull MonotonicClock monotonicClock, @Nullable File systemDir, - @NonNull Handler handler, @Nullable PlatformIdleStateCallback cb, - @Nullable EnergyStatsRetriever energyStatsCb, + @NonNull Handler handler, @Nullable PlatformIdleStateCallback platformIdleStateCallback, + @Nullable EnergyStatsRetriever energyStatsRetriever, @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile, @NonNull CpuScalingPolicies cpuScalingPolicies, @NonNull PowerStatsUidResolver powerStatsUidResolver) { + this(config, clock, monotonicClock, systemDir, handler, platformIdleStateCallback, + energyStatsRetriever, userInfoProvider, powerProfile, cpuScalingPolicies, + powerStatsUidResolver, new FrameworkStatsLogger(), + new BatteryStatsHistory.TraceDelegate(), new BatteryStatsHistory.EventLogger()); + } + + public BatteryStatsImpl(@NonNull BatteryStatsConfig config, @NonNull Clock clock, + @NonNull MonotonicClock monotonicClock, @Nullable File systemDir, + @NonNull Handler handler, @Nullable PlatformIdleStateCallback platformIdleStateCallback, + @Nullable EnergyStatsRetriever energyStatsRetriever, + @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile, + @NonNull CpuScalingPolicies cpuScalingPolicies, + @NonNull PowerStatsUidResolver powerStatsUidResolver, + @NonNull FrameworkStatsLogger frameworkStatsLogger, + @NonNull BatteryStatsHistory.TraceDelegate traceDelegate, + @NonNull BatteryStatsHistory.EventLogger eventLogger) { mClock = clock; initKernelStatsReaders(); @@ -11110,25 +11080,34 @@ public class BatteryStatsImpl extends BatteryStats { mPowerProfile = powerProfile; mCpuScalingPolicies = cpuScalingPolicies; mPowerStatsUidResolver = powerStatsUidResolver; - mFrameworkStatsLogger = new FrameworkStatsLogger(); + mFrameworkStatsLogger = frameworkStatsLogger; initPowerProfile(); - if (systemDir == null) { - mStatsFile = null; - mCheckinFile = null; - mDailyFile = null; - mHistory = new BatteryStatsHistory(mConstants.MAX_HISTORY_BUFFER, - mStepDetailsCalculator, mClock, mMonotonicClock); - } else { + if (systemDir != null) { mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); - mHistory = new BatteryStatsHistory(systemDir, mConstants.MAX_HISTORY_FILES, - mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, mMonotonicClock); + } else { + mStatsFile = null; + mCheckinFile = null; + mDailyFile = null; } - initPowerStatsCollectors(); + mHistory = new BatteryStatsHistory(null /* historyBuffer */, systemDir, + mConstants.MAX_HISTORY_FILES, mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, + mClock, mMonotonicClock, traceDelegate, eventLogger); + + mCpuPowerStatsCollector = new CpuPowerStatsCollector(mPowerStatsCollectorInjector, + mBatteryStatsConfig.getPowerStatsThrottlePeriod( + BatteryConsumer.POWER_COMPONENT_CPU)); + mCpuPowerStatsCollector.addConsumer(this::recordPowerStats); + + mMobileRadioPowerStatsCollector = new MobileRadioPowerStatsCollector( + mPowerStatsCollectorInjector, mBatteryStatsConfig.getPowerStatsThrottlePeriod( + BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)); + mMobileRadioPowerStatsCollector.addConsumer(this::recordPowerStats); + mStartCount++; initTimersAndCounters(); mOnBattery = mOnBatteryInternal = false; @@ -11138,8 +11117,8 @@ public class BatteryStatsImpl extends BatteryStats { mStartPlatformVersion = mEndPlatformVersion = Build.ID; initDischarge(realtimeUs); updateDailyDeadlineLocked(); - mPlatformIdleStateCallback = cb; - mEnergyConsumerRetriever = energyStatsCb; + mPlatformIdleStateCallback = platformIdleStateCallback; + mEnergyConsumerRetriever = energyStatsRetriever; mUserInfoProvider = userInfoProvider; mPowerStatsUidResolver.addListener(new PowerStatsUidResolver.Listener() { diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java index 2ff38616fce5..e4f60ec2cdb8 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java @@ -22,6 +22,7 @@ import android.content.ComponentName; import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback; import android.os.Bundle; import android.os.IBinder; +import android.os.UserHandle; import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsController.Appearance; import android.view.WindowInsetsController.Behavior; @@ -248,10 +249,10 @@ public interface StatusBarManagerInternal { /** * Shows the media output switcher dialog. * - * @param packageName of the session for which the output switcher is shown. + * @param targetPackageName of the session for which the output switcher is shown. * @see com.android.internal.statusbar.IStatusBar#showMediaOutputSwitcher */ - void showMediaOutputSwitcher(String packageName); + void showMediaOutputSwitcher(String targetPackageName, UserHandle targetUserHandle); /** * Add a tile to the Quick Settings Panel diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index cca5beb13405..2c67207f407c 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -850,11 +850,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } @Override - public void showMediaOutputSwitcher(String packageName) { + public void showMediaOutputSwitcher(String targetPackageName, UserHandle targetUserHandle) { IStatusBar bar = mBar; if (bar != null) { try { - bar.showMediaOutputSwitcher(packageName); + bar.showMediaOutputSwitcher(targetPackageName, targetUserHandle); } catch (RemoteException ex) { } } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 88f86cc7cecb..83745edd8132 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1312,6 +1312,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A pw.println(prefix + "supportsPictureInPicture=" + info.supportsPictureInPicture()); pw.println(prefix + "supportsEnterPipOnTaskSwitch: " + supportsEnterPipOnTaskSwitch); + pw.println(prefix + "mPauseSchedulePendingForPip=" + mPauseSchedulePendingForPip); } if (getMaxAspectRatio() != 0) { pw.println(prefix + "maxAspectRatio=" + getMaxAspectRatio()); @@ -8967,8 +8968,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A : mDisplayContent.getDisplayInfo(); final Task task = getTask(); task.calculateInsetFrames(mTmpBounds /* outNonDecorBounds */, - outStableBounds /* outStableBounds */, parentBounds /* bounds */, di, - true /* useLegacyInsetsForStableBounds */); + outStableBounds /* outStableBounds */, parentBounds /* bounds */, di); final int orientationWithInsets = outStableBounds.height() >= outStableBounds.width() ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE; // If orientation does not match the orientation with insets applied, then a diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 354cab364ec1..a5687e6fa4ab 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -3732,16 +3732,17 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return false; } - // If PiP2 flag is on and client-request to enter PiP comes in, - // we request a direct transition from Shell to TRANSIT_PIP to get the startWct - // with the right entry bounds. So PiP activity isn't moved to a pinned task until after - // Shell calls back into Core with the entry bounds passed through. if (isPip2ExperimentEnabled()) { - final Transition legacyEnterPipTransition = new Transition(TRANSIT_PIP, + // If PiP2 flag is on and request to enter PiP comes in, + // we request a direct transition TRANSIT_PIP from Shell to get the right entry bounds. + // So PiP activity isn't moved to a pinned task until after + // Shell calls back into Core with the entry bounds to be applied with startWCT. + final Transition enterPipTransition = new Transition(TRANSIT_PIP, 0 /* flags */, getTransitionController(), mWindowManager.mSyncEngine); - legacyEnterPipTransition.setPipActivity(r); - getTransitionController().startCollectOrQueue(legacyEnterPipTransition, (deferred) -> { - getTransitionController().requestStartTransition(legacyEnterPipTransition, + enterPipTransition.setPipActivity(r); + r.mAutoEnteringPip = isAutoEnter; + getTransitionController().startCollectOrQueue(enterPipTransition, (deferred) -> { + getTransitionController().requestStartTransition(enterPipTransition, r.getTask(), null /* remoteTransition */, null /* displayChange */); }); return true; diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 9dba8c6b90c4..3eea6ac81b04 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2244,9 +2244,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> newTransition.setReady(rootTask, true /* ready */); } - if (!isPip2ExperimentEnabled()) { - resumeFocusedTasksTopActivities(); - } + resumeFocusedTasksTopActivities(); notifyActivityPipModeChanged(r.getTask(), r); } diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index e157318543f6..f8aa69b80253 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -912,7 +912,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { @Override public void grantInputChannel(int displayId, SurfaceControl surface, IBinder clientToken, @Nullable InputTransferToken hostInputTransferToken, int flags, - int privateFlags, int type, int inputFeatures, IBinder windowToken, + int privateFlags, int inputFeatures, int type, IBinder windowToken, InputTransferToken inputTransferToken, String inputHandleName, InputChannel outInputChannel) { if (hostInputTransferToken == null && !mCanAddInternalSystemWindow) { @@ -925,7 +925,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { try { mService.grantInputChannel(this, mUid, mPid, displayId, surface, clientToken, hostInputTransferToken, flags, mCanAddInternalSystemWindow ? privateFlags : 0, - type, inputFeatures, windowToken, inputTransferToken, inputHandleName, + inputFeatures, type, windowToken, inputTransferToken, inputHandleName, outInputChannel); } finally { Binder.restoreCallingIdentity(identity); diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 129af90793b3..218fb7f6b817 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -2309,8 +2309,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { // area, i.e. the screen area without the system bars. // The non decor inset are areas that could never be removed in Honeycomb. See // {@link WindowManagerPolicy#getNonDecorInsetsLw}. - calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, mTmpFullBounds, di, - false /* useLegacyInsetsForStableBounds */); + calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, mTmpFullBounds, di); } else { // Apply the given non-decor and stable insets to calculate the corresponding bounds // for screen size of configuration. @@ -2408,11 +2407,9 @@ class TaskFragment extends WindowContainer<WindowContainer> { * @param outNonDecorBounds where to place bounds with non-decor insets applied. * @param outStableBounds where to place bounds with stable insets applied. * @param bounds the bounds to inset. - * @param useLegacyInsetsForStableBounds {@code true} if we need to use the legacy insets frame - * for apps targeting U or before when calculating stable bounds. */ void calculateInsetFrames(Rect outNonDecorBounds, Rect outStableBounds, Rect bounds, - DisplayInfo displayInfo, boolean useLegacyInsetsForStableBounds) { + DisplayInfo displayInfo) { outNonDecorBounds.set(bounds); outStableBounds.set(bounds); if (mDisplayContent == null) { @@ -2424,11 +2421,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { final DisplayPolicy.DecorInsets.Info info = policy.getDecorInsetsInfo( displayInfo.rotation, displayInfo.logicalWidth, displayInfo.logicalHeight); intersectWithInsetsIfFits(outNonDecorBounds, mTmpBounds, info.mNonDecorInsets); - if (!useLegacyInsetsForStableBounds) { - intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mConfigInsets); - } else { - intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mOverrideConfigInsets); - } + intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mConfigInsets); } /** diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index 222abc35ee0b..ce53290da49c 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -565,6 +565,9 @@ class TransitionController { if (isTransientCollect(ar)) { return true; } + for (int i = mWaitingTransitions.size() - 1; i >= 0; --i) { + if (mWaitingTransitions.get(i).isTransientLaunch(ar)) return true; + } for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) { if (mPlayingTransitions.get(i).isTransientLaunch(ar)) return true; } diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index e7088832500f..e1ad1be2ef68 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -67,6 +67,7 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; import static com.android.server.wm.ActivityRecord.State.PAUSING; +import static com.android.server.wm.ActivityRecord.State.RESUMED; import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission; import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK; @@ -1225,17 +1226,32 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub ActivityRecord pipActivity = pipTask.getActivity( (activity) -> activity.pictureInPictureArgs != null); + if (pipActivity.isState(RESUMED)) { + // schedulePauseActivity() call uses this flag when entering PiP after Recents + // swipe-up TO_FRONT transition. In this case the state of the activity is + // RESUMED until ActivityRecord#makeActiveIfNeeded() makes it PAUSING followed + // by the scheduling for PAUSE. See moveActivityToPinnedRootTask()'s call into + // resumeFocusedTasksTopActivities(). + pipActivity.mAutoEnteringPip = + pipActivity.pictureInPictureArgs.isAutoEnterEnabled(); + } Rect entryBounds = hop.getBounds(); mService.mRootWindowContainer.moveActivityToPinnedRootTask( pipActivity, null /* launchIntoPipHostActivity */, "moveActivityToPinnedRootTask", null /* transition */, entryBounds); - // Continue the pausing process after potential task reparenting. if (pipActivity.isState(PAUSING) && pipActivity.mPauseSchedulePendingForPip) { + // Continue the pausing process. This must be done after moving PiP activity to + // a potentially new pinned task (multi-activity case). This case is only + // triggered if TaskFragment#startPausing() deems this an auto-enter case; + // i.e. we enter this flow during button-nav auto-enter but not gesture-nav + // auto-enter PiP for example. pipActivity.getTask().schedulePauseActivity( pipActivity, false /* userLeaving */, false /* pauseImmediately */, true /* autoEnteringPip */, "auto-pip"); } + // Reset auto-entering PiP info since any internal state updates are finished. + pipActivity.mAutoEnteringPip = false; effects |= TRANSACT_EFFECTS_LIFECYCLE; break; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 7a0245bc1acc..4d9fc6c14bc0 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3701,22 +3701,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mDragResizingChangeReported = true; mWindowFrames.clearReportResizeHints(); - // App window resize may trigger Activity#onConfigurationChanged, so we need to update - // ActivityWindowInfo as well. - final IBinder activityToken; - final ActivityWindowInfo activityWindowInfo; - if (mLastReportedActivityWindowInfo != null) { - activityToken = mActivityRecord.token; - activityWindowInfo = mLastReportedActivityWindowInfo; - } else { - activityToken = null; - activityWindowInfo = null; - } - final int prevRotation = mLastReportedConfiguration .getMergedConfiguration().windowConfiguration.getRotation(); fillClientWindowFramesAndConfiguration(mClientWindowFrames, mLastReportedConfiguration, - activityWindowInfo, true /* useLatestConfig */, false /* relayoutVisible */); + mLastReportedActivityWindowInfo, true /* useLatestConfig */, + false /* relayoutVisible */); final boolean syncRedraw = shouldSendRedrawForSync(); final boolean syncWithBuffers = syncRedraw && shouldSyncWithBuffers(); final boolean reportDraw = syncRedraw || drawPending; @@ -3740,14 +3729,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mLastReportedConfiguration, getCompatInsetsState(), forceRelayout, alwaysConsumeSystemBars, displayId, syncWithBuffers ? mSyncSeqId : -1, isDragResizing, - activityToken, activityWindowInfo)); + mLastReportedActivityWindowInfo)); onResizePostDispatched(drawPending, prevRotation, displayId); } else { // TODO(b/301870955): cleanup after launch try { mClient.resized(mClientWindowFrames, reportDraw, mLastReportedConfiguration, getCompatInsetsState(), forceRelayout, alwaysConsumeSystemBars, displayId, - syncWithBuffers ? mSyncSeqId : -1, isDragResizing, activityWindowInfo); + syncWithBuffers ? mSyncSeqId : -1, isDragResizing, + mLastReportedActivityWindowInfo); onResizePostDispatched(drawPending, prevRotation, displayId); } catch (RemoteException e) { // Cancel orientation change of this window to avoid blocking unfreeze display. diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 3c6b500d9ced..648b8100cd36 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -313,8 +313,8 @@ public final class SystemServer implements Dumpable { private static final long SLOW_DELIVERY_THRESHOLD_MS = 200; /* - * Implementation class names. TODO: Move them to a codegen class or load - * them from the build system somehow. + * Implementation class names for services in the {@code SYSTEMSERVERCLASSPATH} + * from {@code PRODUCT_SYSTEM_SERVER_JARS} that are *not* in {@code services.jar}. */ private static final String ARC_NETWORK_SERVICE_CLASS = "com.android.server.arc.net.ArcNetworkService"; @@ -322,26 +322,6 @@ public final class SystemServer implements Dumpable { "com.android.server.arc.persistent_data_block.ArcPersistentDataBlockService"; private static final String ARC_SYSTEM_HEALTH_SERVICE = "com.android.server.arc.health.ArcSystemHealthService"; - private static final String STATS_COMPANION_APEX_PATH = - "/apex/com.android.os.statsd/javalib/service-statsd.jar"; - private static final String STATS_COMPANION_LIFECYCLE_CLASS = - "com.android.server.stats.StatsCompanion$Lifecycle"; - private static final String SCHEDULING_APEX_PATH = - "/apex/com.android.scheduling/javalib/service-scheduling.jar"; - private static final String REBOOT_READINESS_LIFECYCLE_CLASS = - "com.android.server.scheduling.RebootReadinessManagerService$Lifecycle"; - private static final String WIFI_APEX_SERVICE_JAR_PATH = - "/apex/com.android.wifi/javalib/service-wifi.jar"; - private static final String WIFI_SERVICE_CLASS = - "com.android.server.wifi.WifiService"; - private static final String WIFI_SCANNING_SERVICE_CLASS = - "com.android.server.wifi.scanner.WifiScanningService"; - private static final String WIFI_RTT_SERVICE_CLASS = - "com.android.server.wifi.rtt.RttService"; - private static final String WIFI_AWARE_SERVICE_CLASS = - "com.android.server.wifi.aware.WifiAwareService"; - private static final String WIFI_P2P_SERVICE_CLASS = - "com.android.server.wifi.p2p.WifiP2pService"; private static final String LOWPAN_SERVICE_CLASS = "com.android.server.lowpan.LowpanService"; private static final String THERMAL_OBSERVER_CLASS = @@ -368,21 +348,19 @@ public final class SystemServer implements Dumpable { "com.android.clockwork.settings.WearSettingsService"; private static final String WRIST_ORIENTATION_SERVICE_CLASS = "com.android.clockwork.wristorientation.WristOrientationService"; - private static final String IOT_SERVICE_CLASS = "com.android.things.server.IoTSystemService"; private static final String CAR_SERVICE_HELPER_SERVICE_CLASS = "com.android.internal.car.CarServiceHelperService"; + + /* + * Implementation class names for services in the {@code SYSTEMSERVERCLASSPATH} + * from {@code PRODUCT_APEX_SYSTEM_SERVER_JARS}. + */ private static final String APPSEARCH_MODULE_LIFECYCLE_CLASS = "com.android.server.appsearch.AppSearchModule$Lifecycle"; private static final String ISOLATED_COMPILATION_SERVICE_CLASS = "com.android.server.compos.IsolatedCompilationService"; - private static final String CONNECTIVITY_SERVICE_APEX_PATH = - "/apex/com.android.tethering/javalib/service-connectivity.jar"; - private static final String CONNECTIVITY_SERVICE_INITIALIZER_CLASS = - "com.android.server.ConnectivityServiceInitializer"; - private static final String NETWORK_STATS_SERVICE_INITIALIZER_CLASS = - "com.android.server.NetworkStatsServiceInitializer"; private static final String MEDIA_COMMUNICATION_SERVICE_CLASS = "com.android.server.media.MediaCommunicationService"; private static final String HEALTHCONNECT_MANAGER_SERVICE_CLASS = @@ -390,17 +368,8 @@ public final class SystemServer implements Dumpable { private static final String ROLE_SERVICE_CLASS = "com.android.role.RoleService"; private static final String ENHANCED_CONFIRMATION_SERVICE_CLASS = "com.android.ecm.EnhancedConfirmationService"; - - private static final String UWB_APEX_SERVICE_JAR_PATH = - "/apex/com.android.uwb/javalib/service-uwb.jar"; - private static final String UWB_SERVICE_CLASS = "com.android.server.uwb.UwbService"; - private static final String BLUETOOTH_APEX_SERVICE_JAR_PATH = - "/apex/com.android.btservices/javalib/service-bluetooth.jar"; - private static final String BLUETOOTH_SERVICE_CLASS = - "com.android.server.bluetooth.BluetoothService"; private static final String SAFETY_CENTER_SERVICE_CLASS = "com.android.safetycenter.SafetyCenterService"; - private static final String SDK_SANDBOX_MANAGER_SERVICE_CLASS = "com.android.server.sdksandbox.SdkSandboxManagerService$Lifecycle"; private static final String AD_SERVICES_MANAGER_SERVICE_CLASS = @@ -411,11 +380,47 @@ public final class SystemServer implements Dumpable { private static final String UPDATABLE_DEVICE_CONFIG_SERVICE_CLASS = "com.android.server.deviceconfig.DeviceConfigInit$Lifecycle"; + /* + * Implementation class names and jar locations for services in + * {@code STANDALONE_SYSTEMSERVER_JARS}. + */ + private static final String STATS_COMPANION_APEX_PATH = + "/apex/com.android.os.statsd/javalib/service-statsd.jar"; + private static final String STATS_COMPANION_LIFECYCLE_CLASS = + "com.android.server.stats.StatsCompanion$Lifecycle"; + private static final String SCHEDULING_APEX_PATH = + "/apex/com.android.scheduling/javalib/service-scheduling.jar"; + private static final String REBOOT_READINESS_LIFECYCLE_CLASS = + "com.android.server.scheduling.RebootReadinessManagerService$Lifecycle"; + private static final String WIFI_APEX_SERVICE_JAR_PATH = + "/apex/com.android.wifi/javalib/service-wifi.jar"; + private static final String WIFI_SERVICE_CLASS = + "com.android.server.wifi.WifiService"; + private static final String WIFI_SCANNING_SERVICE_CLASS = + "com.android.server.wifi.scanner.WifiScanningService"; + private static final String WIFI_RTT_SERVICE_CLASS = + "com.android.server.wifi.rtt.RttService"; + private static final String WIFI_AWARE_SERVICE_CLASS = + "com.android.server.wifi.aware.WifiAwareService"; + private static final String WIFI_P2P_SERVICE_CLASS = + "com.android.server.wifi.p2p.WifiP2pService"; + private static final String CONNECTIVITY_SERVICE_APEX_PATH = + "/apex/com.android.tethering/javalib/service-connectivity.jar"; + private static final String CONNECTIVITY_SERVICE_INITIALIZER_CLASS = + "com.android.server.ConnectivityServiceInitializer"; + private static final String NETWORK_STATS_SERVICE_INITIALIZER_CLASS = + "com.android.server.NetworkStatsServiceInitializer"; + private static final String UWB_APEX_SERVICE_JAR_PATH = + "/apex/com.android.uwb/javalib/service-uwb.jar"; + private static final String UWB_SERVICE_CLASS = "com.android.server.uwb.UwbService"; + private static final String BLUETOOTH_APEX_SERVICE_JAR_PATH = + "/apex/com.android.btservices/javalib/service-bluetooth.jar"; + private static final String BLUETOOTH_SERVICE_CLASS = + "com.android.server.bluetooth.BluetoothService"; private static final String DEVICE_LOCK_SERVICE_CLASS = "com.android.server.devicelock.DeviceLockService"; private static final String DEVICE_LOCK_APEX_PATH = "/apex/com.android.devicelock/javalib/service-devicelock.jar"; - private static final String PROFILING_SERVICE_LIFECYCLE_CLASS = "android.os.profiling.ProfilingService$Lifecycle"; private static final String PROFILING_SERVICE_JAR_PATH = diff --git a/services/permission/java/com/android/server/permission/access/AccessPolicy.kt b/services/permission/java/com/android/server/permission/access/AccessPolicy.kt index 36758341d4d7..69a88e982f96 100644 --- a/services/permission/java/com/android/server/permission/access/AccessPolicy.kt +++ b/services/permission/java/com/android/server/permission/access/AccessPolicy.kt @@ -16,7 +16,6 @@ package com.android.server.permission.access -import android.permission.flags.Flags import android.util.Slog import com.android.modules.utils.BinaryXmlPullParser import com.android.modules.utils.BinaryXmlSerializer @@ -79,7 +78,7 @@ private constructor( setPackageStates(packageStates) setDisabledSystemPackageStates(disabledSystemPackageStates) packageStates.forEach { (_, packageState) -> - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return@forEach } mutateAppIdPackageNames() @@ -107,7 +106,7 @@ private constructor( newState.mutateUserStatesNoWrite()[userId] = MutableUserState() forEachSchemePolicy { with(it) { onUserAdded(userId) } } newState.externalState.packageStates.forEach { (_, packageState) -> - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return@forEach } upgradePackageVersion(packageState, userId) @@ -133,7 +132,7 @@ private constructor( setPackageStates(packageStates) setDisabledSystemPackageStates(disabledSystemPackageStates) packageStates.forEach { (packageName, packageState) -> - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return@forEach } if (packageState.volumeUuid == volumeUuid) { @@ -161,7 +160,7 @@ private constructor( with(it) { onStorageVolumeMounted(volumeUuid, packageNames, isSystemUpdated) } } packageStates.forEach { (_, packageState) -> - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return@forEach } if (packageState.volumeUuid == volumeUuid) { 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 63fb468c8f54..87af841b901c 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 @@ -81,7 +81,7 @@ class AppIdPermissionPolicy : SchemePolicy() { override fun MutateStateScope.onUserAdded(userId: Int) { newState.externalState.packageStates.forEach { (_, packageState) -> - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return@forEach } evaluateAllPermissionStatesForPackageAndUser(packageState, userId, null) 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 44ed3df34f24..65feeb027b3e 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 @@ -1445,7 +1445,7 @@ class PermissionService(private val service: AccessCheckingService) : val packageStates = packageManagerLocal.withUnfilteredSnapshot().use { it.packageStates } service.mutateState { packageStates.forEach { (packageName, packageState) -> - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return@forEach } val androidPackage = packageState.androidPackage ?: return@forEach @@ -1880,7 +1880,7 @@ class PermissionService(private val service: AccessCheckingService) : packageManagerLocal.withUnfilteredSnapshot().use { snapshot -> service.mutateState { snapshot.packageStates.forEach { (_, packageState) -> - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return@forEach } with(policy) { resetRuntimePermissions(packageState.packageName, userId) } @@ -1925,7 +1925,7 @@ class PermissionService(private val service: AccessCheckingService) : packageManagerLocal.withUnfilteredSnapshot().use { snapshot -> snapshot.packageStates.forEach { (_, packageState) -> - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return@forEach } val androidPackage = packageState.androidPackage ?: return@forEach @@ -1943,7 +1943,7 @@ class PermissionService(private val service: AccessCheckingService) : val permissions = service.getState { with(policy) { getPermissions() } } packageManagerLocal.withUnfilteredSnapshot().use { snapshot -> snapshot.packageStates.forEach packageStates@{ (_, packageState) -> - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return@packageStates } val androidPackage = packageState.androidPackage ?: return@packageStates @@ -2072,7 +2072,7 @@ class PermissionService(private val service: AccessCheckingService) : val appIdPackageNames = MutableIndexedMap<Int, MutableIndexedSet<String>>() packageStates.forEach { (_, packageState) -> - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return@forEach } appIdPackageNames @@ -2328,7 +2328,7 @@ class PermissionService(private val service: AccessCheckingService) : isInstantApp: Boolean, oldPackage: AndroidPackage? ) { - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return } @@ -2358,7 +2358,7 @@ class PermissionService(private val service: AccessCheckingService) : params: PermissionManagerServiceInternal.PackageInstalledParams, userId: Int ) { - if (Flags.ignoreApexPermissions() && androidPackage.isApex) { + if (androidPackage.isApex) { return } @@ -2414,7 +2414,7 @@ class PermissionService(private val service: AccessCheckingService) : sharedUserPkgs: List<AndroidPackage>, userId: Int ) { - if (Flags.ignoreApexPermissions() && packageState.isApex) { + if (packageState.isApex) { return } diff --git a/services/proguard.flags b/services/proguard.flags index f84eff79bb15..bf30781b434e 100644 --- a/services/proguard.flags +++ b/services/proguard.flags @@ -29,11 +29,6 @@ public protected *; } -# Derivatives of SystemService and other services created via reflection --keep,allowoptimization,allowaccessmodification class * extends com.android.server.SystemService { - public <methods>; -} - # Accessed from com.android.compos APEX -keep,allowoptimization,allowaccessmodification class com.android.internal.art.ArtStatsLog { public static void write(...); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java index 0a9c8c00444a..bbab0eef49cb 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java @@ -36,6 +36,8 @@ import android.hardware.power.stats.EnergyConsumerType; import android.hardware.power.stats.EnergyMeasurement; import android.hardware.power.stats.PowerEntity; import android.hardware.power.stats.StateResidencyResult; +import android.os.Handler; +import android.os.Looper; import android.platform.test.ravenwood.RavenwoodRule; import android.power.PowerStatsInternal; import android.util.IntArray; @@ -45,6 +47,7 @@ import androidx.test.InstrumentationRegistry; import com.android.internal.os.Clock; import com.android.internal.os.CpuScalingPolicies; +import com.android.internal.os.MonotonicClock; import com.android.internal.os.PowerProfile; import org.junit.Before; @@ -65,18 +68,23 @@ import java.util.concurrent.CompletableFuture; public class BatteryExternalStatsWorkerTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); + private BatteryExternalStatsWorker mBatteryExternalStatsWorker; - private TestBatteryStatsImpl mBatteryStatsImpl; private TestPowerStatsInternal mPowerStatsInternal; @Before public void setUp() { final Context context = InstrumentationRegistry.getContext(); - mBatteryStatsImpl = new TestBatteryStatsImpl(context); + BatteryStatsImpl batteryStats = new BatteryStatsImpl( + new BatteryStatsImpl.BatteryStatsConfig.Builder().build(), Clock.SYSTEM_CLOCK, + new MonotonicClock(0, Clock.SYSTEM_CLOCK), null, + new Handler(Looper.getMainLooper()), null, null, null, + new PowerProfile(context, true /* forTest */), buildScalingPolicies(), + new PowerStatsUidResolver()); mPowerStatsInternal = new TestPowerStatsInternal(); - mBatteryExternalStatsWorker = new BatteryExternalStatsWorker(new TestInjector(context), - mBatteryStatsImpl); + mBatteryExternalStatsWorker = + new BatteryExternalStatsWorker(new TestInjector(context), batteryStats); } @Test @@ -218,25 +226,17 @@ public class BatteryExternalStatsWorkerTest { } } - public class TestBatteryStatsImpl extends BatteryStatsImpl { - public TestBatteryStatsImpl(Context context) { - super(new BatteryStatsConfig.Builder().build(), Clock.SYSTEM_CLOCK, null, null, null, - null, null, null); - mPowerProfile = new PowerProfile(context, true /* forTest */); - - SparseArray<int[]> cpusByPolicy = new SparseArray<>(); - cpusByPolicy.put(0, new int[]{0, 1, 2, 3}); - cpusByPolicy.put(4, new int[]{4, 5, 6, 7}); - SparseArray<int[]> freqsByPolicy = new SparseArray<>(); - freqsByPolicy.put(0, new int[]{300000, 1000000, 2000000}); - freqsByPolicy.put(4, new int[]{300000, 1000000, 2500000, 3000000}); - mCpuScalingPolicies = new CpuScalingPolicies(freqsByPolicy, freqsByPolicy); - - initTimersAndCounters(); - } + private static CpuScalingPolicies buildScalingPolicies() { + SparseArray<int[]> cpusByPolicy = new SparseArray<>(); + cpusByPolicy.put(0, new int[]{0, 1, 2, 3}); + cpusByPolicy.put(4, new int[]{4, 5, 6, 7}); + SparseArray<int[]> freqsByPolicy = new SparseArray<>(); + freqsByPolicy.put(0, new int[]{300000, 1000000, 2000000}); + freqsByPolicy.put(4, new int[]{300000, 1000000, 2500000, 3000000}); + return new CpuScalingPolicies(freqsByPolicy, freqsByPolicy); } - public class TestPowerStatsInternal extends PowerStatsInternal { + private static class TestPowerStatsInternal extends PowerStatsInternal { private final SparseArray<EnergyConsumer> mEnergyConsumers = new SparseArray(); private final SparseArray<EnergyConsumerResult> mEnergyConsumerResults = new SparseArray(); private final int mTimeSinceBoot = 0; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java index da3834633552..1d48975c086e 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java @@ -35,6 +35,7 @@ import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeRea import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; import com.android.internal.os.KernelSingleUidTimeReader; +import com.android.internal.os.MonotonicClock; import com.android.internal.os.PowerProfile; import com.android.internal.power.EnergyConsumerStats; @@ -73,10 +74,13 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl { MockBatteryStatsImpl(BatteryStatsConfig config, Clock clock, File historyDirectory, Handler handler, PowerStatsUidResolver powerStatsUidResolver) { - super(config, clock, historyDirectory, handler, powerStatsUidResolver, - mock(FrameworkStatsLogger.class), mock(BatteryStatsHistory.TraceDelegate.class), + super(config, clock, new MonotonicClock(0, clock), historyDirectory, handler, + mock(PlatformIdleStateCallback.class), mock(EnergyStatsRetriever.class), + mock(UserInfoProvider.class), mock(PowerProfile.class), + new CpuScalingPolicies(new SparseArray<>(), new SparseArray<>()), + powerStatsUidResolver, mock(FrameworkStatsLogger.class), + mock(BatteryStatsHistory.TraceDelegate.class), mock(BatteryStatsHistory.EventLogger.class)); - initTimersAndCounters(); setMaxHistoryBuffer(128 * 1024); setExternalStatsSyncLocked(mExternalStatsSync); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsAggregatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsAggregatorTest.java index 03b02cfde146..3929137fa8c3 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsAggregatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsAggregatorTest.java @@ -58,7 +58,7 @@ public class PowerStatsAggregatorTest { @Before public void setup() throws ParseException { - mHistory = new BatteryStatsHistory(1024, + mHistory = new BatteryStatsHistory(null, null, 0, 1024, mock(BatteryStatsHistory.HistoryStepDetailsCalculator.class), mClock, mMonotonicClock, mock(BatteryStatsHistory.TraceDelegate.class), null); diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java index ab36ba250986..0c92abce7254 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java @@ -3194,6 +3194,78 @@ public class AccountManagerServiceTest extends AndroidTestCase { } @SmallTest + public void testAccountsChangedBroadcastMarkedAccountAsVisibleThreeTimes() throws Exception { + unlockSystemUser(); + + HashMap<String, Integer> visibility = new HashMap<>(); + visibility.put("testpackage1", AccountManager.VISIBILITY_VISIBLE); + + addAccountRemovedReceiver("testpackage1"); + mAms.registerAccountListener( + new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, + "testpackage1"); + mAms.addAccountExplicitlyWithVisibility( + AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + /* password= */ "p11", + /* extras= */ null, + visibility, + /* callerPackage= */ null); + + updateBroadcastCounters(2); + assertEquals(mVisibleAccountsChangedBroadcasts, 1); + assertEquals(mLoginAccountsChangedBroadcasts, 1); + assertEquals(mAccountRemovedBroadcasts, 0); + + mAms.setAccountVisibility(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + "testpackage1", + AccountManager.VISIBILITY_VISIBLE); + mAms.setAccountVisibility(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + "testpackage1", + AccountManager.VISIBILITY_VISIBLE); + + updateBroadcastCounters(2); + assertEquals(mVisibleAccountsChangedBroadcasts, 1); + assertEquals(mLoginAccountsChangedBroadcasts, 1); + assertEquals(mAccountRemovedBroadcasts, 0); + } + + @SmallTest + public void testAccountsChangedBroadcastChangedVisibilityTwoTimes() throws Exception { + unlockSystemUser(); + + HashMap<String, Integer> visibility = new HashMap<>(); + visibility.put("testpackage1", AccountManager.VISIBILITY_VISIBLE); + + addAccountRemovedReceiver("testpackage1"); + mAms.registerAccountListener( + new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1}, + "testpackage1"); + mAms.addAccountExplicitlyWithVisibility( + AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + /* password= */ "p11", + /* extras= */ null, + visibility, + /* callerPackage= */ null); + + updateBroadcastCounters(2); + assertEquals(mVisibleAccountsChangedBroadcasts, 1); + assertEquals(mLoginAccountsChangedBroadcasts, 1); + assertEquals(mAccountRemovedBroadcasts, 0); + + mAms.setAccountVisibility(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + "testpackage1", + AccountManager.VISIBILITY_NOT_VISIBLE); + mAms.setAccountVisibility(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + "testpackage1", + AccountManager.VISIBILITY_VISIBLE); + + updateBroadcastCounters(7); + assertEquals(mVisibleAccountsChangedBroadcasts, 3); + assertEquals(mLoginAccountsChangedBroadcasts, 3); + assertEquals(mAccountRemovedBroadcasts, 1); + } + + @SmallTest public void testRegisterAccountListenerCredentialsUpdate() throws Exception { unlockSystemUser(); mAms.registerAccountListener( diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index f08fbde962ef..4a61d32d00b2 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -14011,6 +14011,314 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + @EnableFlags(android.app.Flags.FLAG_SECURE_ALLOWLIST_TOKEN) + public void enqueueNotification_acceptsCorrectToken() throws RemoteException { + Notification sent = new Notification.Builder(mContext, TEST_CHANNEL_ID) + .setContentIntent(createPendingIntent("content")) + .build(); + Notification received = parcelAndUnparcel(sent, Notification.CREATOR); + assertThat(received.getAllowlistToken()).isEqualTo( + NotificationManagerService.ALLOWLIST_TOKEN); + + mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 1, + parcelAndUnparcel(received, Notification.CREATOR), mUserId); + waitForIdle(); + + assertThat(mService.mNotificationList).hasSize(1); + assertThat(mService.mNotificationList.get(0).getNotification().getAllowlistToken()) + .isEqualTo(NotificationManagerService.ALLOWLIST_TOKEN); + } + + @Test + @EnableFlags(android.app.Flags.FLAG_SECURE_ALLOWLIST_TOKEN) + public void enqueueNotification_acceptsNullToken_andPopulatesIt() throws RemoteException { + Notification receivedWithoutParceling = new Notification.Builder(mContext, TEST_CHANNEL_ID) + .setContentIntent(createPendingIntent("content")) + .build(); + assertThat(receivedWithoutParceling.getAllowlistToken()).isNull(); + + mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 1, + parcelAndUnparcel(receivedWithoutParceling, Notification.CREATOR), mUserId); + waitForIdle(); + + assertThat(mService.mNotificationList).hasSize(1); + assertThat(mService.mNotificationList.get(0).getNotification().getAllowlistToken()) + .isEqualTo(NotificationManagerService.ALLOWLIST_TOKEN); + } + + @Test + @EnableFlags(android.app.Flags.FLAG_SECURE_ALLOWLIST_TOKEN) + public void enqueueNotification_rejectsOtherToken() throws RemoteException { + Notification sent = new Notification.Builder(mContext, TEST_CHANNEL_ID) + .setContentIntent(createPendingIntent("content")) + .build(); + sent.overrideAllowlistToken(new Binder()); + Notification received = parcelAndUnparcel(sent, Notification.CREATOR); + assertThat(received.getAllowlistToken()).isEqualTo(sent.getAllowlistToken()); + + assertThrows(SecurityException.class, () -> + mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 1, + parcelAndUnparcel(received, Notification.CREATOR), mUserId)); + waitForIdle(); + + assertThat(mService.mNotificationList).isEmpty(); + } + + @Test + @EnableFlags(android.app.Flags.FLAG_SECURE_ALLOWLIST_TOKEN) + public void enqueueNotification_customParcelingWithFakeInnerToken_hasCorrectTokenInIntents() + throws RemoteException { + Notification sentFromApp = new Notification.Builder(mContext, TEST_CHANNEL_ID) + .setContentIntent(createPendingIntent("content")) + .setPublicVersion(new Notification.Builder(mContext, TEST_CHANNEL_ID) + .setContentIntent(createPendingIntent("public")) + .build()) + .build(); + sentFromApp.publicVersion.overrideAllowlistToken(new Binder()); + + // Instead of using the normal parceling, assume the caller parcels it by hand, including a + // null token in the outer notification (as would be expected, and as is verified by + // enqueue) but trying to sneak in a different one in the inner notification, hoping it gets + // propagated to the PendingIntents. + Parcel parcelSentFromApp = Parcel.obtain(); + writeNotificationToParcelCustom(parcelSentFromApp, sentFromApp, new ArraySet<>( + Lists.newArrayList(sentFromApp.contentIntent, + sentFromApp.publicVersion.contentIntent))); + + // Use the unparceling as received in enqueueNotificationWithTag() + parcelSentFromApp.setDataPosition(0); + Notification receivedByNms = new Notification(parcelSentFromApp); + + // Verify that all the pendingIntents have the correct token. + assertThat(receivedByNms.contentIntent.getWhitelistToken()).isEqualTo( + NotificationManagerService.ALLOWLIST_TOKEN); + assertThat(receivedByNms.publicVersion.contentIntent.getWhitelistToken()).isEqualTo( + NotificationManagerService.ALLOWLIST_TOKEN); + } + + /** + * Replicates the behavior of {@link Notification#writeToParcel} but excluding the + * "always use the same allowlist token as the root notification" parts. + */ + private static void writeNotificationToParcelCustom(Parcel parcel, Notification notif, + ArraySet<PendingIntent> allPendingIntents) { + int flags = 0; + parcel.writeInt(1); // version? + + parcel.writeStrongBinder(notif.getAllowlistToken()); + parcel.writeLong(notif.when); + parcel.writeLong(notif.creationTime); + if (notif.getSmallIcon() != null) { + parcel.writeInt(1); + notif.getSmallIcon().writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + parcel.writeInt(notif.number); + if (notif.contentIntent != null) { + parcel.writeInt(1); + notif.contentIntent.writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + if (notif.deleteIntent != null) { + parcel.writeInt(1); + notif.deleteIntent.writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + if (notif.tickerText != null) { + parcel.writeInt(1); + TextUtils.writeToParcel(notif.tickerText, parcel, flags); + } else { + parcel.writeInt(0); + } + if (notif.tickerView != null) { + parcel.writeInt(1); + notif.tickerView.writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + if (notif.contentView != null) { + parcel.writeInt(1); + notif.contentView.writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + if (notif.getLargeIcon() != null) { + parcel.writeInt(1); + notif.getLargeIcon().writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + + parcel.writeInt(notif.defaults); + parcel.writeInt(notif.flags); + + if (notif.sound != null) { + parcel.writeInt(1); + notif.sound.writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + parcel.writeInt(notif.audioStreamType); + + if (notif.audioAttributes != null) { + parcel.writeInt(1); + notif.audioAttributes.writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + + parcel.writeLongArray(notif.vibrate); + parcel.writeInt(notif.ledARGB); + parcel.writeInt(notif.ledOnMS); + parcel.writeInt(notif.ledOffMS); + parcel.writeInt(notif.iconLevel); + + if (notif.fullScreenIntent != null) { + parcel.writeInt(1); + notif.fullScreenIntent.writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + + parcel.writeInt(notif.priority); + + parcel.writeString8(notif.category); + + parcel.writeString8(notif.getGroup()); + + parcel.writeString8(notif.getSortKey()); + + parcel.writeBundle(notif.extras); // null ok + + parcel.writeTypedArray(notif.actions, 0); // null ok + + if (notif.bigContentView != null) { + parcel.writeInt(1); + notif.bigContentView.writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + + if (notif.headsUpContentView != null) { + parcel.writeInt(1); + notif.headsUpContentView.writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + + parcel.writeInt(notif.visibility); + + if (notif.publicVersion != null) { + parcel.writeInt(1); + writeNotificationToParcelCustom(parcel, notif.publicVersion, new ArraySet<>()); + } else { + parcel.writeInt(0); + } + + parcel.writeInt(notif.color); + + if (notif.getChannelId() != null) { + parcel.writeInt(1); + parcel.writeString8(notif.getChannelId()); + } else { + parcel.writeInt(0); + } + parcel.writeLong(notif.getTimeoutAfter()); + + if (notif.getShortcutId() != null) { + parcel.writeInt(1); + parcel.writeString8(notif.getShortcutId()); + } else { + parcel.writeInt(0); + } + + if (notif.getLocusId() != null) { + parcel.writeInt(1); + notif.getLocusId().writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + + parcel.writeInt(notif.getBadgeIconType()); + + if (notif.getSettingsText() != null) { + parcel.writeInt(1); + TextUtils.writeToParcel(notif.getSettingsText(), parcel, flags); + } else { + parcel.writeInt(0); + } + + parcel.writeInt(notif.getGroupAlertBehavior()); + + if (notif.getBubbleMetadata() != null) { + parcel.writeInt(1); + notif.getBubbleMetadata().writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } + + parcel.writeBoolean(notif.getAllowSystemGeneratedContextualActions()); + + parcel.writeInt(Notification.FOREGROUND_SERVICE_DEFAULT); // no getter for mFgsDeferBehavior + + // mUsesStandardHeader is not written because it should be recomputed in listeners + + parcel.writeArraySet(allPendingIntents); + } + + @Test + @SuppressWarnings("unchecked") + @EnableFlags(android.app.Flags.FLAG_SECURE_ALLOWLIST_TOKEN) + public void getActiveNotifications_doesNotLeakAllowlistToken() throws RemoteException { + Notification sentFromApp = new Notification.Builder(mContext, TEST_CHANNEL_ID) + .setContentIntent(createPendingIntent("content")) + .setPublicVersion(new Notification.Builder(mContext, TEST_CHANNEL_ID) + .setContentIntent(createPendingIntent("public")) + .build()) + .extend(new Notification.WearableExtender() + .addPage(new Notification.Builder(mContext, TEST_CHANNEL_ID) + .setContentIntent(createPendingIntent("wearPage")) + .build())) + .build(); + // Binder transition: app -> NMS + Notification receivedByNms = parcelAndUnparcel(sentFromApp, Notification.CREATOR); + assertThat(receivedByNms.getAllowlistToken()).isEqualTo( + NotificationManagerService.ALLOWLIST_TOKEN); + mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 1, + parcelAndUnparcel(receivedByNms, Notification.CREATOR), mUserId); + waitForIdle(); + assertThat(mService.mNotificationList).hasSize(1); + Notification posted = mService.mNotificationList.get(0).getNotification(); + assertThat(posted.getAllowlistToken()).isEqualTo( + NotificationManagerService.ALLOWLIST_TOKEN); + assertThat(posted.contentIntent.getWhitelistToken()).isEqualTo( + NotificationManagerService.ALLOWLIST_TOKEN); + + ParceledListSlice<StatusBarNotification> listSentFromNms = + mBinderService.getAppActiveNotifications(mPkg, mUserId); + // Binder transition: NMS -> app. App doesn't have the allowlist token so clear it + // (having a different one would produce the same effect; the relevant thing is to not let + // out ALLOWLIST_TOKEN). + // Note: for other tests, this is restored by constructing TestableNMS in setup(). + Notification.processAllowlistToken = null; + ParceledListSlice<StatusBarNotification> listReceivedByApp = parcelAndUnparcel( + listSentFromNms, ParceledListSlice.CREATOR); + Notification gottenBackByApp = listReceivedByApp.getList().get(0).getNotification(); + + assertThat(gottenBackByApp.getAllowlistToken()).isNull(); + assertThat(gottenBackByApp.contentIntent.getWhitelistToken()).isNull(); + assertThat(gottenBackByApp.publicVersion.getAllowlistToken()).isNull(); + assertThat(gottenBackByApp.publicVersion.contentIntent.getWhitelistToken()).isNull(); + assertThat(new Notification.WearableExtender(gottenBackByApp).getPages() + .get(0).getAllowlistToken()).isNull(); + assertThat(new Notification.WearableExtender(gottenBackByApp).getPages() + .get(0).contentIntent.getWhitelistToken()).isNull(); + } + + @Test public void enqueueNotification_allowlistsPendingIntents() throws RemoteException { PendingIntent contentIntent = createPendingIntent("content"); PendingIntent actionIntent1 = createPendingIntent("action1"); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index 3df52c75b52e..43f24750ddef 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -3655,6 +3655,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Create immersive rule AutomaticZenRule immersive = new AutomaticZenRule.Builder("Immersed", CONDITION_ID) .setType(TYPE_IMMERSIVE) + .setZenPolicy(mZenModeHelper.mConfig.toZenPolicy()) // same as the manual rule .build(); String immersiveId = mZenModeHelper.addAutomaticZenRule(mPkg, immersive, UPDATE_ORIGIN_APP, "reason", CUSTOM_PKG_UID); @@ -4242,6 +4243,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { public void updateAutomaticZenRule_fromUser_updatesBitmaskAndValue() { // Adds a starting rule with empty zen policies and device effects AutomaticZenRule azrBase = new AutomaticZenRule.Builder(NAME, CONDITION_ID) + .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) .setZenPolicy(new ZenPolicy.Builder().build()) .setDeviceEffects(new ZenDeviceEffects.Builder().build()) .build(); @@ -4250,7 +4252,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { azrBase, UPDATE_ORIGIN_APP, "reason", Process.SYSTEM_UID); AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); - // Modifies the zen policy and device effects + // Modifies the filter, zen policy, and device effects ZenPolicy policy = new ZenPolicy.Builder(rule.getZenPolicy()) .allowPriorityChannels(false) .build(); diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java index 018600641853..42fe3a747b64 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java @@ -1630,6 +1630,7 @@ public class TransitionTests extends WindowTestsBase { assertTrue(controller.mWaitingTransitions.contains(transition)); assertTrue(controller.isTransientHide(appTask)); assertTrue(controller.isTransientVisible(appTask)); + assertTrue(controller.isTransientLaunch(recent)); } @Test diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt index 92b865542257..063088d54b45 100644 --- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt +++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt @@ -50,6 +50,9 @@ class ShowImeOnAppStartWhenLaunchingAppFromOverviewTest(flicker: LegacyFlickerTe testApp.launchViaIntent(wmHelper) testApp.openIME(wmHelper) this.setRotation(flicker.scenario.startRotation) + if (flicker.scenario.isTablet) { + tapl.launchedAppState.swipeUpToUnstashTaskbar() + } tapl.launchedAppState.switchToOverview() wmHelper.StateSyncBuilder().withRecentsActivityVisible().waitForAndVerify() } |