From 274eec31d0d4942ddb1fca06d0ef1de638bf8eef Mon Sep 17 00:00:00 2001 From: Jiangyou Li Date: Fri, 8 Dec 2023 15:40:43 +0800 Subject: [PATCH 001/447] Fix NPE in BootReceiver BootReceiver is depend on DropboxManagerService. If native crash occured before DropboxManagerService start, BootReceiver.addTombstoneToDropBox will occus NPE due to DropboxManager is null. So it need delay watch the tombstone file. Change-Id: I188f18663ac6966d82b97b77e8fed72238adf683 --- .../java/com/android/server/os/NativeTombstoneManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/os/NativeTombstoneManager.java b/services/core/java/com/android/server/os/NativeTombstoneManager.java index ab0d0d2626db..83b663b87ea7 100644 --- a/services/core/java/com/android/server/os/NativeTombstoneManager.java +++ b/services/core/java/com/android/server/os/NativeTombstoneManager.java @@ -92,12 +92,15 @@ public final class NativeTombstoneManager { mHandler = thread.getThreadHandler(); mWatcher = new TombstoneWatcher(); - mWatcher.startWatching(); } void onSystemReady() { registerForUserRemoval(); registerForPackageRemoval(); + // TombstoneWatcher depends on DropboxManagerService. + // DropboxManagerService started before systemReady. + // So it is good to call startWatching here. + mWatcher.startWatching(); // Scan existing tombstones. mHandler.post(() -> { -- GitLab From dd07f0325c98afca60b230b5b6603e4711e7394c Mon Sep 17 00:00:00 2001 From: Sham Rathod Date: Tue, 9 Apr 2024 00:44:14 +0000 Subject: [PATCH 002/447] MediaCas: Add API to update client priority and nice value. Added updateResourcePriority api to update client priority to a preferred value along with a nice value. Bug: 264857199 Bug: 300565729 Test: atest MediaCasTest (cherry picked from https://android-review.googlesource.com/q/commit:e8d4d794c1a11e864b905ab4696c722731539ff7) Change-Id: If46a294dc63dbcdc1467045b6bebcc2da78541d9 NOTE FOR REVIEWERS - original patch and result patch are not identical. PLEASE REVIEW CAREFULLY. Diffs between the patches: name: "update_client_profile_priority" > + namespace: "media" > + description : "Feature flag to add updateResourcePriority api to MediaCas" > + bug: "300565729" > +} > + > +flag { Original patch: From e8d4d794c1a11e864b905ab4696c722731539ff7 Mon Sep 17 00:00:00 2001 From: Sham Rathod Date: Thu, 18 Jan 2024 17:27:43 +0530 Subject: [PATCH] MediaCas: Add API to update client priority and nice value. Added updateResourcePriority api to update client priority to a preferred value along with a nice value. Bug: 264857199 Bug: 300565729 Test: atest MediaCasTest Change-Id: If46a294dc63dbcdc1467045b6bebcc2da78541d9 --- Result patch: diff --git a/core/api/current.txt b/core/api/current.txt index 13d5e03..dff7d16 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -22486,6 +22486,7 @@ method public void sendEvent(int, int, @Nullable byte[]) throws android.media.MediaCasException; method public void setEventListener(@Nullable android.media.MediaCas.EventListener, @Nullable android.os.Handler); method public void setPrivateData(@NonNull byte[]) throws android.media.MediaCasException; + method @FlaggedApi("com.android.media.flags.update_client_profile_priority") public boolean updateResourcePriority(int, int); field public static final int PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED = 0; // 0x0 field public static final int PLUGIN_STATUS_SESSION_NUMBER_CHANGED = 1; // 0x1 field public static final int SCRAMBLING_MODE_AES128 = 9; // 0x9 diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java index 2d7db5e..8b04644 100644 --- a/media/java/android/media/MediaCas.java +++ [[[Result patch trimmed due to size. Decoded string size: 3244. Decoded string SHA1: b4fc385ecbc79900316f18b31cf82c5f87ec6b69.]]] Change-Id: I34af0b4c66280c74fb742057e1ae3061b43de38e --- core/api/current.txt | 1 + media/java/android/media/MediaCas.java | 24 +++++++++++++++++++ .../media/flags/media_better_together.aconfig | 7 ++++++ 3 files changed, 32 insertions(+) diff --git a/core/api/current.txt b/core/api/current.txt index 13d5e03da7ed..dff7d16a1f1f 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -22486,6 +22486,7 @@ package android.media { method public void sendEvent(int, int, @Nullable byte[]) throws android.media.MediaCasException; method public void setEventListener(@Nullable android.media.MediaCas.EventListener, @Nullable android.os.Handler); method public void setPrivateData(@NonNull byte[]) throws android.media.MediaCasException; + method @FlaggedApi("com.android.media.flags.update_client_profile_priority") public boolean updateResourcePriority(int, int); field public static final int PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED = 0; // 0x0 field public static final int PLUGIN_STATUS_SESSION_NUMBER_CHANGED = 1; // 0x1 field public static final int SCRAMBLING_MODE_AES128 = 9; // 0x9 diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java index 2d7db5e6ed94..8b04644a2989 100644 --- a/media/java/android/media/MediaCas.java +++ b/media/java/android/media/MediaCas.java @@ -16,6 +16,9 @@ package android.media; +import static com.android.media.flags.Flags.FLAG_UPDATE_CLIENT_PROFILE_PRIORITY; + +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -970,6 +973,27 @@ public final class MediaCas implements AutoCloseable { registerClient(context, tvInputServiceSessionId, priorityHint); } + /** + * Updates client priority with an arbitrary value along with a nice value. + * + *

Tuner resource manager (TRM) uses the client priority value to decide whether it is able + * to reclaim insufficient resources from another client. + * + *

The nice value represents how much the client intends to give up the resource when an + * insufficient resource situation happens. + * + * @see + * Priority value and nice value + * @param priority the new priority. Any negative value would cause no-op on priority setting + * and the API would only process nice value setting in that case. + * @param niceValue the nice value. + */ + @FlaggedApi(FLAG_UPDATE_CLIENT_PROFILE_PRIORITY) + public boolean updateResourcePriority(int priority, int niceValue) { + return mTunerResourceManager.updateClientPriority(mClientId, priority, niceValue); + } + IHwBinder getBinder() { if (mICas != null) { return null; // Return IHwBinder only for HIDL diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig index 8d6982e2b122..e64958a86933 100644 --- a/media/java/android/media/flags/media_better_together.aconfig +++ b/media/java/android/media/flags/media_better_together.aconfig @@ -68,6 +68,13 @@ flag { bug: "314324170" } +flag { + name: "update_client_profile_priority" + namespace: "media" + description : "Feature flag to add updateResourcePriority api to MediaCas" + bug: "300565729" +} + flag { name: "enable_built_in_speaker_route_suitability_statuses" is_exported: true -- GitLab From 27e4e6aed07238e1a9cbbf477a5b925be34df8a8 Mon Sep 17 00:00:00 2001 From: Thomas Stuart Date: Thu, 6 Jun 2024 22:36:40 +0000 Subject: [PATCH 003/447] enforce limits for VisualVoicemailSmsFilterSettings properties - clientPrefix is now limited to 256 characters - originatingNumbers is now limited to a list size of 100 and each element is also limited to 256 characters Bug: 308932906 Test: CTS Change-Id: Id4b4358b141bb211a7e340b979774850b4bd2403 Merged-In: Id4b4358b141bb211a7e340b979774850b4bd2403 --- .../VisualVoicemailSmsFilterSettings.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java index eadb726bf63b..2b515c9b5cd1 100644 --- a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java +++ b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java @@ -64,6 +64,14 @@ public final class VisualVoicemailSmsFilterSettings implements Parcelable { * @hide */ public static final int DEFAULT_DESTINATION_PORT = DESTINATION_PORT_ANY; + /** + * @hide + */ + public static final int MAX_STRING_LENGTH = 256; + /** + * @hide + */ + public static final int MAX_LIST_SIZE = 100; /** * Builder class for {@link VisualVoicemailSmsFilterSettings} objects. @@ -82,11 +90,16 @@ public final class VisualVoicemailSmsFilterSettings implements Parcelable { /** * Sets the client prefix for the visual voicemail SMS filter. The client prefix will appear * at the start of a visual voicemail SMS message, followed by a colon(:). + * @throws IllegalArgumentException if the string length is greater than 256 characters */ public Builder setClientPrefix(String clientPrefix) { if (clientPrefix == null) { throw new IllegalArgumentException("Client prefix cannot be null"); } + if (clientPrefix.length() > MAX_STRING_LENGTH) { + throw new IllegalArgumentException("Client prefix cannot be greater than " + + MAX_STRING_LENGTH + " characters"); + } mClientPrefix = clientPrefix; return this; } @@ -95,11 +108,25 @@ public final class VisualVoicemailSmsFilterSettings implements Parcelable { * Sets the originating number allow list for the visual voicemail SMS filter. If the list * is not null only the SMS messages from a number in the list can be considered as a visual * voicemail SMS. Otherwise, messages from any address will be considered. + * @throws IllegalArgumentException if the size of the originatingNumbers list is greater + * than 100 elements + * @throws IllegalArgumentException if an element within the originatingNumbers list has + * a string length greater than 256 */ public Builder setOriginatingNumbers(List originatingNumbers) { if (originatingNumbers == null) { throw new IllegalArgumentException("Originating numbers cannot be null"); } + if (originatingNumbers.size() > MAX_LIST_SIZE) { + throw new IllegalArgumentException("The originatingNumbers list size cannot be" + + " greater than " + MAX_STRING_LENGTH + " elements"); + } + for (String num : originatingNumbers) { + if (num != null && num.length() > MAX_STRING_LENGTH) { + throw new IllegalArgumentException("Numbers within the originatingNumbers list" + + " cannot be greater than" + MAX_STRING_LENGTH + " characters"); + } + } mOriginatingNumbers = originatingNumbers; return this; } -- GitLab From da83213910bec8d8b28b444229e449a1f4cb2868 Mon Sep 17 00:00:00 2001 From: Rubin Xu Date: Wed, 11 Sep 2024 13:58:18 +0100 Subject: [PATCH 004/447] Update documentation for EXTRA_PROVISIONING_ALLOW_OFFLINE Bug: 365955253 Flag: EXEMPT doc change Test: N/A Change-Id: Id603d0dba794d67ebb01713988201462fd572fab --- .../app/admin/DevicePolicyManager.java | 28 ++----------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index d873f5757b29..47f34644f19a 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -473,16 +473,9 @@ public class DevicePolicyManager { * that the user backed-out of provisioning or some precondition for provisioning wasn't met. * *

If a device policy management role holder updater is present on - * the device, an internet connection attempt must be made prior to launching this intent. If - * an internet connection can not be established, provisioning will fail unless {@link - * #EXTRA_PROVISIONING_ALLOW_OFFLINE} is explicitly set to {@code true}, in which case - * provisioning will continue without using the - * device policy management role holder. If an internet connection - * has been established, the device policy management role holder - * updater will be launched, which may update the - * device policy management role holder before continuing - * provisioning. + * the device, an internet connection attempt must be made prior to launching this intent. */ + // See b/365955253 for additional behaviours of this API. @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE"; @@ -963,23 +956,8 @@ public class DevicePolicyManager { * A boolean extra indicating whether offline provisioning should be used. * *

The default value is {@code false}. - * - *

Usually during the provisioning flow, there will be - * an attempt to download and install the latest version of the device - * policy management role holder. The platform will then - * delegate provisioning to the device - * * policy management role holder. - * - *

When this extra is set to {@code true}, the - * provisioning flow will always be handled by the platform - * and the device policy management role holder's part skipped. - * - *

On Android versions prior to {@link Build.VERSION_CODES#TIRAMISU}, when this extra is - * {@code false}, the provisioning flow will enforce that an - * internet connection is established, or otherwise fail. When this extra is {@code true}, a - * connection will still be attempted but when it cannot be established provisioning will - * continue offline. */ + // See b/365955253 for detailed behaviours of this API. public static final String EXTRA_PROVISIONING_ALLOW_OFFLINE = "android.app.extra.PROVISIONING_ALLOW_OFFLINE"; -- GitLab From ab580dd276b05ba1d9c671f7494a2b28afb5560a Mon Sep 17 00:00:00 2001 From: Willie Koomson Date: Tue, 11 Jun 2024 23:29:21 +0000 Subject: [PATCH 005/447] Write RemoteViews actions to proto (3/3) This change adds support for writing the following RemoteViews actions to proto: SetViewOutlinePreferredRadiusAction TextViewDrawableAction TextViewSizeAction ViewGroupAddAction ViewGroupRemoveAction ViewPaddingAction SetDrawInstructionsAction Test: RemoteViewsProto test Bug: 308041327 Flag: android.appwidget.flags.remote_views_proto Change-Id: I31f012bdad04b7e5c55ee0bb1300eb9bfadd3bde --- core/java/android/widget/RemoteViews.java | 558 ++++++++++++++++++++ core/proto/android/widget/remoteviews.proto | 69 +++ 2 files changed, 627 insertions(+) diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 06820cd4c2ce..d7b5211ad9fd 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -46,6 +46,7 @@ import android.app.LoadedApk; import android.app.PendingIntent; import android.app.RemoteInput; import android.appwidget.AppWidgetHostView; +import android.appwidget.flags.Flags; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; @@ -4119,6 +4120,71 @@ public class RemoteViews implements Parcelable, Filter { public void visitUris(@NonNull Consumer visitor) { mNestedViews.visitUris(visitor); } + + @Override + public boolean canWriteToProto() { + return true; + } + + @Override + public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) { + if (!Flags.remoteViewsProto()) return; + final long token = out.start(RemoteViewsProto.Action.VIEW_GROUP_ADD_ACTION); + out.write(RemoteViewsProto.ViewGroupAddAction.VIEW_ID, + appResources.getResourceName(mViewId)); + out.write(RemoteViewsProto.ViewGroupAddAction.INDEX, mIndex); + out.write(RemoteViewsProto.ViewGroupAddAction.STABLE_ID, mStableId); + long rvToken = out.start(RemoteViewsProto.ViewGroupAddAction.NESTED_VIEWS); + mNestedViews.writePreviewToProto(context, out); + out.end(rvToken); + out.end(token); + } + } + + private PendingResources createViewGroupActionAddFromProto(ProtoInputStream in) + throws Exception { + final LongSparseArray values = new LongSparseArray<>(); + + final long token = in.start(RemoteViewsProto.Action.VIEW_GROUP_ADD_ACTION); + while (in.nextField() != NO_MORE_FIELDS) { + switch (in.getFieldNumber()) { + case (int) RemoteViewsProto.ViewGroupAddAction.VIEW_ID: + values.put(RemoteViewsProto.ViewGroupAddAction.VIEW_ID, + in.readString(RemoteViewsProto.ViewGroupAddAction.VIEW_ID)); + break; + case (int) RemoteViewsProto.ViewGroupAddAction.NESTED_VIEWS: + final long nvToken = in.start(RemoteViewsProto.ViewGroupAddAction.NESTED_VIEWS); + values.put(RemoteViewsProto.ViewGroupAddAction.NESTED_VIEWS, + createFromProto(in)); + in.end(nvToken); + break; + case (int) RemoteViewsProto.ViewGroupAddAction.INDEX: + values.put(RemoteViewsProto.ViewGroupAddAction.INDEX, + in.readInt(RemoteViewsProto.ViewGroupAddAction.INDEX)); + break; + case (int) RemoteViewsProto.ViewGroupAddAction.STABLE_ID: + values.put(RemoteViewsProto.ViewGroupAddAction.STABLE_ID, + in.readInt(RemoteViewsProto.ViewGroupAddAction.STABLE_ID)); + break; + default: + Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n" + + ProtoUtils.currentFieldToString(in)); + } + } + in.end(token); + + checkContainsKeys(values, new long[]{RemoteViewsProto.ViewGroupAddAction.VIEW_ID, + RemoteViewsProto.ViewGroupAddAction.NESTED_VIEWS}); + + return (context, resources, rootData, depth) -> { + int viewId = getAsIdentifier(resources, values, + RemoteViewsProto.ViewGroupAddAction.VIEW_ID); + return new ViewGroupActionAdd(viewId, ((PendingResources) values.get( + RemoteViewsProto.ViewGroupAddAction.NESTED_VIEWS)).create(context, resources, + rootData, depth), + (int) values.get(RemoteViewsProto.ViewGroupAddAction.INDEX, 0), + (int) values.get(RemoteViewsProto.ViewGroupAddAction.STABLE_ID, 0)); + }; } /** @@ -4241,6 +4307,60 @@ public class RemoteViews implements Parcelable, Filter { public int mergeBehavior() { return MERGE_APPEND; } + + @Override + public boolean canWriteToProto() { + return true; + } + + @Override + public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) { + final long token = out.start(RemoteViewsProto.Action.VIEW_GROUP_REMOVE_ACTION); + out.write(RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID, + appResources.getResourceName(mViewId)); + if (mViewIdToKeep != REMOVE_ALL_VIEWS_ID) { + out.write(RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID_TO_KEEP, + appResources.getResourceName(mViewIdToKeep)); + } + out.end(token); + } + + public static PendingResources createFromProto(ProtoInputStream in) + throws Exception { + final LongSparseArray values = new LongSparseArray<>(); + + final long token = in.start(RemoteViewsProto.Action.VIEW_GROUP_REMOVE_ACTION); + while (in.nextField() != NO_MORE_FIELDS) { + switch (in.getFieldNumber()) { + case (int) RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID: + values.put(RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID, + in.readString(RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID)); + break; + case (int) RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID_TO_KEEP: + values.put(RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID_TO_KEEP, + in.readString( + RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID_TO_KEEP)); + break; + default: + Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n" + + ProtoUtils.currentFieldToString(in)); + } + } + in.end(token); + + checkContainsKeys(values, new long[]{RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID}); + + return (context, resources, rootData, depth) -> { + int viewId = getAsIdentifier(resources, values, + RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID); + int viewIdToKeep = (values.indexOfKey( + RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID_TO_KEEP) >= 0) + ? getAsIdentifier(resources, values, + RemoteViewsProto.ViewGroupRemoveAction.VIEW_ID_TO_KEEP) + : REMOVE_ALL_VIEWS_ID; + return new ViewGroupActionRemove(viewId, viewIdToKeep); + }; + } } /** @@ -4497,6 +4617,200 @@ public class RemoteViews implements Parcelable, Filter { visitIconUri(mI4, visitor); } } + + @Override + public boolean canWriteToProto() { + return true; + } + + @Override + public void writeToProto(ProtoOutputStream out, Context context, + Resources appResources) { // rebase + final long token = out.start(RemoteViewsProto.Action.TEXT_VIEW_DRAWABLE_ACTION); + out.write(RemoteViewsProto.TextViewDrawableAction.VIEW_ID, + appResources.getResourceName(mViewId)); + out.write(RemoteViewsProto.TextViewDrawableAction.IS_RELATIVE, mIsRelative); + if (mUseIcons) { + long iconsToken = out.start(RemoteViewsProto.TextViewDrawableAction.ICONS); + if (mI1 != null) { + writeIconToProto(out, appResources, mI1, + RemoteViewsProto.TextViewDrawableAction.Icons.ONE); + } + if (mI2 != null) { + writeIconToProto(out, appResources, mI2, + RemoteViewsProto.TextViewDrawableAction.Icons.TWO); + } + if (mI3 != null) { + writeIconToProto(out, appResources, mI3, + RemoteViewsProto.TextViewDrawableAction.Icons.THREE); + } + if (mI4 != null) { + writeIconToProto(out, appResources, mI4, + RemoteViewsProto.TextViewDrawableAction.Icons.FOUR); + } + out.end(iconsToken); + } else { + long resourcesToken = out.start(RemoteViewsProto.TextViewDrawableAction.RESOURCES); + if (mD1 != 0) { + out.write(RemoteViewsProto.TextViewDrawableAction.Resources.ONE, + appResources.getResourceName(mD1)); + } + if (mD2 != 0) { + out.write(RemoteViewsProto.TextViewDrawableAction.Resources.TWO, + appResources.getResourceName(mD2)); + } + if (mD3 != 0) { + out.write(RemoteViewsProto.TextViewDrawableAction.Resources.THREE, + appResources.getResourceName(mD3)); + } + if (mD4 != 0) { + out.write(RemoteViewsProto.TextViewDrawableAction.Resources.FOUR, + appResources.getResourceName(mD4)); + } + out.end(resourcesToken); + } + out.end(token); + } + + public static PendingResources createFromProto(ProtoInputStream in) + throws Exception { + final LongSparseArray values = new LongSparseArray<>(); + + values.put(RemoteViewsProto.TextViewDrawableAction.ICONS, + new SparseArray>()); + values.put(RemoteViewsProto.TextViewDrawableAction.RESOURCES, + new SparseArray()); + final long token = in.start(RemoteViewsProto.Action.TEXT_VIEW_DRAWABLE_ACTION); + while (in.nextField() != NO_MORE_FIELDS) { + switch (in.getFieldNumber()) { + case (int) RemoteViewsProto.TextViewDrawableAction.VIEW_ID: + values.put(RemoteViewsProto.TextViewDrawableAction.VIEW_ID, + in.readString(RemoteViewsProto.TextViewDrawableAction.VIEW_ID)); + break; + case (int) RemoteViewsProto.TextViewDrawableAction.IS_RELATIVE: + values.put(RemoteViewsProto.TextViewDrawableAction.IS_RELATIVE, + in.readBoolean( + RemoteViewsProto.TextViewDrawableAction.IS_RELATIVE)); + break; + case (int) RemoteViewsProto.TextViewDrawableAction.RESOURCES: + final long resourcesToken = in.start( + RemoteViewsProto.TextViewDrawableAction.RESOURCES); + while (in.nextField() != NO_MORE_FIELDS) { + switch (in.getFieldNumber()) { + case (int) RemoteViewsProto.TextViewDrawableAction.Resources.ONE: + ((SparseArray) values.get( + RemoteViewsProto.TextViewDrawableAction.RESOURCES)).put( + 1, in.readString( + RemoteViewsProto + .TextViewDrawableAction.Resources.ONE)); + break; + case (int) RemoteViewsProto.TextViewDrawableAction.Resources.TWO: + ((SparseArray) values.get( + RemoteViewsProto.TextViewDrawableAction.RESOURCES)).put( + 2, in.readString( + RemoteViewsProto + .TextViewDrawableAction.Resources.TWO)); + break; + case (int) RemoteViewsProto.TextViewDrawableAction.Resources.THREE: + ((SparseArray) values.get( + RemoteViewsProto.TextViewDrawableAction.RESOURCES)).put( + 3, in.readString( + RemoteViewsProto + .TextViewDrawableAction + .Resources.THREE)); + break; + case (int) RemoteViewsProto.TextViewDrawableAction.Resources.FOUR: + ((SparseArray) values.get( + RemoteViewsProto.TextViewDrawableAction.RESOURCES)).put( + 4, in.readString( + RemoteViewsProto + .TextViewDrawableAction + .Resources.FOUR)); + break; + default: + Log.w(LOG_TAG, + "Unhandled field while reading RemoteViews proto!\n" + + ProtoUtils.currentFieldToString(in)); + } + } + in.end(resourcesToken); + break; + case (int) RemoteViewsProto.TextViewDrawableAction.ICONS: + final long iconsToken = in.start( + RemoteViewsProto.TextViewDrawableAction.ICONS); + while (in.nextField() != NO_MORE_FIELDS) { + switch (in.getFieldNumber()) { + case (int) RemoteViewsProto.TextViewDrawableAction.Icons.ONE: + ((SparseArray>) values.get( + RemoteViewsProto.TextViewDrawableAction.ICONS)).put(1, + createIconFromProto(in, + RemoteViewsProto + .TextViewDrawableAction.Icons.ONE)); + break; + case (int) RemoteViewsProto.TextViewDrawableAction.Icons.TWO: + ((SparseArray>) values.get( + RemoteViewsProto.TextViewDrawableAction.ICONS)).put(2, + createIconFromProto(in, + RemoteViewsProto + .TextViewDrawableAction.Icons.TWO)); + break; + case (int) RemoteViewsProto.TextViewDrawableAction.Icons.THREE: + ((SparseArray>) values.get( + RemoteViewsProto.TextViewDrawableAction.ICONS)).put(3, + createIconFromProto(in, + RemoteViewsProto + .TextViewDrawableAction.Icons.THREE)); + break; + case (int) RemoteViewsProto.TextViewDrawableAction.Icons.FOUR: + ((SparseArray>) values.get( + RemoteViewsProto.TextViewDrawableAction.ICONS)).put(4, + createIconFromProto(in, + RemoteViewsProto + .TextViewDrawableAction.Icons.FOUR)); + break; + default: + Log.w(LOG_TAG, + "Unhandled field while reading RemoteViews proto!\n" + + ProtoUtils.currentFieldToString(in)); + } + } + in.end(iconsToken); + break; + default: + Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n" + + ProtoUtils.currentFieldToString(in)); + } + } + in.end(token); + + checkContainsKeys(values, new long[]{RemoteViewsProto.TextViewDrawableAction.VIEW_ID}); + + return (context, resources, rootData, depth) -> { + int viewId = getAsIdentifier(resources, values, + RemoteViewsProto.TextViewDrawableAction.VIEW_ID); + SparseArray> icons = + (SparseArray>) values.get( + RemoteViewsProto.TextViewDrawableAction.ICONS); + SparseArray resArray = (SparseArray) values.get( + RemoteViewsProto.TextViewDrawableAction.RESOURCES); + boolean isRelative = (boolean) values.get( + RemoteViewsProto.TextViewDrawableAction.IS_RELATIVE, false); + if (icons.size() > 0) { + return new TextViewDrawableAction(viewId, isRelative, + icons.get(1).create(context, resources, rootData, depth), + icons.get(2).create(context, resources, rootData, depth), + icons.get(3).create(context, resources, rootData, depth), + icons.get(4).create(context, resources, rootData, depth)); + } else { + int first = resArray.contains(1) ? getAsIdentifier(resources, resArray, 1) : 0; + int second = resArray.contains(2) ? getAsIdentifier(resources, resArray, 2) : 0; + int third = resArray.contains(3) ? getAsIdentifier(resources, resArray, 3) : 0; + int fourth = resArray.contains(4) ? getAsIdentifier(resources, resArray, 4) : 0; + return new TextViewDrawableAction(viewId, isRelative, first, second, third, + fourth); + } + }; + } } /** @@ -4535,6 +4849,58 @@ public class RemoteViews implements Parcelable, Filter { public int getActionTag() { return TEXT_VIEW_SIZE_ACTION_TAG; } + + @Override + public boolean canWriteToProto() { + return true; + } + + @Override + public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) { + final long token = out.start(RemoteViewsProto.Action.TEXT_VIEW_SIZE_ACTION); + out.write(RemoteViewsProto.TextViewSizeAction.VIEW_ID, + appResources.getResourceName(mViewId)); + out.write(RemoteViewsProto.TextViewSizeAction.UNITS, mUnits); + out.write(RemoteViewsProto.TextViewSizeAction.SIZE, mSize); + out.end(token); + } + + public static PendingResources createFromProto(ProtoInputStream in) + throws Exception { + final LongSparseArray values = new LongSparseArray<>(); + + final long token = in.start(RemoteViewsProto.Action.TEXT_VIEW_SIZE_ACTION); + while (in.nextField() != NO_MORE_FIELDS) { + switch (in.getFieldNumber()) { + case (int) RemoteViewsProto.TextViewSizeAction.VIEW_ID: + values.put(RemoteViewsProto.TextViewSizeAction.VIEW_ID, + in.readString(RemoteViewsProto.TextViewSizeAction.VIEW_ID)); + break; + case (int) RemoteViewsProto.TextViewSizeAction.UNITS: + values.put(RemoteViewsProto.TextViewSizeAction.UNITS, + in.readInt(RemoteViewsProto.TextViewSizeAction.UNITS)); + break; + case (int) RemoteViewsProto.TextViewSizeAction.SIZE: + values.put(RemoteViewsProto.TextViewSizeAction.SIZE, + in.readFloat(RemoteViewsProto.TextViewSizeAction.SIZE)); + break; + default: + Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n" + + ProtoUtils.currentFieldToString(in)); + } + } + in.end(token); + + checkContainsKeys(values, new long[]{RemoteViewsProto.TextViewSizeAction.VIEW_ID}); + + return (context, resources, rootData, depth) -> { + int viewId = getAsIdentifier(resources, values, + RemoteViewsProto.TextViewSizeAction.VIEW_ID); + return new TextViewSizeAction(viewId, + (int) values.get(RemoteViewsProto.TextViewSizeAction.UNITS, 0), + (float) values.get(RemoteViewsProto.TextViewSizeAction.SIZE, 0)); + }; + } } /** @@ -4579,6 +4945,70 @@ public class RemoteViews implements Parcelable, Filter { public int getActionTag() { return VIEW_PADDING_ACTION_TAG; } + + @Override + public boolean canWriteToProto() { + return true; + } + + @Override + public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) { + final long token = out.start(RemoteViewsProto.Action.VIEW_PADDING_ACTION); + out.write(RemoteViewsProto.ViewPaddingAction.VIEW_ID, + appResources.getResourceName(mViewId)); + out.write(RemoteViewsProto.ViewPaddingAction.LEFT, mLeft); + out.write(RemoteViewsProto.ViewPaddingAction.RIGHT, mRight); + out.write(RemoteViewsProto.ViewPaddingAction.TOP, mTop); + out.write(RemoteViewsProto.ViewPaddingAction.BOTTOM, mBottom); + out.end(token); + } + + public static PendingResources createFromProto(ProtoInputStream in) + throws Exception { + final LongSparseArray values = new LongSparseArray<>(); + + final long token = in.start(RemoteViewsProto.Action.VIEW_PADDING_ACTION); + while (in.nextField() != NO_MORE_FIELDS) { + switch (in.getFieldNumber()) { + case (int) RemoteViewsProto.ViewPaddingAction.VIEW_ID: + values.put(RemoteViewsProto.ViewPaddingAction.VIEW_ID, + in.readString(RemoteViewsProto.ViewPaddingAction.VIEW_ID)); + break; + case (int) RemoteViewsProto.ViewPaddingAction.LEFT: + values.put(RemoteViewsProto.ViewPaddingAction.LEFT, + in.readInt(RemoteViewsProto.ViewPaddingAction.LEFT)); + break; + case (int) RemoteViewsProto.ViewPaddingAction.RIGHT: + values.put(RemoteViewsProto.ViewPaddingAction.RIGHT, + in.readInt(RemoteViewsProto.ViewPaddingAction.RIGHT)); + break; + case (int) RemoteViewsProto.ViewPaddingAction.TOP: + values.put(RemoteViewsProto.ViewPaddingAction.TOP, + in.readInt(RemoteViewsProto.ViewPaddingAction.TOP)); + break; + case (int) RemoteViewsProto.ViewPaddingAction.BOTTOM: + values.put(RemoteViewsProto.ViewPaddingAction.BOTTOM, + in.readInt(RemoteViewsProto.ViewPaddingAction.BOTTOM)); + break; + default: + Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n" + + ProtoUtils.currentFieldToString(in)); + } + } + in.end(token); + + checkContainsKeys(values, new long[]{RemoteViewsProto.ViewPaddingAction.VIEW_ID}); + + return (context, resources, rootData, depth) -> { + int viewId = getAsIdentifier(resources, values, + RemoteViewsProto.ViewPaddingAction.VIEW_ID); + return new ViewPaddingAction(viewId, + (int) values.get(RemoteViewsProto.ViewPaddingAction.LEFT, 0), + (int) values.get(RemoteViewsProto.ViewPaddingAction.TOP, 0), + (int) values.get(RemoteViewsProto.ViewPaddingAction.RIGHT, 0), + (int) values.get(RemoteViewsProto.ViewPaddingAction.BOTTOM, 0)); + }; + } } /** @@ -5241,6 +5671,69 @@ public class RemoteViews implements Parcelable, Filter { public int getActionTag() { return SET_VIEW_OUTLINE_RADIUS_TAG; } + + @Override + public boolean canWriteToProto() { + return true; + } + + @Override + public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) { + final long token = out.start( + RemoteViewsProto.Action.SET_VIEW_OUTLINE_PREFERRED_RADIUS_ACTION); + out.write(RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VIEW_ID, + appResources.getResourceName(mViewId)); + out.write(RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VALUE_TYPE, mValueType); + out.write(RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VALUE, mValue); + out.end(token); + } + + public static PendingResources createFromProto(ProtoInputStream in) + throws Exception { + final LongSparseArray values = new LongSparseArray<>(); + + final long token = in.start( + RemoteViewsProto.Action.SET_VIEW_OUTLINE_PREFERRED_RADIUS_ACTION); + while (in.nextField() != NO_MORE_FIELDS) { + switch (in.getFieldNumber()) { + case (int) RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VIEW_ID: + values.put(RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VIEW_ID, + in.readString( + RemoteViewsProto + .SetViewOutlinePreferredRadiusAction.VIEW_ID)); + break; + case (int) RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VALUE_TYPE: + values.put(RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VALUE_TYPE, + in.readInt( + RemoteViewsProto + .SetViewOutlinePreferredRadiusAction.VALUE_TYPE)); + break; + case (int) RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VALUE: + values.put(RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VALUE, + in.readInt( + RemoteViewsProto + .SetViewOutlinePreferredRadiusAction.VALUE)); + break; + default: + Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n" + + ProtoUtils.currentFieldToString(in)); + } + } + in.end(token); + + checkContainsKeys(values, + new long[]{RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VIEW_ID, + RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VALUE_TYPE}); + + return (context, resources, rootData, depth) -> { + int viewId = getAsIdentifier(resources, values, + RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VIEW_ID); + return new SetViewOutlinePreferredRadiusAction(viewId, + (int) values.get(RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VALUE, + 0), (int) values.get( + RemoteViewsProto.SetViewOutlinePreferredRadiusAction.VALUE_TYPE)); + }; + } } /** @@ -5324,6 +5817,46 @@ public class RemoteViews implements Parcelable, Filter { public int getActionTag() { return SET_DRAW_INSTRUCTION_TAG; } + + @Override + public boolean canWriteToProto() { + return drawDataParcel(); + } + + @Override + public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) { + if (!drawDataParcel()) return; + final long token = out.start(RemoteViewsProto.Action.SET_DRAW_INSTRUCTION_ACTION); + if (mInstructions != null) { + for (byte[] bytes : mInstructions.mInstructions) { + out.write(RemoteViewsProto.SetDrawInstructionAction.INSTRUCTIONS, bytes); + } + } + out.end(token); + } + } + + @FlaggedApi(FLAG_DRAW_DATA_PARCEL) + private PendingResources createSetDrawInstructionActionFromProto(ProtoInputStream in) + throws Exception { + List instructions = new ArrayList(); + + final long token = in.start(RemoteViewsProto.Action.SET_DRAW_INSTRUCTION_ACTION); + while (in.nextField() != NO_MORE_FIELDS) { + switch (in.getFieldNumber()) { + case (int) RemoteViewsProto.SetDrawInstructionAction.INSTRUCTIONS: + instructions.add( + in.readBytes(RemoteViewsProto.SetDrawInstructionAction.INSTRUCTIONS)); + break; + default: + Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n" + + ProtoUtils.currentFieldToString(in)); + } + } + in.end(token); + + return (context, resources, rootData, depth) -> new SetDrawInstructionAction( + new DrawInstructions.Builder(instructions).build()); } /** @@ -9604,12 +10137,20 @@ public class RemoteViews implements Parcelable, Filter { } if (ref.mMode == MODE_NORMAL) { rv.setIdealSize(ref.mIdealSize); + boolean hasDrawInstructionAction = false; for (PendingResources pendingAction : ref.mActions) { Action action = pendingAction.create(appContext, appResources, rootData, depth); if (action != null) { + if (action instanceof SetDrawInstructionAction) { + hasDrawInstructionAction = true; + } rv.addAction(action); } } + if (rv.mHasDrawInstructions && !hasDrawInstructionAction) { + throw new InvalidProtoException( + "RemoteViews proto is missing DrawInstructions"); + } return rv; } else if (ref.mMode == MODE_HAS_SIZED_REMOTEVIEWS) { List sizedViews = new ArrayList<>(); @@ -9685,6 +10226,23 @@ public class RemoteViews implements Parcelable, Filter { return rv.createSetRemoteCollectionItemListAdapterActionFromProto(in); case (int) RemoteViewsProto.Action.SET_RIPPLE_DRAWABLE_COLOR_ACTION: return SetRippleDrawableColor.createFromProto(in); + case (int) RemoteViewsProto.Action.SET_VIEW_OUTLINE_PREFERRED_RADIUS_ACTION: + return SetViewOutlinePreferredRadiusAction.createFromProto(in); + case (int) RemoteViewsProto.Action.TEXT_VIEW_DRAWABLE_ACTION: + return TextViewDrawableAction.createFromProto(in); + case (int) RemoteViewsProto.Action.TEXT_VIEW_SIZE_ACTION: + return TextViewSizeAction.createFromProto(in); + case (int) RemoteViewsProto.Action.VIEW_GROUP_ADD_ACTION: + return rv.createViewGroupActionAddFromProto(in); + case (int) RemoteViewsProto.Action.VIEW_GROUP_REMOVE_ACTION: + return ViewGroupActionRemove.createFromProto(in); + case (int) RemoteViewsProto.Action.VIEW_PADDING_ACTION: + return ViewPaddingAction.createFromProto(in); + case (int) RemoteViewsProto.Action.SET_DRAW_INSTRUCTION_ACTION: + if (!drawDataParcel()) { + return null; + } + return rv.createSetDrawInstructionActionFromProto(in); default: throw new RuntimeException("Unhandled field while reading Action proto!\n" + ProtoUtils.currentFieldToString(in)); diff --git a/core/proto/android/widget/remoteviews.proto b/core/proto/android/widget/remoteviews.proto index f477d32cd915..6a987a475711 100644 --- a/core/proto/android/widget/remoteviews.proto +++ b/core/proto/android/widget/remoteviews.proto @@ -32,6 +32,8 @@ import "frameworks/base/core/proto/android/content/res/color_state_list.proto"; * * Do not change the tag number or type of any fields in order to maintain compatibility with * previous versions. If a field is deleted, use `reserved` to mark its tag number. + * + * Next tag: 17 */ message RemoteViewsProto { option (android.msg_privacy).dest = DEST_AUTOMATIC; @@ -290,6 +292,7 @@ message RemoteViewsProto { } } + // Next tag: 23 message Action { oneof action { AttributeReflectionAction attribute_reflection_action = 1; @@ -307,6 +310,13 @@ message RemoteViewsProto { SetRadioGroupCheckedAction set_radio_group_checked_action = 13; SetRemoteCollectionItemListAdapterAction set_remote_collection_item_list_adapter_action = 14; SetRippleDrawableColorAction set_ripple_drawable_color_action = 15; + SetViewOutlinePreferredRadiusAction set_view_outline_preferred_radius_action = 16; + TextViewDrawableAction text_view_drawable_action = 17; + TextViewSizeAction text_view_size_action = 18; + ViewGroupAddAction view_group_add_action = 19; + ViewGroupRemoveAction view_group_remove_action = 20; + ViewPaddingAction view_padding_action = 21; + SetDrawInstructionAction set_draw_instruction_action = 22; } } @@ -428,6 +438,65 @@ message RemoteViewsProto { optional string view_id = 1; optional android.content.res.ColorStateListProto color_state_list = 2; } + + message SetViewOutlinePreferredRadiusAction { + optional string view_id = 1; + optional int32 value_type = 2; + optional int32 value = 3; + } + + message TextViewDrawableAction { + optional string view_id = 1; + optional bool is_relative = 2; + oneof drawables { + Resources resources = 3; + Icons icons = 4; + }; + + message Resources { + optional string one = 1; + optional string two = 2; + optional string three = 3; + optional string four = 4; + } + + message Icons { + optional Icon one = 1; + optional Icon two = 2; + optional Icon three = 3; + optional Icon four = 4; + } + } + + message TextViewSizeAction { + optional string view_id = 1; + optional int32 units = 2; + optional float size = 3; + } + + message ViewGroupAddAction { + optional string view_id = 1; + optional RemoteViewsProto nested_views = 2; + optional int32 index = 3; + optional int32 stableId = 4; + } + + message ViewGroupRemoveAction { + optional string view_id = 1; + optional string view_id_to_keep = 2; + } + + message ViewPaddingAction { + optional string view_id = 1; + optional int32 left = 2; + optional int32 right = 3; + optional int32 top = 4; + optional int32 bottom = 5; + } + + message SetDrawInstructionAction { + repeated bytes instructions = 1; + } } -- GitLab From 2614f026f949a34cea6b4ac610bd6a1b6277ae10 Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Mon, 23 Sep 2024 11:56:45 -0400 Subject: [PATCH 006/447] Reset screenshot timeout immediately We were only resetting the timeout after the animation finished, meaning that if a second screenshot was invoked toward the end of the timeout period, the old timeout could fire (immediately dismissing the screenshot UI) even though there was a new screenshot visible. This switches to resetting the timeout as soon as we get the new screenshot. Bug: 360043261 Fix: 360043261 Test: ensure that the screenshot UI doesn't time out if there's a second screenshot, even if it's invoked at the end of the timeout period Flag: EXEMPT trivial change Change-Id: I5aee655880fcd0693ef45b18ae09be9c4c4d0d52 --- .../src/com/android/systemui/screenshot/ScreenshotController.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt index 29208f89c4e1..6b96bc0ad631 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt @@ -169,6 +169,7 @@ internal constructor( requestCallback: TakeScreenshotService.RequestCallback, ) { Assert.isMainThread() + screenshotHandler.resetTimeout() currentRequestCallback = requestCallback if (screenshot.type == TAKE_SCREENSHOT_FULLSCREEN && screenshot.bitmap == null) { -- GitLab From 3bf69d6d2a6a0852c149d37304472d82a2f9f961 Mon Sep 17 00:00:00 2001 From: "seokgyun.hong" Date: Fri, 19 Jul 2024 10:26:21 +0900 Subject: [PATCH 007/447] Prevent calls to StatusBarManagerInternal from visible background users Visible background users have access to UI on assigned displays on devices that have config_multiuserVisibleBackgroundUsers enabled. The main use case is Automotive's multi-display Whole Cabin experience where passengers (modeled as visible background users) can interact with the display in front of them concurrently with the driver (modeled as the the current user) interacting with driver's display. - Calls to StatusBarManagerInternal trigger callbacks to the registered IStatusBar for the current user. - However, StatusBarManagerInternal APIs can be called from not only the current user but also visible background users. - We should prevent this to ensure that visible background users do not interfere with the current user's experience. Bug: 332222893 Flag: EXEMPT bugfix Test: atest MagnificationConnectionManagerTest atest WmTests:PhoneWindowManagerTests (cherry picked from https://partner-android-review.googlesource.com/q/commit:62538ec79f939853bd4ea75e81f4f46204fce72d) Change-Id: Icdc6515e69e8044cf972a9e14e2fdd7f7a4b6958 --- .../AccessibilityManagerService.java | 6 ++++ .../MagnificationConnectionManager.java | 10 ++++++ .../server/policy/PhoneWindowManager.java | 36 +++++++++++++++++-- .../server/search/SearchManagerService.java | 12 +++++++ .../MagnificationConnectionManagerTest.java | 7 ++++ 5 files changed, 68 insertions(+), 3 deletions(-) diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 7580b697b516..49f15e46894d 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -3653,6 +3653,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return; } + // Magnification connection should not be requested for visible background users. + // (b/332222893) + if (mUmi.isVisibleBackgroundFullUser(userState.mUserId)) { + return; + } + final boolean shortcutEnabled = (userState.isShortcutMagnificationEnabledLocked() || userState.isMagnificationSingleFingerTripleTapEnabledLocked() || (Flags.enableMagnificationMultipleFingerMultipleTapGesture() diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java index 19e3e690924e..fe06406e580a 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java @@ -19,6 +19,7 @@ package com.android.server.accessibility.magnification; import static android.accessibilityservice.AccessibilityTrace.FLAGS_MAGNIFICATION_CONNECTION; import static android.accessibilityservice.AccessibilityTrace.FLAGS_MAGNIFICATION_CONNECTION_CALLBACK; import static android.os.Build.HW_TIMEOUT_MULTIPLIER; +import static android.os.UserHandle.getCallingUserId; import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK; import static com.android.server.accessibility.AccessibilityManagerService.INVALID_SERVICE_ID; @@ -54,6 +55,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.android.server.accessibility.AccessibilityTraceManager; +import com.android.server.pm.UserManagerInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.wm.WindowManagerInternal; @@ -209,6 +211,7 @@ public class MagnificationConnectionManager implements private final Callback mCallback; private final AccessibilityTraceManager mTrace; private final MagnificationScaleProvider mScaleProvider; + private final UserManagerInternal mUserManagerInternal; public MagnificationConnectionManager(Context context, Object lock, @NonNull Callback callback, AccessibilityTraceManager trace, MagnificationScaleProvider scaleProvider) { @@ -217,6 +220,7 @@ public class MagnificationConnectionManager implements mCallback = callback; mTrace = trace; mScaleProvider = scaleProvider; + mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); } /** @@ -280,12 +284,18 @@ public class MagnificationConnectionManager implements * Requests {@link IMagnificationConnection} through * {@link StatusBarManagerInternal#requestMagnificationConnection(boolean)} and * destroys all window magnifications if necessary. + * NOTE: Currently, this is not allowed to call from visible background users.(b/332222893) * * @param connect {@code true} if needs connection, otherwise set the connection to null and * destroy all window magnifications. * @return {@code true} if {@link IMagnificationConnection} state is going to change. */ public boolean requestConnection(boolean connect) { + final int callingUserId = getCallingUserId(); + if (mUserManagerInternal.isVisibleBackgroundFullUser(callingUserId)) { + throw new SecurityException("Visible background user(u" + callingUserId + + " is not permitted to request magnification connection."); + } if (DBG) { Slog.d(TAG, "requestConnection :" + connect); } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index ca6051874d78..e0c4ebeb9f89 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -734,7 +734,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { KeyEvent.KEYCODE_ASSIST, KeyEvent.KEYCODE_VOICE_ASSIST, KeyEvent.KEYCODE_MUTE, - KeyEvent.KEYCODE_VOLUME_MUTE + KeyEvent.KEYCODE_VOLUME_MUTE, + KeyEvent.KEYCODE_RECENT_APPS, + KeyEvent.KEYCODE_APP_SWITCH, + KeyEvent.KEYCODE_NOTIFICATION )); private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3; @@ -2077,12 +2080,21 @@ public class PhoneWindowManager implements WindowManagerPolicy { } switch (mDoubleTapOnHomeBehavior) { case DOUBLE_TAP_HOME_RECENT_SYSTEM_UI: + if (!isKeyEventForCurrentUser( + event.getDisplayId(), event.getKeyCode(), "toggleRecentApps")) { + break; + } notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH); mHomeConsumed = true; toggleRecentApps(); break; case DOUBLE_TAP_HOME_PIP_MENU: + if (!isKeyEventForCurrentUser( + event.getDisplayId(), event.getKeyCode(), + "showPictureInPictureMenu")) { + break; + } mHomeConsumed = true; showPictureInPictureMenuInternal(); break; @@ -2111,12 +2123,20 @@ public class PhoneWindowManager implements WindowManagerPolicy { } break; case LONG_PRESS_HOME_ASSIST: + if (!isKeyEventForCurrentUser( + event.getDisplayId(), event.getKeyCode(), "launchAssistAction")) { + break; + } notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT); launchAssistAction(null, event.getDeviceId(), event.getEventTime(), AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS); break; case LONG_PRESS_HOME_NOTIFICATION_PANEL: + if (!isKeyEventForCurrentUser( + event.getDisplayId(), event.getKeyCode(), "toggleNotificationPanel")) { + break; + } notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL); toggleNotificationPanel(); @@ -3477,7 +3497,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (isUserSetupComplete() && !keyguardOn) { if (mModifierShortcutManager.interceptKey(event)) { - dismissKeyboardShortcutsMenu(); + if (isKeyEventForCurrentUser( + event.getDisplayId(), event.getKeyCode(), + "dismissKeyboardShortcutsMenu")) { + dismissKeyboardShortcutsMenu(); + } mPendingMetaAction = false; mPendingCapsLockToggle = false; return true; @@ -4733,7 +4757,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { } // no keyguard stuff to worry about, just launch home! - if (mRecentsVisible) { + // If Recents is visible and the action is not from visible background users, + // hide Recents and notify it to launch Home. + if (mRecentsVisible + && (!mVisibleBackgroundUsersEnabled || displayId == DEFAULT_DISPLAY)) { try { ActivityManager.getService().stopAppSwitches(); } catch (RemoteException e) {} @@ -5477,6 +5504,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { * Notify the StatusBar that a system key was pressed. */ private void sendSystemKeyToStatusBar(KeyEvent key) { + if (!isKeyEventForCurrentUser(key.getDisplayId(), key.getKeyCode(), "handleSystemKey")) { + return; + } IStatusBarService statusBar = getStatusBarService(); if (statusBar != null) { try { diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java index 9b39fa1e177c..a49a9fdf4cca 100644 --- a/services/core/java/com/android/server/search/SearchManagerService.java +++ b/services/core/java/com/android/server/search/SearchManagerService.java @@ -46,6 +46,7 @@ import com.android.internal.util.IndentingPrintWriter; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.SystemService.TargetUser; +import com.android.server.pm.UserManagerInternal; import com.android.server.statusbar.StatusBarManagerInternal; import java.io.FileDescriptor; @@ -89,6 +90,8 @@ public class SearchManagerService extends ISearchManager.Stub { @GuardedBy("mSearchables") private final SparseArray mSearchables = new SparseArray<>(); + private final UserManagerInternal mUserManagerInternal; + /** * Initializes the Search Manager service in the provided system context. * Only one instance of this object should be created! @@ -101,6 +104,7 @@ public class SearchManagerService extends ISearchManager.Stub { mMyPackageMonitor.register(context, null, UserHandle.ALL, true); new GlobalSearchProviderObserver(context.getContentResolver()); mHandler = BackgroundThread.getHandler(); + mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); } private Searchables getSearchables(int userId) { @@ -336,6 +340,14 @@ public class SearchManagerService extends ISearchManager.Stub { @Override public void launchAssist(int userHandle, Bundle args) { + // Currently, visible background users are not allowed to launch assist.(b/332222893) + // TODO(b/368715893): Consider indirect calls from system service when checking the + // calling user. + final int callingUserId = UserHandle.getCallingUserId(); + if (mUserManagerInternal.isVisibleBackgroundFullUser(callingUserId)) { + throw new SecurityException("Visible background user(u" + callingUserId + + ") is not permitted to launch assist."); + } StatusBarManagerInternal statusBarManager = LocalServices.getService(StatusBarManagerInternal.class); if (statusBarManager != null) { diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java index 87fe6cf8f283..6d27dddfc357 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java @@ -62,6 +62,7 @@ import androidx.test.filters.FlakyTest; import com.android.internal.util.test.FakeSettingsProvider; import com.android.server.LocalServices; import com.android.server.accessibility.AccessibilityTraceManager; +import com.android.server.pm.UserManagerInternal; import com.android.server.statusbar.StatusBarManagerInternal; import org.junit.Before; @@ -92,12 +93,16 @@ public class MagnificationConnectionManagerTest { private MagnificationConnectionManager.Callback mMockCallback; private MockContentResolver mResolver; private MagnificationConnectionManager mMagnificationConnectionManager; + @Mock + private UserManagerInternal mMockUserManagerInternal; @Before public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); LocalServices.removeServiceForTest(StatusBarManagerInternal.class); + LocalServices.removeServiceForTest(UserManagerInternal.class); LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal); + LocalServices.addService(UserManagerInternal.class, mMockUserManagerInternal); mResolver = new MockContentResolver(); mMockConnection = new MockMagnificationConnection(); mMagnificationConnectionManager = new MagnificationConnectionManager(mContext, new Object(), @@ -110,6 +115,8 @@ public class MagnificationConnectionManagerTest { Settings.Secure.putFloatForUser(mResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 2.5f, CURRENT_USER_ID); + + when(mMockUserManagerInternal.isVisibleBackgroundFullUser(anyInt())).thenReturn(false); } private void stubSetConnection(boolean needDelay) { -- GitLab From 6148e6cad83947dc4ae125e091eaa1ad4af1eb48 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 4 Jul 2024 15:12:19 +1000 Subject: [PATCH 008/447] AudioFormat: Add ENCODING_AC4_L4 Test: m Bug: 266537650 Change-Id: I2b8d2b9089ed800e0e53687d5b3dbb52bcf1305a --- core/api/current.txt | 1 + core/jni/android_media_AudioFormat.h | 5 +++++ media/java/android/media/AudioFormat.java | 23 +++++++++++++++++++++-- media/java/android/media/AudioSystem.java | 2 ++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 9881a90ff003..cfe73205fe48 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -21308,6 +21308,7 @@ package android.media { field public static final int ENCODING_AAC_XHE = 16; // 0x10 field public static final int ENCODING_AC3 = 5; // 0x5 field public static final int ENCODING_AC4 = 17; // 0x11 + field @FlaggedApi("android.media.audio.dolby_ac4_level4_encoding_api") public static final int ENCODING_AC4_L4 = 32; // 0x20 field public static final int ENCODING_DEFAULT = 1; // 0x1 field public static final int ENCODING_DOLBY_MAT = 19; // 0x13 field public static final int ENCODING_DOLBY_TRUEHD = 14; // 0xe diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h index a9b19062b764..704aef3cd131 100644 --- a/core/jni/android_media_AudioFormat.h +++ b/core/jni/android_media_AudioFormat.h @@ -50,6 +50,7 @@ #define ENCODING_DTS_HD_MA 29 #define ENCODING_DTS_UHD_P2 30 #define ENCODING_DSD 31 +#define ENCODING_AC4_L4 32 #define ENCODING_INVALID 0 #define ENCODING_DEFAULT 1 @@ -95,6 +96,8 @@ static inline audio_format_t audioFormatToNative(int audioFormat) return AUDIO_FORMAT_AAC_XHE; case ENCODING_AC4: return AUDIO_FORMAT_AC4; + case ENCODING_AC4_L4: + return AUDIO_FORMAT_AC4_L4; case ENCODING_E_AC3_JOC: return AUDIO_FORMAT_E_AC3_JOC; case ENCODING_DEFAULT: @@ -177,6 +180,8 @@ static inline int audioFormatFromNative(audio_format_t nativeFormat) return ENCODING_AAC_XHE; case AUDIO_FORMAT_AC4: return ENCODING_AC4; + case AUDIO_FORMAT_AC4_L4: + return ENCODING_AC4_L4; case AUDIO_FORMAT_E_AC3_JOC: return ENCODING_E_AC3_JOC; case AUDIO_FORMAT_MAT: diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java index c90c44152440..0da8371bc824 100644 --- a/media/java/android/media/AudioFormat.java +++ b/media/java/android/media/AudioFormat.java @@ -16,6 +16,9 @@ package android.media; +import static android.media.audio.Flags.FLAG_DOLBY_AC4_LEVEL4_ENCODING_API; + +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; @@ -309,7 +312,7 @@ public final class AudioFormat implements Parcelable { public static final int ENCODING_AAC_ELD = 15; /** Audio data format: AAC xHE compressed */ public static final int ENCODING_AAC_XHE = 16; - /** Audio data format: AC-4 sync frame transport format */ + /** Audio data format: AC-4 (levels 0-3) sync frame transport format */ public static final int ENCODING_AC4 = 17; /** Audio data format: E-AC-3-JOC compressed * E-AC-3-JOC streams can be decoded by downstream devices supporting {@link #ENCODING_E_AC3}. @@ -375,6 +378,9 @@ public final class AudioFormat implements Parcelable { public static final int ENCODING_DTS_UHD_P2 = 30; /** Audio data format: Direct Stream Digital */ public static final int ENCODING_DSD = 31; + /** Audio data format: AC-4 level 4 sync frame transport format */ + @FlaggedApi(FLAG_DOLBY_AC4_LEVEL4_ENCODING_API) + public static final int ENCODING_AC4_L4 = 32; /** @hide */ public static String toLogFriendlyEncoding(int enc) { @@ -413,6 +419,8 @@ public final class AudioFormat implements Parcelable { return "ENCODING_AAC_XHE"; case ENCODING_AC4: return "ENCODING_AC4"; + case ENCODING_AC4_L4: + return "ENCODING_AC4_L4"; case ENCODING_E_AC3_JOC: return "ENCODING_E_AC3_JOC"; case ENCODING_DOLBY_MAT: @@ -823,6 +831,7 @@ public final class AudioFormat implements Parcelable { case ENCODING_AAC_ELD: case ENCODING_AAC_XHE: case ENCODING_AC4: + case ENCODING_AC4_L4: case ENCODING_E_AC3_JOC: case ENCODING_DOLBY_MAT: case ENCODING_OPUS: @@ -863,6 +872,7 @@ public final class AudioFormat implements Parcelable { case ENCODING_AAC_ELD: case ENCODING_AAC_XHE: case ENCODING_AC4: + case ENCODING_AC4_L4: case ENCODING_E_AC3_JOC: case ENCODING_DOLBY_MAT: case ENCODING_OPUS: @@ -908,6 +918,7 @@ public final class AudioFormat implements Parcelable { case ENCODING_AAC_ELD: case ENCODING_AAC_XHE: case ENCODING_AC4: + case ENCODING_AC4_L4: case ENCODING_E_AC3_JOC: case ENCODING_DOLBY_MAT: case ENCODING_OPUS: @@ -950,6 +961,7 @@ public final class AudioFormat implements Parcelable { case ENCODING_AAC_ELD: case ENCODING_AAC_XHE: case ENCODING_AC4: + case ENCODING_AC4_L4: case ENCODING_E_AC3_JOC: case ENCODING_DOLBY_MAT: case ENCODING_OPUS: @@ -1238,6 +1250,7 @@ public final class AudioFormat implements Parcelable { case ENCODING_AAC_ELD: case ENCODING_AAC_XHE: case ENCODING_AC4: + case ENCODING_AC4_L4: case ENCODING_E_AC3_JOC: case ENCODING_DOLBY_MAT: case ENCODING_OPUS: @@ -1468,6 +1481,7 @@ public final class AudioFormat implements Parcelable { ENCODING_AAC_ELD, ENCODING_AAC_XHE, ENCODING_AC4, + ENCODING_AC4_L4, ENCODING_E_AC3_JOC, ENCODING_DOLBY_MAT, ENCODING_OPUS, @@ -1506,6 +1520,7 @@ public final class AudioFormat implements Parcelable { ENCODING_AAC_ELD, ENCODING_AAC_XHE, ENCODING_AC4, + ENCODING_AC4_L4, ENCODING_E_AC3_JOC, ENCODING_DOLBY_MAT, ENCODING_OPUS, @@ -1533,6 +1548,7 @@ public final class AudioFormat implements Parcelable { ENCODING_AAC_LC, ENCODING_DOLBY_TRUEHD, ENCODING_AC4, + ENCODING_AC4_L4, ENCODING_E_AC3_JOC, ENCODING_DOLBY_MAT, ENCODING_MPEGH_BL_L3, @@ -1554,6 +1570,7 @@ public final class AudioFormat implements Parcelable { ENCODING_AAC_LC, ENCODING_DOLBY_TRUEHD, ENCODING_AC4, + ENCODING_AC4_L4, ENCODING_E_AC3_JOC, ENCODING_DOLBY_MAT, ENCODING_MPEGH_BL_L3, @@ -1592,7 +1609,9 @@ public final class AudioFormat implements Parcelable { case ENCODING_DOLBY_TRUEHD: return "Dolby TrueHD"; case ENCODING_AC4: - return "Dolby AC-4"; + return "Dolby AC-4 levels 0-3"; + case ENCODING_AC4_L4: + return "Dolby AC-4 level 4"; case ENCODING_E_AC3_JOC: return "Dolby Atmos in Dolby Digital Plus"; case ENCODING_DOLBY_MAT: diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 2d0e7abbe890..7b8702fd5271 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -542,6 +542,8 @@ public class AudioSystem return "AUDIO_FORMAT_AAC_LATM_HE_V2"; // (AAC_LATM | AAC_SUB_HE_V2) case /* AUDIO_FORMAT_E_AC3_JOC */ 0xA000001: return "AUDIO_FORMAT_E_AC3_JOC"; // (E_AC3 | E_AC3_SUB_JOC) + case /* AUDIO_FORMAT_AC4_L4 */ 0x22000001: + return "AUDIO_FORMAT_AC4_L4"; // (AC4 | AC4_SUB_L4) case /* AUDIO_FORMAT_MAT_1_0 */ 0x24000001: return "AUDIO_FORMAT_MAT_1_0"; // (MAT | MAT_SUB_1_0) case /* AUDIO_FORMAT_MAT_2_0 */ 0x24000002: -- GitLab From 4926889715c9a3458d1b3ddb7f29f5dfb04c2be2 Mon Sep 17 00:00:00 2001 From: Chris Li Date: Fri, 27 Sep 2024 05:11:07 +0000 Subject: [PATCH 009/447] Update AE flicker test bug component Need to add at lowest level to take effect Bug: 367899283 Test: build Change-Id: Ia54312057bfae54a2fb1af8ea864ece5f7ec6351 --- .../com/android/server/wm/flicker/activityembedding}/OWNERS | 0 .../com/android/server/wm/flicker/activityembedding/close/OWNERS | 1 + .../server/wm/flicker/activityembedding/layoutchange/OWNERS | 1 + .../com/android/server/wm/flicker/activityembedding/open/OWNERS | 1 + .../com/android/server/wm/flicker/activityembedding/pip/OWNERS | 1 + .../android/server/wm/flicker/activityembedding/rotation/OWNERS | 1 + .../com/android/server/wm/flicker/activityembedding/rtl/OWNERS | 1 + .../server/wm/flicker/activityembedding/splitscreen/OWNERS | 1 + 8 files changed, 7 insertions(+) rename tests/FlickerTests/ActivityEmbedding/{ => src/com/android/server/wm/flicker/activityembedding}/OWNERS (100%) create mode 100644 tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/close/OWNERS create mode 100644 tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/layoutchange/OWNERS create mode 100644 tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OWNERS create mode 100644 tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/pip/OWNERS create mode 100644 tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/OWNERS create mode 100644 tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rtl/OWNERS create mode 100644 tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/OWNERS diff --git a/tests/FlickerTests/ActivityEmbedding/OWNERS b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/OWNERS similarity index 100% rename from tests/FlickerTests/ActivityEmbedding/OWNERS rename to tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/OWNERS diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/close/OWNERS b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/close/OWNERS new file mode 100644 index 000000000000..981b3168cdbb --- /dev/null +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/close/OWNERS @@ -0,0 +1 @@ +# Bug component: 1168918 diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/layoutchange/OWNERS b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/layoutchange/OWNERS new file mode 100644 index 000000000000..981b3168cdbb --- /dev/null +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/layoutchange/OWNERS @@ -0,0 +1 @@ +# Bug component: 1168918 diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OWNERS b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OWNERS new file mode 100644 index 000000000000..981b3168cdbb --- /dev/null +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/OWNERS @@ -0,0 +1 @@ +# Bug component: 1168918 diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/pip/OWNERS b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/pip/OWNERS new file mode 100644 index 000000000000..981b3168cdbb --- /dev/null +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/pip/OWNERS @@ -0,0 +1 @@ +# Bug component: 1168918 diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/OWNERS b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/OWNERS new file mode 100644 index 000000000000..981b3168cdbb --- /dev/null +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/OWNERS @@ -0,0 +1 @@ +# Bug component: 1168918 diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rtl/OWNERS b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rtl/OWNERS new file mode 100644 index 000000000000..981b3168cdbb --- /dev/null +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rtl/OWNERS @@ -0,0 +1 @@ +# Bug component: 1168918 diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/OWNERS b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/OWNERS new file mode 100644 index 000000000000..981b3168cdbb --- /dev/null +++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/OWNERS @@ -0,0 +1 @@ +# Bug component: 1168918 -- GitLab From b8999e7414920fbe301e871e722e43eb0d273f27 Mon Sep 17 00:00:00 2001 From: Tom Chan Date: Fri, 27 Sep 2024 17:53:19 +0000 Subject: [PATCH 010/447] Add enable_concurrent_wearable_connections feature flag Bug: 358133158 Test: It builds Flag: android.app.wearable.enable_concurrent_wearable_connections Change-Id: I0ec1c7af4e6f3d428c29cfbc44440302a5360bb6 --- core/java/android/app/wearable/flags.aconfig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/java/android/app/wearable/flags.aconfig b/core/java/android/app/wearable/flags.aconfig index b68bafe279bf..534f46172fc1 100644 --- a/core/java/android/app/wearable/flags.aconfig +++ b/core/java/android/app/wearable/flags.aconfig @@ -38,4 +38,12 @@ flag { namespace: "machine_learning" description: "This flag enables the APIs related to hotword in WearableSensingManager and WearableSensingService." bug: "310055381" +} + +flag { + name: "enable_concurrent_wearable_connections" + is_exported: true + namespace: "machine_learning" + description: "This flag enables the APIs for providing multiple concurrent connections to the WearableSensingService." + bug: "358133158" } \ No newline at end of file -- GitLab From 178e8c74d92b125b87893128716f4db6bc89ab0f Mon Sep 17 00:00:00 2001 From: tonihei Date: Fri, 27 Sep 2024 18:06:16 +0100 Subject: [PATCH 011/447] Remove STATE_PLAYBACK_SUPPRESSED The state should not be part of the FLAG_ENABLE_NOTIFYING_ACTIVITY_MANAGER_WITH_MEDIA_SESSION_STATUS_CHANGE flag, so removing it entirely for now until we decide how exactly we'd like to use it. Test: Symbol unused Bug: 335561702 Change-Id: Ica7bb7f5ef2b6fe285e7bc4be6a25be6182b1160 --- core/api/current.txt | 1 - .../android/media/session/PlaybackState.java | 44 +++++++------------ 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 9881a90ff003..9a4faaa0ac67 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -26811,7 +26811,6 @@ package android.media.session { field public static final int STATE_FAST_FORWARDING = 4; // 0x4 field public static final int STATE_NONE = 0; // 0x0 field public static final int STATE_PAUSED = 2; // 0x2 - field @FlaggedApi("com.android.media.flags.enable_notifying_activity_manager_with_media_session_status_change") public static final int STATE_PLAYBACK_SUPPRESSED = 12; // 0xc field public static final int STATE_PLAYING = 3; // 0x3 field public static final int STATE_REWINDING = 5; // 0x5 field public static final int STATE_SKIPPING_TO_NEXT = 10; // 0xa diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java index 47637b82111a..290d49b31eb7 100644 --- a/media/java/android/media/session/PlaybackState.java +++ b/media/java/android/media/session/PlaybackState.java @@ -15,10 +15,8 @@ */ package android.media.session; -import static com.android.media.flags.Flags.FLAG_ENABLE_NOTIFYING_ACTIVITY_MANAGER_WITH_MEDIA_SESSION_STATUS_CHANGE; import android.annotation.DrawableRes; -import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.LongDef; import android.annotation.Nullable; @@ -187,13 +185,21 @@ public final class PlaybackState implements Parcelable { */ public static final long ACTION_SET_PLAYBACK_SPEED = 1 << 22; - /** - * @hide - */ - @IntDef({STATE_NONE, STATE_STOPPED, STATE_PAUSED, STATE_PLAYING, STATE_FAST_FORWARDING, - STATE_REWINDING, STATE_BUFFERING, STATE_ERROR, STATE_CONNECTING, - STATE_SKIPPING_TO_PREVIOUS, STATE_SKIPPING_TO_NEXT, STATE_SKIPPING_TO_QUEUE_ITEM, - STATE_PLAYBACK_SUPPRESSED}) + /** @hide */ + @IntDef({ + STATE_NONE, + STATE_STOPPED, + STATE_PAUSED, + STATE_PLAYING, + STATE_FAST_FORWARDING, + STATE_REWINDING, + STATE_BUFFERING, + STATE_ERROR, + STATE_CONNECTING, + STATE_SKIPPING_TO_PREVIOUS, + STATE_SKIPPING_TO_NEXT, + STATE_SKIPPING_TO_QUEUE_ITEM + }) @Retention(RetentionPolicy.SOURCE) public @interface State {} @@ -289,19 +295,6 @@ public final class PlaybackState implements Parcelable { */ public static final int STATE_SKIPPING_TO_QUEUE_ITEM = 11; - /** - * State indicating that playback is paused due to an external transient interruption, like a - * phone call. - * - *

This state is different from {@link #STATE_PAUSED} in that it is deemed transitory, - * possibly allowing the service associated to the session in this state to run in the - * foreground. - * - * @see Builder#setState - */ - @FlaggedApi(FLAG_ENABLE_NOTIFYING_ACTIVITY_MANAGER_WITH_MEDIA_SESSION_STATUS_CHANGE) - public static final int STATE_PLAYBACK_SUPPRESSED = 12; - /** * Use this value for the position to indicate the position is not known. */ @@ -401,7 +394,6 @@ public final class PlaybackState implements Parcelable { *

  • {@link PlaybackState#STATE_SKIPPING_TO_PREVIOUS}
  • *
  • {@link PlaybackState#STATE_SKIPPING_TO_NEXT}
  • *
  • {@link PlaybackState#STATE_SKIPPING_TO_QUEUE_ITEM}
  • - *
  • {@link PlaybackState#STATE_PLAYBACK_SUPPRESSED}
  • * */ @State @@ -525,7 +517,6 @@ public final class PlaybackState implements Parcelable { *
  • {@link #STATE_SKIPPING_TO_NEXT}
  • *
  • {@link #STATE_SKIPPING_TO_PREVIOUS}
  • *
  • {@link #STATE_SKIPPING_TO_QUEUE_ITEM}
  • - *
  • {@link #STATE_PLAYBACK_SUPPRESSED}
  • * */ public boolean isActive() { @@ -538,7 +529,6 @@ public final class PlaybackState implements Parcelable { case PlaybackState.STATE_BUFFERING: case PlaybackState.STATE_CONNECTING: case PlaybackState.STATE_PLAYING: - case PlaybackState.STATE_PLAYBACK_SUPPRESSED: return true; } return false; @@ -584,8 +574,6 @@ public final class PlaybackState implements Parcelable { return "SKIPPING_TO_NEXT"; case STATE_SKIPPING_TO_QUEUE_ITEM: return "SKIPPING_TO_QUEUE_ITEM"; - case STATE_PLAYBACK_SUPPRESSED: - return "STATE_PLAYBACK_SUPPRESSED"; default: return "UNKNOWN"; } @@ -823,7 +811,6 @@ public final class PlaybackState implements Parcelable { *
  • {@link PlaybackState#STATE_SKIPPING_TO_PREVIOUS}
  • *
  • {@link PlaybackState#STATE_SKIPPING_TO_NEXT}
  • *
  • {@link PlaybackState#STATE_SKIPPING_TO_QUEUE_ITEM}
  • - *
  • {@link PlaybackState#STATE_PLAYBACK_SUPPRESSED}
  • * * * @param state The current state of playback. @@ -868,7 +855,6 @@ public final class PlaybackState implements Parcelable { *
  • {@link PlaybackState#STATE_SKIPPING_TO_PREVIOUS}
  • *
  • {@link PlaybackState#STATE_SKIPPING_TO_NEXT}
  • *
  • {@link PlaybackState#STATE_SKIPPING_TO_QUEUE_ITEM}
  • - *
  • {@link PlaybackState#STATE_PLAYBACK_SUPPRESSED}
  • * * * @param state The current state of playback. -- GitLab From dbcd0dd8f4837cc43ef3081f6ed020ccee753ba4 Mon Sep 17 00:00:00 2001 From: Yiyi Shen Date: Sun, 29 Sep 2024 19:51:02 +0800 Subject: [PATCH 012/447] [Audiosharing] Fix primary device summary in call During call, BT stack will keep the broadcast in a hysteresis mode, however BT stack will remove the fallback group id, which leads the primary device summary shows "Active (media only) even though it is listening to the call. Here we check if there is active device on LE_AUDIO profile when the fallback group id is removed. The active device on LE_AUDIO profile should be the primary device in call. Test: atest Bug: 355222285 Bug: 362714470 Flag: com.android.settingslib.flags.enable_le_audio_sharing Change-Id: I7d32c1951aca22bbc3087985389f983eea45cc94 --- .../bluetooth/CachedBluetoothDevice.java | 11 +++--- .../bluetooth/CachedBluetoothDeviceTest.java | 36 ++++++++++++++----- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 92da2be60d1e..8845d2ee5369 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -38,7 +38,6 @@ import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; import android.os.SystemClock; -import android.provider.Settings; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.ForegroundColorSpan; @@ -1291,12 +1290,10 @@ public class CachedBluetoothDevice implements Comparable if (BluetoothUtils.hasConnectedBroadcastSource(this, mBluetoothManager)) { // Gets summary for the buds which are in the audio sharing. int groupId = BluetoothUtils.getGroupId(this); - if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID - && groupId - == Settings.Secure.getInt( - mContext.getContentResolver(), - "bluetooth_le_broadcast_fallback_active_group_id", - BluetoothCsipSetCoordinator.GROUP_ID_INVALID)) { + int primaryGroupId = BluetoothUtils.getPrimaryGroupIdForBroadcast( + mContext.getContentResolver()); + if ((primaryGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) + ? (groupId == primaryGroupId) : isActiveDevice(BluetoothProfile.LE_AUDIO)) { // The buds are primary buds return getSummaryWithBatteryInfo( R.string.bluetooth_active_battery_level_untethered, diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java index 0d814947527c..70cb2ef016ec 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java @@ -1977,12 +1977,12 @@ public class CachedBluetoothDeviceTest { } @Test - public void getConnectionSummary_isBroadcastPrimary_returnActive() { + public void getConnectionSummary_isBroadcastPrimary_fallbackDevice_returnActive() { when(mBroadcast.isEnabled(any())).thenReturn(true); when(mCachedDevice.getDevice()).thenReturn(mDevice); Settings.Secure.putInt( mContext.getContentResolver(), - "bluetooth_le_broadcast_fallback_active_group_id", + BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 1); List bisSyncState = new ArrayList<>(); @@ -1992,12 +1992,30 @@ public class CachedBluetoothDeviceTest { sourceList.add(mLeBroadcastReceiveState); when(mAssistant.getAllSources(any())).thenReturn(sourceList); - when(mCachedDevice.getGroupId()) - .thenReturn( - Settings.Secure.getInt( - mContext.getContentResolver(), - "bluetooth_le_broadcast_fallback_active_group_id", - BluetoothCsipSetCoordinator.GROUP_ID_INVALID)); + when(mCachedDevice.getGroupId()).thenReturn(1); + + assertThat(mCachedDevice.getConnectionSummary(false)) + .isEqualTo(mContext.getString(R.string.bluetooth_active_no_battery_level)); + } + + @Test + public void getConnectionSummary_isBroadcastPrimary_activeDevice_returnActive() { + when(mBroadcast.isEnabled(any())).thenReturn(true); + when(mCachedDevice.getDevice()).thenReturn(mDevice); + Settings.Secure.putInt( + mContext.getContentResolver(), + BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), + BluetoothCsipSetCoordinator.GROUP_ID_INVALID); + + List bisSyncState = new ArrayList<>(); + bisSyncState.add(1L); + when(mLeBroadcastReceiveState.getBisSyncState()).thenReturn(bisSyncState); + List sourceList = new ArrayList<>(); + sourceList.add(mLeBroadcastReceiveState); + when(mAssistant.getAllSources(any())).thenReturn(sourceList); + + when(mCachedDevice.getGroupId()).thenReturn(1); + when(mCachedDevice.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true); assertThat(mCachedDevice.getConnectionSummary(false)) .isEqualTo(mContext.getString(R.string.bluetooth_active_no_battery_level)); @@ -2009,7 +2027,7 @@ public class CachedBluetoothDeviceTest { when(mCachedDevice.getDevice()).thenReturn(mDevice); Settings.Secure.putInt( mContext.getContentResolver(), - "bluetooth_le_broadcast_fallback_active_group_id", + BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 1); List bisSyncState = new ArrayList<>(); -- GitLab From 2546ec04f21b15f64c4e9256de35c753e80e6c45 Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Mon, 30 Sep 2024 13:02:35 +0900 Subject: [PATCH 013/447] Support string-array type value for bootstrap atom Bug: 366068337 Test: statsd_testdrive 732 733 734 Test: adb install && adb reboot Change-Id: I050cd1c97b38eec29ccecc5ddb2077fb02202ad1 --- core/java/android/os/StatsBootstrapAtomValue.aidl | 1 + .../server/stats/bootstrap/StatsBootstrapAtomService.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/core/java/android/os/StatsBootstrapAtomValue.aidl b/core/java/android/os/StatsBootstrapAtomValue.aidl index a90dfa404ee9..b59bc062648f 100644 --- a/core/java/android/os/StatsBootstrapAtomValue.aidl +++ b/core/java/android/os/StatsBootstrapAtomValue.aidl @@ -26,4 +26,5 @@ union StatsBootstrapAtomValue { float floatValue; String stringValue; byte[] bytesValue; + String[] stringArrayValue; } \ No newline at end of file diff --git a/services/core/java/com/android/server/stats/bootstrap/StatsBootstrapAtomService.java b/services/core/java/com/android/server/stats/bootstrap/StatsBootstrapAtomService.java index 0d420a535415..dcb47a7b60b6 100644 --- a/services/core/java/com/android/server/stats/bootstrap/StatsBootstrapAtomService.java +++ b/services/core/java/com/android/server/stats/bootstrap/StatsBootstrapAtomService.java @@ -62,6 +62,9 @@ public class StatsBootstrapAtomService extends IStatsBootstrapAtomService.Stub { case StatsBootstrapAtomValue.bytesValue: builder.writeByteArray(value.getBytesValue()); break; + case StatsBootstrapAtomValue.stringArrayValue: + builder.writeStringArray(value.getStringArrayValue()); + break; default: Slog.e(TAG, "Unexpected value type " + value.getTag() + " when logging atom " + atom.atomId); -- GitLab From 5bec03ed0899e34ab69345b40614995f32cf5540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 19 Sep 2024 11:17:10 +0000 Subject: [PATCH 014/447] AndroidManifest: add missing bluetooth intents to protected-broadcast These should only be able to be broadcasted by stack Bug: 327737205 Test: manual Change-Id: I4910573ce16a0d713188c67c6046c64e7ab02fe2 --- core/res/AndroidManifest.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index c71f9bde6bf1..e4c56a613f12 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -155,6 +155,7 @@ + @@ -239,6 +240,8 @@ android:name="android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED" /> + + -- GitLab From 7477c2251be8b2a3cf836dba900d91d8abc76865 Mon Sep 17 00:00:00 2001 From: Haijie Hong Date: Mon, 30 Sep 2024 16:50:32 +0800 Subject: [PATCH 015/447] make device setting be able to use either Intent or PendingIntent BUG: 343317785 Test: local tested Flag: com.android.settings.flags.enable_bluetooth_device_details_polish Change-Id: I42583b358255c6d0226b739ba33cadc1d67d860a --- .../ActionSwitchPreference.java | 33 +++-- .../devicesettings/DeviceSettingAction.java | 61 ++++++++ .../DeviceSettingActionType.java | 41 ++++++ .../DeviceSettingIntentAction.java | 132 +++++++++++++++++ .../DeviceSettingPendingIntentAction.java | 133 ++++++++++++++++++ .../devicesettings/DeviceSettingType.java | 1 + .../devicesettings/DeviceSettingsConfig.kt | 3 +- .../repository/DeviceSettingRepository.kt | 55 +++++--- .../shared/model/DeviceSettingModel.kt | 11 +- .../ActionSwitchPreferenceTest.java | 40 ++++-- .../DeviceSettingIntentActionTest.java | 73 ++++++++++ .../DeviceSettingPendingIntentActionTest.java | 83 +++++++++++ 12 files changed, 616 insertions(+), 50 deletions(-) create mode 100644 packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingAction.java create mode 100644 packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingActionType.java create mode 100644 packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingIntentAction.java create mode 100644 packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPendingIntentAction.java create mode 100644 packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingIntentActionTest.java create mode 100644 packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPendingIntentActionTest.java diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreference.java index 1cbb8b4faaa8..2b9088f39b6a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreference.java @@ -16,7 +16,6 @@ package com.android.settingslib.bluetooth.devicesettings; -import android.content.Intent; import android.graphics.Bitmap; import android.os.Bundle; import android.os.Parcel; @@ -36,7 +35,7 @@ public class ActionSwitchPreference extends DeviceSettingPreference implements P private final String mTitle; private final String mSummary; private final Bitmap mIcon; - private final Intent mIntent; + private final DeviceSettingAction mAction; private final boolean mHasSwitch; private final boolean mChecked; private final boolean mIsAllowedChangingState; @@ -46,7 +45,7 @@ public class ActionSwitchPreference extends DeviceSettingPreference implements P String title, @Nullable String summary, @Nullable Bitmap icon, - @Nullable Intent intent, + @NonNull DeviceSettingAction action, boolean hasSwitch, boolean checked, boolean allowChangingState, @@ -56,7 +55,7 @@ public class ActionSwitchPreference extends DeviceSettingPreference implements P mTitle = title; mSummary = summary; mIcon = icon; - mIntent = intent; + mAction = action; mHasSwitch = hasSwitch; mChecked = checked; mIsAllowedChangingState = allowChangingState; @@ -79,13 +78,13 @@ public class ActionSwitchPreference extends DeviceSettingPreference implements P String title = in.readString(); String summary = in.readString(); Bitmap icon = in.readParcelable(Bitmap.class.getClassLoader()); - Intent intent = in.readParcelable(Intent.class.getClassLoader()); + DeviceSettingAction action = DeviceSettingAction.readFromParcel(in); boolean hasSwitch = in.readBoolean(); boolean checked = in.readBoolean(); boolean allowChangingState = in.readBoolean(); Bundle extras = in.readBundle(Bundle.class.getClassLoader()); return new ActionSwitchPreference( - title, summary, icon, intent, hasSwitch, checked, allowChangingState, extras); + title, summary, icon, action, hasSwitch, checked, allowChangingState, extras); } public static final Creator CREATOR = @@ -115,7 +114,7 @@ public class ActionSwitchPreference extends DeviceSettingPreference implements P dest.writeString(mTitle); dest.writeString(mSummary); dest.writeParcelable(mIcon, flags); - dest.writeParcelable(mIntent, flags); + mAction.writeToParcel(dest, flags); dest.writeBoolean(mHasSwitch); dest.writeBoolean(mChecked); dest.writeBoolean(mIsAllowedChangingState); @@ -127,7 +126,7 @@ public class ActionSwitchPreference extends DeviceSettingPreference implements P private String mTitle; private String mSummary; private Bitmap mIcon; - private Intent mIntent; + private DeviceSettingAction mAction = DeviceSettingAction.EMPTY_ACTION; private boolean mHasSwitch; private boolean mChecked; private boolean mIsAllowedChangingState; @@ -170,14 +169,14 @@ public class ActionSwitchPreference extends DeviceSettingPreference implements P } /** - * Sets the Intent to launch when the preference is clicked, optional. + * Sets the action to trigger when the preference is clicked, optional. * - * @param intent The Intent. + * @param action The action to trigger. * @return Returns the Builder object. */ @NonNull - public Builder setIntent(@Nullable Intent intent) { - mIntent = intent; + public Builder setAction(@Nullable DeviceSettingAction action) { + mAction = action == null ? DeviceSettingAction.EMPTY_ACTION : action; return this; } @@ -239,7 +238,7 @@ public class ActionSwitchPreference extends DeviceSettingPreference implements P mTitle, mSummary, mIcon, - mIntent, + mAction, mHasSwitch, mChecked, mIsAllowedChangingState, @@ -278,13 +277,13 @@ public class ActionSwitchPreference extends DeviceSettingPreference implements P } /** - * Gets the Intent to launch when the preference is clicked. + * Gets the action to trigger when the preference is clicked. * * @return Returns the intent to launch. */ - @Nullable - public Intent getIntent() { - return mIntent; + @NonNull + public DeviceSettingAction getAction() { + return mAction; } /** diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingAction.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingAction.java new file mode 100644 index 000000000000..01783e01e971 --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingAction.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.bluetooth.devicesettings; + +import android.os.Parcel; + +import androidx.annotation.NonNull; + +/** An abstract class representing a device setting action. */ +public abstract class DeviceSettingAction { + @DeviceSettingActionType private final int mActionType; + + public static final DeviceSettingAction EMPTY_ACTION = + new DeviceSettingAction(DeviceSettingActionType.DEVICE_SETTING_ACTION_TYPE_UNKNOWN) {}; + + protected DeviceSettingAction(@DeviceSettingActionType int actionType) { + mActionType = actionType; + } + + /** Read a {@link DeviceSettingPreference} instance from {@link Parcel} */ + @NonNull + public static DeviceSettingAction readFromParcel(@NonNull Parcel in) { + int type = in.readInt(); + return switch (type) { + case DeviceSettingActionType.DEVICE_SETTING_ACTION_TYPE_INTENT -> + DeviceSettingIntentAction.readFromParcel(in); + case DeviceSettingActionType.DEVICE_SETTING_ACTION_TYPE_PENDING_INTENT -> + DeviceSettingPendingIntentAction.readFromParcel(in); + default -> EMPTY_ACTION; + }; + } + + /** Writes the instance to {@link Parcel}. */ + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mActionType); + } + + /** + * Gets the setting action type, as defined by IntDef {@link DeviceSettingActionType}. + * + * @return the setting action type. + */ + @DeviceSettingType + public int getActionType() { + return mActionType; + } +} diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingActionType.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingActionType.java new file mode 100644 index 000000000000..13d3583f1928 --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingActionType.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.bluetooth.devicesettings; + +import androidx.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.SOURCE) +@IntDef( + value = { + DeviceSettingActionType.DEVICE_SETTING_ACTION_TYPE_UNKNOWN, + DeviceSettingActionType.DEVICE_SETTING_ACTION_TYPE_INTENT, + DeviceSettingActionType.DEVICE_SETTING_ACTION_TYPE_PENDING_INTENT, + }, + open = true) +public @interface DeviceSettingActionType { + /** Device setting action type is unknown. */ + int DEVICE_SETTING_ACTION_TYPE_UNKNOWN = 0; + + /** Device setting action is an intent to start an activity. */ + int DEVICE_SETTING_ACTION_TYPE_INTENT = 1; + + /** Device setting action is a pending intent. */ + int DEVICE_SETTING_ACTION_TYPE_PENDING_INTENT = 2; +} diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingIntentAction.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingIntentAction.java new file mode 100644 index 000000000000..a1136e65576d --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingIntentAction.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.bluetooth.devicesettings; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; + +import java.util.Objects; + +/** An abstract class representing a device setting action. */ +public class DeviceSettingIntentAction extends DeviceSettingAction implements Parcelable { + private final Intent mIntent; + private final Bundle mExtras; + + DeviceSettingIntentAction(@NonNull Intent intent, @NonNull Bundle extras) { + super(DeviceSettingActionType.DEVICE_SETTING_ACTION_TYPE_INTENT); + validate(intent); + mIntent = intent; + mExtras = extras; + } + + private static void validate(Intent intent) { + if (Objects.isNull(intent)) { + throw new IllegalArgumentException("Intent must be set"); + } + } + + /** Read a {@link DeviceSettingIntentAction} instance from {@link Parcel} */ + @NonNull + public static DeviceSettingIntentAction readFromParcel(@NonNull Parcel in) { + Intent intent = in.readParcelable(Intent.class.getClassLoader()); + Bundle extras = in.readBundle(Bundle.class.getClassLoader()); + return new DeviceSettingIntentAction(intent, extras); + } + + public static final Creator CREATOR = + new Creator<>() { + @Override + @NonNull + public DeviceSettingIntentAction createFromParcel(@NonNull Parcel in) { + in.readInt(); + return readFromParcel(in); + } + + @Override + @NonNull + public DeviceSettingIntentAction[] newArray(int size) { + return new DeviceSettingIntentAction[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + /** Writes the instance to {@link Parcel}. */ + public void writeToParcel(@NonNull Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeParcelable(mIntent, flags); + dest.writeBundle(mExtras); + } + + /** Builder class for {@link DeviceSettingFooterPreference}. */ + public static final class Builder { + private Intent mIntent = null; + private Bundle mExtras = Bundle.EMPTY; + + /** + * Sets the intent for the action. + * + * @param intent The intent. + * @return Returns the Builder object. + */ + @NonNull + public Builder setIntent(@NonNull Intent intent) { + mIntent = intent; + return this; + } + + /** + * Sets the extras bundle. + * + * @return Returns the Builder object. + */ + @NonNull + public Builder setExtras(@NonNull Bundle extras) { + mExtras = extras; + return this; + } + + /** + * Builds the {@link DeviceSettingIntentAction} object. + * + * @return Returns the built {@link DeviceSettingIntentAction} object. + */ + @NonNull + public DeviceSettingIntentAction build() { + return new DeviceSettingIntentAction(mIntent, mExtras); + } + } + + /** Gets the intent. */ + @NonNull + public Intent getIntent() { + return mIntent; + } + + /** Gets the extra bundle. */ + @NonNull + public Bundle getExtras() { + return mExtras; + } +} diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPendingIntentAction.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPendingIntentAction.java new file mode 100644 index 000000000000..3d4282cfb6e4 --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPendingIntentAction.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.bluetooth.devicesettings; + +import android.app.PendingIntent; +import android.content.Intent; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; + +import java.util.Objects; + +/** An abstract class representing a device setting action. */ +public class DeviceSettingPendingIntentAction extends DeviceSettingAction implements Parcelable { + private final PendingIntent mPendingIntent; + private final Bundle mExtras; + + DeviceSettingPendingIntentAction(@NonNull PendingIntent pendingIntent, @NonNull Bundle extras) { + super(DeviceSettingActionType.DEVICE_SETTING_ACTION_TYPE_PENDING_INTENT); + validate(pendingIntent); + mPendingIntent = pendingIntent; + mExtras = extras; + } + + private static void validate(PendingIntent pendingIntent) { + if (Objects.isNull(pendingIntent)) { + throw new IllegalArgumentException("PendingIntent must be set"); + } + } + + /** Read a {@link DeviceSettingPendingIntentAction} instance from {@link Parcel} */ + @NonNull + public static DeviceSettingPendingIntentAction readFromParcel(@NonNull Parcel in) { + PendingIntent pendingIntent = in.readParcelable(Intent.class.getClassLoader()); + Bundle extras = in.readBundle(Bundle.class.getClassLoader()); + return new DeviceSettingPendingIntentAction(pendingIntent, extras); + } + + public static final Creator CREATOR = + new Creator<>() { + @Override + @NonNull + public DeviceSettingPendingIntentAction createFromParcel(@NonNull Parcel in) { + in.readInt(); + return readFromParcel(in); + } + + @Override + @NonNull + public DeviceSettingPendingIntentAction[] newArray(int size) { + return new DeviceSettingPendingIntentAction[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + /** Writes the instance to {@link Parcel}. */ + public void writeToParcel(@NonNull Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeParcelable(mPendingIntent, flags); + dest.writeBundle(mExtras); + } + + /** Builder class for {@link DeviceSettingFooterPreference}. */ + public static final class Builder { + private PendingIntent mPendingIntent = null; + private Bundle mExtras = Bundle.EMPTY; + + /** + * Sets the intent for the action. + * + * @param pendingIntent The pending intent. + * @return Returns the Builder object. + */ + @NonNull + public Builder setPendingIntent(@NonNull PendingIntent pendingIntent) { + mPendingIntent = pendingIntent; + return this; + } + + /** + * Sets the extras bundle. + * + * @return Returns the Builder object. + */ + @NonNull + public Builder setExtras(@NonNull Bundle extras) { + mExtras = extras; + return this; + } + + /** + * Builds the {@link DeviceSettingPendingIntentAction} object. + * + * @return Returns the built {@link DeviceSettingPendingIntentAction} object. + */ + @NonNull + public DeviceSettingPendingIntentAction build() { + return new DeviceSettingPendingIntentAction(mPendingIntent, mExtras); + } + } + + /** Gets the pending intent. */ + @NonNull + public PendingIntent getPendingIntent() { + return mPendingIntent; + } + + /** Gets the extra bundle. */ + @NonNull + public Bundle getExtras() { + return mExtras; + } +} diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingType.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingType.java index ae3bf5e3fc72..3cc13431fb69 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingType.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingType.java @@ -28,6 +28,7 @@ import java.lang.annotation.RetentionPolicy; DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH, DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE, DeviceSettingType.DEVICE_SETTING_TYPE_FOOTER, + DeviceSettingType.DEVICE_SETTING_TYPE_HELP, }, open = true) public @interface DeviceSettingType { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.kt index 5656f38a0a11..36276696e3ec 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.kt +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.kt @@ -63,7 +63,8 @@ data class DeviceSettingsConfig( }, moreSettingsHelpItem = readParcelable( DeviceSettingItem::class.java.classLoader - ) + ), + extras = readBundle((Bundle::class.java.classLoader)) ?: Bundle.EMPTY, ) } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/data/repository/DeviceSettingRepository.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/data/repository/DeviceSettingRepository.kt index 851b614f5279..8537897cb329 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/data/repository/DeviceSettingRepository.kt +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/data/repository/DeviceSettingRepository.kt @@ -22,14 +22,18 @@ import android.text.TextUtils import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.settingslib.bluetooth.devicesettings.ActionSwitchPreference import com.android.settingslib.bluetooth.devicesettings.DeviceSetting +import com.android.settingslib.bluetooth.devicesettings.DeviceSettingAction import com.android.settingslib.bluetooth.devicesettings.DeviceSettingContract +import com.android.settingslib.bluetooth.devicesettings.DeviceSettingFooterPreference +import com.android.settingslib.bluetooth.devicesettings.DeviceSettingHelpPreference import com.android.settingslib.bluetooth.devicesettings.DeviceSettingId +import com.android.settingslib.bluetooth.devicesettings.DeviceSettingIntentAction import com.android.settingslib.bluetooth.devicesettings.DeviceSettingItem +import com.android.settingslib.bluetooth.devicesettings.DeviceSettingPendingIntentAction import com.android.settingslib.bluetooth.devicesettings.DeviceSettingsConfig -import com.android.settingslib.bluetooth.devicesettings.DeviceSettingFooterPreference -import com.android.settingslib.bluetooth.devicesettings.DeviceSettingHelpPreference import com.android.settingslib.bluetooth.devicesettings.MultiTogglePreference import com.android.settingslib.bluetooth.devicesettings.ToggleInfo +import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingActionModel import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingConfigItemModel import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingConfigItemModel.AppProvidedItem import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingConfigItemModel.BuiltinItem.BluetoothProfilesItem @@ -58,7 +62,7 @@ interface DeviceSettingRepository { /** Gets device setting for the bluetooth device. */ fun getDeviceSetting( cachedDevice: CachedBluetoothDevice, - @DeviceSettingId settingId: Int + @DeviceSettingId settingId: Int, ): Flow } @@ -84,7 +88,8 @@ class DeviceSettingRepositoryImpl( coroutineScope, backgroundCoroutineContext, ) - }) + } + ) override suspend fun getDeviceSettingsConfig( cachedDevice: CachedBluetoothDevice @@ -93,7 +98,7 @@ class DeviceSettingRepositoryImpl( override fun getDeviceSetting( cachedDevice: CachedBluetoothDevice, - settingId: Int + settingId: Int, ): Flow = connectionCache.get(cachedDevice).let { connection -> connection.getDeviceSetting(settingId).map { it?.toModel(cachedDevice, connection) } @@ -103,7 +108,8 @@ class DeviceSettingRepositoryImpl( DeviceSettingConfigModel( mainItems = mainContentItems.map { it.toModel() }, moreSettingsItems = moreSettingsItems.map { it.toModel() }, - moreSettingsHelpItem = moreSettingsHelpItem?.toModel(), ) + moreSettingsHelpItem = moreSettingsHelpItem?.toModel(), + ) private fun DeviceSettingItem.toModel(): DeviceSettingConfigItemModel { return if (!TextUtils.isEmpty(preferenceKey)) { @@ -113,7 +119,7 @@ class DeviceSettingRepositoryImpl( highlighted, preferenceKey!!, extras.getStringArrayList(DeviceSettingContract.INVISIBLE_PROFILES) - ?: emptyList() + ?: emptyList(), ) } else { CommonBuiltinItem(settingId, highlighted, preferenceKey!!) @@ -123,9 +129,17 @@ class DeviceSettingRepositoryImpl( } } + private fun DeviceSettingAction.toModel(): DeviceSettingActionModel? = + when (this) { + is DeviceSettingIntentAction -> DeviceSettingActionModel.IntentAction(this.intent) + is DeviceSettingPendingIntentAction -> + DeviceSettingActionModel.PendingIntentAction(this.pendingIntent) + else -> null + } + private fun DeviceSetting.toModel( cachedDevice: CachedBluetoothDevice, - connection: DeviceSettingServiceConnection + connection: DeviceSettingServiceConnection, ): DeviceSettingModel = when (val pref = preference) { is ActionSwitchPreference -> @@ -136,7 +150,7 @@ class DeviceSettingRepositoryImpl( summary = pref.summary, icon = pref.icon?.let { DeviceSettingIcon.BitmapIcon(it) }, isAllowedChangingState = pref.isAllowedChangingState, - intent = pref.intent, + action = pref.action?.toModel(), switchState = if (pref.hasSwitch()) { DeviceSettingStateModel.ActionSwitchPreferenceState(pref.checked) @@ -145,10 +159,7 @@ class DeviceSettingRepositoryImpl( }, updateState = { newState -> coroutineScope.launch(backgroundCoroutineContext) { - connection.updateDeviceSettings( - settingId, - newState.toParcelable(), - ) + connection.updateDeviceSettings(settingId, newState.toParcelable()) } }, ) @@ -167,12 +178,18 @@ class DeviceSettingRepositoryImpl( } }, ) - is DeviceSettingFooterPreference -> DeviceSettingModel.FooterPreference( - cachedDevice = cachedDevice, - id = settingId, footerText = pref.footerText) - is DeviceSettingHelpPreference -> DeviceSettingModel.HelpPreference( - cachedDevice = cachedDevice, - id = settingId, intent = pref.intent) + is DeviceSettingFooterPreference -> + DeviceSettingModel.FooterPreference( + cachedDevice = cachedDevice, + id = settingId, + footerText = pref.footerText, + ) + is DeviceSettingHelpPreference -> + DeviceSettingModel.HelpPreference( + cachedDevice = cachedDevice, + id = settingId, + intent = pref.intent, + ) else -> DeviceSettingModel.Unknown(cachedDevice, settingId) } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/shared/model/DeviceSettingModel.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/shared/model/DeviceSettingModel.kt index 73648acd801e..4d9f2d67dda9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/shared/model/DeviceSettingModel.kt +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/shared/model/DeviceSettingModel.kt @@ -16,6 +16,7 @@ package com.android.settingslib.bluetooth.devicesettings.shared.model +import android.app.PendingIntent import android.content.Intent import android.graphics.Bitmap import androidx.annotation.DrawableRes @@ -34,7 +35,7 @@ sealed interface DeviceSettingModel { val title: String, val summary: String? = null, val icon: DeviceSettingIcon? = null, - val intent: Intent? = null, + val action: DeviceSettingActionModel? = null, val switchState: DeviceSettingStateModel.ActionSwitchPreferenceState? = null, val isAllowedChangingState: Boolean = true, val updateState: ((DeviceSettingStateModel.ActionSwitchPreferenceState) -> Unit)? = null, @@ -83,3 +84,11 @@ sealed interface DeviceSettingIcon { data class ResourceIcon(@DrawableRes val resId: Int) : DeviceSettingIcon } + +/** Models an action in device settings. */ +sealed interface DeviceSettingActionModel { + + data class IntentAction(val intent: Intent) : DeviceSettingActionModel + + data class PendingIntentAction(val pendingIntent: PendingIntent) : DeviceSettingActionModel +} diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceTest.java index 354d0f658544..7148618aaedb 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceTest.java @@ -50,11 +50,15 @@ public final class ActionSwitchPreferenceTest { @Test public void build_withAllFields_successfully() { + DeviceSettingIntentAction action = + new DeviceSettingIntentAction.Builder() + .setIntent(new Intent("intent_action")) + .build(); ActionSwitchPreference unused = new ActionSwitchPreference.Builder() .setTitle("title") .setSummary("summary") - .setIntent(new Intent("intent_action")) + .setAction(action) .setIcon(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)) .setHasSwitch(true) .setChecked(true) @@ -65,14 +69,17 @@ public final class ActionSwitchPreferenceTest { @Test public void getMethods() { - Intent intent = new Intent("intent_action"); + DeviceSettingIntentAction action = + new DeviceSettingIntentAction.Builder() + .setIntent(new Intent("intent_action")) + .build(); Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); - ActionSwitchPreference preference = builder().setIcon(icon).setIntent(intent).build(); + ActionSwitchPreference preference = builder().setIcon(icon).setAction(action).build(); assertThat(preference.getTitle()).isEqualTo("title"); assertThat(preference.getSummary()).isEqualTo("summary"); assertThat(preference.getIcon()).isSameInstanceAs(icon); - assertThat(preference.getIntent()).isSameInstanceAs(intent); + assertThat(preference.getAction()).isSameInstanceAs(action); assertThat(preference.hasSwitch()).isTrue(); assertThat(preference.getChecked()).isTrue(); assertThat(preference.isAllowedChangingState()).isTrue(); @@ -81,16 +88,20 @@ public final class ActionSwitchPreferenceTest { @Test public void parcelOperation() { - Intent intent = new Intent("intent_action"); + DeviceSettingIntentAction action = + new DeviceSettingIntentAction.Builder() + .setIntent(new Intent("intent_action")) + .build(); Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); - ActionSwitchPreference preference = builder().setIcon(icon).setIntent(intent).build(); + ActionSwitchPreference preference = builder().setIcon(icon).setAction(action).build(); ActionSwitchPreference fromParcel = writeAndRead(preference); assertThat(fromParcel.getTitle()).isEqualTo(preference.getTitle()); assertThat(fromParcel.getSummary()).isEqualTo(preference.getSummary()); assertThat(fromParcel.getIcon().sameAs(preference.getIcon())).isTrue(); - assertThat(fromParcel.getIntent().getAction()).isSameInstanceAs("intent_action"); + assertThat(((DeviceSettingIntentAction) fromParcel.getAction()).getIntent().getAction()) + .isEqualTo("intent_action"); assertThat(fromParcel.hasSwitch()).isEqualTo(preference.hasSwitch()); assertThat(fromParcel.getChecked()).isEqualTo(preference.getChecked()); assertThat(fromParcel.isAllowedChangingState()) @@ -102,14 +113,15 @@ public final class ActionSwitchPreferenceTest { @Test public void parcelOperation_noIntent() { Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); - ActionSwitchPreference preference = builder().setIcon(icon).setIntent(null).build(); + ActionSwitchPreference preference = builder().setIcon(icon).setAction(null).build(); ActionSwitchPreference fromParcel = writeAndRead(preference); assertThat(fromParcel.getTitle()).isEqualTo(preference.getTitle()); assertThat(fromParcel.getSummary()).isEqualTo(preference.getSummary()); assertThat(fromParcel.getIcon().sameAs(preference.getIcon())).isTrue(); - assertThat(preference.getIntent()).isNull(); + assertThat(preference.getAction().getActionType()) + .isEqualTo(DeviceSettingActionType.DEVICE_SETTING_ACTION_TYPE_UNKNOWN); assertThat(fromParcel.hasSwitch()).isEqualTo(preference.hasSwitch()); assertThat(fromParcel.getChecked()).isEqualTo(preference.getChecked()); assertThat(fromParcel.isAllowedChangingState()) @@ -120,15 +132,19 @@ public final class ActionSwitchPreferenceTest { @Test public void parcelOperation_noIcon() { - Intent intent = new Intent("intent_action"); - ActionSwitchPreference preference = builder().setIcon(null).setIntent(intent).build(); + DeviceSettingIntentAction action = + new DeviceSettingIntentAction.Builder() + .setIntent(new Intent("intent_action")) + .build(); + ActionSwitchPreference preference = builder().setIcon(null).setAction(action).build(); ActionSwitchPreference fromParcel = writeAndRead(preference); assertThat(fromParcel.getTitle()).isEqualTo(preference.getTitle()); assertThat(fromParcel.getSummary()).isEqualTo(preference.getSummary()); assertThat(fromParcel.getIcon()).isNull(); - assertThat(fromParcel.getIntent().getAction()).isSameInstanceAs("intent_action"); + assertThat(((DeviceSettingIntentAction) fromParcel.getAction()).getIntent().getAction()) + .isEqualTo("intent_action"); assertThat(fromParcel.hasSwitch()).isEqualTo(preference.hasSwitch()); assertThat(fromParcel.getChecked()).isEqualTo(preference.getChecked()); assertThat(fromParcel.isAllowedChangingState()) diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingIntentActionTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingIntentActionTest.java new file mode 100644 index 000000000000..d33db4f13fc4 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingIntentActionTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.bluetooth.devicesettings; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Parcel; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public final class DeviceSettingIntentActionTest { + + @Test + public void getMethods() { + DeviceSettingIntentAction action = + new DeviceSettingIntentAction.Builder() + .setIntent(new Intent("intent_action")) + .setExtras(buildBundle("key1", "value1")) + .build(); + + assertThat(action.getIntent().getAction()).isEqualTo("intent_action"); + assertThat(action.getExtras().getString("key1")).isEqualTo("value1"); + } + + @Test + public void parcelOperation() { + DeviceSettingIntentAction action = + new DeviceSettingIntentAction.Builder() + .setIntent(new Intent("intent_action")) + .setExtras(buildBundle("key1", "value1")) + .build(); + + DeviceSettingIntentAction fromParcel = writeAndRead(action); + + assertThat(fromParcel.getIntent().getAction()).isEqualTo(action.getIntent().getAction()); + assertThat(fromParcel.getExtras().getString("key1")) + .isEqualTo(action.getExtras().getString("key1")); + } + + private Bundle buildBundle(String key, String value) { + Bundle bundle = new Bundle(); + bundle.putString(key, value); + return bundle; + } + + private DeviceSettingIntentAction writeAndRead(DeviceSettingIntentAction preference) { + Parcel parcel = Parcel.obtain(); + preference.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + DeviceSettingIntentAction fromParcel = + DeviceSettingIntentAction.CREATOR.createFromParcel(parcel); + return fromParcel; + } +} diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPendingIntentActionTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPendingIntentActionTest.java new file mode 100644 index 000000000000..3c35147c3a3f --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPendingIntentActionTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.bluetooth.devicesettings; + +import static com.google.common.truth.Truth.assertThat; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Parcel; + +import androidx.test.core.app.ApplicationProvider; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public final class DeviceSettingPendingIntentActionTest { + + private Context mContext = ApplicationProvider.getApplicationContext(); + + @Test + public void getMethods() { + DeviceSettingPendingIntentAction action = + new DeviceSettingPendingIntentAction.Builder() + .setPendingIntent( + PendingIntent.getBroadcast(mContext, 0, new Intent("action"), 0)) + .setExtras(buildBundle("key1", "value1")) + .build(); + + assertThat(action.getPendingIntent()).isSameInstanceAs(action.getPendingIntent()); + assertThat(action.getExtras().getString("key1")).isEqualTo("value1"); + } + + @Test + public void parcelOperation() { + DeviceSettingPendingIntentAction action = + new DeviceSettingPendingIntentAction.Builder() + .setPendingIntent( + PendingIntent.getBroadcast(mContext, 0, new Intent("action"), 0)) + .setExtras(buildBundle("key1", "value1")) + .build(); + + DeviceSettingPendingIntentAction fromParcel = writeAndRead(action); + + assertThat(action.getPendingIntent().getIntent()) + .isEqualTo(action.getPendingIntent().getIntent()); + assertThat(fromParcel.getExtras().getString("key1")) + .isEqualTo(action.getExtras().getString("key1")); + } + + private Bundle buildBundle(String key, String value) { + Bundle bundle = new Bundle(); + bundle.putString(key, value); + return bundle; + } + + private DeviceSettingPendingIntentAction writeAndRead( + DeviceSettingPendingIntentAction preference) { + Parcel parcel = Parcel.obtain(); + preference.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + DeviceSettingPendingIntentAction fromParcel = + DeviceSettingPendingIntentAction.CREATOR.createFromParcel(parcel); + return fromParcel; + } +} -- GitLab From ac8b7da38ad194bdb342149e361cf0cd7adfccab Mon Sep 17 00:00:00 2001 From: Victor Gabriel Savu Date: Tue, 1 Oct 2024 07:52:17 +0000 Subject: [PATCH 016/447] Fix typos in AppOps.md Change-Id: I25562445e3a39fb337134d0697c928d647539ef8 --- core/java/android/app/AppOps.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/java/android/app/AppOps.md b/core/java/android/app/AppOps.md index 7b11a0351ebe..535d62ce033e 100644 --- a/core/java/android/app/AppOps.md +++ b/core/java/android/app/AppOps.md @@ -119,20 +119,20 @@ those. In addition to proc state, the `AppOpsService` also receives process capability update from the `ActivityManagerService`. Proc capability specifies what while-in-use(`MODE_FOREGROUND`) operations the proc is allowed to perform in its current proc state. There are three proc capabilities - defined so far: + defined so far: `PROCESS_CAPABILITY_FOREGROUND_LOCATION`, `PROCESS_CAPABILITY_FOREGROUND_CAMERA` and `PROCESS_CAPABILITY_FOREGROUND_MICROPHONE`, they correspond to the while-in-use operation of location, camera and microphone (microphone is `RECORD_AUDIO`). In `ActivityManagerService`, `PROCESS_STATE_TOP` and `PROCESS_STATE_PERSISTENT` have all three capabilities, `PROCESS_STATE_FOREGROUND_SERVICE` has capabilities defined by - `foregroundServiceType` that is specified in foreground service's manifest file. A client process + `foregroundServiceType` that is specified in foreground service's manifest file. A client process can pass its capabilities to service using `BIND_INCLUDE_CAPABILITIES` flag. The proc state and capability are used for two use cases: Firstly, Tracking remembers the proc state for each tracked event. Secondly, `noteOp`/`checkOp` calls for app-op that are set to `MODE_FOREGROUND` are translated using the `AppOpsService.UidState.evalMode` method into - `MODE_ALLOWED` when the app has the capability and `MODE_IGNORED` when the app does not have the + `MODE_ALLOWED` when the app has the capability and `MODE_IGNORED` when the app does not have the capability. `checkOpRaw` calls are not affected. The current proc state and capability for an app can be read from `dumpsys appops`. @@ -284,7 +284,7 @@ indicating what code accesses what private data. ##### Self data accesses This is similar to the [synchronous data access](#synchronous-data-accesses) case only that the data -provider and client are in the same process. In this case Android's RPC code is no involved and +provider and client are in the same process. In this case Android's RPC code is not involved and `AppOpsManager.noteOp` directly triggers `OnOpNotedCallback.onSelfNoted`. This should be a uncommon case as it is uncommon for an app to provide data, esp. to itself. -- GitLab From a65450bf20a0da794ac8d17d23e3c7aa83a978bc Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Mon, 23 Sep 2024 11:21:26 -0400 Subject: [PATCH 017/447] Handle ScreenshotHelper references correctly The screenshot service is a singleton, but there may be multiple instances of ScreenshotHelper, each with their own 'finish' callbacks that tell them to reset their connection to the screenshot service. For example, in general each invocation method has its own instance of ScreenshotHelper. However, when we get a new invocation while the ScreenshotController is running, we just update our pointer to the new callback, losing the reference to the old callback. This means that if screenshots are invoked with two different instances of ScreenshotHelper simultaneously (e.g. by invoking via quick tap and then by keychord while the UI is still up) we will never call finish() on the first instance and it will keep holding on to its connection to the screenshot service (so the screenshot service will never be unbound). This change keeps track of all the currently held callbacks and calls them when the screenshot controller finishes. Bug: 334551134 Fix: 334551134 Test: take two screenshots in succession using different invocation methods; verify that the screenshot process is unbound and destroyed Flag: EXEMPT minor change Change-Id: I1df15abf82b5b1348485148956cd2f386aed5bdb --- .../systemui/screenshot/ScreenshotController.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt index 29208f89c4e1..d7fec8f5b1a3 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt @@ -97,12 +97,13 @@ internal constructor( private val window: ScreenshotWindow private val actionExecutor: ActionExecutor private val copyBroadcastReceiver: BroadcastReceiver + private val currentRequestCallbacks: MutableList = + mutableListOf() private var screenshotSoundController: ScreenshotSoundController? = null private var screenBitmap: Bitmap? = null private var screenshotTakenInPortrait = false private var screenshotAnimation: Animator? = null - private var currentRequestCallback: TakeScreenshotService.RequestCallback? = null private var packageName = "" /** Tracks config changes that require re-creating UI */ @@ -170,7 +171,6 @@ internal constructor( ) { Assert.isMainThread() - currentRequestCallback = requestCallback if (screenshot.type == TAKE_SCREENSHOT_FULLSCREEN && screenshot.bitmap == null) { val bounds = fullScreenRect screenshot.bitmap = imageCapture.captureDisplay(display.displayId, bounds) @@ -181,7 +181,7 @@ internal constructor( if (currentBitmap == null) { Log.e(TAG, "handleScreenshot: Screenshot bitmap was null") notificationController.notifyScreenshotError(R.string.screenshot_failed_to_capture_text) - currentRequestCallback?.reportError() + requestCallback.reportError() return } @@ -194,8 +194,10 @@ internal constructor( // User setup isn't complete, so we don't want to show any UI beyond a toast, as editing // and sharing shouldn't be exposed to the user. saveScreenshotAndToast(screenshot, finisher) + requestCallback.onFinish() return } + currentRequestCallbacks.add(requestCallback) broadcastSender.sendBroadcast( Intent(ClipboardOverlayController.SCREENSHOT_ACTION), @@ -499,8 +501,8 @@ internal constructor( Log.d(TAG, "finishDismiss") actionsController.endScreenshotSession() scrollCaptureExecutor.close() - currentRequestCallback?.onFinish() - currentRequestCallback = null + currentRequestCallbacks.forEach { it.onFinish() } + currentRequestCallbacks.clear() viewProxy.reset() removeWindow() screenshotHandler.cancelTimeout() -- GitLab From 1d520de7e396b43b76b2060dcab52bb483316c4e Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Tue, 1 Oct 2024 12:29:32 -0400 Subject: [PATCH 018/447] [sat] Add more logs around registering callbacks There are instances where we really want to know exactly _when_ a callback was registered. This adds that for the remaining callbacks in DeviceBasedSatelliteRepositoryImpl Bug: 363283221 Flag: EXEMPT logging Test: DeviceBasedSatelliteRepositoryImplTest Change-Id: I68dfdda668ef6787c3547483d713861891d1fd3b --- .../DeviceBasedSatelliteRepositoryImpl.kt | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt index 03ec41d5af46..470abe63b568 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt @@ -182,7 +182,7 @@ constructor( .stateIn( scope, SharingStarted.WhileSubscribed(), - TelephonyManager.RADIO_POWER_UNAVAILABLE + TelephonyManager.RADIO_POWER_UNAVAILABLE, ) /** @@ -265,9 +265,10 @@ constructor( var registered = false try { + logBuffer.i { "registerForCommunicationAllowedStateChanged" } sm.registerForCommunicationAllowedStateChanged( bgDispatcher.asExecutor(), - callback + callback, ) registered = true } catch (e: Exception) { @@ -276,6 +277,7 @@ constructor( awaitClose { if (registered) { + logBuffer.i { "unRegisterForCommunicationAllowedStateChanged" } sm.unregisterForCommunicationAllowedStateChanged(callback) } } @@ -321,9 +323,10 @@ constructor( var registered = false try { + logBuffer.i { "registerForSupportedStateChanged" } satelliteManager.registerForSupportedStateChanged( bgDispatcher.asExecutor(), - callback + callback, ) registered = true } catch (e: Exception) { @@ -332,6 +335,7 @@ constructor( awaitClose { if (registered) { + logBuffer.i { "unregisterForSupportedStateChanged" } satelliteManager.unregisterForSupportedStateChanged(callback) } } @@ -366,10 +370,7 @@ constructor( var registered = false try { logBuffer.i { "registerForProvisionStateChanged" } - sm.registerForProvisionStateChanged( - bgDispatcher.asExecutor(), - callback, - ) + sm.registerForProvisionStateChanged(bgDispatcher.asExecutor(), callback) registered = true } catch (e: Exception) { logBuffer.e("error registering for provisioning state callback", e) @@ -377,6 +378,7 @@ constructor( awaitClose { if (registered) { + logBuffer.i { "unregisterForProvisionStateChanged" } sm.unregisterForProvisionStateChanged(callback) } } @@ -526,17 +528,10 @@ constructor( uptime - (clock.uptimeMillis() - android.os.Process.getStartUptimeMillis()) /** A couple of convenience logging methods rather than a whole class */ - private fun LogBuffer.i( - initializer: MessageInitializer = {}, - printer: MessagePrinter, - ) = this.log(TAG, LogLevel.INFO, initializer, printer) + private fun LogBuffer.i(initializer: MessageInitializer = {}, printer: MessagePrinter) = + this.log(TAG, LogLevel.INFO, initializer, printer) private fun LogBuffer.e(message: String, exception: Throwable? = null) = - this.log( - tag = TAG, - level = LogLevel.ERROR, - message = message, - exception = exception, - ) + this.log(tag = TAG, level = LogLevel.ERROR, message = message, exception = exception) } } -- GitLab From b24e8baa723e6fe5e234abe66e708beeb382823c Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Wed, 2 Oct 2024 04:11:01 +0000 Subject: [PATCH 019/447] Add OWNERS for stats service AIDL and Java files. Bug: n/a Test: ONWERS modified Change-Id: I63cf7ff77aea61074c947da2bb603ffcd28fc73a --- core/java/android/os/OWNERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS index 7d3076d6611f..a1b75034442e 100644 --- a/core/java/android/os/OWNERS +++ b/core/java/android/os/OWNERS @@ -115,3 +115,10 @@ per-file OomKillRecord.java = file:/MEMORY_OWNERS # MessageQueue per-file MessageQueue.java = mfasheh@google.com, shayba@google.com per-file Message.java = mfasheh@google.com, shayba@google.com + +# Stats +per-file IStatsBootstrapAtomService.aidl = file:/services/core/java/com/android/server/stats/OWNERS +per-file StatsBootstrapAtom.aidl = file:/services/core/java/com/android/server/stats/OWNERS +per-file StatsBootstrapAtomValue.aidl = file:/services/core/java/com/android/server/stats/OWNERS +per-file StatsBootstrapAtomService.java = file:/services/core/java/com/android/server/stats/OWNERS +per-file StatsServiceManager.java = file:/services/core/java/com/android/server/stats/OWNERS -- GitLab From e38d5e033538493276e3791f1a5b3a2cf51513fa Mon Sep 17 00:00:00 2001 From: Matthew Sedam Date: Wed, 2 Oct 2024 17:08:43 +0000 Subject: [PATCH 020/447] Reduce locking in ContextHubTransactionManager This CL replaces a global synchronization lock in ContextHubManager with individual locks to reduce locking time. Bug: 362299144 Change-Id: Ib19f7ebe093b2ed0c0065f0e9896df16255fb6e4 Flag: android.chre.flags.reduce_locking_context_hub_transaction_manager Test: Run the reliable message test --- .../contexthub/ContextHubService.java | 13 +- .../ContextHubTransactionManager.java | 575 +++++++++++------- .../ContextHubTransactionManagerOld.java | 475 +++++++++++++++ 3 files changed, 847 insertions(+), 216 deletions(-) create mode 100644 services/core/java/com/android/server/location/contexthub/ContextHubTransactionManagerOld.java diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java index 3f4a9bb4d864..ed69f7ad32f6 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java @@ -444,8 +444,17 @@ public class ContextHubService extends IContextHubService.Stub { mSupportedContextHubPerms = hubInfo.second; mContextHubInfoList = new ArrayList<>(mContextHubIdToInfoMap.values()); mClientManager = new ContextHubClientManager(mContext, mContextHubWrapper); - mTransactionManager = new ContextHubTransactionManager( - mContextHubWrapper, mClientManager, mNanoAppStateManager); + + if (Flags.reduceLockingContextHubTransactionManager()) { + mTransactionManager = + new ContextHubTransactionManager( + mContextHubWrapper, mClientManager, mNanoAppStateManager); + } else { + mTransactionManager = + new ContextHubTransactionManagerOld( + mContextHubWrapper, mClientManager, mNanoAppStateManager); + } + mSensorPrivacyManagerInternal = LocalServices.getService(SensorPrivacyManagerInternal.class); return true; diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java index 2a0b1afde27b..da31bf29a8e8 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java @@ -26,6 +26,8 @@ import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; +import com.android.internal.annotations.GuardedBy; + import java.time.Duration; import java.util.ArrayDeque; import java.util.Collections; @@ -43,8 +45,8 @@ import java.util.concurrent.atomic.AtomicInteger; /** * Manages transactions at the Context Hub Service. - *

    - * This class maintains a queue of transaction requests made to the ContextHubService by clients, + * + *

    This class maintains a queue of transaction requests made to the ContextHubService by clients, * and executes them through the Context Hub. At any point in time, either the transaction queue is * empty, or there is a pending transaction that is waiting for an asynchronous response from the * hub. This class also handles synchronous errors and timeouts of each transaction. @@ -52,66 +54,80 @@ import java.util.concurrent.atomic.AtomicInteger; * @hide */ /* package */ class ContextHubTransactionManager { - private static final String TAG = "ContextHubTransactionManager"; + protected static final String TAG = "ContextHubTransactionManager"; public static final Duration RELIABLE_MESSAGE_TIMEOUT = Duration.ofSeconds(1); public static final Duration RELIABLE_MESSAGE_DUPLICATE_DETECTION_TIMEOUT = RELIABLE_MESSAGE_TIMEOUT.multipliedBy(3); - private static final int MAX_PENDING_REQUESTS = 10000; + // TODO: b/362299144: When cleaning up the flag + // reduce_locking_context_hub_transaction_manager, change these to private + protected static final int MAX_PENDING_REQUESTS = 10000; - private static final int RELIABLE_MESSAGE_MAX_NUM_RETRY = 3; + protected static final int RELIABLE_MESSAGE_MAX_NUM_RETRY = 3; - private static final Duration RELIABLE_MESSAGE_RETRY_WAIT_TIME = Duration.ofMillis(250); + protected static final Duration RELIABLE_MESSAGE_RETRY_WAIT_TIME = Duration.ofMillis(250); - private static final Duration RELIABLE_MESSAGE_MIN_WAIT_TIME = Duration.ofNanos(1000); + protected static final Duration RELIABLE_MESSAGE_MIN_WAIT_TIME = Duration.ofNanos(1000); - private final IContextHubWrapper mContextHubProxy; + protected final IContextHubWrapper mContextHubProxy; - private final ContextHubClientManager mClientManager; + protected final ContextHubClientManager mClientManager; - private final NanoAppStateManager mNanoAppStateManager; + protected final NanoAppStateManager mNanoAppStateManager; - private final ArrayDeque mTransactionQueue = new ArrayDeque<>(); + @GuardedBy("mTransactionLock") + protected final ArrayDeque mTransactionQueue = new ArrayDeque<>(); - private final Map mReliableMessageTransactionMap = + @GuardedBy("mReliableMessageLock") + protected final Map mReliableMessageTransactionMap = new HashMap<>(); /** A set of host endpoint IDs that have an active pending transaction. */ - private final Set mReliableMessageHostEndpointIdActiveSet = new HashSet<>(); + @GuardedBy("mReliableMessageLock") + protected final Set mReliableMessageHostEndpointIdActiveSet = new HashSet<>(); - private final AtomicInteger mNextAvailableId = new AtomicInteger(); + protected final AtomicInteger mNextAvailableId = new AtomicInteger(); /** - * The next available message sequence number. We choose a random - * number to start with to avoid collisions and limit the bound to - * half of the max value to avoid overflow. + * The next available message sequence number. We choose a random number to start with to avoid + * collisions and limit the bound to half of the max value to avoid overflow. */ - private final AtomicInteger mNextAvailableMessageSequenceNumber = + protected final AtomicInteger mNextAvailableMessageSequenceNumber = new AtomicInteger(new Random().nextInt(Integer.MAX_VALUE / 2)); /* - * An executor and the future object for scheduling timeout timers and + * An executor and the future objects for scheduling timeout timers and * for scheduling the processing of reliable message transactions. */ - private final ScheduledThreadPoolExecutor mExecutor = new ScheduledThreadPoolExecutor(1); - private ScheduledFuture mTimeoutFuture = null; - private ScheduledFuture mReliableMessageTransactionFuture = null; + protected final ScheduledThreadPoolExecutor mExecutor = new ScheduledThreadPoolExecutor(2); + + @GuardedBy("mTransactionLock") + protected ScheduledFuture mTimeoutFuture = null; + + @GuardedBy("mReliableMessageLock") + protected ScheduledFuture mReliableMessageTransactionFuture = null; /* * The list of previous transaction records. */ - private static final int NUM_TRANSACTION_RECORDS = 20; - private final ConcurrentLinkedEvictingDeque mTransactionRecordDeque = + protected static final int NUM_TRANSACTION_RECORDS = 20; + protected final ConcurrentLinkedEvictingDeque mTransactionRecordDeque = new ConcurrentLinkedEvictingDeque<>(NUM_TRANSACTION_RECORDS); - /** - * A container class to store a record of transactions. + /* + * Locks for synchronization of normal transactions separately from reliable message + * transactions. */ - private class TransactionRecord { - private final String mTransaction; - private final long mTimestamp; + protected final Object mTransactionLock = new Object(); + protected final Object mReliableMessageLock = new Object(); + protected final Object mTransactionRecordLock = new Object(); + + /** A container class to store a record of transactions. */ + protected static class TransactionRecord { + protected final String mTransaction; + protected final long mTimestamp; TransactionRecord(String transaction) { mTransaction = transaction; @@ -126,8 +142,18 @@ import java.util.concurrent.atomic.AtomicInteger; } } + /** Used when finishing a transaction. */ + interface TransactionAcceptConditions { + /** + * Returns whether to accept the found transaction when receiving a response from the + * Context Hub. + */ + boolean acceptTransaction(ContextHubServiceTransaction transaction); + } + /* package */ ContextHubTransactionManager( - IContextHubWrapper contextHubProxy, ContextHubClientManager clientManager, + IContextHubWrapper contextHubProxy, + ContextHubClientManager clientManager, NanoAppStateManager nanoAppStateManager) { mContextHubProxy = contextHubProxy; mClientManager = clientManager; @@ -409,34 +435,47 @@ import java.util.concurrent.atomic.AtomicInteger; /** * Adds a new transaction to the queue. - *

    - * If there was no pending transaction at the time, the transaction that was added will be + * + *

    If there was no pending transaction at the time, the transaction that was added will be * started in this method. If there were too many transactions in the queue, an exception will * be thrown. * * @param transaction the transaction to add - * @throws IllegalStateException if the queue is full */ /* package */ - synchronized void addTransaction( - ContextHubServiceTransaction transaction) throws IllegalStateException { + void addTransaction(ContextHubServiceTransaction transaction) { if (transaction == null) { return; } - if (mTransactionQueue.size() >= MAX_PENDING_REQUESTS - || mReliableMessageTransactionMap.size() >= MAX_PENDING_REQUESTS) { - throw new IllegalStateException("Transaction queue is full (capacity = " - + MAX_PENDING_REQUESTS + ")"); + synchronized (mTransactionRecordLock) { + mTransactionRecordDeque.add(new TransactionRecord(transaction.toString())); } - mTransactionRecordDeque.add(new TransactionRecord(transaction.toString())); if (Flags.reliableMessageRetrySupportService() && transaction.getTransactionType() == ContextHubTransaction.TYPE_RELIABLE_MESSAGE) { - mReliableMessageTransactionMap.put(transaction.getMessageSequenceNumber(), transaction); + synchronized (mReliableMessageLock) { + if (mReliableMessageTransactionMap.size() >= MAX_PENDING_REQUESTS) { + throw new IllegalStateException( + "Reliable message transaction queue is full " + + "(capacity = " + + MAX_PENDING_REQUESTS + + ")"); + } + mReliableMessageTransactionMap.put( + transaction.getMessageSequenceNumber(), transaction); + } mExecutor.execute(() -> processMessageTransactions()); - } else { + return; + } + + synchronized (mTransactionLock) { + if (mTransactionQueue.size() >= MAX_PENDING_REQUESTS) { + throw new IllegalStateException( + "Transaction queue is full (capacity = " + MAX_PENDING_REQUESTS + ")"); + } + mTransactionQueue.add(transaction); if (mTransactionQueue.size() == 1) { startNextTransaction(); @@ -448,62 +487,85 @@ import java.util.concurrent.atomic.AtomicInteger; * Handles a transaction response from a Context Hub. * * @param transactionId the transaction ID of the response - * @param success true if the transaction succeeded + * @param success true if the transaction succeeded */ /* package */ - synchronized void onTransactionResponse(int transactionId, boolean success) { - ContextHubServiceTransaction transaction = mTransactionQueue.peek(); + void onTransactionResponse(int transactionId, boolean success) { + TransactionAcceptConditions conditions = + transaction -> transaction.getTransactionId() == transactionId; + ContextHubServiceTransaction transaction = getTransactionAndHandleNext(conditions); if (transaction == null) { - Log.w(TAG, "Received unexpected transaction response (no transaction pending)"); - return; - } - if (transaction.getTransactionId() != transactionId) { Log.w(TAG, "Received unexpected transaction response (expected ID = " - + transaction.getTransactionId() + ", received ID = " + transactionId + ")"); + + transactionId + + ", received ID = " + + transaction.getTransactionId() + + ")"); return; } - transaction.onTransactionComplete(success ? ContextHubTransaction.RESULT_SUCCESS : - ContextHubTransaction.RESULT_FAILED_AT_HUB); - removeTransactionAndStartNext(); + synchronized (transaction) { + transaction.onTransactionComplete( + success + ? ContextHubTransaction.RESULT_SUCCESS + : ContextHubTransaction.RESULT_FAILED_AT_HUB); + transaction.setComplete(); + } } + /** + * Handles a message delivery response from a Context Hub. + * + * @param messageSequenceNumber the message sequence number of the response + * @param success true if the message was delivered successfully + */ /* package */ - synchronized void onMessageDeliveryResponse(int messageSequenceNumber, boolean success) { + void onMessageDeliveryResponse(int messageSequenceNumber, boolean success) { if (!Flags.reliableMessageRetrySupportService()) { - ContextHubServiceTransaction transaction = mTransactionQueue.peek(); + TransactionAcceptConditions conditions = + transaction -> transaction.getTransactionType() + == ContextHubTransaction.TYPE_RELIABLE_MESSAGE + && transaction.getMessageSequenceNumber() + == messageSequenceNumber; + ContextHubServiceTransaction transaction = getTransactionAndHandleNext(conditions); if (transaction == null) { - Log.w(TAG, "Received unexpected transaction response (no transaction pending)"); + Log.w(TAG, "Received unexpected message delivery response (expected" + + " message sequence number = " + + messageSequenceNumber + + ", received messageSequenceNumber = " + + messageSequenceNumber + + ")"); return; } - int transactionMessageSequenceNumber = transaction.getMessageSequenceNumber(); - if (transaction.getTransactionType() != ContextHubTransaction.TYPE_RELIABLE_MESSAGE - || transactionMessageSequenceNumber != messageSequenceNumber) { - Log.w(TAG, "Received unexpected message transaction response (expected message " - + "sequence number = " - + transaction.getMessageSequenceNumber() - + ", received messageSequenceNumber = " + messageSequenceNumber + ")"); - return; + synchronized (transaction) { + transaction.onTransactionComplete( + success + ? ContextHubTransaction.RESULT_SUCCESS + : ContextHubTransaction.RESULT_FAILED_AT_HUB); + transaction.setComplete(); } - - transaction.onTransactionComplete(success ? ContextHubTransaction.RESULT_SUCCESS : - ContextHubTransaction.RESULT_FAILED_AT_HUB); - removeTransactionAndStartNext(); return; } - ContextHubServiceTransaction transaction = - mReliableMessageTransactionMap.get(messageSequenceNumber); - if (transaction == null) { - Log.w(TAG, "Could not find reliable message transaction with " - + "message sequence number = " - + messageSequenceNumber); - return; + ContextHubServiceTransaction transaction = null; + synchronized (mReliableMessageLock) { + transaction = mReliableMessageTransactionMap.get(messageSequenceNumber); + if (transaction == null) { + Log.w( + TAG, + "Could not find reliable message transaction with " + + "message sequence number = " + + messageSequenceNumber); + return; + } + + removeMessageTransaction(transaction); } - completeMessageTransaction(transaction, - success ? ContextHubTransaction.RESULT_SUCCESS + completeMessageTransaction( + transaction, + success + ? ContextHubTransaction.RESULT_SUCCESS : ContextHubTransaction.RESULT_FAILED_AT_HUB); mExecutor.execute(() -> processMessageTransactions()); } @@ -514,77 +576,116 @@ import java.util.concurrent.atomic.AtomicInteger; * @param nanoAppStateList the list of nanoapps included in the response */ /* package */ - synchronized void onQueryResponse(List nanoAppStateList) { - ContextHubServiceTransaction transaction = mTransactionQueue.peek(); + void onQueryResponse(List nanoAppStateList) { + TransactionAcceptConditions conditions = transaction -> + transaction.getTransactionType() == ContextHubTransaction.TYPE_QUERY_NANOAPPS; + ContextHubServiceTransaction transaction = getTransactionAndHandleNext(conditions); if (transaction == null) { - Log.w(TAG, "Received unexpected query response (no transaction pending)"); - return; - } - if (transaction.getTransactionType() != ContextHubTransaction.TYPE_QUERY_NANOAPPS) { Log.w(TAG, "Received unexpected query response (expected " + transaction + ")"); return; } - transaction.onQueryResponse(ContextHubTransaction.RESULT_SUCCESS, nanoAppStateList); - removeTransactionAndStartNext(); + synchronized (transaction) { + transaction.onQueryResponse(ContextHubTransaction.RESULT_SUCCESS, nanoAppStateList); + transaction.setComplete(); + } } - /** - * Handles a hub reset event by stopping a pending transaction and starting the next. - */ + /** Handles a hub reset event by stopping a pending transaction and starting the next. */ /* package */ - synchronized void onHubReset() { + void onHubReset() { if (Flags.reliableMessageRetrySupportService()) { - Iterator> iter = - mReliableMessageTransactionMap.entrySet().iterator(); - while (iter.hasNext()) { - completeMessageTransaction(iter.next().getValue(), - ContextHubTransaction.RESULT_FAILED_AT_HUB, iter); + synchronized (mReliableMessageLock) { + Iterator> iter = + mReliableMessageTransactionMap.entrySet().iterator(); + while (iter.hasNext()) { + removeAndCompleteMessageTransaction( + iter.next().getValue(), + ContextHubTransaction.RESULT_FAILED_AT_HUB, + iter); + } } } - ContextHubServiceTransaction transaction = mTransactionQueue.peek(); - if (transaction == null) { - return; + synchronized (mTransactionLock) { + ContextHubServiceTransaction transaction = mTransactionQueue.peek(); + if (transaction == null) { + return; + } + + removeTransactionAndStartNext(); } + } - removeTransactionAndStartNext(); + /** + * This function also starts the next transaction and removes the active transaction from the + * queue. The caller should complete the transaction. + * + *

    Returns the active transaction if the transaction queue is not empty, the transaction is + * not null, and the transaction matches the conditions. + */ + private ContextHubServiceTransaction getTransactionAndHandleNext( + TransactionAcceptConditions conditions) { + ContextHubServiceTransaction transaction = null; + synchronized (mTransactionLock) { + transaction = mTransactionQueue.peek(); + if (transaction == null + || (conditions != null && !conditions.acceptTransaction(transaction))) { + return null; + } + + cancelTimeoutFuture(); + mTransactionQueue.remove(); + if (!mTransactionQueue.isEmpty()) { + startNextTransaction(); + } + } + return transaction; } /** * Pops the front transaction from the queue and starts the next pending transaction request. - *

    - * Removing elements from the transaction queue must only be done through this method. When a + * + *

    Removing elements from the transaction queue must only be done through this method. When a * pending transaction is removed, the timeout timer is cancelled and the transaction is marked * complete. - *

    - * It is assumed that the transaction queue is non-empty when this method is invoked, and that - * the caller has obtained a lock on this ContextHubTransactionManager object. + * + *

    It is assumed that the transaction queue is non-empty when this method is invoked, and + * that the caller has obtained mTransactionLock. */ + @GuardedBy("mTransactionLock") private void removeTransactionAndStartNext() { - if (mTimeoutFuture != null) { - mTimeoutFuture.cancel(/* mayInterruptIfRunning= */ false); - mTimeoutFuture = null; - } + cancelTimeoutFuture(); ContextHubServiceTransaction transaction = mTransactionQueue.remove(); - transaction.setComplete(); + synchronized (transaction) { + transaction.setComplete(); + } if (!mTransactionQueue.isEmpty()) { startNextTransaction(); } } + /** Cancels the timeout future. */ + @GuardedBy("mTransactionLock") + private void cancelTimeoutFuture() { + if (mTimeoutFuture != null) { + mTimeoutFuture.cancel(/* mayInterruptIfRunning= */ false); + mTimeoutFuture = null; + } + } + /** * Starts the next pending transaction request. - *

    - * Starting new transactions must only be done through this method. This method continues to + * + *

    Starting new transactions must only be done through this method. This method continues to * process the transaction queue as long as there are pending requests, and no transaction is * pending. - *

    - * It is assumed that the caller has obtained a lock on this ContextHubTransactionManager - * object. + * + *

    It is assumed that the caller has obtained a lock on mTransactionLock. */ + @GuardedBy("mTransactionLock") private void startNextTransaction() { int result = ContextHubTransaction.RESULT_FAILED_UNKNOWN; while (result != ContextHubTransaction.RESULT_SUCCESS && !mTransactionQueue.isEmpty()) { @@ -592,28 +693,36 @@ import java.util.concurrent.atomic.AtomicInteger; result = transaction.onTransact(); if (result == ContextHubTransaction.RESULT_SUCCESS) { - Runnable onTimeoutFunc = () -> { - synchronized (this) { - if (!transaction.isComplete()) { - Log.d(TAG, transaction + " timed out"); - transaction.onTransactionComplete( - ContextHubTransaction.RESULT_FAILED_TIMEOUT); - - removeTransactionAndStartNext(); - } - } - }; + Runnable onTimeoutFunc = + () -> { + synchronized (transaction) { + if (!transaction.isComplete()) { + Log.d(TAG, transaction + " timed out"); + transaction.onTransactionComplete( + ContextHubTransaction.RESULT_FAILED_TIMEOUT); + transaction.setComplete(); + } + } + + synchronized (mTransactionLock) { + removeTransactionAndStartNext(); + } + }; long timeoutMs = transaction.getTimeout(TimeUnit.MILLISECONDS); try { - mTimeoutFuture = mExecutor.schedule( - onTimeoutFunc, timeoutMs, TimeUnit.MILLISECONDS); + mTimeoutFuture = + mExecutor.schedule(onTimeoutFunc, timeoutMs, TimeUnit.MILLISECONDS); } catch (Exception e) { Log.e(TAG, "Error when schedule a timer", e); } } else { - transaction.onTransactionComplete( - ContextHubServiceUtil.toTransactionResult(result)); + synchronized (transaction) { + transaction.onTransactionComplete( + ContextHubServiceUtil.toTransactionResult(result)); + transaction.setComplete(); + } + mTransactionQueue.remove(); } } @@ -621,81 +730,97 @@ import java.util.concurrent.atomic.AtomicInteger; /** * Processes message transactions, starting and completing them as needed. - *

    - * This function is called when adding a message transaction or when a timer - * expires for an existing message transaction's retry or timeout. The - * internal processing loop will iterate at most twice as if one iteration - * completes a transaction, the next iteration can only start new transactions. - * If the first iteration does not complete any transaction, the loop will - * only iterate once. + * + *

    This function is called when adding a message transaction or when a timer expires for an + * existing message transaction's retry or timeout. The internal processing loop will iterate at + * most twice as if one iteration completes a transaction, the next iteration can only start new + * transactions. If the first iteration does not complete any transaction, the loop will only + * iterate once. + * *

    */ - private synchronized void processMessageTransactions() { - if (!Flags.reliableMessageRetrySupportService()) { - return; - } - - if (mReliableMessageTransactionFuture != null) { - mReliableMessageTransactionFuture.cancel(/* mayInterruptIfRunning= */ false); - mReliableMessageTransactionFuture = null; - } + private void processMessageTransactions() { + synchronized (mReliableMessageLock) { + if (!Flags.reliableMessageRetrySupportService()) { + return; + } - long now = SystemClock.elapsedRealtimeNanos(); - long nextExecutionTime = Long.MAX_VALUE; - boolean continueProcessing; - do { - continueProcessing = false; - Iterator> iter = - mReliableMessageTransactionMap.entrySet().iterator(); - while (iter.hasNext()) { - ContextHubServiceTransaction transaction = iter.next().getValue(); - short hostEndpointId = transaction.getHostEndpointId(); - int numCompletedStartCalls = transaction.getNumCompletedStartCalls(); - if (numCompletedStartCalls == 0 - && mReliableMessageHostEndpointIdActiveSet.contains(hostEndpointId)) { - continue; - } + if (mReliableMessageTransactionFuture != null) { + mReliableMessageTransactionFuture.cancel(/* mayInterruptIfRunning= */ false); + mReliableMessageTransactionFuture = null; + } - long nextRetryTime = transaction.getNextRetryTime(); - long timeoutTime = transaction.getTimeoutTime(); - boolean transactionTimedOut = timeoutTime <= now; - boolean transactionHitMaxRetries = nextRetryTime <= now - && numCompletedStartCalls > RELIABLE_MESSAGE_MAX_NUM_RETRY; - if (transactionTimedOut || transactionHitMaxRetries) { - completeMessageTransaction(transaction, - ContextHubTransaction.RESULT_FAILED_TIMEOUT, iter); - continueProcessing = true; - } else { - if (nextRetryTime <= now || numCompletedStartCalls <= 0) { - startMessageTransaction(transaction, now); + long now = SystemClock.elapsedRealtimeNanos(); + long nextExecutionTime = Long.MAX_VALUE; + boolean continueProcessing; + do { + continueProcessing = false; + Iterator> iter = + mReliableMessageTransactionMap.entrySet().iterator(); + while (iter.hasNext()) { + ContextHubServiceTransaction transaction = iter.next().getValue(); + short hostEndpointId = transaction.getHostEndpointId(); + int numCompletedStartCalls = transaction.getNumCompletedStartCalls(); + if (numCompletedStartCalls == 0 + && mReliableMessageHostEndpointIdActiveSet.contains(hostEndpointId)) { + continue; } - nextExecutionTime = Math.min(nextExecutionTime, - transaction.getNextRetryTime()); - nextExecutionTime = Math.min(nextExecutionTime, - transaction.getTimeoutTime()); + long nextRetryTime = transaction.getNextRetryTime(); + long timeoutTime = transaction.getTimeoutTime(); + boolean transactionTimedOut = timeoutTime <= now; + boolean transactionHitMaxRetries = + nextRetryTime <= now + && numCompletedStartCalls > RELIABLE_MESSAGE_MAX_NUM_RETRY; + if (transactionTimedOut || transactionHitMaxRetries) { + removeAndCompleteMessageTransaction( + transaction, ContextHubTransaction.RESULT_FAILED_TIMEOUT, iter); + continueProcessing = true; + } else { + if (nextRetryTime <= now || numCompletedStartCalls <= 0) { + startMessageTransaction(transaction, now); + } + + nextExecutionTime = + Math.min(nextExecutionTime, transaction.getNextRetryTime()); + nextExecutionTime = + Math.min(nextExecutionTime, transaction.getTimeoutTime()); + } } + } while (continueProcessing); + + if (nextExecutionTime < Long.MAX_VALUE) { + mReliableMessageTransactionFuture = + mExecutor.schedule( + () -> processMessageTransactions(), + Math.max( + nextExecutionTime - SystemClock.elapsedRealtimeNanos(), + RELIABLE_MESSAGE_MIN_WAIT_TIME.toNanos()), + TimeUnit.NANOSECONDS); } - } while (continueProcessing); - - if (nextExecutionTime < Long.MAX_VALUE) { - mReliableMessageTransactionFuture = mExecutor.schedule( - () -> processMessageTransactions(), - Math.max(nextExecutionTime - SystemClock.elapsedRealtimeNanos(), - RELIABLE_MESSAGE_MIN_WAIT_TIME.toNanos()), - TimeUnit.NANOSECONDS); } } /** - * Completes a message transaction and removes it from the reliable message map. + * Completes a message transaction. * * @param transaction The transaction to complete. * @param result The result code. */ - private void completeMessageTransaction(ContextHubServiceTransaction transaction, - @ContextHubTransaction.Result int result) { - completeMessageTransaction(transaction, result, /* iter= */ null); + private void completeMessageTransaction( + ContextHubServiceTransaction transaction, @ContextHubTransaction.Result int result) { + synchronized (transaction) { + transaction.onTransactionComplete(result); + transaction.setComplete(); + } + + Log.d( + TAG, + "Successfully completed reliable message transaction with " + + "message sequence number = " + + transaction.getMessageSequenceNumber() + + " and result = " + + result); } /** @@ -705,25 +830,41 @@ import java.util.concurrent.atomic.AtomicInteger; * @param result The result code. * @param iter The iterator for the reliable message map - used to remove the message directly. */ - private void completeMessageTransaction(ContextHubServiceTransaction transaction, + @GuardedBy("mReliableMessageLock") + private void removeAndCompleteMessageTransaction( + ContextHubServiceTransaction transaction, @ContextHubTransaction.Result int result, Iterator> iter) { - transaction.onTransactionComplete(result); + removeMessageTransaction(transaction, iter); + completeMessageTransaction(transaction, result); + } + /** + * Removes a message transaction from the reliable message map. + * + * @param transaction The transaction to remove. + */ + @GuardedBy("mReliableMessageLock") + private void removeMessageTransaction(ContextHubServiceTransaction transaction) { + removeMessageTransaction(transaction, /* iter= */ null); + } + + /** + * Removes a message transaction from the reliable message map. + * + * @param transaction The transaction to remove. + * @param iter The iterator for the reliable message map - used to remove the message directly. + */ + @GuardedBy("mReliableMessageLock") + private void removeMessageTransaction( + ContextHubServiceTransaction transaction, + Iterator> iter) { if (iter == null) { mReliableMessageTransactionMap.remove(transaction.getMessageSequenceNumber()); } else { iter.remove(); } mReliableMessageHostEndpointIdActiveSet.remove(transaction.getHostEndpointId()); - - Log.d( - TAG, - "Successfully completed reliable message transaction with " - + "message sequence number = " - + transaction.getMessageSequenceNumber() - + " and result = " - + result); } /** @@ -732,24 +873,25 @@ import java.util.concurrent.atomic.AtomicInteger; * @param transaction The transaction to start. * @param now The now time. */ + @GuardedBy("mReliableMessageLock") private void startMessageTransaction(ContextHubServiceTransaction transaction, long now) { int numCompletedStartCalls = transaction.getNumCompletedStartCalls(); @ContextHubTransaction.Result int result = transaction.onTransact(); if (result == ContextHubTransaction.RESULT_SUCCESS) { - Log.d( - TAG, - "Successfully " - + (numCompletedStartCalls == 0 ? "started" : "retried") - + " reliable message transaction with message sequence number = " - + transaction.getMessageSequenceNumber()); + Log.d( + TAG, + "Successfully " + + (numCompletedStartCalls == 0 ? "started" : "retried") + + " reliable message transaction with message sequence number = " + + transaction.getMessageSequenceNumber()); } else { - Log.w( - TAG, - "Could not start reliable message transaction with " - + "message sequence number = " - + transaction.getMessageSequenceNumber() - + ", result = " - + result); + Log.w( + TAG, + "Could not start reliable message transaction with " + + "message sequence number = " + + transaction.getMessageSequenceNumber() + + ", result = " + + result); } transaction.setNextRetryTime(now + RELIABLE_MESSAGE_RETRY_WAIT_TIME.toNanos()); @@ -788,17 +930,19 @@ import java.util.concurrent.atomic.AtomicInteger; public String toString() { StringBuilder sb = new StringBuilder(); int i = 0; - synchronized (this) { - for (ContextHubServiceTransaction transaction: mTransactionQueue) { + synchronized (mTransactionLock) { + for (ContextHubServiceTransaction transaction : mTransactionQueue) { sb.append(i); sb.append(": "); sb.append(transaction.toString()); sb.append("\n"); ++i; } + } - if (Flags.reliableMessageRetrySupportService()) { - for (ContextHubServiceTransaction transaction: + if (Flags.reliableMessageRetrySupportService()) { + synchronized (mReliableMessageLock) { + for (ContextHubServiceTransaction transaction : mReliableMessageTransactionMap.values()) { sb.append(i); sb.append(": "); @@ -807,7 +951,9 @@ import java.util.concurrent.atomic.AtomicInteger; ++i; } } + } + synchronized (mTransactionRecordLock) { sb.append("Transaction History:\n"); Iterator iterator = mTransactionRecordDeque.descendingIterator(); while (iterator.hasNext()) { @@ -815,6 +961,7 @@ import java.util.concurrent.atomic.AtomicInteger; sb.append("\n"); } } + return sb.toString(); } } diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManagerOld.java b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManagerOld.java new file mode 100644 index 000000000000..a67fa308a6ea --- /dev/null +++ b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManagerOld.java @@ -0,0 +1,475 @@ +/* + * 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.location.contexthub; + +import android.chre.flags.Flags; +import android.hardware.location.ContextHubTransaction; +import android.hardware.location.IContextHubTransactionCallback; +import android.hardware.location.NanoAppBinary; +import android.hardware.location.NanoAppMessage; +import android.hardware.location.NanoAppState; +import android.os.RemoteException; +import android.os.SystemClock; +import android.util.Log; + +import java.time.Duration; +import java.util.ArrayDeque; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Manages transactions at the Context Hub Service. + * + *

    This class maintains a queue of transaction requests made to the ContextHubService by clients, + * and executes them through the Context Hub. At any point in time, either the transaction queue is + * empty, or there is a pending transaction that is waiting for an asynchronous response from the + * hub. This class also handles synchronous errors and timeouts of each transaction. + * + *

    This is the old version of ContextHubTransactionManager that uses global synchronization + * instead of individual locks. This will be deleted when the + * reduce_locking_context_hub_transaction_manager flag is cleaned up. + * + * @hide + */ +/* package */ class ContextHubTransactionManagerOld extends ContextHubTransactionManager { + /* package */ ContextHubTransactionManagerOld( + IContextHubWrapper contextHubProxy, + ContextHubClientManager clientManager, + NanoAppStateManager nanoAppStateManager) { + super(contextHubProxy, clientManager, nanoAppStateManager); + } + + /** + * Adds a new transaction to the queue. + * + *

    If there was no pending transaction at the time, the transaction that was added will be + * started in this method. If there were too many transactions in the queue, an exception will + * be thrown. + * + * @param transaction the transaction to add + * @throws IllegalStateException if the queue is full + */ + /* package */ + @Override + synchronized void addTransaction(ContextHubServiceTransaction transaction) + throws IllegalStateException { + if (transaction == null) { + return; + } + + if (mTransactionQueue.size() >= MAX_PENDING_REQUESTS + || mReliableMessageTransactionMap.size() >= MAX_PENDING_REQUESTS) { + throw new IllegalStateException( + "Transaction queue is full (capacity = " + MAX_PENDING_REQUESTS + ")"); + } + + mTransactionRecordDeque.add(new TransactionRecord(transaction.toString())); + if (Flags.reliableMessageRetrySupportService() + && transaction.getTransactionType() + == ContextHubTransaction.TYPE_RELIABLE_MESSAGE) { + mReliableMessageTransactionMap.put(transaction.getMessageSequenceNumber(), transaction); + mExecutor.execute(() -> processMessageTransactions()); + } else { + mTransactionQueue.add(transaction); + if (mTransactionQueue.size() == 1) { + startNextTransaction(); + } + } + } + + /** + * Handles a transaction response from a Context Hub. + * + * @param transactionId the transaction ID of the response + * @param success true if the transaction succeeded + */ + /* package */ + @Override + synchronized void onTransactionResponse(int transactionId, boolean success) { + ContextHubServiceTransaction transaction = mTransactionQueue.peek(); + if (transaction == null) { + Log.w(TAG, "Received unexpected transaction response (no transaction pending)"); + return; + } + if (transaction.getTransactionId() != transactionId) { + Log.w( + TAG, + "Received unexpected transaction response (expected ID = " + + transaction.getTransactionId() + + ", received ID = " + + transactionId + + ")"); + return; + } + + transaction.onTransactionComplete( + success + ? ContextHubTransaction.RESULT_SUCCESS + : ContextHubTransaction.RESULT_FAILED_AT_HUB); + removeTransactionAndStartNext(); + } + + /* package */ + @Override + synchronized void onMessageDeliveryResponse(int messageSequenceNumber, boolean success) { + if (!Flags.reliableMessageRetrySupportService()) { + ContextHubServiceTransaction transaction = mTransactionQueue.peek(); + if (transaction == null) { + Log.w(TAG, "Received unexpected transaction response (no transaction pending)"); + return; + } + + int transactionMessageSequenceNumber = transaction.getMessageSequenceNumber(); + if (transaction.getTransactionType() != ContextHubTransaction.TYPE_RELIABLE_MESSAGE + || transactionMessageSequenceNumber != messageSequenceNumber) { + Log.w( + TAG, + "Received unexpected message transaction response (expected message " + + "sequence number = " + + transaction.getMessageSequenceNumber() + + ", received messageSequenceNumber = " + + messageSequenceNumber + + ")"); + return; + } + + transaction.onTransactionComplete( + success + ? ContextHubTransaction.RESULT_SUCCESS + : ContextHubTransaction.RESULT_FAILED_AT_HUB); + removeTransactionAndStartNext(); + return; + } + + ContextHubServiceTransaction transaction = + mReliableMessageTransactionMap.get(messageSequenceNumber); + if (transaction == null) { + Log.w( + TAG, + "Could not find reliable message transaction with " + + "message sequence number = " + + messageSequenceNumber); + return; + } + + completeMessageTransaction( + transaction, + success + ? ContextHubTransaction.RESULT_SUCCESS + : ContextHubTransaction.RESULT_FAILED_AT_HUB); + mExecutor.execute(() -> processMessageTransactions()); + } + + /** + * Handles a query response from a Context Hub. + * + * @param nanoAppStateList the list of nanoapps included in the response + */ + /* package */ + @Override + synchronized void onQueryResponse(List nanoAppStateList) { + ContextHubServiceTransaction transaction = mTransactionQueue.peek(); + if (transaction == null) { + Log.w(TAG, "Received unexpected query response (no transaction pending)"); + return; + } + if (transaction.getTransactionType() != ContextHubTransaction.TYPE_QUERY_NANOAPPS) { + Log.w(TAG, "Received unexpected query response (expected " + transaction + ")"); + return; + } + + transaction.onQueryResponse(ContextHubTransaction.RESULT_SUCCESS, nanoAppStateList); + removeTransactionAndStartNext(); + } + + /** Handles a hub reset event by stopping a pending transaction and starting the next. */ + /* package */ + @Override + synchronized void onHubReset() { + if (Flags.reliableMessageRetrySupportService()) { + Iterator> iter = + mReliableMessageTransactionMap.entrySet().iterator(); + while (iter.hasNext()) { + completeMessageTransaction( + iter.next().getValue(), ContextHubTransaction.RESULT_FAILED_AT_HUB, iter); + } + } + + ContextHubServiceTransaction transaction = mTransactionQueue.peek(); + if (transaction == null) { + return; + } + + removeTransactionAndStartNext(); + } + + /** + * Pops the front transaction from the queue and starts the next pending transaction request. + * + *

    Removing elements from the transaction queue must only be done through this method. When a + * pending transaction is removed, the timeout timer is cancelled and the transaction is marked + * complete. + * + *

    It is assumed that the transaction queue is non-empty when this method is invoked, and + * that the caller has obtained a lock on this ContextHubTransactionManager object. + */ + private void removeTransactionAndStartNext() { + if (mTimeoutFuture != null) { + mTimeoutFuture.cancel(/* mayInterruptIfRunning= */ false); + mTimeoutFuture = null; + } + + ContextHubServiceTransaction transaction = mTransactionQueue.remove(); + transaction.setComplete(); + + if (!mTransactionQueue.isEmpty()) { + startNextTransaction(); + } + } + + /** + * Starts the next pending transaction request. + * + *

    Starting new transactions must only be done through this method. This method continues to + * process the transaction queue as long as there are pending requests, and no transaction is + * pending. + * + *

    It is assumed that the caller has obtained a lock on this ContextHubTransactionManager + * object. + */ + private void startNextTransaction() { + int result = ContextHubTransaction.RESULT_FAILED_UNKNOWN; + while (result != ContextHubTransaction.RESULT_SUCCESS && !mTransactionQueue.isEmpty()) { + ContextHubServiceTransaction transaction = mTransactionQueue.peek(); + result = transaction.onTransact(); + + if (result == ContextHubTransaction.RESULT_SUCCESS) { + Runnable onTimeoutFunc = + () -> { + synchronized (this) { + if (!transaction.isComplete()) { + Log.d(TAG, transaction + " timed out"); + transaction.onTransactionComplete( + ContextHubTransaction.RESULT_FAILED_TIMEOUT); + + removeTransactionAndStartNext(); + } + } + }; + + long timeoutMs = transaction.getTimeout(TimeUnit.MILLISECONDS); + try { + mTimeoutFuture = + mExecutor.schedule(onTimeoutFunc, timeoutMs, TimeUnit.MILLISECONDS); + } catch (Exception e) { + Log.e(TAG, "Error when schedule a timer", e); + } + } else { + transaction.onTransactionComplete( + ContextHubServiceUtil.toTransactionResult(result)); + mTransactionQueue.remove(); + } + } + } + + /** + * Processes message transactions, starting and completing them as needed. + * + *

    This function is called when adding a message transaction or when a timer expires for an + * existing message transaction's retry or timeout. The internal processing loop will iterate at + * most twice as if one iteration completes a transaction, the next iteration can only start new + * transactions. If the first iteration does not complete any transaction, the loop will only + * iterate once. + * + *

    + */ + private synchronized void processMessageTransactions() { + if (!Flags.reliableMessageRetrySupportService()) { + return; + } + + if (mReliableMessageTransactionFuture != null) { + mReliableMessageTransactionFuture.cancel(/* mayInterruptIfRunning= */ false); + mReliableMessageTransactionFuture = null; + } + + long now = SystemClock.elapsedRealtimeNanos(); + long nextExecutionTime = Long.MAX_VALUE; + boolean continueProcessing; + do { + continueProcessing = false; + Iterator> iter = + mReliableMessageTransactionMap.entrySet().iterator(); + while (iter.hasNext()) { + ContextHubServiceTransaction transaction = iter.next().getValue(); + short hostEndpointId = transaction.getHostEndpointId(); + int numCompletedStartCalls = transaction.getNumCompletedStartCalls(); + if (numCompletedStartCalls == 0 + && mReliableMessageHostEndpointIdActiveSet.contains(hostEndpointId)) { + continue; + } + + long nextRetryTime = transaction.getNextRetryTime(); + long timeoutTime = transaction.getTimeoutTime(); + boolean transactionTimedOut = timeoutTime <= now; + boolean transactionHitMaxRetries = + nextRetryTime <= now + && numCompletedStartCalls > RELIABLE_MESSAGE_MAX_NUM_RETRY; + if (transactionTimedOut || transactionHitMaxRetries) { + completeMessageTransaction( + transaction, ContextHubTransaction.RESULT_FAILED_TIMEOUT, iter); + continueProcessing = true; + } else { + if (nextRetryTime <= now || numCompletedStartCalls <= 0) { + startMessageTransaction(transaction, now); + } + + nextExecutionTime = Math.min(nextExecutionTime, transaction.getNextRetryTime()); + nextExecutionTime = Math.min(nextExecutionTime, transaction.getTimeoutTime()); + } + } + } while (continueProcessing); + + if (nextExecutionTime < Long.MAX_VALUE) { + mReliableMessageTransactionFuture = + mExecutor.schedule( + () -> processMessageTransactions(), + Math.max( + nextExecutionTime - SystemClock.elapsedRealtimeNanos(), + RELIABLE_MESSAGE_MIN_WAIT_TIME.toNanos()), + TimeUnit.NANOSECONDS); + } + } + + /** + * Completes a message transaction and removes it from the reliable message map. + * + * @param transaction The transaction to complete. + * @param result The result code. + */ + private void completeMessageTransaction( + ContextHubServiceTransaction transaction, @ContextHubTransaction.Result int result) { + completeMessageTransaction(transaction, result, /* iter= */ null); + } + + /** + * Completes a message transaction and removes it from the reliable message map using iter. + * + * @param transaction The transaction to complete. + * @param result The result code. + * @param iter The iterator for the reliable message map - used to remove the message directly. + */ + private void completeMessageTransaction( + ContextHubServiceTransaction transaction, + @ContextHubTransaction.Result int result, + Iterator> iter) { + transaction.onTransactionComplete(result); + + if (iter == null) { + mReliableMessageTransactionMap.remove(transaction.getMessageSequenceNumber()); + } else { + iter.remove(); + } + mReliableMessageHostEndpointIdActiveSet.remove(transaction.getHostEndpointId()); + + Log.d( + TAG, + "Successfully completed reliable message transaction with " + + "message sequence number = " + + transaction.getMessageSequenceNumber() + + " and result = " + + result); + } + + /** + * Starts a message transaction. + * + * @param transaction The transaction to start. + * @param now The now time. + */ + private void startMessageTransaction(ContextHubServiceTransaction transaction, long now) { + int numCompletedStartCalls = transaction.getNumCompletedStartCalls(); + @ContextHubTransaction.Result int result = transaction.onTransact(); + if (result == ContextHubTransaction.RESULT_SUCCESS) { + Log.d( + TAG, + "Successfully " + + (numCompletedStartCalls == 0 ? "started" : "retried") + + " reliable message transaction with message sequence number = " + + transaction.getMessageSequenceNumber()); + } else { + Log.w( + TAG, + "Could not start reliable message transaction with " + + "message sequence number = " + + transaction.getMessageSequenceNumber() + + ", result = " + + result); + } + + transaction.setNextRetryTime(now + RELIABLE_MESSAGE_RETRY_WAIT_TIME.toNanos()); + if (transaction.getTimeoutTime() == Long.MAX_VALUE) { // first time starting transaction + transaction.setTimeoutTime(now + RELIABLE_MESSAGE_TIMEOUT.toNanos()); + } + transaction.setNumCompletedStartCalls(numCompletedStartCalls + 1); + mReliableMessageHostEndpointIdActiveSet.add(transaction.getHostEndpointId()); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + int i = 0; + synchronized (this) { + for (ContextHubServiceTransaction transaction : mTransactionQueue) { + sb.append(i); + sb.append(": "); + sb.append(transaction.toString()); + sb.append("\n"); + ++i; + } + + if (Flags.reliableMessageRetrySupportService()) { + for (ContextHubServiceTransaction transaction : + mReliableMessageTransactionMap.values()) { + sb.append(i); + sb.append(": "); + sb.append(transaction.toString()); + sb.append("\n"); + ++i; + } + } + + sb.append("Transaction History:\n"); + Iterator iterator = mTransactionRecordDeque.descendingIterator(); + while (iterator.hasNext()) { + sb.append(iterator.next()); + sb.append("\n"); + } + } + return sb.toString(); + } +} -- GitLab From 3d5f5686b45edfaab33d7e1684a50424225a9c18 Mon Sep 17 00:00:00 2001 From: Liran Binyamin Date: Wed, 2 Oct 2024 12:23:31 -0400 Subject: [PATCH 021/447] Pass bubble flyout from wm shell to launcher Flag: com.android.wm.shell.enable_bubble_bar Bug: 277815200 Test: atest BubbleInfoTest Change-Id: I4d9165d511015739b1a621eea56a73927255e40d --- .../wm/shell/shared/bubbles/BubbleInfo.java | 32 +++++++---- .../shared/bubbles/ParcelableFlyoutMessage.kt | 55 +++++++++++++++++++ .../com/android/wm/shell/bubbles/Bubble.java | 18 +++++- .../wm/shell/bubbles/BubbleViewInfoTask.java | 6 +- .../bubbles/BubbleViewInfoTaskLegacy.java | 6 +- .../wm/shell/shared/bubbles/BubbleInfoTest.kt | 14 ++++- 6 files changed, 117 insertions(+), 14 deletions(-) create mode 100644 libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/ParcelableFlyoutMessage.kt diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleInfo.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleInfo.java index 58766826bd3b..85dabce8ac20 100644 --- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleInfo.java +++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleInfo.java @@ -30,29 +30,32 @@ import java.util.Objects; */ public class BubbleInfo implements Parcelable { - private String mKey; // Same key as the Notification + private final String mKey; // Same key as the Notification private int mFlags; // Flags from BubbleMetadata @Nullable - private String mShortcutId; - private int mUserId; - private String mPackageName; + private final String mShortcutId; + private final int mUserId; + private final String mPackageName; /** * All notification bubbles require a shortcut to be set on the notification, however, the * app could still specify an Icon and PendingIntent to use for the bubble. In that case * this icon will be populated. If the bubble is entirely shortcut based, this will be null. */ @Nullable - private Icon mIcon; + private final Icon mIcon; @Nullable - private String mTitle; + private final String mTitle; @Nullable - private String mAppName; - private boolean mIsImportantConversation; - private boolean mShowAppBadge; + private final String mAppName; + private final boolean mIsImportantConversation; + private final boolean mShowAppBadge; + @Nullable + private final ParcelableFlyoutMessage mParcelableFlyoutMessage; public BubbleInfo(String key, int flags, @Nullable String shortcutId, @Nullable Icon icon, int userId, String packageName, @Nullable String title, @Nullable String appName, - boolean isImportantConversation, boolean showAppBadge) { + boolean isImportantConversation, boolean showAppBadge, + @Nullable ParcelableFlyoutMessage flyoutMessage) { mKey = key; mFlags = flags; mShortcutId = shortcutId; @@ -63,6 +66,7 @@ public class BubbleInfo implements Parcelable { mAppName = appName; mIsImportantConversation = isImportantConversation; mShowAppBadge = showAppBadge; + mParcelableFlyoutMessage = flyoutMessage; } private BubbleInfo(Parcel source) { @@ -76,6 +80,8 @@ public class BubbleInfo implements Parcelable { mAppName = source.readString(); mIsImportantConversation = source.readBoolean(); mShowAppBadge = source.readBoolean(); + mParcelableFlyoutMessage = source.readParcelable( + ParcelableFlyoutMessage.class.getClassLoader(), ParcelableFlyoutMessage.class); } public String getKey() { @@ -122,6 +128,11 @@ public class BubbleInfo implements Parcelable { return mShowAppBadge; } + @Nullable + public ParcelableFlyoutMessage getParcelableFlyoutMessage() { + return mParcelableFlyoutMessage; + } + /** * Whether this bubble is currently being hidden from the stack. */ @@ -180,6 +191,7 @@ public class BubbleInfo implements Parcelable { parcel.writeString(mAppName); parcel.writeBoolean(mIsImportantConversation); parcel.writeBoolean(mShowAppBadge); + parcel.writeParcelable(mParcelableFlyoutMessage, flags); } @NonNull diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/ParcelableFlyoutMessage.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/ParcelableFlyoutMessage.kt new file mode 100644 index 000000000000..294d5e552684 --- /dev/null +++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/ParcelableFlyoutMessage.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.shared.bubbles + +import android.graphics.drawable.Icon +import android.os.Parcel +import android.os.Parcelable + +/** The contents of the flyout message to be passed to launcher for rendering in the bubble bar. */ +class ParcelableFlyoutMessage( + val icon: Icon?, + val title: String?, + val message: String?, +) : Parcelable { + + constructor( + parcel: Parcel + ) : this( + icon = parcel.readParcelable(Icon::class.java.classLoader), + title = parcel.readString(), + message = parcel.readString(), + ) + + override fun writeToParcel(parcel: Parcel, flags: Int) { + parcel.writeParcelable(icon, flags) + parcel.writeString(title) + parcel.writeString(message) + } + + override fun describeContents() = 0 + + companion object { + @JvmField + val CREATOR = + object : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel) = ParcelableFlyoutMessage(parcel) + + override fun newArray(size: Int) = arrayOfNulls(size) + } + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java index 169361ad5f6b..e3fc5c2273e2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java @@ -56,6 +56,7 @@ import com.android.wm.shell.bubbles.bar.BubbleBarLayerView; import com.android.wm.shell.shared.annotations.ShellBackgroundThread; import com.android.wm.shell.shared.annotations.ShellMainThread; import com.android.wm.shell.shared.bubbles.BubbleInfo; +import com.android.wm.shell.shared.bubbles.ParcelableFlyoutMessage; import java.io.PrintWriter; import java.util.List; @@ -350,7 +351,22 @@ public class Bubble implements BubbleViewProvider { getTitle(), getAppName(), isImportantConversation(), - !isAppLaunchIntent()); + !isAppLaunchIntent(), + getParcelableFlyoutMessage()); + } + + /** Creates a parcelable flyout message to send to launcher. */ + @Nullable + private ParcelableFlyoutMessage getParcelableFlyoutMessage() { + if (mFlyoutMessage == null) { + return null; + } + // the icon is only used in group chats + Icon icon = mFlyoutMessage.isGroupChat ? mFlyoutMessage.senderIcon : null; + String title = + mFlyoutMessage.senderName == null ? null : mFlyoutMessage.senderName.toString(); + String message = mFlyoutMessage.message == null ? null : mFlyoutMessage.message.toString(); + return new ParcelableFlyoutMessage(icon, title, message); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java index 3982a237dd3b..c5e3afda34dd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java @@ -274,7 +274,7 @@ public class BubbleViewInfoTask { @Nullable BubbleExpandedView expandedView; int dotColor; Path dotPath; - @Nullable Bubble.FlyoutMessage flyoutMessage; + Bubble.FlyoutMessage flyoutMessage; Bitmap bubbleBitmap; Bitmap badgeBitmap; @@ -300,6 +300,10 @@ public class BubbleViewInfoTask { return null; } + // set the flyout message but don't load the avatar because we can't pass it on the + // binder to launcher + info.flyoutMessage = b.getFlyoutMessage(); + return info; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskLegacy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskLegacy.java index 1b7bb0db6516..c12822a27662 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskLegacy.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskLegacy.java @@ -181,7 +181,7 @@ public class BubbleViewInfoTaskLegacy extends @Nullable BubbleExpandedView expandedView; int dotColor; Path dotPath; - @Nullable Bubble.FlyoutMessage flyoutMessage; + Bubble.FlyoutMessage flyoutMessage; Bitmap bubbleBitmap; Bitmap badgeBitmap; @@ -221,6 +221,10 @@ public class BubbleViewInfoTaskLegacy extends return null; } + // set the flyout message but don't load the avatar because we can't pass it on the + // binder to launcher + info.flyoutMessage = b.getFlyoutMessage(); + return info; } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/BubbleInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/BubbleInfoTest.kt index 641063c27076..205defef5dd5 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/BubbleInfoTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/BubbleInfoTest.kt @@ -16,6 +16,8 @@ package com.android.wm.shell.shared.bubbles +import android.graphics.drawable.Icon +import android.net.Uri import android.os.Parcel import android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE import android.testing.AndroidTestingRunner @@ -42,7 +44,12 @@ class BubbleInfoTest : ShellTestCase() { "title", "Some app", true, - true + true, + ParcelableFlyoutMessage( + Icon.createWithContentUri(Uri.parse("content://image/123")), + "sender", + "message" + ) ) val parcel = Parcel.obtain() bubbleInfo.writeToParcel(parcel, PARCELABLE_WRITE_RETURN_VALUE) @@ -60,5 +67,10 @@ class BubbleInfoTest : ShellTestCase() { assertThat(bubbleInfo.appName).isEqualTo(bubbleInfoFromParcel.appName) assertThat(bubbleInfo.isImportantConversation) .isEqualTo(bubbleInfoFromParcel.isImportantConversation) + with(bubbleInfo.parcelableFlyoutMessage!!) { + assertThat(icon!!.uri.toString()).isEqualTo("content://image/123") + assertThat(title).isEqualTo("sender") + assertThat(message).isEqualTo("message") + } } } -- GitLab From ad25f42cd12d940a18e90e5e21562958b0ad711b Mon Sep 17 00:00:00 2001 From: Haoran Zhang Date: Wed, 2 Oct 2024 20:47:25 +0000 Subject: [PATCH 022/447] Post onProvideAutofillStructure in Augment Autofill flow to UI thread This is to fix the issue that onProvideAutofillStructure is called on the binder thread causing CtsInputMethodTestCases FocusHandlingTest#testOnCheckIsTextEditorRunOnUIThreadWithInputMethodManagerIsActive to fail. Bug: b/362908997 Change-Id: Ic68dca1e0baef2e5b00c248c4417b8891749cdcf Test: atest CtsAutoFillServiceTestCases:android.autofillservice.cts.augmented Flag: EXEMPT bugfix --- .../view/autofill/AutofillManager.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 79ecfe1e9141..1a45939f65b6 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -117,6 +117,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import sun.misc.Cleaner; @@ -4914,7 +4916,22 @@ public final class AutofillManager { && (root.getWindowFlags() & WindowManager.LayoutParams.FLAG_SECURE) == 0) { ViewNodeBuilder viewStructure = new ViewNodeBuilder(); viewStructure.setAutofillId(view.getAutofillId()); - view.onProvideAutofillStructure(viewStructure, /* flags= */ 0); + + // Post onProvideAutofillStructure to the UI thread + final CountDownLatch latch = new CountDownLatch(1); + afm.post( + () -> { + view.onProvideAutofillStructure(viewStructure, /* flags= */ 0); + latch.countDown(); + } + ); + try { + latch.await(5000, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return null; + } + // TODO(b/141703532): We don't call View#onProvideAutofillVirtualStructure for // efficiency reason. But this also means we will return null for virtual views // for now. We will add a new API to fetch the view node info of the virtual -- GitLab From d04cea5ea08f91f55a14209c1e424e163e2d50ab Mon Sep 17 00:00:00 2001 From: Dmitry Dementyev Date: Tue, 1 Oct 2024 14:57:44 -0700 Subject: [PATCH 023/447] Update checkKeyIntent 1) Explicityly set component after target activity check. 2) Update Intent subclass check. Bug: 360846772 Test: manual Flag: EXEMPT bugfix Change-Id: Ied7961c73299681aa5b523cf3f00fd905893116f (cherry picked from commit cde345a7ee06db716e613e12a2c218ce248ad1c4) --- .../android/server/accounts/AccountManagerService.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index fe5375233d8f..70f66cae50f0 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -4917,6 +4917,8 @@ public class AccountManagerService Log.e(TAG, String.format(tmpl, activityName, pkgName, mAccountType)); return false; } + intent.setComponent(targetActivityInfo.getComponentName()); + bundle.putParcelable(AccountManager.KEY_INTENT, intent); return true; } finally { Binder.restoreCallingIdentity(bid); @@ -4938,14 +4940,15 @@ public class AccountManagerService Bundle simulateBundle = p.readBundle(); p.recycle(); Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT, Intent.class); - if (intent != null && intent.getClass() != Intent.class) { - return false; - } Intent simulateIntent = simulateBundle.getParcelable(AccountManager.KEY_INTENT, Intent.class); if (intent == null) { return (simulateIntent == null); } + if (intent.getClass() != Intent.class || simulateIntent.getClass() != Intent.class) { + return false; + } + if (!intent.filterEquals(simulateIntent)) { return false; } -- GitLab From fb138f4865c733270a293d90f196bbc8c2632d53 Mon Sep 17 00:00:00 2001 From: Gabriel Biren Date: Wed, 2 Oct 2024 17:00:19 +0000 Subject: [PATCH 024/447] Convert migrateLegacyKeystoreToWifiBlobstore to an asynchronous method. API council suggested that the migration can be a heavy operation, so it is best handled in the background. Bug: 358618927 Flag: android.net.wifi.flags.legacy_keystore_to_wifi_blobstore_migration_read_only Test: atest WifiMigrationTest Change-Id: I1a61eda93e9f3e2cf0081326777d20a618acb456 --- core/api/module-lib-current.txt | 2 +- .../src/android/net/wifi/WifiMigration.java | 30 +++++++++++++++++-- .../android/net/wifi/WifiMigrationTest.java | 12 ++++---- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 8447a7feb54e..d38a4e7505fd 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -321,7 +321,7 @@ package android.net.netstats { package android.net.wifi { public final class WifiMigration { - method @FlaggedApi("android.net.wifi.flags.legacy_keystore_to_wifi_blobstore_migration_read_only") public static int migrateLegacyKeystoreToWifiBlobstore(); + method @FlaggedApi("android.net.wifi.flags.legacy_keystore_to_wifi_blobstore_migration_read_only") public static void migrateLegacyKeystoreToWifiBlobstore(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer); field @FlaggedApi("android.net.wifi.flags.legacy_keystore_to_wifi_blobstore_migration_read_only") public static final int KEYSTORE_MIGRATION_FAILURE_ENCOUNTERED_EXCEPTION = 2; // 0x2 field @FlaggedApi("android.net.wifi.flags.legacy_keystore_to_wifi_blobstore_migration_read_only") public static final int KEYSTORE_MIGRATION_SUCCESS_MIGRATION_COMPLETE = 0; // 0x0 field @FlaggedApi("android.net.wifi.flags.legacy_keystore_to_wifi_blobstore_migration_read_only") public static final int KEYSTORE_MIGRATION_SUCCESS_MIGRATION_NOT_NEEDED = 1; // 0x1 diff --git a/wifi/java/src/android/net/wifi/WifiMigration.java b/wifi/java/src/android/net/wifi/WifiMigration.java index f1850dd91b5f..28e9c45fb6cb 100644 --- a/wifi/java/src/android/net/wifi/WifiMigration.java +++ b/wifi/java/src/android/net/wifi/WifiMigration.java @@ -38,6 +38,8 @@ import android.util.AtomicFile; import android.util.Log; import android.util.SparseArray; +import com.android.internal.os.BackgroundThread; + import java.io.File; import java.io.FileNotFoundException; import java.io.InputStream; @@ -48,6 +50,8 @@ import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.concurrent.Executor; +import java.util.function.IntConsumer; /** * Class used to provide one time hooks for existing OEM devices to migrate their config store @@ -605,13 +609,35 @@ public final class WifiMigration { /** * Migrate any certificates in Legacy Keystore to the newer WifiBlobstore database. * - * If there are no certificates to migrate, this method will return immediately. + * Operation will be handled on the BackgroundThread, and the result will be posted + * to the provided Executor. + * + * @param executor The executor on which callback will be invoked + * @param resultsCallback Callback to receive the status code * * @hide */ @FlaggedApi(Flags.FLAG_LEGACY_KEYSTORE_TO_WIFI_BLOBSTORE_MIGRATION_READ_ONLY) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public static @KeystoreMigrationStatus int migrateLegacyKeystoreToWifiBlobstore() { + public static void migrateLegacyKeystoreToWifiBlobstore( + @NonNull Executor executor, @NonNull IntConsumer resultsCallback) { + Objects.requireNonNull(executor, "executor cannot be null"); + Objects.requireNonNull(resultsCallback, "resultsCallback cannot be null"); + BackgroundThread.getHandler().post(() -> { + int status = migrateLegacyKeystoreToWifiBlobstoreInternal(); + executor.execute(() -> { + resultsCallback.accept(status); + }); + }); + } + + /** + * Synchronously perform the Keystore migration described in + * {@link #migrateLegacyKeystoreToWifiBlobstore(Executor, IntConsumer)} + * + * @hide + */ + public static @KeystoreMigrationStatus int migrateLegacyKeystoreToWifiBlobstoreInternal() { if (!WifiBlobStore.supplicantCanAccessBlobstore()) { // Supplicant cannot access WifiBlobstore, so keep the certs in Legacy Keystore Log.i(TAG, "Avoiding migration since supplicant cannot access WifiBlobstore"); diff --git a/wifi/tests/src/android/net/wifi/WifiMigrationTest.java b/wifi/tests/src/android/net/wifi/WifiMigrationTest.java index 0aa299f959fe..ce5b60a2da9f 100644 --- a/wifi/tests/src/android/net/wifi/WifiMigrationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiMigrationTest.java @@ -81,7 +81,7 @@ public class WifiMigrationTest { public void testKeystoreMigrationAvoidedOnLegacyVendorPartition() { when(WifiBlobStore.supplicantCanAccessBlobstore()).thenReturn(false); assertEquals(WifiMigration.KEYSTORE_MIGRATION_SUCCESS_MIGRATION_NOT_NEEDED, - WifiMigration.migrateLegacyKeystoreToWifiBlobstore()); + WifiMigration.migrateLegacyKeystoreToWifiBlobstoreInternal()); verifyNoMoreInteractions(mLegacyKeystore, mWifiBlobStore); } @@ -93,7 +93,7 @@ public class WifiMigrationTest { public void testKeystoreMigrationNoLegacyAliases() throws Exception { when(mLegacyKeystore.list(anyString(), anyInt())).thenReturn(new String[0]); assertEquals(WifiMigration.KEYSTORE_MIGRATION_SUCCESS_MIGRATION_NOT_NEEDED, - WifiMigration.migrateLegacyKeystoreToWifiBlobstore()); + WifiMigration.migrateLegacyKeystoreToWifiBlobstoreInternal()); verify(mLegacyKeystore).list(anyString(), anyInt()); verifyNoMoreInteractions(mLegacyKeystore, mWifiBlobStore); } @@ -110,7 +110,7 @@ public class WifiMigrationTest { when(mWifiBlobStore.list(anyString())).thenReturn(blobstoreAliases); assertEquals(WifiMigration.KEYSTORE_MIGRATION_SUCCESS_MIGRATION_COMPLETE, - WifiMigration.migrateLegacyKeystoreToWifiBlobstore()); + WifiMigration.migrateLegacyKeystoreToWifiBlobstoreInternal()); verify(mWifiBlobStore, times(legacyAliases.length)).put(anyString(), any(byte[].class)); } @@ -129,7 +129,7 @@ public class WifiMigrationTest { // Expect that only the unique legacy alias is migrated to the blobstore assertEquals(WifiMigration.KEYSTORE_MIGRATION_SUCCESS_MIGRATION_COMPLETE, - WifiMigration.migrateLegacyKeystoreToWifiBlobstore()); + WifiMigration.migrateLegacyKeystoreToWifiBlobstoreInternal()); verify(mWifiBlobStore).list(anyString()); verify(mWifiBlobStore).put(eq(uniqueLegacyAlias), any(byte[].class)); verifyNoMoreInteractions(mWifiBlobStore); @@ -146,7 +146,7 @@ public class WifiMigrationTest { when(mLegacyKeystore.list(anyString(), anyInt())).thenThrow( new ServiceSpecificException(ILegacyKeystore.ERROR_SYSTEM_ERROR)); assertEquals(WifiMigration.KEYSTORE_MIGRATION_SUCCESS_MIGRATION_NOT_NEEDED, - WifiMigration.migrateLegacyKeystoreToWifiBlobstore()); + WifiMigration.migrateLegacyKeystoreToWifiBlobstoreInternal()); } /** @@ -157,6 +157,6 @@ public class WifiMigrationTest { public void testKeystoreMigrationFailsIfExceptionEncountered() throws Exception { when(mLegacyKeystore.list(anyString(), anyInt())).thenThrow(new RemoteException()); assertEquals(WifiMigration.KEYSTORE_MIGRATION_FAILURE_ENCOUNTERED_EXCEPTION, - WifiMigration.migrateLegacyKeystoreToWifiBlobstore()); + WifiMigration.migrateLegacyKeystoreToWifiBlobstoreInternal()); } } -- GitLab From 8c629e91f579e109bd8ca4f70c63e9e5a3c81f62 Mon Sep 17 00:00:00 2001 From: Austin Borger Date: Thu, 11 Jul 2024 08:56:24 -0700 Subject: [PATCH 025/447] Use context AttributionSource as the identity source-of-truth for connection CameraService::connect and ::connectDevice allow an argument of USE_CALLING_* for both the pid and uid of the client. In this change, USE_CALLING_* is retired in favor of using the AttributionSource provided by the calling Context. The AttributionSource pid/uid is verified to be truthful via getCallingPid() / getCallingUid(). This change has no impact on APIs which do not pass the pid/uid through ICameraService - the AttributionSource pid/uid are ignored for those APIs and the calling pid / uid are still universally used. Bug: 190657833 Bug: 369850244 Change-Id: I622c24b7ace926645b64ac70650e401dc7ad5f1e Flag: com.android.internal.camera.flags.use_context_attribution_source Test: Ran new CTS test with flag on/off --- .../hardware/camera2/CameraManager.java | 71 ++++++++++++++----- core/jni/Android.bp | 1 + core/jni/android_hardware_Camera.cpp | 23 ++++-- 3 files changed, 71 insertions(+), 24 deletions(-) diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index 21627920f598..344f6b61423b 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -19,6 +19,7 @@ package android.hardware.camera2; import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA; import static android.content.Context.DEVICE_ID_DEFAULT; +import static android.content.Context.DEVICE_ID_INVALID; import android.annotation.CallbackExecutor; import android.annotation.FlaggedApi; @@ -36,6 +37,7 @@ import android.companion.virtual.VirtualDeviceManager; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.compat.annotation.Overridable; +import android.content.AttributionSource; import android.content.AttributionSourceState; import android.content.Context; import android.content.pm.PackageManager; @@ -674,8 +676,8 @@ public final class CameraManager { } try { for (String physicalCameraId : physicalCameraIds) { - AttributionSourceState clientAttribution = getClientAttribution(); - clientAttribution.deviceId = DEVICE_ID_DEFAULT; + AttributionSourceState clientAttribution = getClientAttribution(DEVICE_ID_DEFAULT, + /* useContextAttributionSource= */ false); CameraMetadataNative physicalCameraInfo = cameraService.getCameraCharacteristics( physicalCameraId, @@ -972,27 +974,58 @@ public final class CameraManager { } /** - * Constructs an AttributionSourceState with only the uid, pid, and deviceId fields set + * Retrieves the AttributionSourceState to pass to the CameraService. * - *

    This method is a temporary stopgap in the transition to using AttributionSource. Currently - * AttributionSourceState is only used as a vehicle for passing deviceId, uid, and pid - * arguments.

    + * @param deviceIdOverride An override of the AttributionSource's deviceId, if not equal to + * DEVICE_ID_INVALID + * @param useContextAttributionSource Whether to return the full attribution source provided by + * the Context. + * + * @hide + */ + public AttributionSourceState getClientAttribution(int deviceIdOverride, + boolean useContextAttributionSource) { + AttributionSource contextAttributionSource = mContext.getAttributionSource(); + if (deviceIdOverride != DEVICE_ID_INVALID) { + contextAttributionSource = contextAttributionSource.withDeviceId(deviceIdOverride); + } + AttributionSourceState contextAttributionSourceState = + contextAttributionSource.asState(); + + if (Flags.useContextAttributionSource() && useContextAttributionSource) { + return contextAttributionSourceState; + } else { + AttributionSourceState clientAttribution = + new AttributionSourceState(); + clientAttribution.uid = USE_CALLING_UID; + clientAttribution.pid = USE_CALLING_PID; + clientAttribution.deviceId = contextAttributionSourceState.deviceId; + clientAttribution.packageName = mContext.getOpPackageName(); + clientAttribution.attributionTag = mContext.getAttributionTag(); + clientAttribution.next = new AttributionSourceState[0]; + return clientAttribution; + } + } + + /** + * Retrieves the AttributionSourceState to pass to the CameraService. + * + * @param useContextAttributionSource Whether to return the full attribution source provided by + * the Context. + * + * @hide + */ + public AttributionSourceState getClientAttribution(boolean useContextAttributionSource) { + return getClientAttribution(DEVICE_ID_INVALID, useContextAttributionSource); + } + + /** + * Retrieves the AttributionSourceState to pass to the CameraService. * * @hide */ public AttributionSourceState getClientAttribution() { - // TODO: Send the full contextAttribution over aidl, remove USE_CALLING_* - AttributionSourceState contextAttribution = - mContext.getAttributionSource().asState(); - AttributionSourceState clientAttribution = - new AttributionSourceState(); - clientAttribution.uid = USE_CALLING_UID; - clientAttribution.pid = USE_CALLING_PID; - clientAttribution.deviceId = contextAttribution.deviceId; - clientAttribution.packageName = mContext.getOpPackageName(); - clientAttribution.attributionTag = mContext.getAttributionTag(); - clientAttribution.next = new AttributionSourceState[0]; - return clientAttribution; + return getClientAttribution(DEVICE_ID_INVALID, /* useContextAttributionSource= */ false); } /** @@ -1047,7 +1080,7 @@ public final class CameraManager { } AttributionSourceState clientAttribution = - getClientAttribution(); + getClientAttribution(/* useContextAttributionSource= */ true); cameraUser = cameraService.connectDevice( callbacks, diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 9a4ff8fc264f..f2ca44c41b8c 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -307,6 +307,7 @@ cc_library_shared_for_libandroid_runtime { "spatializer-aidl-cpp", "av-types-aidl-cpp", "android.hardware.camera.device@3.2", + "camera_platform_flags_c_lib", "libandroid_net", "libbattery", "libnetdutils", diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index 3f74fac35bb7..10e49efee92e 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include "jni.h" using namespace android; +namespace flags = com::android::internal::camera::flags; enum { // Keep up to date with Camera.java @@ -527,14 +529,19 @@ void JNICameraContext::clearCallbackBuffers_l(JNIEnv *env, Vector *b } static bool attributionSourceStateForJavaParcel(JNIEnv *env, jobject jClientAttributionParcel, + bool useContextAttributionSource, AttributionSourceState &clientAttribution) { const Parcel *clientAttributionParcel = parcelForJavaObject(env, jClientAttributionParcel); if (clientAttribution.readFromParcel(clientAttributionParcel) != ::android::OK) { jniThrowRuntimeException(env, "Fail to unparcel AttributionSourceState"); return false; } - clientAttribution.uid = Camera::USE_CALLING_UID; - clientAttribution.pid = Camera::USE_CALLING_PID; + + if (!(useContextAttributionSource && flags::use_context_attribution_source())) { + clientAttribution.uid = Camera::USE_CALLING_UID; + clientAttribution.pid = Camera::USE_CALLING_PID; + } + return true; } @@ -542,7 +549,9 @@ static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz jobject jClientAttributionParcel, jint devicePolicy) { AttributionSourceState clientAttribution; - if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, clientAttribution)) { + if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, + /* useContextAttributionSource= */ false, + clientAttribution)) { return 0; } return Camera::getNumberOfCameras(clientAttribution, devicePolicy); @@ -553,7 +562,9 @@ static void android_hardware_Camera_getCameraInfo(JNIEnv *env, jobject thiz, jin jobject jClientAttributionParcel, jint devicePolicy, jobject info_obj) { AttributionSourceState clientAttribution; - if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, clientAttribution)) { + if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, + /* useContextAttributionSource= */ false, + clientAttribution)) { return; } @@ -587,7 +598,9 @@ static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobj jobject jClientAttributionParcel, jint devicePolicy) { AttributionSourceState clientAttribution; - if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, clientAttribution)) { + if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, + /* useContextAttributionSource= */ true, + clientAttribution)) { return -EACCES; } -- GitLab From a46fb7c5c16c158b78f8c548f2e26b0f89ae7c1e Mon Sep 17 00:00:00 2001 From: Daichi Hirono Date: Wed, 2 Oct 2024 08:21:38 +0900 Subject: [PATCH 026/447] Add flag for "move to next display" shortcut in desktop Flag: EXEMPT adding flag Bug: 364154795 Test: m Change-Id: I28e3a8d47b4b2b51672395d5ed9958db27c91683 --- .../android/window/flags/lse_desktop_experience.aconfig | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig index 70ac12f07a23..25884f4b0ffc 100644 --- a/core/java/android/window/flags/lse_desktop_experience.aconfig +++ b/core/java/android/window/flags/lse_desktop_experience.aconfig @@ -312,4 +312,11 @@ flag { namespace: "lse_desktop_experience" description: "Enables custom transitions for alt-tab app launches in Desktop Mode." bug: "370735595" -} \ No newline at end of file +} + +flag { + name: "enable_move_to_next_display_shortcut" + namespace: "lse_desktop_experience" + description: "Add new keyboard shortcut of moving a task into next display" + bug: "364154795" +} -- GitLab From 69f781014ea220802a60abf8c865c7f8bf0a7025 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Tue, 1 Oct 2024 13:24:52 +0900 Subject: [PATCH 027/447] Add aconfig flag for enlaring pointer icon with magnification Bug: 355734856 Test: build Flag: com.android.server.accessibility.magnification_enlarge_pointer Change-Id: Ia041e5651a434feb12884f92e19029eda411b994 --- services/accessibility/accessibility.aconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig index ee3bbcaf711d..034127c0420e 100644 --- a/services/accessibility/accessibility.aconfig +++ b/services/accessibility/accessibility.aconfig @@ -161,6 +161,13 @@ flag { } } +flag { + name: "magnification_enlarge_pointer" + namespace: "accessibility" + description: "When fullscreen magnification is enabled, pointer icon is enlarged" + bug: "355734856" +} + flag { name: "manager_avoid_receiver_timeout" namespace: "accessibility" -- GitLab From 18f2caa2d22da29e226b5db8c73390cd15dd94da Mon Sep 17 00:00:00 2001 From: Santiago Seifert Date: Thu, 3 Oct 2024 14:07:16 +0000 Subject: [PATCH 028/447] Clean up manager record logs for binder exceptions - Add information about the failing target operations. Such as package name, user id, and manager id. - Prevents the logging of the stacktrace. The operation name is sufficient. Bug: b/360129098 Test: atest CtsMediaBetterTogetherTestCases Test: Manually by testing output switcher on different media apps. Flag: EXEMPT loggging only change Change-Id: I2fbec8676390918ef49fd20e50b88289c88e996c --- .../server/media/MediaRouter2ServiceImpl.java | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index 8b06dadbaeeb..d1d5d4868c6f 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -1112,19 +1112,12 @@ class MediaRouter2ServiceImpl { continue; } - Log.w( - TAG, - TextUtils.formatSimple( - "Revoking access to manager record id: %d, package: %s, userId:" - + " %d", - manager.mManagerId, manager.mOwnerPackageName, userRecord.mUserId)); - + Slog.w(TAG, "Revoking access for " + manager.getDebugString()); unregisterManagerLocked(manager.mManager, /* died */ false); - try { manager.mManager.invalidateInstance(); } catch (RemoteException ex) { - Slog.w(TAG, "Failed to notify manager= " + manager + " of permission revocation."); + manager.logRemoteException("invalidateInstance", ex); } } } @@ -2428,10 +2421,7 @@ class MediaRouter2ServiceImpl { try { mManager.notifyRequestFailed(requestId, reason); } catch (RemoteException ex) { - Slog.w( - TAG, - "Failed to notify manager of the request failure. Manager probably died.", - ex); + logRemoteException("notifyRequestFailed", ex); } } @@ -2444,7 +2434,7 @@ class MediaRouter2ServiceImpl { try { mManager.notifyRoutesUpdated(routes); } catch (RemoteException ex) { - Slog.w(TAG, "Failed to notify routes. Manager probably died.", ex); + logRemoteException("notifyRoutesUpdated", ex); } } @@ -2457,10 +2447,7 @@ class MediaRouter2ServiceImpl { try { mManager.notifySessionUpdated(sessionInfo); } catch (RemoteException ex) { - Slog.w( - TAG, - "notifySessionUpdatedToManagers: Failed to notify. Manager probably died.", - ex); + logRemoteException("notifySessionUpdated", ex); } } @@ -2473,13 +2460,18 @@ class MediaRouter2ServiceImpl { try { mManager.notifySessionReleased(sessionInfo); } catch (RemoteException ex) { - Slog.w( - TAG, - "notifySessionReleasedToManagers: Failed to notify. Manager probably died.", - ex); + logRemoteException("notifySessionReleased", ex); } } + private void logRemoteException(String operation, RemoteException exception) { + String message = + TextUtils.formatSimple( + "%s failed for %s due to %s", + operation, getDebugString(), exception.toString()); + Slog.w(TAG, message); + } + private void updateScanningState(@ScanningState int scanningState) { if (mScanningState == scanningState) { return; @@ -2492,9 +2484,16 @@ class MediaRouter2ServiceImpl { UserHandler::updateDiscoveryPreferenceOnHandler, mUserRecord.mHandler)); } - @Override - public String toString() { - return "Manager " + mOwnerPackageName + " (pid " + mOwnerPid + ")"; + /** Returns a human readable representation of this manager record for logging purposes. */ + public String getDebugString() { + return TextUtils.formatSimple( + "Manager %s (id=%d,pid=%d,userId=%d,uid=%d,targetPkg=%s)", + mOwnerPackageName, + mManagerId, + mOwnerPid, + mUserRecord.mUserId, + mOwnerUid, + mTargetPackageName); } } -- GitLab From b024e5e870e9f583369b73c9720d9d0aaeb7665f Mon Sep 17 00:00:00 2001 From: Stefan Andonian Date: Mon, 23 Sep 2024 22:59:19 +0000 Subject: [PATCH 029/447] Refactor the TraceurMessenger code into a ServiceConnection class. This change has identical behavior to the code that was already there. The reason behind it is to distinguish the behavioral changes from the refactor for the following code changes to the Issue Recording Service code. Bug: 364824477 Test: Verified that this code still works the exact same as before. Flag: EXEMPT non-behavioral, small refactor Change-Id: I3d320d84392393cf27e05a6a9202872c0f2b6a7d --- .../IssueRecordingServiceSessionTest.kt | 12 +- .../RecordIssueDialogDelegateTest.kt | 12 +- .../recordissue/TraceurConnectionTest.kt | 77 +++++++ .../recordissue/UserAwareConnectionTest.kt | 70 +++++++ .../systemui/qs/tiles/RecordIssueTile.kt | 12 +- .../recordissue/IssueRecordingService.kt | 4 +- .../IssueRecordingServiceSession.kt | 8 +- .../recordissue/RecordIssueDialogDelegate.kt | 10 +- .../systemui/recordissue/TraceurConnection.kt | 145 ++++++++++++++ .../recordissue/TraceurMessageSender.kt | 189 ------------------ .../recordissue/UserAwareConnection.kt | 76 +++++++ .../systemui/qs/tiles/RecordIssueTileTest.kt | 8 +- 12 files changed, 401 insertions(+), 222 deletions(-) create mode 100644 packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/TraceurConnectionTest.kt create mode 100644 packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/UserAwareConnectionTest.kt create mode 100644 packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt delete mode 100644 packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt create mode 100644 packages/SystemUI/src/com/android/systemui/recordissue/UserAwareConnection.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt index 3e5dee69c85c..8e57914050d6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt @@ -53,7 +53,7 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() { private val bgExecutor = kosmos.fakeExecutor private val userContextProvider: UserContextProvider = kosmos.userTracker private val dialogTransitionAnimator: DialogTransitionAnimator = kosmos.dialogTransitionAnimator - private lateinit var traceurMessageSender: TraceurMessageSender + private lateinit var traceurConnection: TraceurConnection private val issueRecordingState = IssueRecordingState(kosmos.userTracker, kosmos.userFileManager) @@ -65,13 +65,13 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() { @Before fun setup() { - traceurMessageSender = mock() + traceurConnection = mock() underTest = IssueRecordingServiceSession( bgExecutor, dialogTransitionAnimator, panelInteractor, - traceurMessageSender, + traceurConnection, issueRecordingState, iActivityManager, notificationManager, @@ -85,7 +85,7 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() { bgExecutor.runAllReady() Truth.assertThat(issueRecordingState.isRecording).isTrue() - verify(traceurMessageSender).startTracing(any()) + verify(traceurConnection).startTracing(any()) } @Test @@ -94,7 +94,7 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() { bgExecutor.runAllReady() Truth.assertThat(issueRecordingState.isRecording).isFalse() - verify(traceurMessageSender).stopTracing() + verify(traceurConnection).stopTracing() } @Test @@ -124,7 +124,7 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() { underTest.share(0, uri, mContext) bgExecutor.runAllReady() - verify(traceurMessageSender).shareTraces(mContext, uri) + verify(traceurConnection).shareTraces(mContext, uri) } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt index 8d84c3e7392e..9ca8f447d374 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt @@ -78,7 +78,7 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() { @Mock private lateinit var sysuiState: SysUiState @Mock private lateinit var systemUIDialogManager: SystemUIDialogManager @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher - @Mock private lateinit var traceurMessageSender: TraceurMessageSender + @Mock private lateinit var traceurConnection: TraceurConnection private val systemClock = FakeSystemClock() private val bgExecutor = FakeExecutor(systemClock) private val mainExecutor = FakeExecutor(systemClock) @@ -104,7 +104,7 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() { systemUIDialogManager, sysuiState, broadcastDispatcher, - mDialogTransitionAnimator + mDialogTransitionAnimator, ) ) @@ -120,7 +120,7 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() { mediaProjectionMetricsLogger, screenCaptureDisabledDialogDelegate, state, - traceurMessageSender + traceurConnection, ) { latch.countDown() } @@ -166,7 +166,7 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() { verify(mediaProjectionMetricsLogger, never()) .notifyProjectionInitiated( anyInt(), - eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER) + eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER), ) assertThat(screenRecordSwitch.isChecked).isFalse() } @@ -188,7 +188,7 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() { verify(mediaProjectionMetricsLogger) .notifyProjectionInitiated( anyInt(), - eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER) + eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER), ) verify(factory, times(2)).create(any(SystemUIDialog.Delegate::class.java)) } @@ -208,7 +208,7 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() { verify(mediaProjectionMetricsLogger) .notifyProjectionInitiated( anyInt(), - eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER) + eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER), ) verify(factory, never()).create() } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/TraceurConnectionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/TraceurConnectionTest.kt new file mode 100644 index 000000000000..85a8237ff955 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/TraceurConnectionTest.kt @@ -0,0 +1,77 @@ +/* + * 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.recordissue + +import android.os.IBinder +import android.os.Looper +import android.os.Messenger +import android.testing.TestableLooper +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import androidx.test.platform.app.InstrumentationRegistry +import com.android.systemui.SysuiTestCase +import com.android.systemui.settings.UserContextProvider +import com.android.traceur.PresetTraceConfigs +import java.util.concurrent.CountDownLatch +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.mock +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.any +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +@SmallTest +@RunWith(AndroidJUnit4::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class TraceurConnectionTest : SysuiTestCase() { + + @Mock private lateinit var userContextProvider: UserContextProvider + + private lateinit var underTest: TraceurConnection + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + whenever(userContextProvider.userContext).thenReturn(mContext) + underTest = TraceurConnection(userContextProvider, Looper.getMainLooper()) + } + + @Test + fun onBoundRunnables_areRun_whenServiceIsBound() { + val latch = CountDownLatch(1) + underTest.onBound.add { latch.countDown() } + + underTest.onServiceConnected( + InstrumentationRegistry.getInstrumentation().componentName, + mock(IBinder::class.java), + ) + + latch.await() + } + + @Test + fun startTracing_sendsMsg_toStartTracing() { + underTest.binder = mock(Messenger::class.java) + + underTest.startTracing(PresetTraceConfigs.getThermalConfig()) + + verify(underTest.binder)!!.send(any()) + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/UserAwareConnectionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/UserAwareConnectionTest.kt new file mode 100644 index 000000000000..f671bf44c42b --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/UserAwareConnectionTest.kt @@ -0,0 +1,70 @@ +/* + * 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.recordissue + +import android.content.Context +import android.content.Intent +import android.testing.TestableLooper +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.settings.UserContextProvider +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.any +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.times +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +@SmallTest +@RunWith(AndroidJUnit4::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class UserAwareConnectionTest : SysuiTestCase() { + + @Mock private lateinit var userContextProvider: UserContextProvider + @Mock private lateinit var mockContext: Context + + private lateinit var underTest: UserAwareConnection + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + whenever(userContextProvider.userContext).thenReturn(mockContext) + whenever(mockContext.bindService(any(), any(), anyInt())).thenReturn(true) + underTest = UserAwareConnection(userContextProvider, Intent()) + } + + @Test + fun doBindService_requestToBindToTheService_viaTheCorrectUserContext() { + underTest.doBind() + + verify(userContextProvider).userContext + } + + @Test + fun doBindService_DoesntRequestToBindToTheService_IfAlreadyRequested() { + underTest.doBind() + underTest.doBind() + underTest.doBind() + + verify(userContextProvider, times(1)).userContext + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt index d89e73d2c69f..c316c8626e8e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt @@ -48,7 +48,7 @@ import com.android.systemui.recordissue.IssueRecordingService.Companion.getStopI import com.android.systemui.recordissue.IssueRecordingState import com.android.systemui.recordissue.RecordIssueDialogDelegate import com.android.systemui.recordissue.RecordIssueModule.Companion.TILE_SPEC -import com.android.systemui.recordissue.TraceurMessageSender +import com.android.systemui.recordissue.TraceurConnection import com.android.systemui.res.R import com.android.systemui.screenrecord.RecordingController import com.android.systemui.screenrecord.RecordingService @@ -78,7 +78,7 @@ constructor( private val dialogTransitionAnimator: DialogTransitionAnimator, private val panelInteractor: PanelInteractor, private val userContextProvider: UserContextProvider, - private val traceurMessageSender: TraceurMessageSender, + private val traceurConnection: TraceurConnection, @Background private val bgExecutor: Executor, private val issueRecordingState: IssueRecordingState, private val delegateFactory: RecordIssueDialogDelegate.Factory, @@ -93,7 +93,7 @@ constructor( metricsLogger, statusBarStateController, activityStarter, - qsLogger + qsLogger, ) { private val onRecordingChangeListener = Runnable { refreshState() } @@ -109,7 +109,7 @@ constructor( override fun handleDestroy() { super.handleDestroy() - bgExecutor.execute { traceurMessageSender.unbindFromTraceur(mContext) } + bgExecutor.execute { traceurConnection.doUnBind() } } override fun getTileLabel(): CharSequence = mContext.getString(R.string.qs_record_issue_label) @@ -142,7 +142,7 @@ constructor( DELAY_MS, INTERVAL_MS, pendingServiceIntent(getStartIntent(userContextProvider.userContext)), - pendingServiceIntent(getStopIntent(userContextProvider.userContext)) + pendingServiceIntent(getStopIntent(userContextProvider.userContext)), ) private fun stopIssueRecordingService() = @@ -154,7 +154,7 @@ constructor( userContextProvider.userContext, RecordingService.REQUEST_CODE, action, - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, ) private fun showPrompt(expandable: Expandable?) { diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt index 4d2bc91aa52a..e804baffce05 100644 --- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt +++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt @@ -50,7 +50,7 @@ constructor( keyguardDismissUtil: KeyguardDismissUtil, dialogTransitionAnimator: DialogTransitionAnimator, panelInteractor: PanelInteractor, - traceurMessageSender: TraceurMessageSender, + traceurConnection: TraceurConnection, private val issueRecordingState: IssueRecordingState, iActivityManager: IActivityManager, ) : @@ -69,7 +69,7 @@ constructor( bgExecutor, dialogTransitionAnimator, panelInteractor, - traceurMessageSender, + traceurConnection, issueRecordingState, iActivityManager, notificationManager, diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt index e4d3e6cae502..6fc248ffa459 100644 --- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt +++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt @@ -42,7 +42,7 @@ class IssueRecordingServiceSession( private val bgExecutor: Executor, private val dialogTransitionAnimator: DialogTransitionAnimator, private val panelInteractor: PanelInteractor, - private val traceurMessageSender: TraceurMessageSender, + private val traceurConnection: TraceurConnection, private val issueRecordingState: IssueRecordingState, private val iActivityManager: IActivityManager, private val notificationManager: NotificationManager, @@ -50,7 +50,7 @@ class IssueRecordingServiceSession( ) { fun start() { - bgExecutor.execute { traceurMessageSender.startTracing(issueRecordingState.traceConfig) } + bgExecutor.execute { traceurConnection.startTracing(issueRecordingState.traceConfig) } issueRecordingState.isRecording = true } @@ -59,7 +59,7 @@ class IssueRecordingServiceSession( if (issueRecordingState.traceConfig.longTrace) { Settings.Global.putInt(contentResolver, NOTIFY_SESSION_ENDED_SETTING, DISABLED) } - traceurMessageSender.stopTracing() + traceurConnection.stopTracing() } issueRecordingState.isRecording = false } @@ -75,7 +75,7 @@ class IssueRecordingServiceSession( if (issueRecordingState.takeBugreport) { iActivityManager.requestBugReportWithExtraAttachment(screenRecording) } else { - traceurMessageSender.shareTraces(context, screenRecording) + traceurConnection.shareTraces(context, screenRecording) } } diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt index ed67e64dfb76..e38fe9aafe32 100644 --- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt @@ -64,7 +64,7 @@ constructor( private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger, private val screenCaptureDisabledDialogDelegate: ScreenCaptureDisabledDialogDelegate, private val state: IssueRecordingState, - private val traceurMessageSender: TraceurMessageSender, + private val traceurConnection: TraceurConnection, @Assisted private val onStarted: Runnable, ) : SystemUIDialog.Delegate { @@ -88,8 +88,8 @@ constructor( setPositiveButton(R.string.qs_record_issue_start) { _, _ -> onStarted.run() } } bgExecutor.execute { - traceurMessageSender.onBoundToTraceur.add { traceurMessageSender.getTags(state) } - traceurMessageSender.bindToTraceur(dialog.context) + traceurConnection.onBound.add { traceurConnection.getTags(state) } + traceurConnection.doBind() } } @@ -151,7 +151,7 @@ constructor( mediaProjectionMetricsLogger.notifyProjectionInitiated( userTracker.userId, - SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER + SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER, ) if (!state.hasUserApprovedScreenRecording) { @@ -189,7 +189,7 @@ constructor( CustomTraceSettingsDialogDelegate( factory, state.customTraceState, - state.tagTitles + state.tagTitles, ) { onMenuItemClickListener.onMenuItemClick(it) } diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt new file mode 100644 index 000000000000..75df49e3676f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt @@ -0,0 +1,145 @@ +/* + * 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.recordissue + +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.os.Handler +import android.os.IBinder +import android.os.Looper +import android.os.Message +import android.os.Messenger +import android.util.Log +import androidx.annotation.WorkerThread +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.recordissue.IssueRecordingState.Companion.TAG_TITLE_DELIMITER +import com.android.systemui.settings.UserContextProvider +import com.android.traceur.FileSender +import com.android.traceur.MessageConstants +import com.android.traceur.MessageConstants.TRACING_APP_ACTIVITY +import com.android.traceur.MessageConstants.TRACING_APP_PACKAGE_NAME +import com.android.traceur.TraceConfig +import java.util.concurrent.CopyOnWriteArrayList +import javax.inject.Inject + +private const val TAG = "TraceurConnection" + +@SysUISingleton +class TraceurConnection +@Inject +constructor(userContextProvider: UserContextProvider, @Background private val bgLooper: Looper) : + UserAwareConnection( + userContextProvider, + Intent().setClassName(TRACING_APP_PACKAGE_NAME, TRACING_APP_ACTIVITY), + ) { + + val onBound: MutableList = CopyOnWriteArrayList(mutableListOf()) + + override fun onServiceConnected(className: ComponentName, service: IBinder) { + super.onServiceConnected(className, service) + onBound.forEach(Runnable::run) + onBound.clear() + } + + @WorkerThread + fun startTracing(traceType: TraceConfig) { + val data = + Bundle().apply { putParcelable(MessageConstants.INTENT_EXTRA_TRACE_TYPE, traceType) } + sendMessage(MessageConstants.START_WHAT, data) + } + + @WorkerThread fun stopTracing() = sendMessage(MessageConstants.STOP_WHAT) + + @WorkerThread + fun shareTraces(context: Context, screenRecord: Uri?) { + val replyHandler = Messenger(ShareFilesHandler(context, screenRecord, bgLooper)) + sendMessage(MessageConstants.SHARE_WHAT, replyTo = replyHandler) + } + + @WorkerThread + fun getTags(state: IssueRecordingState) = + sendMessage(MessageConstants.TAGS_WHAT, replyTo = Messenger(TagsHandler(bgLooper, state))) + + @WorkerThread + private fun sendMessage(what: Int, data: Bundle = Bundle(), replyTo: Messenger? = null) = + try { + val msg = + Message.obtain().apply { + this.what = what + this.data = data + this.replyTo = replyTo + } + binder!!.send(msg) + } catch (e: Exception) { + Log.e(TAG, "failed to notify Traceur", e) + } +} + +private class ShareFilesHandler( + private val context: Context, + private val screenRecord: Uri?, + looper: Looper, +) : Handler(looper) { + + override fun handleMessage(msg: Message) { + if (MessageConstants.SHARE_WHAT == msg.what) { + shareTraces( + msg.data.getParcelable(MessageConstants.EXTRA_PERFETTO, Uri::class.java), + msg.data.getParcelable(MessageConstants.EXTRA_WINSCOPE, Uri::class.java), + ) + } else { + throw IllegalArgumentException("received unknown msg.what: " + msg.what) + } + } + + private fun shareTraces(perfetto: Uri?, winscope: Uri?) { + val uris: ArrayList = + ArrayList().apply { + perfetto?.let { add(it) } + winscope?.let { add(it) } + screenRecord?.let { add(it) } + } + val fileSharingIntent = + FileSender.buildSendIntent(context, uris) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) + context.startActivity(fileSharingIntent) + } +} + +private class TagsHandler(looper: Looper, private val state: IssueRecordingState) : + Handler(looper) { + + override fun handleMessage(msg: Message) { + if (MessageConstants.TAGS_WHAT == msg.what) { + val keys = msg.data.getStringArrayList(MessageConstants.BUNDLE_KEY_TAGS) + val values = msg.data.getStringArrayList(MessageConstants.BUNDLE_KEY_TAG_DESCRIPTIONS) + if (keys == null || values == null) { + throw IllegalArgumentException( + "Neither keys: $keys, nor values: $values can be null" + ) + } + state.tagTitles = + keys.zip(values).map { it.first + TAG_TITLE_DELIMITER + it.second }.toSet() + } else { + throw IllegalArgumentException("received unknown msg.what: " + msg.what) + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt deleted file mode 100644 index 8bfd14a68811..000000000000 --- a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt +++ /dev/null @@ -1,189 +0,0 @@ -/* - * 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.recordissue - -import android.annotation.SuppressLint -import android.content.ComponentName -import android.content.Context -import android.content.Intent -import android.content.ServiceConnection -import android.content.pm.PackageManager -import android.net.Uri -import android.os.Bundle -import android.os.Handler -import android.os.IBinder -import android.os.Looper -import android.os.Message -import android.os.Messenger -import android.util.Log -import androidx.annotation.WorkerThread -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.recordissue.IssueRecordingState.Companion.TAG_TITLE_DELIMITER -import com.android.traceur.FileSender -import com.android.traceur.MessageConstants -import com.android.traceur.TraceConfig -import javax.inject.Inject - -private const val TAG = "TraceurMessageSender" - -@SysUISingleton -class TraceurMessageSender @Inject constructor(@Background private val backgroundLooper: Looper) { - private var binder: Messenger? = null - private var isBound: Boolean = false - - val onBoundToTraceur = mutableListOf() - - private val traceurConnection = - object : ServiceConnection { - override fun onServiceConnected(className: ComponentName, service: IBinder) { - binder = Messenger(service) - isBound = true - onBoundToTraceur.forEach(Runnable::run) - onBoundToTraceur.clear() - } - - override fun onServiceDisconnected(className: ComponentName) { - binder = null - isBound = false - } - } - - @SuppressLint("WrongConstant") - @WorkerThread - fun bindToTraceur(context: Context) { - if (isBound) { - // Binding needs to happen after the phone has been unlocked. The RecordIssueTile is - // initialized before this happens though, so binding is placed at a later time, during - // normal operations that can be repeated. This check avoids calling "bindService" 2x+ - return - } - try { - val info = - context.packageManager.getPackageInfo( - MessageConstants.TRACING_APP_PACKAGE_NAME, - PackageManager.MATCH_SYSTEM_ONLY - ) - val intent = - Intent().setClassName(info.packageName, MessageConstants.TRACING_APP_ACTIVITY) - val flags = - Context.BIND_AUTO_CREATE or - Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE or - Context.BIND_WAIVE_PRIORITY - context.bindService(intent, traceurConnection, flags) - } catch (e: Exception) { - Log.e(TAG, "failed to bind to Traceur's service", e) - } - } - - @WorkerThread - fun unbindFromTraceur(context: Context) { - if (isBound) { - context.unbindService(traceurConnection) - } - } - - @WorkerThread - fun startTracing(traceType: TraceConfig) { - val data = - Bundle().apply { putParcelable(MessageConstants.INTENT_EXTRA_TRACE_TYPE, traceType) } - notifyTraceur(MessageConstants.START_WHAT, data) - } - - @WorkerThread fun stopTracing() = notifyTraceur(MessageConstants.STOP_WHAT) - - @WorkerThread - fun shareTraces(context: Context, screenRecord: Uri?) { - val replyHandler = Messenger(ShareFilesHandler(context, screenRecord, backgroundLooper)) - notifyTraceur(MessageConstants.SHARE_WHAT, replyTo = replyHandler) - } - - @WorkerThread - fun getTags(state: IssueRecordingState) { - val replyHandler = Messenger(TagsHandler(backgroundLooper, state)) - notifyTraceur(MessageConstants.TAGS_WHAT, replyTo = replyHandler) - } - - @WorkerThread - private fun notifyTraceur(what: Int, data: Bundle = Bundle(), replyTo: Messenger? = null) { - try { - binder!!.send( - Message.obtain().apply { - this.what = what - this.data = data - this.replyTo = replyTo - } - ) - } catch (e: Exception) { - Log.e(TAG, "failed to notify Traceur", e) - } - } - - private class ShareFilesHandler( - private val context: Context, - private val screenRecord: Uri?, - looper: Looper, - ) : Handler(looper) { - - override fun handleMessage(msg: Message) { - if (MessageConstants.SHARE_WHAT == msg.what) { - shareTraces( - msg.data.getParcelable(MessageConstants.EXTRA_PERFETTO, Uri::class.java), - msg.data.getParcelable(MessageConstants.EXTRA_WINSCOPE, Uri::class.java) - ) - } else { - throw IllegalArgumentException("received unknown msg.what: " + msg.what) - } - } - - private fun shareTraces(perfetto: Uri?, winscope: Uri?) { - val uris: List = - mutableListOf().apply { - perfetto?.let { add(it) } - winscope?.let { add(it) } - screenRecord?.let { add(it) } - } - val fileSharingIntent = - FileSender.buildSendIntent(context, uris) - .addFlags( - Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT - ) - context.startActivity(fileSharingIntent) - } - } - - private class TagsHandler(looper: Looper, private val state: IssueRecordingState) : - Handler(looper) { - - override fun handleMessage(msg: Message) { - if (MessageConstants.TAGS_WHAT == msg.what) { - val keys = msg.data.getStringArrayList(MessageConstants.BUNDLE_KEY_TAGS) - val values = - msg.data.getStringArrayList(MessageConstants.BUNDLE_KEY_TAG_DESCRIPTIONS) - if (keys == null || values == null) { - throw IllegalArgumentException( - "Neither keys: $keys, nor values: $values can be null" - ) - } - state.tagTitles = - keys.zip(values).map { it.first + TAG_TITLE_DELIMITER + it.second }.toSet() - } else { - throw IllegalArgumentException("received unknown msg.what: " + msg.what) - } - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/UserAwareConnection.kt b/packages/SystemUI/src/com/android/systemui/recordissue/UserAwareConnection.kt new file mode 100644 index 000000000000..6aaa27dd7387 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recordissue/UserAwareConnection.kt @@ -0,0 +1,76 @@ +/* + * 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.recordissue + +import android.annotation.SuppressLint +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection +import android.os.IBinder +import android.os.Messenger +import android.util.Log +import androidx.annotation.VisibleForTesting +import androidx.annotation.WorkerThread +import com.android.systemui.settings.UserContextProvider + +private const val TAG = "UserAwareConnection" +private const val BIND_FLAGS = + Context.BIND_AUTO_CREATE or + Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE or + Context.BIND_WAIVE_PRIORITY + +/** ServiceConnection class that can be used to keep an IntentService alive. */ +open class UserAwareConnection( + protected val userContextProvider: UserContextProvider, + private val intent: Intent, +) : ServiceConnection { + @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) var binder: Messenger? = null + private var shouldUnBind = false + + override fun onServiceConnected(className: ComponentName, service: IBinder) { + binder = Messenger(service) + } + + override fun onServiceDisconnected(className: ComponentName) { + binder = null + } + + @SuppressLint("WrongConstant") + @WorkerThread + fun doBind() { + if (shouldUnBind) { + // Binding needs to happen after the phone has been unlocked. The RecordIssueTile is + // initialized before this happens though, so binding is placed at a later time, during + // normal operations that can be repeated. This check avoids calling "bindService" 2x+ + return + } + try { + shouldUnBind = userContextProvider.userContext.bindService(intent, this, BIND_FLAGS) + } catch (e: Exception) { + Log.e(TAG, "failed to bind to the service", e) + } + } + + @WorkerThread + fun doUnBind() { + if (shouldUnBind) { + userContextProvider.userContext.unbindService(this) + shouldUnBind = false + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt index ca518f9bc5d7..833cf424ef93 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt @@ -33,7 +33,7 @@ import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor import com.android.systemui.recordissue.IssueRecordingState import com.android.systemui.recordissue.RecordIssueDialogDelegate -import com.android.systemui.recordissue.TraceurMessageSender +import com.android.systemui.recordissue.TraceurConnection import com.android.systemui.res.R import com.android.systemui.screenrecord.RecordingController import com.android.systemui.settings.UserContextProvider @@ -75,7 +75,7 @@ class RecordIssueTileTest : SysuiTestCase() { @Mock private lateinit var panelInteractor: PanelInteractor @Mock private lateinit var userContextProvider: UserContextProvider @Mock private lateinit var issueRecordingState: IssueRecordingState - @Mock private lateinit var traceurMessageSender: TraceurMessageSender + @Mock private lateinit var traceurConnection: TraceurConnection @Mock private lateinit var delegateFactory: RecordIssueDialogDelegate.Factory @Mock private lateinit var dialogDelegate: RecordIssueDialogDelegate @Mock private lateinit var dialog: SystemUIDialog @@ -107,7 +107,7 @@ class RecordIssueTileTest : SysuiTestCase() { dialogLauncherAnimator, panelInteractor, userContextProvider, - traceurMessageSender, + traceurConnection, Executors.newSingleThreadExecutor(), issueRecordingState, delegateFactory, @@ -169,7 +169,7 @@ class RecordIssueTileTest : SysuiTestCase() { .executeWhenUnlocked( isA(ActivityStarter.OnDismissAction::class.java), eq(false), - eq(true) + eq(true), ) } } -- GitLab From c0a488ea49fc9f1528b9fd2c9386cfb1a5e87303 Mon Sep 17 00:00:00 2001 From: Stefan Andonian Date: Mon, 23 Sep 2024 23:13:36 +0000 Subject: [PATCH 030/447] Explicitly state which user to start Record Issue interactions inside. Also add a mechanism to handle tracuer requests that are made before the service is bound. This can happen if the service is in a different tile from the Record Issue Tile, and binding takes longer than expected. Bug: 364824477 Test: Verified that this works on device (when combined with all other changes in CL chain). Flag: EXEMPT bug fix Change-Id: Iba6f416d7d614f21f5cb1de5dba6aa577313a94b --- .../IssueRecordingServiceSessionTest.kt | 10 +++++----- .../recordissue/IssueRecordingService.kt | 1 - .../recordissue/IssueRecordingServiceSession.kt | 5 ++--- .../systemui/recordissue/TraceurConnection.kt | 16 +++++++++------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt index 8e57914050d6..a1edfc1dbcd5 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt @@ -99,7 +99,7 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() { @Test fun cancelsNotification_afterReceivingShareCommand() { - underTest.share(0, null, mContext) + underTest.share(0, null) bgExecutor.runAllReady() verify(notificationManager).cancelAsUser(isNull(), anyInt(), any()) @@ -110,7 +110,7 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() { issueRecordingState.takeBugreport = true val uri = mock() - underTest.share(0, uri, mContext) + underTest.share(0, uri) bgExecutor.runAllReady() verify(iActivityManager).requestBugReportWithExtraAttachment(uri) @@ -121,17 +121,17 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() { issueRecordingState.takeBugreport = false val uri = mock() - underTest.share(0, uri, mContext) + underTest.share(0, uri) bgExecutor.runAllReady() - verify(traceurConnection).shareTraces(mContext, uri) + verify(traceurConnection).shareTraces(uri) } @Test fun closesShade_afterReceivingShareCommand() { val uri = mock() - underTest.share(0, uri, mContext) + underTest.share(0, uri) bgExecutor.runAllReady() verify(panelInteractor).collapsePanels() diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt index e804baffce05..d1fa94e0a65e 100644 --- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt +++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt @@ -99,7 +99,6 @@ constructor( session.share( intent.getIntExtra(EXTRA_NOTIFICATION_ID, mNotificationId), intent.getParcelableExtra(EXTRA_PATH, Uri::class.java), - this, ) // Unlike all other actions, action_share has different behavior for the screen // recording qs tile than it does for the record issue qs tile. Return sticky to diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt index 6fc248ffa459..ad9b4fe164e8 100644 --- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt +++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceSession.kt @@ -19,7 +19,6 @@ package com.android.systemui.recordissue import android.app.IActivityManager import android.app.NotificationManager import android.content.ContentResolver -import android.content.Context import android.net.Uri import android.os.UserHandle import android.provider.Settings @@ -64,7 +63,7 @@ class IssueRecordingServiceSession( issueRecordingState.isRecording = false } - fun share(notificationId: Int, screenRecording: Uri?, context: Context) { + fun share(notificationId: Int, screenRecording: Uri?) { bgExecutor.execute { notificationManager.cancelAsUser( null, @@ -75,7 +74,7 @@ class IssueRecordingServiceSession( if (issueRecordingState.takeBugreport) { iActivityManager.requestBugReportWithExtraAttachment(screenRecording) } else { - traceurConnection.shareTraces(context, screenRecording) + traceurConnection.shareTraces(screenRecording) } } diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt index 75df49e3676f..9494da91afe0 100644 --- a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt +++ b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt @@ -17,7 +17,6 @@ package com.android.systemui.recordissue import android.content.ComponentName -import android.content.Context import android.content.Intent import android.net.Uri import android.os.Bundle @@ -69,8 +68,8 @@ constructor(userContextProvider: UserContextProvider, @Background private val bg @WorkerThread fun stopTracing() = sendMessage(MessageConstants.STOP_WHAT) @WorkerThread - fun shareTraces(context: Context, screenRecord: Uri?) { - val replyHandler = Messenger(ShareFilesHandler(context, screenRecord, bgLooper)) + fun shareTraces(screenRecord: Uri?) { + val replyHandler = Messenger(ShareFilesHandler(screenRecord, userContextProvider, bgLooper)) sendMessage(MessageConstants.SHARE_WHAT, replyTo = replyHandler) } @@ -87,15 +86,15 @@ constructor(userContextProvider: UserContextProvider, @Background private val bg this.data = data this.replyTo = replyTo } - binder!!.send(msg) + binder?.send(msg) ?: onBound.add { binder!!.send(msg) } } catch (e: Exception) { Log.e(TAG, "failed to notify Traceur", e) } } private class ShareFilesHandler( - private val context: Context, private val screenRecord: Uri?, + private val userContextProvider: UserContextProvider, looper: Looper, ) : Handler(looper) { @@ -118,9 +117,12 @@ private class ShareFilesHandler( screenRecord?.let { add(it) } } val fileSharingIntent = - FileSender.buildSendIntent(context, uris) + FileSender.buildSendIntent(userContextProvider.userContext, uris) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) - context.startActivity(fileSharingIntent) + userContextProvider.userContext.startActivityAsUser( + fileSharingIntent, + userContextProvider.userContext.user, + ) } } -- GitLab From 70b54e38d928b308bea19fdd9bf5d55d1125ca1a Mon Sep 17 00:00:00 2001 From: Stefan Andonian Date: Mon, 23 Sep 2024 23:37:15 +0000 Subject: [PATCH 031/447] Make RecordIssueTile's ServiceConnections not injected, but created. This fixes the issue of sometimes having the dagger injection giving the same instance in the tile and the service, and sometimes not. We can avoid this by ensuring the service connections are always different. Also, by Binding to IssueRecordingService, we can avoid "leaking" the traceurConnection which would otherwise need to be created / destroyed with every notification action. Bug: 364824477 Test: Verified locally that System Tracing via the Record Issue Tile works great in Headless System User Mode. Flag: EXEMPT bug fix Change-Id: I076f7a9c058fbc725296a3c2bb34cbc75675d30c --- .../RecordIssueDialogDelegateTest.kt | 2 - .../recordissue/TraceurConnectionTest.kt | 2 +- .../systemui/qs/tiles/RecordIssueTile.kt | 26 ++++++++++-- .../recordissue/IssueRecordingService.kt | 25 +++++++++++- .../IssueRecordingServiceConnection.kt | 40 +++++++++++++++++++ .../recordissue/RecordIssueDialogDelegate.kt | 5 --- .../systemui/recordissue/TraceurConnection.kt | 19 +++++---- .../systemui/qs/tiles/RecordIssueTileTest.kt | 12 +++++- 8 files changed, 110 insertions(+), 21 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceConnection.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt index 9ca8f447d374..963973588236 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt @@ -78,7 +78,6 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() { @Mock private lateinit var sysuiState: SysUiState @Mock private lateinit var systemUIDialogManager: SystemUIDialogManager @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher - @Mock private lateinit var traceurConnection: TraceurConnection private val systemClock = FakeSystemClock() private val bgExecutor = FakeExecutor(systemClock) private val mainExecutor = FakeExecutor(systemClock) @@ -120,7 +119,6 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() { mediaProjectionMetricsLogger, screenCaptureDisabledDialogDelegate, state, - traceurConnection, ) { latch.countDown() } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/TraceurConnectionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/TraceurConnectionTest.kt index 85a8237ff955..d90cca9b23fe 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/TraceurConnectionTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/TraceurConnectionTest.kt @@ -50,7 +50,7 @@ class TraceurConnectionTest : SysuiTestCase() { fun setup() { MockitoAnnotations.initMocks(this) whenever(userContextProvider.userContext).thenReturn(mContext) - underTest = TraceurConnection(userContextProvider, Looper.getMainLooper()) + underTest = TraceurConnection.Provider(userContextProvider, Looper.getMainLooper()).create() } @Test diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt index c316c8626e8e..fb406d47d7a6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt @@ -45,6 +45,7 @@ import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.recordissue.IssueRecordingService.Companion.getStartIntent import com.android.systemui.recordissue.IssueRecordingService.Companion.getStopIntent +import com.android.systemui.recordissue.IssueRecordingServiceConnection import com.android.systemui.recordissue.IssueRecordingState import com.android.systemui.recordissue.RecordIssueDialogDelegate import com.android.systemui.recordissue.RecordIssueModule.Companion.TILE_SPEC @@ -66,7 +67,7 @@ class RecordIssueTile constructor( host: QSHost, uiEventLogger: QsEventLogger, - @Background backgroundLooper: Looper, + @Background private val backgroundLooper: Looper, @Main mainHandler: Handler, falsingManager: FalsingManager, metricsLogger: MetricsLogger, @@ -78,7 +79,8 @@ constructor( private val dialogTransitionAnimator: DialogTransitionAnimator, private val panelInteractor: PanelInteractor, private val userContextProvider: UserContextProvider, - private val traceurConnection: TraceurConnection, + irsConnProvider: IssueRecordingServiceConnection.Provider, + traceurConnProvider: TraceurConnection.Provider, @Background private val bgExecutor: Executor, private val issueRecordingState: IssueRecordingState, private val delegateFactory: RecordIssueDialogDelegate.Factory, @@ -98,6 +100,15 @@ constructor( private val onRecordingChangeListener = Runnable { refreshState() } + private val irsConnection: IssueRecordingServiceConnection = irsConnProvider.create() + private val traceurConnection = + traceurConnProvider.create().apply { + onBound.add { + getTags(issueRecordingState) + doUnBind() + } + } + override fun handleSetListening(listening: Boolean) { super.handleSetListening(listening) if (listening) { @@ -109,7 +120,7 @@ constructor( override fun handleDestroy() { super.handleDestroy() - bgExecutor.execute { traceurConnection.doUnBind() } + bgExecutor.execute { irsConnection.doUnBind() } } override fun getTileLabel(): CharSequence = mContext.getString(R.string.qs_record_issue_label) @@ -158,6 +169,15 @@ constructor( ) private fun showPrompt(expandable: Expandable?) { + bgExecutor.execute { + // We only want to get the tags once per session, as this is not likely to change, if at + // all on a month to month basis. Using onBound's size is a way to verify if the tag + // retrieval has already happened or not. + if (traceurConnection.onBound.isNotEmpty()) { + traceurConnection.doBind() + } + irsConnection.doBind() + } val dialog: AlertDialog = delegateFactory .create { diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt index d1fa94e0a65e..3f875bcc288b 100644 --- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt +++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt @@ -23,9 +23,12 @@ import android.content.Intent import android.content.res.Resources import android.net.Uri import android.os.Handler +import android.os.IBinder +import android.os.Looper import android.util.Log import com.android.internal.logging.UiEventLogger import com.android.systemui.animation.DialogTransitionAnimator +import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.LongRunning import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor @@ -42,6 +45,7 @@ class IssueRecordingService @Inject constructor( controller: RecordingController, + @Background private val bgLooper: Looper, @LongRunning private val bgExecutor: Executor, @Main handler: Handler, uiEventLogger: UiEventLogger, @@ -50,8 +54,8 @@ constructor( keyguardDismissUtil: KeyguardDismissUtil, dialogTransitionAnimator: DialogTransitionAnimator, panelInteractor: PanelInteractor, - traceurConnection: TraceurConnection, private val issueRecordingState: IssueRecordingState, + traceurConnectionProvider: TraceurConnection.Provider, iActivityManager: IActivityManager, ) : RecordingService( @@ -64,6 +68,8 @@ constructor( keyguardDismissUtil, ) { + private val traceurConnection: TraceurConnection = traceurConnectionProvider.create() + private val session = IssueRecordingServiceSession( bgExecutor, @@ -76,6 +82,23 @@ constructor( userContextProvider, ) + /** + * It is necessary to bind to IssueRecordingService from the Record Issue Tile because there are + * instances where this service is not created in the same user profile as the record issue tile + * aka, headless system user mode. In those instances, the TraceurConnection will be considered + * a leak in between notification actions unless the tile is bound to this service to keep it + * alive. + */ + override fun onBind(intent: Intent): IBinder? { + traceurConnection.doBind() + return super.onBind(intent) + } + + override fun onUnbind(intent: Intent?): Boolean { + traceurConnection.doUnBind() + return super.onUnbind(intent) + } + override fun getTag(): String = TAG override fun getChannelId(): String = CHANNEL_ID diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceConnection.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceConnection.kt new file mode 100644 index 000000000000..85a580558125 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingServiceConnection.kt @@ -0,0 +1,40 @@ +/* + * 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.recordissue + +import android.content.Intent +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.settings.UserContextProvider +import com.android.traceur.MessageConstants.SYSTEM_UI_PACKAGE_NAME +import javax.inject.Inject + +/** + * It is necessary to bind to IssueRecordingService from the Record Issue Tile because there are + * instances where this service is not created in the same user profile as the record issue tile + * aka, headless system user mode. In those instances, the TraceurConnection will be considered a + * leak in between notification actions unless the tile is bound to this service to keep it alive. + */ +class IssueRecordingServiceConnection(userContextProvider: UserContextProvider) : + UserAwareConnection( + userContextProvider, + Intent().setClassName(SYSTEM_UI_PACKAGE_NAME, IssueRecordingService::class.java.name), + ) { + @SysUISingleton + class Provider @Inject constructor(private val userContextProvider: UserContextProvider) { + fun create() = IssueRecordingServiceConnection(userContextProvider) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt index e38fe9aafe32..6758c3ba0767 100644 --- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt @@ -64,7 +64,6 @@ constructor( private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger, private val screenCaptureDisabledDialogDelegate: ScreenCaptureDisabledDialogDelegate, private val state: IssueRecordingState, - private val traceurConnection: TraceurConnection, @Assisted private val onStarted: Runnable, ) : SystemUIDialog.Delegate { @@ -87,10 +86,6 @@ constructor( setNegativeButton(R.string.cancel) { _, _ -> } setPositiveButton(R.string.qs_record_issue_start) { _, _ -> onStarted.run() } } - bgExecutor.execute { - traceurConnection.onBound.add { traceurConnection.getTags(state) } - traceurConnection.doBind() - } } override fun createDialog(): SystemUIDialog = factory.create(this) diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt index 9494da91afe0..81529b357527 100644 --- a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt +++ b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurConnection.kt @@ -41,15 +41,23 @@ import javax.inject.Inject private const val TAG = "TraceurConnection" -@SysUISingleton class TraceurConnection -@Inject -constructor(userContextProvider: UserContextProvider, @Background private val bgLooper: Looper) : +private constructor(userContextProvider: UserContextProvider, private val bgLooper: Looper) : UserAwareConnection( userContextProvider, Intent().setClassName(TRACING_APP_PACKAGE_NAME, TRACING_APP_ACTIVITY), ) { + @SysUISingleton + class Provider + @Inject + constructor( + private val userContextProvider: UserContextProvider, + @Background private val bgLooper: Looper, + ) { + fun create() = TraceurConnection(userContextProvider, bgLooper) + } + val onBound: MutableList = CopyOnWriteArrayList(mutableListOf()) override fun onServiceConnected(className: ComponentName, service: IBinder) { @@ -119,10 +127,7 @@ private class ShareFilesHandler( val fileSharingIntent = FileSender.buildSendIntent(userContextProvider.userContext, uris) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) - userContextProvider.userContext.startActivityAsUser( - fileSharingIntent, - userContextProvider.userContext.user, - ) + userContextProvider.userContext.startActivity(fileSharingIntent) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt index 833cf424ef93..c7da03dbbf30 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt @@ -17,6 +17,7 @@ package com.android.systemui.qs.tiles import android.os.Handler +import android.os.Looper import android.service.quicksettings.Tile import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -31,6 +32,7 @@ import com.android.systemui.qs.QSHost import com.android.systemui.qs.QsEventLogger import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor +import com.android.systemui.recordissue.IssueRecordingServiceConnection import com.android.systemui.recordissue.IssueRecordingState import com.android.systemui.recordissue.RecordIssueDialogDelegate import com.android.systemui.recordissue.TraceurConnection @@ -75,13 +77,14 @@ class RecordIssueTileTest : SysuiTestCase() { @Mock private lateinit var panelInteractor: PanelInteractor @Mock private lateinit var userContextProvider: UserContextProvider @Mock private lateinit var issueRecordingState: IssueRecordingState - @Mock private lateinit var traceurConnection: TraceurConnection @Mock private lateinit var delegateFactory: RecordIssueDialogDelegate.Factory @Mock private lateinit var dialogDelegate: RecordIssueDialogDelegate @Mock private lateinit var dialog: SystemUIDialog private lateinit var testableLooper: TestableLooper private lateinit var tile: RecordIssueTile + private lateinit var irsConnProvider: IssueRecordingServiceConnection.Provider + private lateinit var traceurConnProvider: TraceurConnection.Provider @Before fun setUp() { @@ -90,6 +93,10 @@ class RecordIssueTileTest : SysuiTestCase() { whenever(delegateFactory.create(any())).thenReturn(dialogDelegate) whenever(dialogDelegate.createDialog()).thenReturn(dialog) + irsConnProvider = IssueRecordingServiceConnection.Provider(userContextProvider) + traceurConnProvider = + TraceurConnection.Provider(userContextProvider, Looper.getMainLooper()) + testableLooper = TestableLooper.get(this) tile = RecordIssueTile( @@ -107,7 +114,8 @@ class RecordIssueTileTest : SysuiTestCase() { dialogLauncherAnimator, panelInteractor, userContextProvider, - traceurConnection, + irsConnProvider, + traceurConnProvider, Executors.newSingleThreadExecutor(), issueRecordingState, delegateFactory, -- GitLab From 72b27bcbd26d16ced14f483f41e5f233d1d9b127 Mon Sep 17 00:00:00 2001 From: Christopher Werner Date: Fri, 10 May 2024 00:46:16 +0000 Subject: [PATCH 032/447] Add API to move contacts to Cloud DCA Bug: b/330324156 Test: atest android.provider.cts.contacts.ContactsContract_MoveToCloudDeviceContactsAccount Flag: android.provider.new_default_account_api_enabled On branch cp2-move Changes to be committed: modified: core/api/system-current.txt modified: core/java/android/provider/ContactsContract.java Change-Id: If223387d6a5cd5aa8a46707633d51f042ed4e5d7 --- core/api/system-current.txt | 4 + .../android/provider/ContactsContract.java | 191 +++++++++++++++++- 2 files changed, 190 insertions(+), 5 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 7e43e4664d8a..0bc333836090 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -11951,6 +11951,10 @@ package android.provider { } @FlaggedApi("android.provider.new_default_account_api_enabled") public static final class ContactsContract.RawContacts.DefaultAccount { + method @FlaggedApi("android.provider.new_default_account_api_enabled") @RequiresPermission(allOf={android.Manifest.permission.READ_CONTACTS, android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS}) public static int getNumberOfMovableLocalContacts(@NonNull android.content.ContentResolver); + method @FlaggedApi("android.provider.new_default_account_api_enabled") @RequiresPermission(allOf={android.Manifest.permission.READ_CONTACTS, android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS}) public static int getNumberOfMovableSimContacts(@NonNull android.content.ContentResolver); + method @FlaggedApi("android.provider.new_default_account_api_enabled") @RequiresPermission(allOf={android.Manifest.permission.WRITE_CONTACTS, android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS}) public static void moveLocalContactsToCloudDefaultAccount(@NonNull android.content.ContentResolver); + method @FlaggedApi("android.provider.new_default_account_api_enabled") @RequiresPermission(allOf={android.Manifest.permission.WRITE_CONTACTS, android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS}) public static void moveSimContactsToCloudDefaultAccount(@NonNull android.content.ContentResolver); method @FlaggedApi("android.provider.new_default_account_api_enabled") @RequiresPermission(android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS) public static void setDefaultAccountForNewContacts(@NonNull android.content.ContentResolver, @NonNull android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState); } diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index d557046280d9..e65f0d2214b6 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -3027,6 +3027,13 @@ public final class ContactsContract { */ @FlaggedApi(Flags.FLAG_NEW_DEFAULT_ACCOUNT_API_ENABLED) public static final class DefaultAccount { + /** + * no public constructor since this is a utility class + */ + private DefaultAccount() { + + } + /** * Key in the outgoing Bundle for the default account list. * @@ -3063,11 +3070,6 @@ public final class ContactsContract { public static final String QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD = "queryDefaultAccountForNewContacts"; - private DefaultAccount() { - - } - - /** * Represents the state of the default account, and the actual {@link Account} if it's * a cloud account. @@ -3356,6 +3358,161 @@ public final class ContactsContract { nullSafeCall(resolver, ContactsContract.AUTHORITY_URI, SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD, null, extras); } + + + + /** + * The method to invoke to move local {@link RawContacts} and {@link Groups} from local + * account(s) to the Cloud Default Account (if any). + * + * @hide + */ + public static final String MOVE_LOCAL_CONTACTS_TO_CLOUD_DEFAULT_ACCOUNT_METHOD = + "moveLocalContactsToCloudDefaultAccount"; + + /** + * Move {@link RawContacts} and {@link Groups} (if any) from the local account to the + * Cloud Default Account (if any). + * @param resolver the ContentResolver to query. + * @throws RuntimeException if it fails to move contacts to the default account. + * + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_NEW_DEFAULT_ACCOUNT_API_ENABLED) + @RequiresPermission(allOf = {android.Manifest.permission.WRITE_CONTACTS, + android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS}) + public static void moveLocalContactsToCloudDefaultAccount( + @NonNull ContentResolver resolver) { + + Bundle extras = new Bundle(); + Bundle result = nullSafeCall( + resolver, + ContactsContract.AUTHORITY_URI, + MOVE_LOCAL_CONTACTS_TO_CLOUD_DEFAULT_ACCOUNT_METHOD, + null, + extras); + } + + /** + * The method to invoke to move {@link RawContacts} and {@link Groups} from SIM + * account(s) to the Cloud Default Account (if any). + * + * @hide + */ + public static final String MOVE_SIM_CONTACTS_TO_CLOUD_DEFAULT_ACCOUNT_METHOD = + "moveSimContactsToCloudDefaultAccount"; + + /** + * Move {@link RawContacts} and {@link Groups} (if any) from the local account to the + * Cloud Default Account (if any). + * @param resolver the ContentResolver to query. + * @throws RuntimeException if it fails to move contacts to the default account. + * + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_NEW_DEFAULT_ACCOUNT_API_ENABLED) + @RequiresPermission(allOf = {android.Manifest.permission.WRITE_CONTACTS, + android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS}) + public static void moveSimContactsToCloudDefaultAccount( + @NonNull ContentResolver resolver) { + Bundle result = nullSafeCall( + resolver, + ContactsContract.AUTHORITY_URI, + MOVE_SIM_CONTACTS_TO_CLOUD_DEFAULT_ACCOUNT_METHOD, + /* arg= */ null, + /* extras= */ null); + } + + /** + * The method to invoke to get the number of {@link RawContacts} that are in local + * account(s) and movable to the Cloud Default Account (if any). + * + * @hide + */ + public static final String GET_NUMBER_OF_MOVABLE_LOCAL_CONTACTS_METHOD = + "getNumberOfMovableLocalContacts"; + + /** + * The result key for moving local {@link RawContacts} and {@link Groups} from SIM + * account(s) to the Cloud Default Account (if any). + * + * @hide + */ + public static final String KEY_NUMBER_OF_MOVABLE_LOCAL_CONTACTS = + "key_number_of_movable_local_contacts"; + + /** + * Gets the number of {@link RawContacts} in the local account(s) which may be moved + * using {@link DefaultAccount#moveLocalContactsToCloudDefaultAccount} (if any). + * @param resolver the ContentResolver to query. + * @return the number of {@link RawContacts} in the local account(s), or 0 if there is + * no Cloud Default Account. + * @throws RuntimeException if it fails get the number of movable local contacts. + * + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_NEW_DEFAULT_ACCOUNT_API_ENABLED) + @RequiresPermission(allOf = {android.Manifest.permission.READ_CONTACTS, + android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS}) + public static int getNumberOfMovableLocalContacts( + @NonNull ContentResolver resolver) { + Bundle result = nullSafeCall( + resolver, + ContactsContract.AUTHORITY_URI, + GET_NUMBER_OF_MOVABLE_LOCAL_CONTACTS_METHOD, + /* arg= */ null, + /* extras= */ null); + return result.getInt(KEY_NUMBER_OF_MOVABLE_LOCAL_CONTACTS, + /* defaultValue= */ 0); + } + + /** + * The method to invoke to get the number of {@link RawContacts} that are in SIM + * account(s) and movable to the Cloud Default Account (if any). + * + * @hide + */ + public static final String GET_NUMBER_OF_MOVABLE_SIM_CONTACTS_METHOD = + "getNumberOfMovableSimContacts"; + + /** + * The result key for moving local {@link RawContacts} and {@link Groups} from SIM + * account(s) to the Cloud Default Account (if any). + * + * @hide + */ + public static final String KEY_NUMBER_OF_MOVABLE_SIM_CONTACTS = + "key_number_of_movable_sim_contacts"; + + /** + * Gets the number of {@link RawContacts} in the SIM account(s) which may be moved using + * {@link DefaultAccount#moveSimContactsToCloudDefaultAccount} (if any). + * @param resolver the ContentResolver to query. + * @return the number of {@link RawContacts} in the SIM account(s), or 0 if there is + * no Cloud Default Account. + * @throws RuntimeException if it fails get the number of movable sim contacts. + * + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_NEW_DEFAULT_ACCOUNT_API_ENABLED) + @RequiresPermission(allOf = {android.Manifest.permission.READ_CONTACTS, + android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS}) + public static int getNumberOfMovableSimContacts( + @NonNull ContentResolver resolver) { + Bundle result = nullSafeCall( + resolver, + ContactsContract.AUTHORITY_URI, + GET_NUMBER_OF_MOVABLE_SIM_CONTACTS_METHOD, + /* arg= */ null, + /* extras= */ null); + return result.getInt(KEY_NUMBER_OF_MOVABLE_SIM_CONTACTS, + /* defaultValue= */ 0); + } + } /** @@ -9182,6 +9339,30 @@ public final class ContactsContract { */ public static final String KEY_DEFAULT_ACCOUNT = "key_default_account"; + /** + * Key in the Bundle for the default account state. + * + * @hide + */ + public static final String KEY_DEFAULT_ACCOUNT_STATE = + "key_default_contacts_account_state"; + + /** + * The method to invoke in order to set the default account. + * + * @hide + */ + public static final String SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD = + "setDefaultAccountForNewContacts"; + + /** + * The method to invoke in order to query the default account. + * + * @hide + */ + public static final String QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD = + "queryDefaultAccountForNewContacts"; + /** * Get the account that is set as the default account for new contacts, which should be * initially selected when creating a new contact on contact management apps. -- GitLab From cd195faa9d2480fa63c083f895ecd0fa839280d2 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Thu, 3 Oct 2024 23:22:45 +0000 Subject: [PATCH 033/447] Use jni_libs to install shared library dependency `jni_libs` is more specific than `required`, and allows Soong to be more restrictive when creating the dependency edge from the java_binary to the cc_library. Bug: 370110572 Test: m installclean && m Test: verified that the jni libs are installed in out/target/product/... Change-Id: I52857314eed5944971b8f5993879a9609f1ea24e --- cmds/hid/Android.bp | 2 +- cmds/uinput/Android.bp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmds/hid/Android.bp b/cmds/hid/Android.bp index a6e27698e36c..b93227a60d99 100644 --- a/cmds/hid/Android.bp +++ b/cmds/hid/Android.bp @@ -22,5 +22,5 @@ java_binary { name: "hid", wrapper: "hid.sh", srcs: ["**/*.java"], - required: ["libhidcommand_jni"], + jni_libs: ["libhidcommand_jni"], } diff --git a/cmds/uinput/Android.bp b/cmds/uinput/Android.bp index da497dcf908e..cec8a0d88b99 100644 --- a/cmds/uinput/Android.bp +++ b/cmds/uinput/Android.bp @@ -25,7 +25,7 @@ java_binary { "src/**/*.java", ":uinputcommand_aidl", ], - required: ["libuinputcommand_jni"], + jni_libs: ["libuinputcommand_jni"], } filegroup { -- GitLab From 141ba6b1e3abde6763639b4a2a15cd6961296ec3 Mon Sep 17 00:00:00 2001 From: joonhunshin Date: Wed, 11 Sep 2024 07:17:05 +0000 Subject: [PATCH 034/447] Update API description for setDeviceAlignedWithSatellite() Bug: 365906559 Test: build pass Flag: EXEMPT update java doc Change-Id: Ic3050673eade8e521a6e48c4ee1c26e20ae7496f --- .../android/telephony/satellite/SatelliteManager.java | 11 ++++++----- .../com/android/internal/telephony/ITelephony.aidl | 6 +++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java index bd5c7597ba14..b6eb5373e83e 100644 --- a/telephony/java/android/telephony/satellite/SatelliteManager.java +++ b/telephony/java/android/telephony/satellite/SatelliteManager.java @@ -1958,13 +1958,14 @@ public final class SatelliteManager { } /** - * Inform whether the device is aligned with the satellite for demo mode. + * Inform whether the device is aligned with the satellite in both real and demo mode. * - * Framework can send datagram to modem only when device is aligned with the satellite. - * This method helps framework to simulate the experience of sending datagram over satellite. + * In demo mode, framework will send datagram to modem only when device is aligned with + * the satellite. This method helps framework to simulate the experience of sending datagram + * over satellite. * - * @param isAligned {@true} Device is aligned with the satellite for demo mode - * {@false} Device is not aligned with the satellite for demo mode + * @param isAligned {code @true} Device is aligned with the satellite + * {code @false} Device is not aligned with the satellite * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 3161d17681ed..b4bfff6adae4 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2977,10 +2977,10 @@ interface ITelephony { void requestTimeForNextSatelliteVisibility(in ResultReceiver receiver); /** - * Inform whether the device is aligned with the satellite within in margin for demo mode. + * Inform whether the device is aligned with the satellite in both real and demo mode. * - * @param isAligned {@true} Device is aligned with the satellite for demo mode - * {@false} Device is not aligned with the satellite for demo mode + * @param isAligned {@true} Device is aligned with the satellite. + * {@false} Device is not aligned with the satellite. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.SATELLITE_COMMUNICATION)") -- GitLab From 39b09273eadd404fcb305ff901d6e642d30cb6b7 Mon Sep 17 00:00:00 2001 From: Sally Qi Date: Tue, 1 Oct 2024 21:16:06 +0000 Subject: [PATCH 035/447] Update android/hardware/OWNERS for new file. Bug: 349667978 Change-Id: I937cf524459637ffbb873744bf1c8606df069de7 Test: builds Flag: EXEMPT only changing OWNERS --- core/java/android/hardware/OWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/java/android/hardware/OWNERS b/core/java/android/hardware/OWNERS index 43d3f5466ccf..f11625ed9d61 100644 --- a/core/java/android/hardware/OWNERS +++ b/core/java/android/hardware/OWNERS @@ -19,3 +19,6 @@ per-file DataSpace* = file:/graphics/java/android/graphics/OWNERS # OverlayProperties per-file OverlayProperties* = file:/graphics/java/android/graphics/OWNERS + +# Lut related files +per-file *Lut* = file:/graphics/java/android/graphics/OWNERS \ No newline at end of file -- GitLab From b355d2c9ea643cedb69977a7d9d65f25acac7a0e Mon Sep 17 00:00:00 2001 From: Yeabkal Wubshit Date: Thu, 3 Oct 2024 17:58:23 -0700 Subject: [PATCH 036/447] Limit display batterystats to internal/external displays Bug: 366112793 Test: atest DisplayPowerControllerTest Flag: com.android.server.display.feature.flags.enable_battery_stats_for_all_displays Change-Id: I5cac2e2bdef6472430104c83c5f0c04f991ce484 --- core/java/android/view/Display.java | 7 ++ .../display/DisplayPowerController.java | 13 +++- .../display/DisplayPowerControllerTest.java | 77 ++++++++++++++----- 3 files changed, 76 insertions(+), 21 deletions(-) diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 53935e810913..8a8022c0206a 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -448,6 +448,13 @@ public final class Display { @TestApi public static final int TYPE_VIRTUAL = 5; + /** + * The maximum display type value. + * Helpful to get all possible display values. + * @hide + */ + public static final int TYPE_MAX = TYPE_VIRTUAL; + /** * Display state: The display state is unknown. * diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 03fec0115613..95266219948a 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -537,7 +537,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mLastBrightnessEvent = new BrightnessEvent(mDisplayId); mTempBrightnessEvent = new BrightnessEvent(mDisplayId); - if (flags.isBatteryStatsEnabledForAllDisplays()) { + if (flags.isBatteryStatsEnabledForAllDisplays() + && isDisplaySupportedForBatteryStats(displayDeviceInfo)) { mBatteryStats = BatteryStatsService.getService(); } else if (mDisplayId == Display.DEFAULT_DISPLAY) { mBatteryStats = BatteryStatsService.getService(); @@ -2762,6 +2763,16 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } + private static boolean isDisplaySupportedForBatteryStats(DisplayDeviceInfo displayDeviceInfo) { + switch (displayDeviceInfo.type) { + case Display.TYPE_INTERNAL: + case Display.TYPE_EXTERNAL: + return true; + default: + return false; + } + } + private void dumpBrightnessEvents(PrintWriter pw) { int size = mBrightnessEventRingBuffer.size(); if (size < 1) { diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java index c70bf8abaef6..01b2d3e34bdc 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java @@ -35,6 +35,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.description; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; @@ -2278,29 +2279,44 @@ public final class DisplayPowerControllerTest { throws Exception { when(mDisplayManagerFlagsMock.isBatteryStatsEnabledForAllDisplays()).thenReturn(false); - verifyNoteScreenState(Display.DEFAULT_DISPLAY, /* expectNote= */ true); + verifyNoteScreenState( + Display.DEFAULT_DISPLAY, Display.TYPE_INTERNAL, /* expectNote= */ true); } @Test public void testBatteryStatNotes_enabledOnDefaultDisplayWhenEnabledOnOthers() throws Exception { when(mDisplayManagerFlagsMock.isBatteryStatsEnabledForAllDisplays()).thenReturn(true); - verifyNoteScreenState(Display.DEFAULT_DISPLAY, /* expectNote= */ true); + verifyNoteScreenState( + Display.DEFAULT_DISPLAY, Display.TYPE_INTERNAL, /* expectNote= */ true); } @Test - public void testBatteryStatNotes_flagGuardedOnNonDefaultDisplays() throws Exception { + public void testBatteryStatNotes_flagOff_disabledForNonDefaultDisplays() throws Exception { when(mDisplayManagerFlagsMock.isBatteryStatsEnabledForAllDisplays()).thenReturn(false); - verifyNoteScreenState(/* displayId= */ 2, /* expectNote= */ false); + verifyNoteScreenState(/* displayId= */ 2, Display.TYPE_INTERNAL, /* expectNote= */ false); + } + @Test + public void testBatteryStatNotes_enabledOnlyOnInternalOrExternalDisplays() throws Exception { when(mDisplayManagerFlagsMock.isBatteryStatsEnabledForAllDisplays()).thenReturn(true); - verifyNoteScreenState(/* displayId= */ 2, /* expectNote= */ true); + for (int displayType = 0; displayType < Display.TYPE_MAX; displayType++) { + boolean expectNote = + (displayType == Display.TYPE_INTERNAL) + || (displayType == Display.TYPE_EXTERNAL); + verifyNoteScreenState(/* displayId= */ 2, displayType, expectNote); + } } - private void verifyNoteScreenState(int displayId, boolean expectNote) throws Exception { - mHolder = createDisplayPowerController(displayId, UNIQUE_ID); + private void verifyNoteScreenState(int displayId, int displayDeviceType, boolean expectNote) + throws Exception { + clearInvocations(mMockBatteryStats); + DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo(); + deviceInfo.type = displayDeviceType; + deviceInfo.uniqueId = UNIQUE_ID; + mHolder = createDisplayPowerController(displayId, deviceInfo); DisplayPowerRequest dpr = new DisplayPowerRequest(); dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); @@ -2308,14 +2324,22 @@ public final class DisplayPowerControllerTest { mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); advanceTime(1); // Run updatePowerState + final String baseErrorMessage = + String.format("[display id=%d type=%d]", displayId, displayDeviceType); + final String errorMessage; if (expectNote) { - verify(mMockBatteryStats) + errorMessage = "Expected battery stats: " + baseErrorMessage; + verify(mMockBatteryStats, description(errorMessage)) .noteScreenState( displayId, Display.STATE_ON, Display.STATE_REASON_DEFAULT_POLICY); - verify(mMockBatteryStats).noteScreenBrightness(eq(displayId), anyInt()); + verify(mMockBatteryStats, description(errorMessage)) + .noteScreenBrightness(eq(displayId), anyInt()); } else { - verify(mMockBatteryStats, never()).noteScreenState(anyInt(), anyInt(), anyInt()); - verify(mMockBatteryStats, never()).noteScreenBrightness(anyInt(), anyInt()); + errorMessage = "Expected no battery stats: " + baseErrorMessage; + verify(mMockBatteryStats, never().description(errorMessage)) + .noteScreenState(anyInt(), anyInt(), anyInt()); + verify(mMockBatteryStats, never().description(errorMessage)) + .noteScreenBrightness(anyInt(), anyInt()); } } @@ -2350,17 +2374,16 @@ public final class DisplayPowerControllerTest { private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock, DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock, boolean isEnabled) { - - setUpDisplay(displayId, uniqueId, logicalDisplayMock, displayDeviceMock, + DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo(); + deviceInfo.uniqueId = uniqueId; + setUpDisplay(displayId, deviceInfo, logicalDisplayMock, displayDeviceMock, displayDeviceConfigMock, isEnabled, "display_name"); } - private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock, - DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock, - boolean isEnabled, String displayName) { + private void setUpDisplay(int displayId, DisplayDeviceInfo deviceInfo, + LogicalDisplay logicalDisplayMock, DisplayDevice displayDeviceMock, + DisplayDeviceConfig displayDeviceConfigMock, boolean isEnabled, String displayName) { DisplayInfo info = new DisplayInfo(); - DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo(); - deviceInfo.uniqueId = uniqueId; when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId); when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock); @@ -2368,7 +2391,7 @@ public final class DisplayPowerControllerTest { when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled); when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false); when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo); - when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId); + when(displayDeviceMock.getUniqueId()).thenReturn(deviceInfo.uniqueId); when(displayDeviceMock.getNameLocked()).thenReturn(displayName); when(displayDeviceMock.getDisplayDeviceConfig()).thenReturn(displayDeviceConfigMock); when(displayDeviceConfigMock.getProximitySensor()).thenReturn( @@ -2415,6 +2438,12 @@ public final class DisplayPowerControllerTest { hysteresisLevels); } + private DisplayPowerControllerHolder createDisplayPowerController( + int displayId, DisplayDeviceInfo info) { + return createDisplayPowerController( + displayId, info, /* isEnabled= */ true, /* isAutoBrightnessAvailable= */ true); + } + private DisplayPowerControllerHolder createDisplayPowerController(int displayId, String uniqueId) { return createDisplayPowerController(displayId, uniqueId, /* isEnabled= */ true); @@ -2428,6 +2457,14 @@ public final class DisplayPowerControllerTest { private DisplayPowerControllerHolder createDisplayPowerController(int displayId, String uniqueId, boolean isEnabled, boolean isAutoBrightnessAvailable) { + DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo(); + deviceInfo.uniqueId = uniqueId; + return createDisplayPowerController( + displayId, deviceInfo, isEnabled, isAutoBrightnessAvailable); + } + + private DisplayPowerControllerHolder createDisplayPowerController(int displayId, + DisplayDeviceInfo deviceInfo, boolean isEnabled, boolean isAutoBrightnessAvailable) { final DisplayPowerState displayPowerState = mock(DisplayPowerState.class); final DualRampAnimator animator = mock(DualRampAnimator.class); final AutomaticBrightnessController automaticBrightnessController = @@ -2469,7 +2506,7 @@ public final class DisplayPowerControllerTest { when(config.getScreenBrightnessHysteresis()).thenReturn(hysteresisLevels); when(config.getScreenBrightnessIdleHysteresis()).thenReturn(hysteresisLevels); - setUpDisplay(displayId, uniqueId, display, device, config, isEnabled); + setUpDisplay(displayId, deviceInfo, display, device, config, isEnabled, "display_name"); when(config.isAutoBrightnessAvailable()).thenReturn(isAutoBrightnessAvailable); final DisplayPowerController dpc = new DisplayPowerController( -- GitLab From 456c0935c4ff371e7a1d6eaca7de96a1e8cd0b99 Mon Sep 17 00:00:00 2001 From: Atneya Nair Date: Thu, 3 Oct 2024 18:45:18 -0700 Subject: [PATCH 037/447] Fix recording config mic indicator suppression We should suppress the indicator when AllOf the configs are silenced, instead of AnyOf. Bug: 293603271 Test: CtsMediaAudioPermissionTestCases Test: AppOpsControllerTest Flag: EXEMPT security Change-Id: I8b1fe0bc2a4474467a1ef2510b29c5164e32aad8 --- .../systemui/appops/AppOpsControllerImpl.java | 13 ++++---- .../systemui/appops/AppOpsControllerTest.java | 30 ++++++++++++++----- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index e0f73a63113a..cbdb8827e39c 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -319,7 +319,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon if (item == null && active) { item = new AppOpItem(code, uid, packageName, mClock.elapsedRealtime()); if (isOpMicrophone(code)) { - item.setDisabled(isAnyRecordingPausedLocked(uid)); + item.setDisabled(isAllRecordingPausedLocked(uid)); } else if (isOpCamera(code)) { item.setDisabled(mCameraDisabled); } @@ -521,18 +521,21 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon } - private boolean isAnyRecordingPausedLocked(int uid) { + // TODO(b/365843152) remove AudioRecordingConfiguration listening + private boolean isAllRecordingPausedLocked(int uid) { if (mMicMuted) { return true; } List configs = mRecordingsByUid.get(uid); if (configs == null) return false; + // If we are aware of AudioRecordConfigs, suppress the indicator if all of them are known + // to be silenced. int configsNum = configs.size(); for (int i = 0; i < configsNum; i++) { AudioRecordingConfiguration config = configs.get(i); - if (config.isClientSilenced()) return true; + if (!config.isClientSilenced()) return false; } - return false; + return true; } private void updateSensorDisabledStatus() { @@ -543,7 +546,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon boolean paused = false; if (isOpMicrophone(item.getCode())) { - paused = isAnyRecordingPausedLocked(item.getUid()); + paused = isAllRecordingPausedLocked(item.getUid()); } else if (isOpCamera(item.getCode())) { paused = mCameraDisabled; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java index 476d6e373df3..7c0892891707 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java @@ -103,11 +103,10 @@ public class AppOpsControllerTest extends SysuiTestCase { @Mock() private BroadcastDispatcher mDispatcher; @Mock(stubOnly = true) - private AudioManager.AudioRecordingCallback mRecordingCallback; - @Mock(stubOnly = true) private AudioRecordingConfiguration mPausedMockRecording; private AppOpsControllerImpl mController; + private AudioManager.AudioRecordingCallback mRecordingCallback; private TestableLooper mTestableLooper; private final FakeExecutor mBgExecutor = new FakeExecutor(new FakeSystemClock()); @@ -975,6 +974,7 @@ public class AppOpsControllerTest extends SysuiTestCase { } private void verifyUnPausedSentActive(int micOpCode) { + // Setup stubs the initial active recording list with a single silenced client mController.addCallback(new int[]{micOpCode}, mCallback); mBgExecutor.runAllReady(); mTestableLooper.processAllMessages(); @@ -982,11 +982,20 @@ public class AppOpsControllerTest extends SysuiTestCase { TEST_PACKAGE_NAME, true); mTestableLooper.processAllMessages(); - mRecordingCallback.onRecordingConfigChanged(Collections.emptyList()); + + // Update with multiple recording configs, of which one is unsilenced + var mockARCUnsilenced = mock(AudioRecordingConfiguration.class); + when(mockARCUnsilenced.getClientUid()).thenReturn(TEST_UID); + when(mockARCUnsilenced.isClientSilenced()).thenReturn(false); + + mRecordingCallback.onRecordingConfigChanged(List.of( + mockARCUnsilenced, mPausedMockRecording)); mTestableLooper.processAllMessages(); verify(mCallback).onActiveStateChanged(micOpCode, TEST_UID, TEST_PACKAGE_NAME, true); + // For consistency since this runs in a loop + mController.removeCallback(new int[]{micOpCode}, mCallback); } private void verifyAudioPausedSentInactive(int micOpCode) { @@ -997,11 +1006,16 @@ public class AppOpsControllerTest extends SysuiTestCase { TEST_PACKAGE_NAME, true); mTestableLooper.processAllMessages(); - AudioRecordingConfiguration mockARC = mock(AudioRecordingConfiguration.class); - when(mockARC.getClientUid()).thenReturn(TEST_UID_OTHER); - when(mockARC.isClientSilenced()).thenReturn(true); + // Multiple recording configs, which are all silenced + AudioRecordingConfiguration mockARCOne = mock(AudioRecordingConfiguration.class); + when(mockARCOne.getClientUid()).thenReturn(TEST_UID_OTHER); + when(mockARCOne.isClientSilenced()).thenReturn(true); + + AudioRecordingConfiguration mockARCTwo = mock(AudioRecordingConfiguration.class); + when(mockARCTwo.getClientUid()).thenReturn(TEST_UID_OTHER); + when(mockARCTwo.isClientSilenced()).thenReturn(true); - mRecordingCallback.onRecordingConfigChanged(List.of(mockARC)); + mRecordingCallback.onRecordingConfigChanged(List.of(mockARCOne, mockARCTwo)); mTestableLooper.processAllMessages(); InOrder inOrder = inOrder(mCallback); @@ -1009,6 +1023,8 @@ public class AppOpsControllerTest extends SysuiTestCase { micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, true); inOrder.verify(mCallback).onActiveStateChanged( micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, false); + // For consistency since this runs in a loop + mController.removeCallback(new int[]{micOpCode}, mCallback); } private void verifySingleActiveOps(int op) { -- GitLab From eb7142dd7cb6ad264765d7441188cae013d80946 Mon Sep 17 00:00:00 2001 From: Eden Mendel Date: Fri, 4 Oct 2024 02:41:33 +0000 Subject: [PATCH 038/447] Add new onboarded native namespace to SettingsToPropertiesMapper for native flag access Change-Id: I8042f65a015cfee7daa4126b456a347a56c6b60d Flag: EXEMPT trunk stable namespace onboarding Bug: b/369769282, b/368341182, b/368692752, b/368395439, b/370052920 --- .../com/android/server/am/SettingsToPropertiesMapper.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index bae9a670c438..a815f72ca09e 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -138,6 +138,7 @@ public class SettingsToPropertiesMapper { // The list is sorted. @VisibleForTesting static final String[] sDeviceConfigAconfigScopes = new String[] { + "aaos_sdv", "accessibility", "android_core_networking", "android_health_services", @@ -150,6 +151,7 @@ public class SettingsToPropertiesMapper { "art_performance", "attack_tools", "avic", + "desktop_firmware", "biometrics", "biometrics_framework", "biometrics_integration", @@ -211,6 +213,7 @@ public class SettingsToPropertiesMapper { "preload_safety", "printing", "privacy_infra_policy", + "ravenwood", "resource_manager", "responsible_apis", "rust", @@ -243,8 +246,10 @@ public class SettingsToPropertiesMapper { "wear_system_health", "wear_systems", "wear_sysui", + "wear_system_managed_surfaces", "window_surfaces", "windowing_frontend", + "xr", }; public static final String NAMESPACE_REBOOT_STAGING = "staged"; -- GitLab From 16a74e092f12b648a9c7abe27193f75aa87e6c3d Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Sat, 3 Aug 2024 13:34:42 +0900 Subject: [PATCH 039/447] Connect stored variation settings to Minikin Bug: 361260253 Test: minikin_tests Flag: com.android.text.flags.typeface_redesign Change-Id: I69218ca84b66e4d0a2b3bc4ec5fbc8c20ef105d6 --- libs/hwui/hwui/MinikinUtils.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp index ede385adc779..9cd6e253140e 100644 --- a/libs/hwui/hwui/MinikinUtils.cpp +++ b/libs/hwui/hwui/MinikinUtils.cpp @@ -48,6 +48,7 @@ minikin::MinikinPaint MinikinUtils::prepareMinikinPaint(const Paint* paint, minikinPaint.localeListId = paint->getMinikinLocaleListId(); minikinPaint.fontStyle = resolvedFace->fStyle; minikinPaint.fontFeatureSettings = paint->getFontFeatureSettings(); + minikinPaint.fontVariationSettings = paint->getFontVariationOverride(); const std::optional& familyVariant = paint->getFamilyVariant(); if (familyVariant.has_value()) { -- GitLab From d0ea4c323144913bd470e7f99747c59fbafeed38 Mon Sep 17 00:00:00 2001 From: Wilson Wu Date: Fri, 16 Aug 2024 02:32:38 +0000 Subject: [PATCH 040/447] Backup & restore for ringtone vibrations After CL[1] and CL[2], the ringtone/notification support custome vibration playback. If the user choose ringtone/notification with a vibration, backup original value and use the same value directly for restoring. [1]: I8fc4f49e3801caec1dc2b0b611dd5b3854c6395f [2]: I864c42b5c30f41328633bd37fe8fb571fb9cdbe4 Flag: android.media.audio.enable_ringtone_haptics_customization Bug: 358525300 Bug: 371474327 Bug: 371471679 Test: atest SettingsHelperTest Test: Set up a ringtone with a vibration -> Backup the settings -> Factory reset the device -> Restore the settings from the same user -> Verify the ringtone and vibration are restored Change-Id: I0ff20125baf2b0df225f25439c849cd7aee90a72 Change-Id: Ic15a2912becccf53e44188d8ae26bd683bb2f1cf --- packages/SettingsProvider/Android.bp | 1 + .../providers/settings/SettingsHelper.java | 30 ++++++++ .../settings/SettingsHelperTest.java | 69 +++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp index 1a99d25786ff..65b22758946d 100644 --- a/packages/SettingsProvider/Android.bp +++ b/packages/SettingsProvider/Android.bp @@ -39,6 +39,7 @@ android_library { "configinfra_framework_flags_java_lib", "device_config_service_flags_java", "libaconfig_java_proto_lite", + "notification_flags_lib", "SettingsLibDeviceStateRotationLock", "SettingsLibDisplayUtils", ], diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java index 6c3183191163..ec3bd90b91ea 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java @@ -29,6 +29,7 @@ import android.hardware.display.ColorDisplayManager; import android.icu.util.ULocale; import android.media.AudioManager; import android.media.RingtoneManager; +import android.media.Utils; import android.net.Uri; import android.os.LocaleList; import android.os.RemoteException; @@ -309,6 +310,13 @@ public class SettingsHelper { return SILENT_RINGTONE; } } else { + // If the ringtone/notification support the vibration, use the original value. + final int ringtoneType = getRingtoneType(name); + if ((Settings.System.RINGTONE.equals(name) + || Settings.System.NOTIFICATION_SOUND.equals(name)) + && hasVibrationSettings(value, ringtoneType)) { + return value; + } return getCanonicalRingtoneValue(value); } } @@ -362,6 +370,15 @@ public class SettingsHelper { return; } + // If the ringtone/notification has vibration, we backup original value in onBackupValue. + // So use the value directly for restoring. + if ((ringtoneType == RingtoneManager.TYPE_RINGTONE + || ringtoneType == RingtoneManager.TYPE_NOTIFICATION) + && hasVibrationSettings(value, ringtoneType)) { + RingtoneManager.setActualDefaultRingtoneUri(mContext, ringtoneType, Uri.parse(value)); + return; + } + Uri ringtoneUri = null; try { ringtoneUri = @@ -617,6 +634,19 @@ public class SettingsHelper { return allLocales.remove(toFullLocale(filteredLocale)); } + private boolean hasVibrationSettings(String value, int type) { + if (Utils.hasVibration(Uri.parse(value)) && mContext.getResources().getBoolean( + com.android.internal.R.bool.config_ringtoneVibrationSettingsSupported)) { + if (type == RingtoneManager.TYPE_RINGTONE) { + return android.media.audio.Flags.enableRingtoneHapticsCustomization(); + } + if (type == RingtoneManager.TYPE_NOTIFICATION) { + return com.android.server.notification.Flags.notificationVibrationInSoundUri(); + } + } + return false; + } + /** * Sets the locale specified. Input data is the byte representation of comma separated * multiple BCP-47 language tags. For backwards compatibility, strings of the form diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java index 4b10b56f49fb..babc1a37cc61 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java @@ -37,9 +37,12 @@ import android.content.res.Resources; import android.database.Cursor; import android.database.MatrixCursor; import android.media.AudioManager; +import android.media.Utils; import android.net.Uri; import android.os.Bundle; import android.os.LocaleList; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.BaseColumns; import android.provider.MediaStore; import android.provider.Settings; @@ -54,6 +57,7 @@ import com.android.internal.R; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -74,9 +78,13 @@ public class SettingsHelperTest { "content://media/internal/audio/media/20?title=DefaultNotification&canonical=1"; private static final String DEFAULT_ALARM_VALUE = "content://media/internal/audio/media/30?title=DefaultAlarm&canonical=1"; + private static final String VIBRATION_FILE_NAME = "haptics.xml"; private SettingsHelper mSettingsHelper; + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Mock private Context mContext; @Mock private Resources mResources; @Mock private AudioManager mAudioManager; @@ -119,6 +127,22 @@ public class SettingsHelperTest { assertEquals(SETTING_REAL_VALUE, mSettingsHelper.onBackupValue(SETTING_KEY, SETTING_VALUE)); } + @Test + @EnableFlags({android.media.audio.Flags.FLAG_ENABLE_RINGTONE_HAPTICS_CUSTOMIZATION, + com.android.server.notification.Flags.FLAG_NOTIFICATION_VIBRATION_IN_SOUND_URI}) + public void testOnBackupValue_ringtoneVibrationSupport_returnsSameValue() { + when(mResources.getBoolean( + com.android.internal.R.bool.config_ringtoneVibrationSettingsSupported)).thenReturn( + true); + String testRingtoneVibrationValue = createUriWithVibration(DEFAULT_RINGTONE_VALUE); + String testNotificationVibrationValue = createUriWithVibration(DEFAULT_NOTIFICATION_VALUE); + + assertEquals(testRingtoneVibrationValue, mSettingsHelper.onBackupValue( + Settings.System.RINGTONE, testRingtoneVibrationValue)); + assertEquals(testNotificationVibrationValue, mSettingsHelper.onBackupValue( + Settings.System.NOTIFICATION_SOUND, testNotificationVibrationValue)); + } + @Test public void testGetRealValue_settingNotReplaced_returnsSameValue() { when(mSettingsHelper.isReplacedSystemSetting(eq(SETTING_KEY))).thenReturn(false); @@ -675,6 +699,30 @@ public class SettingsHelperTest { .isEqualTo(null); } + @Test + @EnableFlags({android.media.audio.Flags.FLAG_ENABLE_RINGTONE_HAPTICS_CUSTOMIZATION, + com.android.server.notification.Flags.FLAG_NOTIFICATION_VIBRATION_IN_SOUND_URI}) + public void testRestoreValue_ringtoneVibrationSupport_restoreValue() { + when(mResources.getBoolean( + com.android.internal.R.bool.config_ringtoneVibrationSettingsSupported)).thenReturn( + true); + String testRingtoneVibrationValue = createUriWithVibration(DEFAULT_RINGTONE_VALUE); + String testNotificationVibrationValue = createUriWithVibration(DEFAULT_NOTIFICATION_VALUE); + ContentProvider mockMediaContentProvider = + new MockContentProvider(mContext) { + @Override + public String getType(Uri url) { + return "audio/ogg"; + } + }; + mContentResolver.addProvider(MediaStore.AUTHORITY, mockMediaContentProvider); + resetRingtoneSettingsToDefault(); + + assertRingtoneSettingsRestoring(Settings.System.RINGTONE, testRingtoneVibrationValue); + assertRingtoneSettingsRestoring( + Settings.System.NOTIFICATION_SOUND, testNotificationVibrationValue); + } + private static class MockSettingsProvider extends MockContentProvider { private final ArrayMap mKeyValueStore = new ArrayMap<>(); MockSettingsProvider(Context context) { @@ -766,4 +814,25 @@ public class SettingsHelperTest { assertThat(Settings.System.getString(mContentResolver, Settings.System.ALARM_ALERT)) .isEqualTo(DEFAULT_ALARM_VALUE); } + + private String createUriWithVibration(String defaultUriString) { + return Uri.parse(defaultUriString).buildUpon() + .appendQueryParameter( + Utils.VIBRATION_URI_PARAM, VIBRATION_FILE_NAME).build().toString(); + } + + private void assertRingtoneSettingsRestoring( + String settings, String testRingtoneSettingsValue) { + mSettingsHelper.restoreValue( + mContext, + mContentResolver, + new ContentValues(), + Uri.EMPTY, + settings, + testRingtoneSettingsValue, + 0); + + assertThat(Settings.System.getString(mContentResolver, settings)) + .isEqualTo(testRingtoneSettingsValue); + } } -- GitLab From 9fd025cd7b438b27d8d3f8376bb0421c9063bd28 Mon Sep 17 00:00:00 2001 From: Merissa Mitchell Date: Mon, 30 Sep 2024 16:40:36 -0700 Subject: [PATCH 041/447] [PIP2] Attach PiP menu to leash. Recall: http://recall/clips/a4248f21-10d6-422c-837c-30117540bac4 Winscope: https://screenshot.googleplex.com/6yTWd3Q5HZKZhsb Bug: 322548939 Test: Launch PiP and verify menu is present and app actions are usable. Flag: com.android.wm.shell.enable_pip2 Change-Id: I9d21f576b7764bb5d697573f93be0260e2367327 --- .../Shell/res/layout/pip2_menu_action.xml | 39 +++++++++++++++ .../wm/shell/dagger/pip/Pip2Module.java | 9 ++-- .../pip2/phone/PhonePipMenuController.java | 49 ++++++++++++++++--- .../wm/shell/pip2/phone/PipMenuView.java | 2 +- .../wm/shell/pip2/phone/PipScheduler.java | 4 -- .../wm/shell/pip2/phone/PipTaskListener.java | 28 +++++++++++ 6 files changed, 115 insertions(+), 16 deletions(-) create mode 100644 libs/WindowManager/Shell/res/layout/pip2_menu_action.xml diff --git a/libs/WindowManager/Shell/res/layout/pip2_menu_action.xml b/libs/WindowManager/Shell/res/layout/pip2_menu_action.xml new file mode 100644 index 000000000000..04ece31cb820 --- /dev/null +++ b/libs/WindowManager/Shell/res/layout/pip2_menu_action.xml @@ -0,0 +1,39 @@ + + + + + + + + + diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java index 3464fef07f33..b27cad87f4eb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java @@ -125,11 +125,9 @@ public abstract class Pip2Module { @Provides static PipScheduler providePipScheduler(Context context, PipBoundsState pipBoundsState, - PhonePipMenuController pipMenuController, @ShellMainThread ShellExecutor mainExecutor, PipTransitionState pipTransitionState) { - return new PipScheduler(context, pipBoundsState, pipMenuController, - mainExecutor, pipTransitionState); + return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState); } @WMSingleton @@ -138,10 +136,13 @@ public abstract class Pip2Module { PipBoundsState pipBoundsState, PipMediaController pipMediaController, SystemWindows systemWindows, PipUiEventLogger pipUiEventLogger, + PipTaskListener pipTaskListener, + @NonNull PipTransitionState pipTransitionState, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler) { return new PhonePipMenuController(context, pipBoundsState, pipMediaController, - systemWindows, pipUiEventLogger, mainExecutor, mainHandler); + systemWindows, pipUiEventLogger, pipTaskListener, pipTransitionState, mainExecutor, + mainHandler); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java index 9cfe1620a2ff..02e6670470d7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java @@ -18,10 +18,12 @@ package com.android.wm.shell.pip2.phone; import static android.view.WindowManager.SHELL_ROOT_LAYER_PIP; +import android.annotation.NonNull; import android.annotation.Nullable; import android.app.RemoteAction; import android.content.Context; import android.graphics.Rect; +import android.os.Bundle; import android.os.Debug; import android.os.Handler; import android.os.RemoteException; @@ -52,7 +54,8 @@ import java.util.List; * The current media session provides actions whenever there are no valid actions provided by the * current PiP activity. Otherwise, those actions always take precedence. */ -public class PhonePipMenuController implements PipMenuController { +public class PhonePipMenuController implements PipMenuController, + PipTransitionState.PipTransitionStateChangedListener { private static final String TAG = "PhonePipMenuController"; private static final boolean DEBUG = false; @@ -113,6 +116,11 @@ public class PhonePipMenuController implements PipMenuController { private PipMenuView mPipMenuView; + private final PipTaskListener mPipTaskListener; + + @NonNull + private final PipTransitionState mPipTransitionState; + private SurfaceControl mLeash; private ActionListener mMediaActionListener = new ActionListener() { @@ -125,15 +133,27 @@ public class PhonePipMenuController implements PipMenuController { public PhonePipMenuController(Context context, PipBoundsState pipBoundsState, PipMediaController mediaController, SystemWindows systemWindows, - PipUiEventLogger pipUiEventLogger, - ShellExecutor mainExecutor, Handler mainHandler) { + PipUiEventLogger pipUiEventLogger, PipTaskListener pipTaskListener, + @NonNull PipTransitionState pipTransitionState, ShellExecutor mainExecutor, + Handler mainHandler) { mContext = context; mPipBoundsState = pipBoundsState; mMediaController = mediaController; mSystemWindows = systemWindows; + mPipTaskListener = pipTaskListener; + mPipTransitionState = pipTransitionState; mMainExecutor = mainExecutor; mMainHandler = mainHandler; mPipUiEventLogger = pipUiEventLogger; + + mPipTransitionState.addPipTransitionStateChangedListener(this); + + mPipTaskListener.addParamsChangedListener(new PipTaskListener.PipParamsChangedCallback() { + @Override + public void onActionsChanged(List actions, RemoteAction closeAction) { + setAppActions(actions, closeAction); + } + }); } public boolean isMenuVisible() { @@ -438,8 +458,7 @@ public class PhonePipMenuController implements PipMenuController { * Sets the menu actions to the actions provided by the current PiP menu. */ @Override - public void setAppActions(List appActions, - RemoteAction closeAction) { + public void setAppActions(List appActions, RemoteAction closeAction) { mAppActions = appActions; mCloseAction = closeAction; updateMenuActions(); @@ -468,8 +487,8 @@ public class PhonePipMenuController implements PipMenuController { */ private void updateMenuActions() { if (mPipMenuView != null) { - mPipMenuView.setActions(mPipBoundsState.getBounds(), - resolveMenuActions(), mCloseAction); + mPipMenuView.setActions(mPipBoundsState.getBounds(), resolveMenuActions(), + mCloseAction); } } @@ -567,6 +586,22 @@ public class PhonePipMenuController implements PipMenuController { } } + @Override + public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, + @PipTransitionState.TransitionState int newState, Bundle extra) { + switch (newState) { + case PipTransitionState.ENTERED_PIP: + attach(mPipTransitionState.mPinnedTaskLeash); + break; + case PipTransitionState.EXITED_PIP: + detach(); + break; + case PipTransitionState.CHANGED_PIP_BOUNDS: + updateMenuLayout(mPipBoundsState.getBounds()); + break; + } + } + void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; pw.println(prefix + TAG); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java index a29104c4aafd..0910919b3064 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java @@ -447,7 +447,7 @@ public class PipMenuView extends FrameLayout { final LayoutInflater inflater = LayoutInflater.from(mContext); while (mActionsGroup.getChildCount() < mActions.size()) { final PipMenuActionView actionView = (PipMenuActionView) inflater.inflate( - R.layout.pip_menu_action, mActionsGroup, false); + R.layout.pip2_menu_action, mActionsGroup, false); mActionsGroup.addView(actionView); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java index f4defdc7963c..d4f190ebd2a2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java @@ -52,7 +52,6 @@ public class PipScheduler { private final Context mContext; private final PipBoundsState mPipBoundsState; - private final PhonePipMenuController mPipMenuController; private final ShellExecutor mMainExecutor; private final PipTransitionState mPipTransitionState; private PipSchedulerReceiver mSchedulerReceiver; @@ -97,12 +96,10 @@ public class PipScheduler { public PipScheduler(Context context, PipBoundsState pipBoundsState, - PhonePipMenuController pipMenuController, ShellExecutor mainExecutor, PipTransitionState pipTransitionState) { mContext = context; mPipBoundsState = pipBoundsState; - mPipMenuController = pipMenuController; mMainExecutor = mainExecutor; mPipTransitionState = pipTransitionState; @@ -263,7 +260,6 @@ public class PipScheduler { return; } mPipBoundsState.setBounds(newBounds); - mPipMenuController.updateMenuLayout(newBounds); maybeUpdateMovementBounds(); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java index 262c14d2bfe3..c58de2c3512a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java @@ -20,6 +20,7 @@ import static com.android.wm.shell.pip2.phone.PipTransition.ANIMATING_BOUNDS_CHA import android.app.ActivityManager; import android.app.PictureInPictureParams; +import android.app.RemoteAction; import android.content.Context; import android.graphics.Rect; import android.os.Bundle; @@ -37,6 +38,9 @@ import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.pip2.animation.PipResizeAnimator; import com.android.wm.shell.shared.annotations.ShellMainThread; +import java.util.ArrayList; +import java.util.List; + /** * A Task Listener implementation used only for CUJs and trigger paths that cannot be initiated via * Transitions framework directly. @@ -57,6 +61,7 @@ public class PipTaskListener implements ShellTaskOrganizer.TaskListener, new PictureInPictureParams.Builder().build(); private boolean mWaitingForAspectRatioChange = false; + private final List mPipParamsChangedListeners = new ArrayList<>(); public PipTaskListener(Context context, ShellTaskOrganizer shellTaskOrganizer, @@ -85,10 +90,25 @@ public class PipTaskListener implements ShellTaskOrganizer.TaskListener, if (mPictureInPictureParams.equals(params)) { return; } + if (PipUtils.remoteActionsChanged(params.getActions(), mPictureInPictureParams.getActions()) + || !PipUtils.remoteActionsMatch(params.getCloseAction(), + mPictureInPictureParams.getCloseAction())) { + for (PipParamsChangedCallback listener : mPipParamsChangedListeners) { + listener.onActionsChanged(params.getActions(), params.getCloseAction()); + } + } mPictureInPictureParams.copyOnlySet(params != null ? params : new PictureInPictureParams.Builder().build()); } + /** Add a PipParamsChangedCallback listener. */ + public void addParamsChangedListener(PipParamsChangedCallback listener) { + if (mPipParamsChangedListeners.contains(listener)) { + return; + } + mPipParamsChangedListeners.add(listener); + } + @NonNull public PictureInPictureParams getPictureInPictureParams() { return mPictureInPictureParams; @@ -164,4 +184,12 @@ public class PipTaskListener implements ShellTaskOrganizer.TaskListener, break; } } + + public interface PipParamsChangedCallback { + /** + * Called if either the actions or the close action changed. + */ + default void onActionsChanged(List actions, RemoteAction closeAction) { + } + } } -- GitLab From efc6bd8e33c44ec8714852f87917793dd20a485d Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Fri, 4 Oct 2024 06:55:13 +0000 Subject: [PATCH 042/447] Add temp value for BiometricEnrolled.template_id Bug: 345478069 Test: m Flag: EXEMPT adding logs Change-Id: If09b039da6be1f903148fad7c75101e1910eb4e9 --- .../server/biometrics/log/BiometricFrameworkStatsLogger.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java b/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java index bc58501f5b59..93b0e66d1ae5 100644 --- a/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java +++ b/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java @@ -123,7 +123,8 @@ public class BiometricFrameworkStatsLogger { enrollSuccessful, -1, /* sensorId */ ambientLightLux, - source); + source, + -1 /* templateId*/); } /** {@see FrameworkStatsLog.BIOMETRIC_ERROR_OCCURRED}. */ -- GitLab From 5557dd75eeba18837b0585208ce1581a25502e0d Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Fri, 4 Oct 2024 06:07:35 +0000 Subject: [PATCH 043/447] Handle apexd failures Rethrowing RemoteException causes PackageManager crash. This happens when a device shutting down (init kills apexd while it's being used by PM). Instead, apexd logs an error and returns a reasonable default value (null or empty), except wrapping it in a PackageManagerException in a few methods, which is handled by PM. Bug: 370264486 Change-Id: Ie8aed22f16599f7e1769df2abd4a1e13013d9105 Test: ApexManagerTest --- .../java/com/android/server/pm/ApexManager.java | 14 +++++++++----- .../com/android/server/pm/ApexManagerTest.java | 15 ++++++++------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index 5d71439e8f46..458b46dab54c 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -592,7 +592,7 @@ public abstract class ApexManager { return apexSessionInfo; } catch (RemoteException re) { Slog.e(TAG, "Unable to contact apexservice", re); - throw new RuntimeException(re); + return null; } } @@ -607,7 +607,7 @@ public abstract class ApexManager { return result; } catch (RemoteException re) { Slog.e(TAG, "Unable to contact apexservice", re); - throw new RuntimeException(re); + return new SparseArray<>(0); } } @@ -619,7 +619,9 @@ public abstract class ApexManager { return apexInfoList; } catch (RemoteException re) { Slog.e(TAG, "Unable to contact apexservice", re); - throw new RuntimeException(re); + throw new PackageManagerException( + PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, + "apexd verification failed : " + re.getMessage()); } catch (Exception e) { throw new PackageManagerException( PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, @@ -633,7 +635,7 @@ public abstract class ApexManager { return waitForApexService().getStagedApexInfos(params); } catch (RemoteException re) { Slog.w(TAG, "Unable to contact apexservice" + re.getMessage()); - throw new RuntimeException(re); + return new ApexInfo[0]; } catch (Exception e) { Slog.w(TAG, "Failed to collect staged apex infos" + e.getMessage()); return new ApexInfo[0]; @@ -646,7 +648,9 @@ public abstract class ApexManager { waitForApexService().markStagedSessionReady(sessionId); } catch (RemoteException re) { Slog.e(TAG, "Unable to contact apexservice", re); - throw new RuntimeException(re); + throw new PackageManagerException( + PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, + "Failed to mark apexd session as ready : " + re.getMessage()); } catch (Exception e) { throw new PackageManagerException( PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java index d08cdc718a82..769f071e3ddc 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java @@ -265,19 +265,19 @@ public class ApexManagerTest { } @Test - public void testSubmitStagedSession_throwRunTimeException() throws RemoteException { + public void testSubmitStagedSession_throwPackageManagerExceptionOnRemoteException() + throws RemoteException { doThrow(RemoteException.class).when(mApexService).submitStagedSession(any(), any()); - assertThrows(RuntimeException.class, + assertThrows(PackageManagerException.class, () -> mApexManager.submitStagedSession(testParamsWithChildren())); } @Test - public void testGetStagedApexInfos_throwRunTimeException() throws RemoteException { + public void testGetStagedApexInfos_returnsEmptyOnRemoteException() throws RemoteException { doThrow(RemoteException.class).when(mApexService).getStagedApexInfos(any()); - assertThrows(RuntimeException.class, - () -> mApexManager.getStagedApexInfos(testParamsWithChildren())); + assertThat(mApexManager.getStagedApexInfos(testParamsWithChildren())).hasLength(0); } @Test @@ -298,10 +298,11 @@ public class ApexManagerTest { } @Test - public void testMarkStagedSessionReady_throwRunTimeException() throws RemoteException { + public void testMarkStagedSessionReady_throwPackageManagerExceptionOnRemoteException() + throws RemoteException { doThrow(RemoteException.class).when(mApexService).markStagedSessionReady(anyInt()); - assertThrows(RuntimeException.class, + assertThrows(PackageManagerException.class, () -> mApexManager.markStagedSessionReady(TEST_SESSION_ID)); } -- GitLab From 3257839d747c76a35472016fe4f81ef9d5cf1ad0 Mon Sep 17 00:00:00 2001 From: John Wu Date: Fri, 4 Oct 2024 00:43:21 +0000 Subject: [PATCH 044/447] [Ravenwood] Add runtime Mockito version check To prevent future Ravenwood tests from using an incorrect Mockito version, add this new runtime environment check. Bug: 292141694 Flag: EXEMPT host test change only Test: $ANDROID_BUILD_TOP/frameworks/base/ravenwood/scripts/run-ravenwood-tests.sh Change-Id: I52303e744465c26721baaba85aded907af2a06eb --- ...RavenwoodRuntimeEnvironmentController.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java index 805b0c161cb3..4ae5bd1f7b71 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java @@ -21,6 +21,8 @@ import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOUR import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING; import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERSION_JAVA_SYSPROP; +import static org.junit.Assert.assertThrows; + import android.app.ActivityManager; import android.app.Instrumentation; import android.app.ResourcesManager; @@ -167,6 +169,8 @@ public class RavenwoodRuntimeEnvironmentController { // This will let AndroidJUnit4 use the original runner. System.setProperty("android.junit.runner", "androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner"); + + assertMockitoVersion(); } /** @@ -381,6 +385,28 @@ public class RavenwoodRuntimeEnvironmentController { } } + private static final String MOCKITO_ERROR = "FATAL: Unsupported Mockito detected!" + + " Your test or its dependencies use one of the \"mockito-target-*\"" + + " modules as static library, which is unusable on host side." + + " Please switch over to use \"mockito-ravenwood-prebuilt\" as shared library, or" + + " as a last resort, set `ravenizer: { strip_mockito: true }` in your test module."; + + /** + * Assert the Mockito version at runtime to ensure no incorrect Mockito classes are loaded. + */ + private static void assertMockitoVersion() { + // DexMaker should not exist + assertThrows( + MOCKITO_ERROR, + ClassNotFoundException.class, + () -> Class.forName("com.android.dx.DexMaker")); + // Mockito 2 should not exist + assertThrows( + MOCKITO_ERROR, + ClassNotFoundException.class, + () -> Class.forName("org.mockito.Matchers")); + } + @SuppressWarnings("unused") // Called from native code (ravenwood_sysprop.cpp) private static void checkSystemPropertyAccess(String key, boolean write) { boolean result = write ? sProps.isKeyWritable(key) : sProps.isKeyReadable(key); -- GitLab From 60d2dfc6ef6f9aa36ca505cd904e32506c94aa8e Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Fri, 4 Oct 2024 17:18:32 +0900 Subject: [PATCH 045/447] Update the impl of wghtOverride and italOverride The wghtOverride and italOverride are not used in the redesigned variation settings. These values are stored in the variation settings instead. To keep the existing behavior, find the value from variation settings and return it. Bug: 361260253 Test: minikin_tests Flag: com.android.text.flags.typeface_redesign Change-Id: I2fc987ea3db14cf62d5aa807f428d19f3892cbfa --- libs/hwui/jni/text/TextShaper.cpp | 35 +++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/libs/hwui/jni/text/TextShaper.cpp b/libs/hwui/jni/text/TextShaper.cpp index 6c05346d26da..456338631ae4 100644 --- a/libs/hwui/jni/text/TextShaper.cpp +++ b/libs/hwui/jni/text/TextShaper.cpp @@ -156,16 +156,47 @@ static jboolean TextShaper_Result_getFakeItalic(CRITICAL_JNI_PARAMS_COMMA jlong return layout->layout.getFakery(i).isFakeItalic(); } +float findValueFromVariationSettings(const minikin::FontFakery& fakery, minikin::AxisTag tag) { + for (const minikin::FontVariation& fv : fakery.variationSettings()) { + if (fv.axisTag == tag) { + return fv.value; + } + } + return std::numeric_limits::quiet_NaN(); +} + // CriticalNative static jfloat TextShaper_Result_getWeightOverride(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) { const LayoutWrapper* layout = reinterpret_cast(ptr); - return layout->layout.getFakery(i).wghtAdjustment(); + if (text_feature::typeface_redesign()) { + float value = + findValueFromVariationSettings(layout->layout.getFakery(i), minikin::TAG_wght); + if (!std::isnan(value)) { + return value; + } else { + const std::shared_ptr& font = layout->layout.getFontRef(i); + return font->style().weight(); + } + } else { + return layout->layout.getFakery(i).wghtAdjustment(); + } } // CriticalNative static jfloat TextShaper_Result_getItalicOverride(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) { const LayoutWrapper* layout = reinterpret_cast(ptr); - return layout->layout.getFakery(i).italAdjustment(); + if (text_feature::typeface_redesign()) { + float value = + findValueFromVariationSettings(layout->layout.getFakery(i), minikin::TAG_ital); + if (!std::isnan(value)) { + return value; + } else { + const std::shared_ptr& font = layout->layout.getFontRef(i); + return font->style().isItalic(); + } + } else { + return layout->layout.getFakery(i).italAdjustment(); + } } // CriticalNative -- GitLab From 1f22de8f08259291cc6e4beff5446f125f764793 Mon Sep 17 00:00:00 2001 From: Ivo Kay Date: Thu, 22 Aug 2024 12:42:43 +0000 Subject: [PATCH 046/447] Declare flag accumulate_network_stats_since_boot Bug: 352537247 Test: m Flag: com.android.server.stats.accumulate_network_stats_since_boot Change-Id: I81cc2cfca8d438ca485b290ebb7cd90c45a9c749 --- .../java/com/android/server/stats/stats_flags.aconfig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/services/core/java/com/android/server/stats/stats_flags.aconfig b/services/core/java/com/android/server/stats/stats_flags.aconfig index afea3038bcbb..8686458ff8d4 100644 --- a/services/core/java/com/android/server/stats/stats_flags.aconfig +++ b/services/core/java/com/android/server/stats/stats_flags.aconfig @@ -30,3 +30,11 @@ flag { bug: "352495181" is_fixed_read_only: true } + +flag { + name: "accumulate_network_stats_since_boot" + namespace: "statsd" + description: "Accumulate results of NetworkStats queries to avoid hitting NetworkStats persistence limit" + bug: "352537247" + is_fixed_read_only: true +} -- GitLab From 78d1ad2c157f1859864b5c7520511178ce51cdbb Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Mon, 30 Sep 2024 07:06:20 +0000 Subject: [PATCH 047/447] Do not delete task snapshot files when user stopped. While pause a user, the tasks of the user will be removed from recents. But there should just release memory vs delete snapshot files when unloadUserDataFromMemoryLocked called. So the snapshot can be reload from disk when user unlocked again. Bug: 366374788 Flag: EXEMPT bugfix Test: turn off device while some tasks of second user are exist, turn on device, verify those tasks of second user shown on recents. Stop second user without launch any task, verify no tasks of second user shown on recents. Enable second user again, verify those tasks can shown on recents. Test: atest RecentTasksTest Test: follow issue description. Change-Id: I9a98339eaf6bd1a171aced598f61396eea7f8af2 --- .../com/android/server/wm/RecentTasks.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index bf623b2e2105..3f0718f56ef4 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -551,6 +551,12 @@ class RecentTasks { long currentElapsedTime = SystemClock.elapsedRealtime(); for (int i = 0; i < tasks.size(); i++) { Task task = tasks.get(i); + // Remove the task restored from xml if any existing tasks match. + if (findRemoveIndexForAddTask(task) >= 0) { + tasks.remove(i); + i--; + continue; + } task.lastActiveTime = currentElapsedTime - i; } @@ -561,6 +567,7 @@ class RecentTasks { if (existedTaskIds.size() > 0) { syncPersistentTaskIdsLocked(); } + mTaskNotificationController.notifyTaskListUpdated(); } private boolean isRecentTasksLoaded(int userId) { @@ -679,27 +686,35 @@ class RecentTasks { if (isRecentTasksLoaded(userId)) { Slog.i(TAG, "Unloading recents for user " + userId + " from memory."); mUsersWithRecentsLoaded.delete(userId); - removeTasksForUserLocked(userId); + removeTasksForUserFromMemoryLocked(userId); } mPersistedTaskIds.delete(userId); mTaskPersister.unloadUserDataFromMemory(userId); } /** Remove recent tasks for a user. */ - private void removeTasksForUserLocked(int userId) { + private void removeTasksForUserFromMemoryLocked(int userId) { if (userId <= 0) { Slog.i(TAG, "Can't remove recent task on user " + userId); return; } + boolean notifyTaskUpdated = false; for (int i = mTasks.size() - 1; i >= 0; --i) { Task task = mTasks.get(i); if (task.mUserId == userId) { ProtoLog.i(WM_DEBUG_TASKS, "remove RecentTask %s when finishing user " + "%d", task, userId); - remove(task); + mTasks.remove(task); + mService.mWindowManager.mSnapshotController.mTaskSnapshotController + .removeSnapshotCache(task.mTaskId); + // Only notify if list has changed. + notifyTaskUpdated = true; } } + if (notifyTaskUpdated) { + mTaskNotificationController.notifyTaskListUpdated(); + } } void onPackagesSuspendedChanged(String[] packages, boolean suspended, int userId) { -- GitLab From d24ae5991d0dfe0fca7e67c890e8c5a9dd32f942 Mon Sep 17 00:00:00 2001 From: Utkarsh Nigam Date: Fri, 4 Oct 2024 09:56:29 +0000 Subject: [PATCH 048/447] Add calling package onExecuteAppFunction Flag: android.app.appfunctions.flags.enable_app_function_manager Test: cts Bug: 357551503 Change-Id: I54440175a5c327d0af4b3605904064c080dd76ff --- core/api/current.txt | 3 +- .../app/appfunctions/AppFunctionService.java | 54 +++++++++++++++---- .../app/appfunctions/IAppFunctionService.aidl | 2 + libs/appfunctions/api/current.txt | 3 +- .../sidecar/AppFunctionService.java | 50 +++++++++++++++-- .../sidecar/ExecuteAppFunctionResponse.java | 13 ++--- .../AppFunctionManagerServiceImpl.java | 2 +- .../RunAppFunctionServiceCallback.java | 22 ++------ 8 files changed, 108 insertions(+), 41 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 4f913613cfd5..8478b409b12a 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -8788,7 +8788,8 @@ package android.app.appfunctions { ctor public AppFunctionService(); method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent); method @Deprecated @MainThread public void onExecuteFunction(@NonNull android.app.appfunctions.ExecuteAppFunctionRequest, @NonNull java.util.function.Consumer); - method @MainThread public void onExecuteFunction(@NonNull android.app.appfunctions.ExecuteAppFunctionRequest, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer); + method @Deprecated @MainThread public void onExecuteFunction(@NonNull android.app.appfunctions.ExecuteAppFunctionRequest, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer); + method @MainThread public void onExecuteFunction(@NonNull android.app.appfunctions.ExecuteAppFunctionRequest, @NonNull String, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer); field @NonNull public static final String SERVICE_INTERFACE = "android.app.appfunctions.AppFunctionService"; } diff --git a/core/java/android/app/appfunctions/AppFunctionService.java b/core/java/android/app/appfunctions/AppFunctionService.java index 7a68a656564b..ceca850a1037 100644 --- a/core/java/android/app/appfunctions/AppFunctionService.java +++ b/core/java/android/app/appfunctions/AppFunctionService.java @@ -29,11 +29,9 @@ import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Binder; -import android.os.Bundle; +import android.os.CancellationSignal; import android.os.IBinder; import android.os.ICancellationSignal; -import android.os.CancellationSignal; -import android.os.RemoteCallback; import android.os.RemoteException; import android.util.Log; @@ -80,6 +78,7 @@ public abstract class AppFunctionService extends Service { */ void perform( @NonNull ExecuteAppFunctionRequest request, + @NonNull String callingPackage, @NonNull CancellationSignal cancellationSignal, @NonNull Consumer callback); } @@ -92,6 +91,7 @@ public abstract class AppFunctionService extends Service { @Override public void executeAppFunction( @NonNull ExecuteAppFunctionRequest request, + @NonNull String callingPackage, @NonNull ICancellationCallback cancellationCallback, @NonNull IExecuteAppFunctionCallback callback) { if (context.checkCallingPermission(BIND_APP_FUNCTION_SERVICE) @@ -103,6 +103,7 @@ public abstract class AppFunctionService extends Service { try { onExecuteFunction.perform( request, + callingPackage, buildCancellationSignal(cancellationCallback), safeCallback::onResult); } catch (Exception ex) { @@ -128,12 +129,11 @@ public abstract class AppFunctionService extends Service { throw e.rethrowFromSystemServer(); } - return cancellationSignal ; + return cancellationSignal; } - private final Binder mBinder = createBinder( - AppFunctionService.this, - AppFunctionService.this::onExecuteFunction); + private final Binder mBinder = + createBinder(AppFunctionService.this, AppFunctionService.this::onExecuteFunction); @NonNull @Override @@ -141,7 +141,6 @@ public abstract class AppFunctionService extends Service { return mBinder; } - /** * Called by the system to execute a specific app function. * @@ -161,7 +160,6 @@ public abstract class AppFunctionService extends Service { * * @param request The function execution request. * @param callback A callback to report back the result. - * * @deprecated Use {@link #onExecuteFunction(ExecuteAppFunctionRequest, CancellationSignal, * Consumer)} instead. This method will be removed once usage references are updated. */ @@ -198,12 +196,50 @@ public abstract class AppFunctionService extends Service { * @param request The function execution request. * @param cancellationSignal A signal to cancel the execution. * @param callback A callback to report back the result. + * @deprecated Use {@link #onExecuteFunction(ExecuteAppFunctionRequest, String, + * CancellationSignal, Consumer)} instead. This method will be removed once usage references + * are updated. */ @MainThread + @Deprecated public void onExecuteFunction( @NonNull ExecuteAppFunctionRequest request, @NonNull CancellationSignal cancellationSignal, @NonNull Consumer callback) { onExecuteFunction(request, callback); } + + /** + * Called by the system to execute a specific app function. + * + *

    This method is triggered when the system requests your AppFunctionService to handle a + * particular function you have registered and made available. + * + *

    To ensure proper routing of function requests, assign a unique identifier to each + * function. This identifier doesn't need to be globally unique, but it must be unique within + * your app. For example, a function to order food could be identified as "orderFood". In most + * cases this identifier should come from the ID automatically generated by the AppFunctions + * SDK. You can determine the specific function to invoke by calling {@link + * ExecuteAppFunctionRequest#getFunctionIdentifier()}. + * + *

    This method is always triggered in the main thread. You should run heavy tasks on a worker + * thread and dispatch the result with the given callback. You should always report back the + * result using the callback, no matter if the execution was successful or not. + * + *

    This method also accepts a {@link CancellationSignal} that the app should listen to cancel + * the execution of function if requested by the system. + * + * @param request The function execution request. + * @param callingPackage The package name of the app that is requesting the execution. + * @param cancellationSignal A signal to cancel the execution. + * @param callback A callback to report back the result. + */ + @MainThread + public void onExecuteFunction( + @NonNull ExecuteAppFunctionRequest request, + @NonNull String callingPackage, + @NonNull CancellationSignal cancellationSignal, + @NonNull Consumer callback) { + onExecuteFunction(request, cancellationSignal, callback); + } } diff --git a/core/java/android/app/appfunctions/IAppFunctionService.aidl b/core/java/android/app/appfunctions/IAppFunctionService.aidl index 291f33ccb1b8..bf935d2a102b 100644 --- a/core/java/android/app/appfunctions/IAppFunctionService.aidl +++ b/core/java/android/app/appfunctions/IAppFunctionService.aidl @@ -34,11 +34,13 @@ oneway interface IAppFunctionService { * Called by the system to execute a specific app function. * * @param request the function execution request. + * @param callingPackage The package name of the app that is requesting the execution. * @param cancellationCallback a callback to send back the cancellation transport. * @param callback a callback to report back the result. */ void executeAppFunction( in ExecuteAppFunctionRequest request, + in String callingPackage, in ICancellationCallback cancellationCallback, in IExecuteAppFunctionCallback callback ); diff --git a/libs/appfunctions/api/current.txt b/libs/appfunctions/api/current.txt index bc269fedddfe..e9845c1d9f13 100644 --- a/libs/appfunctions/api/current.txt +++ b/libs/appfunctions/api/current.txt @@ -15,7 +15,8 @@ package com.google.android.appfunctions.sidecar { public abstract class AppFunctionService extends android.app.Service { ctor public AppFunctionService(); method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent); - method @MainThread public void onExecuteFunction(@NonNull com.google.android.appfunctions.sidecar.ExecuteAppFunctionRequest, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer); + method @MainThread public void onExecuteFunction(@NonNull com.google.android.appfunctions.sidecar.ExecuteAppFunctionRequest, @NonNull String, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer); + method @Deprecated @MainThread public void onExecuteFunction(@NonNull com.google.android.appfunctions.sidecar.ExecuteAppFunctionRequest, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer); method @Deprecated @MainThread public void onExecuteFunction(@NonNull com.google.android.appfunctions.sidecar.ExecuteAppFunctionRequest, @NonNull java.util.function.Consumer); field @NonNull public static final String BIND_APP_FUNCTION_SERVICE = "android.permission.BIND_APP_FUNCTION_SERVICE"; field @NonNull public static final String SERVICE_INTERFACE = "android.app.appfunctions.AppFunctionService"; diff --git a/libs/appfunctions/java/com/google/android/appfunctions/sidecar/AppFunctionService.java b/libs/appfunctions/java/com/google/android/appfunctions/sidecar/AppFunctionService.java index 6e91de6bbcf2..2a168e871713 100644 --- a/libs/appfunctions/java/com/google/android/appfunctions/sidecar/AppFunctionService.java +++ b/libs/appfunctions/java/com/google/android/appfunctions/sidecar/AppFunctionService.java @@ -24,8 +24,8 @@ import android.annotation.Nullable; import android.app.Service; import android.content.Intent; import android.os.Binder; -import android.os.IBinder; import android.os.CancellationSignal; +import android.os.IBinder; import android.util.Log; import java.util.function.Consumer; @@ -71,18 +71,21 @@ public abstract class AppFunctionService extends Service { private final Binder mBinder = android.app.appfunctions.AppFunctionService.createBinder( /* context= */ this, - /* onExecuteFunction= */ (platformRequest, cancellationSignal, callback) -> { + /* onExecuteFunction= */ (platformRequest, + callingPackage, + cancellationSignal, + callback) -> { AppFunctionService.this.onExecuteFunction( SidecarConverter.getSidecarExecuteAppFunctionRequest( platformRequest), + callingPackage, cancellationSignal, (sidecarResponse) -> { callback.accept( SidecarConverter.getPlatformExecuteAppFunctionResponse( sidecarResponse)); }); - } - ); + }); @NonNull @Override @@ -90,6 +93,40 @@ public abstract class AppFunctionService extends Service { return mBinder; } + /** + * Called by the system to execute a specific app function. + * + *

    This method is triggered when the system requests your AppFunctionService to handle a + * particular function you have registered and made available. + * + *

    To ensure proper routing of function requests, assign a unique identifier to each + * function. This identifier doesn't need to be globally unique, but it must be unique within + * your app. For example, a function to order food could be identified as "orderFood". In most + * cases this identifier should come from the ID automatically generated by the AppFunctions + * SDK. You can determine the specific function to invoke by calling {@link + * ExecuteAppFunctionRequest#getFunctionIdentifier()}. + * + *

    This method is always triggered in the main thread. You should run heavy tasks on a worker + * thread and dispatch the result with the given callback. You should always report back the + * result using the callback, no matter if the execution was successful or not. + * + *

    This method also accepts a {@link CancellationSignal} that the app should listen to cancel + * the execution of function if requested by the system. + * + * @param request The function execution request. + * @param callingPackage The package name of the app that is requesting the execution. + * @param cancellationSignal A signal to cancel the execution. + * @param callback A callback to report back the result. + */ + @MainThread + public void onExecuteFunction( + @NonNull ExecuteAppFunctionRequest request, + @NonNull String callingPackage, + @NonNull CancellationSignal cancellationSignal, + @NonNull Consumer callback) { + onExecuteFunction(request, cancellationSignal, callback); + } + /** * Called by the system to execute a specific app function. * @@ -110,8 +147,12 @@ public abstract class AppFunctionService extends Service { * @param request The function execution request. * @param cancellationSignal A {@link CancellationSignal} to cancel the request. * @param callback A callback to report back the result. + * @deprecated Use {@link #onExecuteFunction(ExecuteAppFunctionRequest, String, + * CancellationSignal, Consumer)} instead. This method will be removed once usage references + * are updated. */ @MainThread + @Deprecated public void onExecuteFunction( @NonNull ExecuteAppFunctionRequest request, @NonNull CancellationSignal cancellationSignal, @@ -138,7 +179,6 @@ public abstract class AppFunctionService extends Service { * * @param request The function execution request. * @param callback A callback to report back the result. - * * @deprecated Use {@link #onExecuteFunction(ExecuteAppFunctionRequest, CancellationSignal, * Consumer)} instead. This method will be removed once usage references are updated. */ diff --git a/libs/appfunctions/java/com/google/android/appfunctions/sidecar/ExecuteAppFunctionResponse.java b/libs/appfunctions/java/com/google/android/appfunctions/sidecar/ExecuteAppFunctionResponse.java index d87fec7985e9..969e5d58b909 100644 --- a/libs/appfunctions/java/com/google/android/appfunctions/sidecar/ExecuteAppFunctionResponse.java +++ b/libs/appfunctions/java/com/google/android/appfunctions/sidecar/ExecuteAppFunctionResponse.java @@ -234,12 +234,13 @@ public final class ExecuteAppFunctionResponse { @IntDef( prefix = {"RESULT_"}, value = { - RESULT_OK, - RESULT_DENIED, - RESULT_APP_UNKNOWN_ERROR, - RESULT_INTERNAL_ERROR, - RESULT_INVALID_ARGUMENT, - RESULT_DISABLED + RESULT_OK, + RESULT_DENIED, + RESULT_APP_UNKNOWN_ERROR, + RESULT_INTERNAL_ERROR, + RESULT_INVALID_ARGUMENT, + RESULT_DISABLED, + RESULT_CANCELLED }) @Retention(RetentionPolicy.SOURCE) public @interface ResultCode {} diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java index d0c3dafd6e81..853399b79342 100644 --- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java @@ -438,7 +438,7 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { targetUser, mServiceConfig.getExecuteAppFunctionCancellationTimeoutMillis(), cancellationSignal, - RunAppFunctionServiceCallback.create( + new RunAppFunctionServiceCallback( requestInternal, cancellationCallback, safeExecuteAppFunctionCallback), diff --git a/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java b/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java index 7820390dd544..129be65f3153 100644 --- a/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java +++ b/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java @@ -27,17 +27,17 @@ import android.util.Slog; import com.android.server.appfunctions.RemoteServiceCaller.RunServiceCallCallback; import com.android.server.appfunctions.RemoteServiceCaller.ServiceUsageCompleteListener; - /** * A callback to forward a request to the {@link IAppFunctionService} and report back the result. */ public class RunAppFunctionServiceCallback implements RunServiceCallCallback { + private static final String TAG = RunAppFunctionServiceCallback.class.getSimpleName(); private final ExecuteAppFunctionAidlRequest mRequestInternal; private final SafeOneTimeExecuteAppFunctionCallback mSafeExecuteAppFunctionCallback; private final ICancellationCallback mCancellationCallback; - private RunAppFunctionServiceCallback( + public RunAppFunctionServiceCallback( ExecuteAppFunctionAidlRequest requestInternal, ICancellationCallback cancellationCallback, SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback) { @@ -46,21 +46,6 @@ public class RunAppFunctionServiceCallback implements RunServiceCallCallback Date: Fri, 4 Oct 2024 10:11:39 +0000 Subject: [PATCH 049/447] AudioService: fix BT SCO audio starting from system server When a request to use Bluetooth SCO for calls comes from the system UID, it means this request is from Telecom package and should not trigger calls to startScoUsingVirtualVoiceCall(). Flag: EXEMPT bug fix Test: repor steps in bug Bug: 366363233 Change-Id: I0c7a71fe2b24b3cf995f02f53d15836e3f2974eb --- .../core/java/com/android/server/audio/AudioDeviceBroker.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index 0475b94c784a..60dbf3f21587 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -389,7 +389,8 @@ public class AudioDeviceBroker { */ private boolean shouldStartScoForUid(int uid) { return !(UserHandle.isSameApp(uid, Process.BLUETOOTH_UID) - || UserHandle.isSameApp(uid, Process.PHONE_UID)); + || UserHandle.isSameApp(uid, Process.PHONE_UID) + || UserHandle.isSameApp(uid, Process.SYSTEM_UID)); } @GuardedBy("mDeviceStateLock") -- GitLab From 13d2169decf85b16412e3deb4a654eacdbda4564 Mon Sep 17 00:00:00 2001 From: Pablo Gamito Date: Wed, 11 Sep 2024 12:54:21 +0000 Subject: [PATCH 050/447] Move ProtoLog tests to seperate test directory dedicated to tracing tests Bug: 371483999 Bug: 364255103 Flag: TEST_ONLY Test: atest TracingTests Merged-In: I1f53100c03e71647746d2214f1bf23ec30ec3129 Change-Id: I1f53100c03e71647746d2214f1bf23ec30ec3129 --- tests/Tracing/Android.bp | 33 +++++++++++++++ tests/Tracing/AndroidManifest.xml | 33 +++++++++++++++ tests/Tracing/AndroidTest.xml | 40 +++++++++++++++++++ .../internal/protolog => Tracing}/OWNERS | 2 +- tests/Tracing/TEST_MAPPING | 7 ++++ .../res/xml/network_security_config.xml | 21 ++++++++++ .../protolog/LegacyProtoLogImplTest.java | 1 - ...LegacyProtoLogViewerConfigReaderTest.java} | 2 +- .../protolog/PerfettoProtoLogImplTest.java | 0 .../internal/protolog/ProtoLogImplTest.java | 0 .../protolog/ProtologDataSourceTest.java | 0 .../protolog/common/LogDataTypeTest.java | 0 12 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 tests/Tracing/Android.bp create mode 100644 tests/Tracing/AndroidManifest.xml create mode 100644 tests/Tracing/AndroidTest.xml rename tests/{Internal/src/com/android/internal/protolog => Tracing}/OWNERS (81%) create mode 100644 tests/Tracing/TEST_MAPPING create mode 100644 tests/Tracing/res/xml/network_security_config.xml rename tests/{Internal => Tracing}/src/com/android/internal/protolog/LegacyProtoLogImplTest.java (99%) rename tests/{Internal/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java => Tracing/src/com/android/internal/protolog/LegacyProtoLogViewerConfigReaderTest.java} (98%) rename tests/{Internal => Tracing}/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java (100%) rename tests/{Internal => Tracing}/src/com/android/internal/protolog/ProtoLogImplTest.java (100%) rename tests/{Internal => Tracing}/src/com/android/internal/protolog/ProtologDataSourceTest.java (100%) rename tests/{Internal => Tracing}/src/com/android/internal/protolog/common/LogDataTypeTest.java (100%) diff --git a/tests/Tracing/Android.bp b/tests/Tracing/Android.bp new file mode 100644 index 000000000000..f5c1ae57e8c2 --- /dev/null +++ b/tests/Tracing/Android.bp @@ -0,0 +1,33 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_team: "trendy_team_windowing_tools", + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test { + name: "TracingTests", + proto: { + type: "nano", + }, + // Include some source files directly to be able to access package members + srcs: ["src/**/*.java"], + libs: ["android.test.runner.impl"], + static_libs: [ + "junit", + "androidx.test.rules", + "mockito-target-minus-junit4", + "truth", + "platform-test-annotations", + "flickerlib-parsers", + "perfetto_trace_java_protos", + "flickerlib-trace_processor_shell", + ], + java_resource_dirs: ["res"], + certificate: "platform", + platform_apis: true, + test_suites: ["device-tests"], +} diff --git a/tests/Tracing/AndroidManifest.xml b/tests/Tracing/AndroidManifest.xml new file mode 100644 index 000000000000..7254f81307ad --- /dev/null +++ b/tests/Tracing/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/tests/Tracing/AndroidTest.xml b/tests/Tracing/AndroidTest.xml new file mode 100644 index 000000000000..9a404203ee18 --- /dev/null +++ b/tests/Tracing/AndroidTest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + \ No newline at end of file diff --git a/tests/Internal/src/com/android/internal/protolog/OWNERS b/tests/Tracing/OWNERS similarity index 81% rename from tests/Internal/src/com/android/internal/protolog/OWNERS rename to tests/Tracing/OWNERS index 18cf2be9f7df..4a5033800b8e 100644 --- a/tests/Internal/src/com/android/internal/protolog/OWNERS +++ b/tests/Tracing/OWNERS @@ -1,3 +1,3 @@ -# ProtoLog owners +# Tracing owners # Bug component: 1157642 include platform/development:/tools/winscope/OWNERS diff --git a/tests/Tracing/TEST_MAPPING b/tests/Tracing/TEST_MAPPING new file mode 100644 index 000000000000..7f58fceee24d --- /dev/null +++ b/tests/Tracing/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "postsubmit": [ + { + "name": "TracingTests" + } + ] +} \ No newline at end of file diff --git a/tests/Tracing/res/xml/network_security_config.xml b/tests/Tracing/res/xml/network_security_config.xml new file mode 100644 index 000000000000..fdf1dbbe7672 --- /dev/null +++ b/tests/Tracing/res/xml/network_security_config.xml @@ -0,0 +1,21 @@ + + + + + localhost + + diff --git a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java b/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java similarity index 99% rename from tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java rename to tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java index 5a27593c7a36..e9ff691151fe 100644 --- a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java +++ b/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java @@ -181,7 +181,6 @@ public class LegacyProtoLogImplTest { verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq( LogLevel.INFO), eq("test 5")); - verify(mReader, never()).getViewerString(anyLong()); } @Test diff --git a/tests/Internal/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java b/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogViewerConfigReaderTest.java similarity index 98% rename from tests/Internal/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java rename to tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogViewerConfigReaderTest.java index dbd85d38b7f2..253965337824 100644 --- a/tests/Internal/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java +++ b/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogViewerConfigReaderTest.java @@ -38,7 +38,7 @@ import java.util.zip.GZIPOutputStream; @SmallTest @Presubmit @RunWith(JUnit4.class) -public class ProtoLogViewerConfigReaderTest { +public class LegacyProtoLogViewerConfigReaderTest { private static final String TEST_VIEWER_CONFIG = "{\n" + " \"version\": \"1.0.0\",\n" + " \"messages\": {\n" diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java b/tests/Tracing/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java similarity index 100% rename from tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java rename to tests/Tracing/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java diff --git a/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java b/tests/Tracing/src/com/android/internal/protolog/ProtoLogImplTest.java similarity index 100% rename from tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java rename to tests/Tracing/src/com/android/internal/protolog/ProtoLogImplTest.java diff --git a/tests/Internal/src/com/android/internal/protolog/ProtologDataSourceTest.java b/tests/Tracing/src/com/android/internal/protolog/ProtologDataSourceTest.java similarity index 100% rename from tests/Internal/src/com/android/internal/protolog/ProtologDataSourceTest.java rename to tests/Tracing/src/com/android/internal/protolog/ProtologDataSourceTest.java diff --git a/tests/Internal/src/com/android/internal/protolog/common/LogDataTypeTest.java b/tests/Tracing/src/com/android/internal/protolog/common/LogDataTypeTest.java similarity index 100% rename from tests/Internal/src/com/android/internal/protolog/common/LogDataTypeTest.java rename to tests/Tracing/src/com/android/internal/protolog/common/LogDataTypeTest.java -- GitLab From 04a358e0836818274b4cb868cabe45d049c2a282 Mon Sep 17 00:00:00 2001 From: Jordan Demeulenaere Date: Fri, 4 Oct 2024 14:33:31 +0200 Subject: [PATCH 051/447] Reapply "Don't install a pointer input when there are no user actions" This is a reland of ag/29669127, which was broken (and reverted in ag/29690066) because SwipeToSceneNode was not properly handling the update of its draggableHandler. This reland fixes the issue by introducing a SwipeToSceneRootNode, which recreates a new delegate node whenever draggableHandler has changed. This approach was suggested by the Compose team in http://shortn/_MUgPp4TRmY. A test covering this case was added in SwipeToSceneTest.swipeToSceneSupportsUpdates(). Bug: 370913106 Test: atest SwipeToSceneTest Flag: com.android.systemui.scene_container Change-Id: Ifc1b88a813b6de153028db64aac6cd1103c94a66 --- .../animation/scene/MultiPointerDraggable.kt | 38 +-------- .../compose/animation/scene/SwipeToScene.kt | 85 +++++++++++-------- .../scene/MultiPointerDraggableTest.kt | 36 ++++---- .../animation/scene/SwipeToSceneTest.kt | 67 +++++++++++++++ 4 files changed, 135 insertions(+), 91 deletions(-) diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt index dc3135ddbf54..aa70a0ce156b 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt @@ -42,10 +42,8 @@ import androidx.compose.ui.input.pointer.util.addPointerInputChange import androidx.compose.ui.node.CompositionLocalConsumerModifierNode import androidx.compose.ui.node.DelegatingNode import androidx.compose.ui.node.ModifierNodeElement -import androidx.compose.ui.node.ObserverModifierNode import androidx.compose.ui.node.PointerInputModifierNode import androidx.compose.ui.node.currentValueOf -import androidx.compose.ui.node.observeReads import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.Velocity @@ -79,7 +77,6 @@ import kotlinx.coroutines.launch @Stable internal fun Modifier.multiPointerDraggable( orientation: Orientation, - enabled: () -> Boolean, startDragImmediately: (startedPosition: Offset) -> Boolean, onDragStarted: (startedPosition: Offset, overSlop: Float, pointersDown: Int) -> DragController, onFirstPointerDown: () -> Unit = {}, @@ -89,7 +86,6 @@ internal fun Modifier.multiPointerDraggable( this.then( MultiPointerDraggableElement( orientation, - enabled, startDragImmediately, onDragStarted, onFirstPointerDown, @@ -100,7 +96,6 @@ internal fun Modifier.multiPointerDraggable( private data class MultiPointerDraggableElement( private val orientation: Orientation, - private val enabled: () -> Boolean, private val startDragImmediately: (startedPosition: Offset) -> Boolean, private val onDragStarted: (startedPosition: Offset, overSlop: Float, pointersDown: Int) -> DragController, @@ -111,7 +106,6 @@ private data class MultiPointerDraggableElement( override fun create(): MultiPointerDraggableNode = MultiPointerDraggableNode( orientation = orientation, - enabled = enabled, startDragImmediately = startDragImmediately, onDragStarted = onDragStarted, onFirstPointerDown = onFirstPointerDown, @@ -121,7 +115,6 @@ private data class MultiPointerDraggableElement( override fun update(node: MultiPointerDraggableNode) { node.orientation = orientation - node.enabled = enabled node.startDragImmediately = startDragImmediately node.onDragStarted = onDragStarted node.onFirstPointerDown = onFirstPointerDown @@ -131,27 +124,23 @@ private data class MultiPointerDraggableElement( internal class MultiPointerDraggableNode( orientation: Orientation, - enabled: () -> Boolean, var startDragImmediately: (startedPosition: Offset) -> Boolean, var onDragStarted: (startedPosition: Offset, overSlop: Float, pointersDown: Int) -> DragController, var onFirstPointerDown: () -> Unit, - var swipeDetector: SwipeDetector = DefaultSwipeDetector, + swipeDetector: SwipeDetector = DefaultSwipeDetector, private val dispatcher: NestedScrollDispatcher, ) : DelegatingNode(), PointerInputModifierNode, CompositionLocalConsumerModifierNode, - ObserverModifierNode, SpaceVectorConverter { private val pointerTracker = delegate(SuspendingPointerInputModifierNode { pointerTracker() }) private val pointerInput = delegate(SuspendingPointerInputModifierNode { pointerInput() }) private val velocityTracker = VelocityTracker() - private var previousEnabled: Boolean = false - var enabled: () -> Boolean = enabled + var swipeDetector: SwipeDetector = swipeDetector set(value) { - // Reset the pointer input whenever enabled changed. if (value != field) { field = value pointerInput.resetPointerInputHandler() @@ -178,21 +167,6 @@ internal class MultiPointerDraggableNode( } } - override fun onAttach() { - previousEnabled = enabled() - onObservedReadsChanged() - } - - override fun onObservedReadsChanged() { - observeReads { - val newEnabled = enabled() - if (newEnabled != previousEnabled) { - pointerInput.resetPointerInputHandler() - } - previousEnabled = newEnabled - } - } - override fun onCancelPointerInput() { pointerTracker.onCancelPointerInput() pointerInput.onCancelPointerInput() @@ -254,9 +228,7 @@ internal class MultiPointerDraggableNode( velocityTracker.resetTracking() velocityTracker.addPointerInputChange(firstPointerDown) startedPosition = firstPointerDown.position - if (enabled()) { - onFirstPointerDown() - } + onFirstPointerDown() } // Changes with at least one pointer @@ -295,10 +267,6 @@ internal class MultiPointerDraggableNode( } private suspend fun PointerInputScope.pointerInput() { - if (!enabled()) { - return - } - val currentContext = currentCoroutineContext() awaitPointerEventScope { while (currentContext.isActive) { diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt index 98d4aaa91458..061583a64702 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt @@ -41,30 +41,69 @@ internal fun Modifier.swipeToScene( draggableHandler: DraggableHandlerImpl, swipeDetector: SwipeDetector, ): Modifier { - return this.then(SwipeToSceneElement(draggableHandler, swipeDetector)) + return if (draggableHandler.enabled()) { + this.then(SwipeToSceneElement(draggableHandler, swipeDetector)) + } else { + this + } +} + +private fun DraggableHandlerImpl.enabled(): Boolean { + return isDrivingTransition || contentForSwipes().shouldEnableSwipes(orientation) +} + +private fun DraggableHandlerImpl.contentForSwipes(): Content { + return layoutImpl.contentForUserActions() +} + +/** Whether swipe should be enabled in the given [orientation]. */ +private fun Content.shouldEnableSwipes(orientation: Orientation): Boolean { + if (userActions.isEmpty()) { + return false + } + + return userActions.keys.any { it is Swipe.Resolved && it.direction.orientation == orientation } } private data class SwipeToSceneElement( val draggableHandler: DraggableHandlerImpl, val swipeDetector: SwipeDetector, -) : ModifierNodeElement() { - override fun create(): SwipeToSceneNode = SwipeToSceneNode(draggableHandler, swipeDetector) +) : ModifierNodeElement() { + override fun create(): SwipeToSceneRootNode = + SwipeToSceneRootNode(draggableHandler, swipeDetector) - override fun update(node: SwipeToSceneNode) { - node.draggableHandler = draggableHandler + override fun update(node: SwipeToSceneRootNode) { + node.update(draggableHandler, swipeDetector) } } -private class SwipeToSceneNode( +private class SwipeToSceneRootNode( draggableHandler: DraggableHandlerImpl, swipeDetector: SwipeDetector, +) : DelegatingNode() { + private var delegate = delegate(SwipeToSceneNode(draggableHandler, swipeDetector)) + + fun update(draggableHandler: DraggableHandlerImpl, swipeDetector: SwipeDetector) { + if (draggableHandler == delegate.draggableHandler) { + // Simple update, just update the swipe detector directly and keep the node. + delegate.swipeDetector = swipeDetector + } else { + // The draggableHandler changed, force recreate the underlying SwipeToSceneNode. + undelegate(delegate) + delegate = delegate(SwipeToSceneNode(draggableHandler, swipeDetector)) + } + } +} + +private class SwipeToSceneNode( + val draggableHandler: DraggableHandlerImpl, + swipeDetector: SwipeDetector, ) : DelegatingNode(), PointerInputModifierNode { private val dispatcher = NestedScrollDispatcher() private val multiPointerDraggableNode = delegate( MultiPointerDraggableNode( orientation = draggableHandler.orientation, - enabled = ::enabled, startDragImmediately = ::startDragImmediately, onDragStarted = draggableHandler::onDragStarted, onFirstPointerDown = ::onFirstPointerDown, @@ -73,18 +112,10 @@ private class SwipeToSceneNode( ) ) - private var _draggableHandler = draggableHandler - var draggableHandler: DraggableHandlerImpl - get() = _draggableHandler + var swipeDetector: SwipeDetector + get() = multiPointerDraggableNode.swipeDetector set(value) { - if (_draggableHandler != value) { - _draggableHandler = value - - // Make sure to update the delegate orientation. Note that this will automatically - // reset the underlying pointer input handler, so previous gestures will be - // cancelled. - multiPointerDraggableNode.orientation = value.orientation - } + multiPointerDraggableNode.swipeDetector = value } private val nestedScrollHandlerImpl = @@ -124,22 +155,6 @@ private class SwipeToSceneNode( override fun onCancelPointerInput() = multiPointerDraggableNode.onCancelPointerInput() - private fun enabled(): Boolean { - return draggableHandler.isDrivingTransition || - contentForSwipes().shouldEnableSwipes(multiPointerDraggableNode.orientation) - } - - private fun contentForSwipes(): Content { - return draggableHandler.layoutImpl.contentForUserActions() - } - - /** Whether swipe should be enabled in the given [orientation]. */ - private fun Content.shouldEnableSwipes(orientation: Orientation): Boolean { - return userActions.keys.any { - it is Swipe.Resolved && it.direction.orientation == orientation - } - } - private fun startDragImmediately(startedPosition: Offset): Boolean { // Immediately start the drag if the user can't swipe in the other direction and the gesture // handler can intercept it. @@ -152,7 +167,7 @@ private class SwipeToSceneNode( Orientation.Vertical -> Orientation.Horizontal Orientation.Horizontal -> Orientation.Vertical } - return contentForSwipes().shouldEnableSwipes(oppositeOrientation) + return draggableHandler.contentForSwipes().shouldEnableSwipes(oppositeOrientation) } } diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt index 493f3a1377cc..c8f6e6d99933 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt @@ -45,6 +45,7 @@ import androidx.compose.ui.test.performTouchInput import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Velocity import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.compose.modifiers.thenIf import com.android.compose.nestedscroll.SuspendedValue import com.google.common.truth.Truth.assertThat import kotlin.properties.Delegates @@ -94,19 +95,20 @@ class MultiPointerDraggableTest { Box( Modifier.size(with(LocalDensity.current) { Size(size, size).toDpSize() }) .nestedScrollDispatcher() - .multiPointerDraggable( - orientation = Orientation.Vertical, - enabled = { enabled }, - startDragImmediately = { false }, - onDragStarted = { _, _, _ -> - started = true - SimpleDragController( - onDrag = { dragged = true }, - onStop = { stopped = true }, - ) - }, - dispatcher = defaultDispatcher, - ) + .thenIf(enabled) { + Modifier.multiPointerDraggable( + orientation = Orientation.Vertical, + startDragImmediately = { false }, + onDragStarted = { _, _, _ -> + started = true + SimpleDragController( + onDrag = { dragged = true }, + onStop = { stopped = true }, + ) + }, + dispatcher = defaultDispatcher, + ) + } ) } @@ -164,7 +166,6 @@ class MultiPointerDraggableTest { .nestedScrollDispatcher() .multiPointerDraggable( orientation = Orientation.Vertical, - enabled = { true }, // We want to start a drag gesture immediately startDragImmediately = { true }, onDragStarted = { _, _, _ -> @@ -238,7 +239,6 @@ class MultiPointerDraggableTest { .nestedScrollDispatcher() .multiPointerDraggable( orientation = Orientation.Vertical, - enabled = { true }, startDragImmediately = { false }, onDragStarted = { _, _, _ -> started = true @@ -358,7 +358,6 @@ class MultiPointerDraggableTest { .nestedScrollDispatcher() .multiPointerDraggable( orientation = Orientation.Vertical, - enabled = { true }, startDragImmediately = { false }, onDragStarted = { _, _, _ -> started = true @@ -464,7 +463,6 @@ class MultiPointerDraggableTest { .nestedScrollDispatcher() .multiPointerDraggable( orientation = Orientation.Vertical, - enabled = { true }, startDragImmediately = { false }, onDragStarted = { _, _, _ -> verticalStarted = true @@ -477,7 +475,6 @@ class MultiPointerDraggableTest { ) .multiPointerDraggable( orientation = Orientation.Horizontal, - enabled = { true }, startDragImmediately = { false }, onDragStarted = { _, _, _ -> horizontalStarted = true @@ -570,7 +567,6 @@ class MultiPointerDraggableTest { .nestedScrollDispatcher() .multiPointerDraggable( orientation = Orientation.Vertical, - enabled = { true }, startDragImmediately = { false }, swipeDetector = object : SwipeDetector { @@ -672,7 +668,6 @@ class MultiPointerDraggableTest { .nestedScrollDispatcher() .multiPointerDraggable( orientation = Orientation.Vertical, - enabled = { true }, startDragImmediately = { false }, onDragStarted = { _, _, _ -> SimpleDragController( @@ -744,7 +739,6 @@ class MultiPointerDraggableTest { .nestedScrollDispatcher() .multiPointerDraggable( orientation = Orientation.Vertical, - enabled = { true }, startDragImmediately = { false }, onDragStarted = { _, _, _ -> SimpleDragController( diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt index 25e87132eb0e..28d0a473935d 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt @@ -22,11 +22,15 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.size +import androidx.compose.material3.Button +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollConnection @@ -36,9 +40,14 @@ import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.platform.testTag import androidx.compose.ui.test.assertPositionInRootIsEqualTo +import androidx.compose.ui.test.assertTextEquals import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onRoot +import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performTouchInput +import androidx.compose.ui.test.swipeRight +import androidx.compose.ui.test.swipeUp import androidx.compose.ui.test.swipeWithVelocity import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.IntSize @@ -844,4 +853,62 @@ class SwipeToSceneTest { assertThat(transition.progress).isEqualTo(1f) assertThat(availableOnPostScroll).isEqualTo(ovescrollPx) } + + @Test + fun sceneWithoutSwipesDoesNotConsumeGestures() { + val buttonTag = "button" + + rule.setContent { + Box { + var count by remember { mutableStateOf(0) } + Button(onClick = { count++ }, Modifier.testTag(buttonTag).align(Alignment.Center)) { + Text("Count: $count") + } + + SceneTransitionLayout(remember { MutableSceneTransitionLayoutState(SceneA) }) { + scene(SceneA) { Box(Modifier.fillMaxSize()) } + } + } + } + + rule.onNodeWithTag(buttonTag).assertTextEquals("Count: 0") + + // Click on the root at its center, where the button is located. Clicks should go through + // the STL and reach the button given that there is no swipes for the current scene. + repeat(3) { rule.onRoot().performClick() } + rule.onNodeWithTag(buttonTag).assertTextEquals("Count: 3") + } + + @Test + fun swipeToSceneSupportsUpdates() { + val state = rule.runOnUiThread { MutableSceneTransitionLayoutState(SceneA) } + + rule.setContent { + SceneTransitionLayout(state) { + // SceneA only has vertical actions, so only one vertical Modifier.swipeToScene() + // is composed. + scene(SceneA, mapOf(Swipe.Up to SceneB)) { Box(Modifier.fillMaxSize()) } + + // SceneB only has horizontal actions, so only one vertical Modifier.swipeToScene() + // is composed, which will be force update it with a new draggableHandler. + scene(SceneB, mapOf(Swipe.Right to SceneC)) { Box(Modifier.fillMaxSize()) } + scene(SceneC) { Box(Modifier.fillMaxSize()) } + } + } + + assertThat(state.transitionState).isIdle() + assertThat(state.transitionState).hasCurrentScene(SceneA) + + // Swipe up to scene B. + rule.onRoot().performTouchInput { swipeUp() } + rule.waitForIdle() + assertThat(state.transitionState).isIdle() + assertThat(state.transitionState).hasCurrentScene(SceneB) + + // Swipe right to scene C. + rule.onRoot().performTouchInput { swipeRight() } + rule.waitForIdle() + assertThat(state.transitionState).isIdle() + assertThat(state.transitionState).hasCurrentScene(SceneC) + } } -- GitLab From d3bae4991ebe1b634867b8e0fca89c5a908b8624 Mon Sep 17 00:00:00 2001 From: Anton Potapov Date: Fri, 4 Oct 2024 14:07:56 +0100 Subject: [PATCH 052/447] Bind volume dialog settings button Flag: com.android.systemui.volume_redesign Test: passes presubmits Fixes: 369992665 Change-Id: Ib4a432d13517398706fdd5eeedb73fea9a75c4bb --- .../VolumeDialogVisibilityInteractor.kt | 4 +- .../VolumeDialogSettingsButtonInteractor.kt | 58 +++++++++++++++++++ .../VolumeDialogSettingsButtonViewBinder.kt | 54 +++++++++++++++++ .../VolumeDialogSettingsButtonViewModel.kt | 49 ++++++++++++++++ .../dialog/ui/binder/VolumeDialogBinder.kt | 12 ++-- .../ui/binder/VolumeDialogViewBinder.kt | 4 +- .../viewmodel/VolumeDialogPluginViewModel.kt | 29 +++++----- 7 files changed, 184 insertions(+), 26 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/volume/dialog/settings/domain/VolumeDialogSettingsButtonInteractor.kt create mode 100644 packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/binder/VolumeDialogSettingsButtonViewBinder.kt create mode 100644 packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/viewmodel/VolumeDialogSettingsButtonViewModel.kt diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogVisibilityInteractor.kt index 6c92754b6f60..f7d6d90ef6f0 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogVisibilityInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogVisibilityInteractor.kt @@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.update -private val maxDialogShowTime: Duration = 3.seconds +private val MAX_DIALOG_SHOW_TIME: Duration = 3.seconds /** * Handles Volume Dialog visibility state. It might change from several sources: @@ -65,7 +65,7 @@ constructor( init { merge( mutableDismissDialogEvents.mapLatest { - delay(maxDialogShowTime) + delay(MAX_DIALOG_SHOW_TIME) VolumeDialogEventModel.DismissRequested(Events.DISMISS_REASON_TIMEOUT) }, callbacksInteractor.event, diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/domain/VolumeDialogSettingsButtonInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/domain/VolumeDialogSettingsButtonInteractor.kt new file mode 100644 index 000000000000..db196347d4a9 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/domain/VolumeDialogSettingsButtonInteractor.kt @@ -0,0 +1,58 @@ +/* + * 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.dialog.settings.domain + +import android.app.ActivityManager +import com.android.app.tracing.coroutines.flow.map +import com.android.systemui.statusbar.policy.DeviceProvisionedController +import com.android.systemui.volume.Events +import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog +import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope +import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor +import com.android.systemui.volume.dialog.domain.model.VolumeDialogVisibilityModel +import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractor +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.stateIn + +@VolumeDialogScope +class VolumeDialogSettingsButtonInteractor +@Inject +constructor( + @VolumeDialog private val coroutineScope: CoroutineScope, + private val deviceProvisionedController: DeviceProvisionedController, + private val volumePanelGlobalStateInteractor: VolumePanelGlobalStateInteractor, + private val visibilityInteractor: VolumeDialogVisibilityInteractor, +) { + + val isVisible: StateFlow = + visibilityInteractor.dialogVisibility + .filterIsInstance(VolumeDialogVisibilityModel.Visible::class) + .map { model -> + deviceProvisionedController.isCurrentUserSetup() && + model.lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE + } + .stateIn(coroutineScope, SharingStarted.Eagerly, false) + + fun onButtonClicked() { + volumePanelGlobalStateInteractor.setVisible(true) + visibilityInteractor.dismissDialog(Events.DISMISS_REASON_SETTINGS_CLICKED) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/binder/VolumeDialogSettingsButtonViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/binder/VolumeDialogSettingsButtonViewBinder.kt new file mode 100644 index 000000000000..ba08876609ae --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/binder/VolumeDialogSettingsButtonViewBinder.kt @@ -0,0 +1,54 @@ +/* + * 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.dialog.settings.ui.binder + +import android.view.View +import com.android.systemui.lifecycle.WindowLifecycleState +import com.android.systemui.lifecycle.repeatWhenAttached +import com.android.systemui.lifecycle.setSnapshotBinding +import com.android.systemui.lifecycle.viewModel +import com.android.systemui.res.R +import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope +import com.android.systemui.volume.dialog.settings.ui.viewmodel.VolumeDialogSettingsButtonViewModel +import javax.inject.Inject +import kotlinx.coroutines.awaitCancellation + +@VolumeDialogScope +class VolumeDialogSettingsButtonViewBinder +@Inject +constructor(private val viewModelFactory: VolumeDialogSettingsButtonViewModel.Factory) { + + fun bind(view: View) { + with(view) { + val button = requireViewById(R.id.settings) + repeatWhenAttached { + viewModel( + traceName = "VolumeDialogViewBinder", + minWindowLifecycleState = WindowLifecycleState.ATTACHED, + factory = { viewModelFactory.create() }, + ) { viewModel -> + setSnapshotBinding { + visibility = if (viewModel.isVisible) View.VISIBLE else View.GONE + button.setOnClickListener { viewModel.onButtonClicked() } + } + + awaitCancellation() + } + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/viewmodel/VolumeDialogSettingsButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/viewmodel/VolumeDialogSettingsButtonViewModel.kt new file mode 100644 index 000000000000..2acc33b79656 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/viewmodel/VolumeDialogSettingsButtonViewModel.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.dialog.settings.ui.viewmodel + +import androidx.compose.runtime.getValue +import com.android.systemui.lifecycle.ExclusiveActivatable +import com.android.systemui.lifecycle.Hydrator +import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope +import com.android.systemui.volume.dialog.settings.domain.VolumeDialogSettingsButtonInteractor +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject + +class VolumeDialogSettingsButtonViewModel +@AssistedInject +constructor(private val interactor: VolumeDialogSettingsButtonInteractor) : ExclusiveActivatable() { + + private val hydrator = Hydrator("VolumeDialog_settings_button") + + val isVisible by hydrator.hydratedStateOf("isVisible", interactor.isVisible) + + override suspend fun onActivated(): Nothing { + hydrator.activate() + } + + fun onButtonClicked() { + interactor.onButtonClicked() + } + + @VolumeDialogScope + @AssistedFactory + interface Factory { + + fun create(): VolumeDialogSettingsButtonViewModel + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogBinder.kt index 3f2c39bba6e7..9c88303106ae 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogBinder.kt @@ -20,21 +20,18 @@ import android.app.Dialog import android.graphics.Color import android.graphics.PixelFormat import android.graphics.drawable.ColorDrawable -import android.view.View import android.view.ViewGroup import android.view.Window import android.view.WindowManager -import androidx.lifecycle.lifecycleScope -import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope +import com.android.systemui.volume.dialog.settings.ui.binder.VolumeDialogSettingsButtonViewBinder import com.android.systemui.volume.dialog.ui.viewmodel.VolumeDialogGravityViewModel import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch @VolumeDialogScope class VolumeDialogBinder @@ -42,6 +39,7 @@ class VolumeDialogBinder constructor( @VolumeDialog private val coroutineScope: CoroutineScope, private val volumeDialogViewBinder: VolumeDialogViewBinder, + private val settingsButtonViewBinder: VolumeDialogSettingsButtonViewBinder, private val gravityViewModel: VolumeDialogGravityViewModel, ) { @@ -50,10 +48,8 @@ constructor( setupWindow(window!!) dialog.setContentView(R.layout.volume_dialog) - val volumeDialogView: View = dialog.requireViewById(R.id.volume_dialog_container) - volumeDialogView.repeatWhenAttached { - lifecycleScope.launch { volumeDialogViewBinder.bind(volumeDialogView) } - } + settingsButtonViewBinder.bind(dialog.requireViewById(R.id.settings_container)) + volumeDialogViewBinder.bind(dialog.requireViewById(R.id.volume_dialog_container)) } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt index 700225d521c8..600d17603964 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt @@ -21,15 +21,17 @@ import com.android.systemui.lifecycle.WindowLifecycleState import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.lifecycle.setSnapshotBinding import com.android.systemui.lifecycle.viewModel +import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope import com.android.systemui.volume.dialog.ui.viewmodel.VolumeDialogViewModel import javax.inject.Inject import kotlinx.coroutines.awaitCancellation +@VolumeDialogScope class VolumeDialogViewBinder @Inject constructor(private val volumeDialogViewModelFactory: VolumeDialogViewModel.Factory) { - suspend fun bind(view: View) { + fun bind(view: View) { view.repeatWhenAttached { view.viewModel( traceName = "VolumeDialogViewBinder", diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt index 329a947f24ef..8aa0d09157ad 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt @@ -52,7 +52,7 @@ constructor( .mapLatest { visibilityModel -> with(visibilityModel) { if (this is VolumeDialogVisibilityModel.Visible) { - showDialog(reason, keyguardLocked, lockTaskModeState) + showDialog(reason, keyguardLocked) } if (this is VolumeDialogVisibilityModel.Dismissed) { Events.writeEvent(Events.EVENT_DISMISS_DIALOG, reason) @@ -65,24 +65,23 @@ constructor( awaitCancellation() } - suspend fun showDialog(reason: Int, keyguardLocked: Boolean, lockTaskModeState: Int): Unit = - coroutineScope { - logger.onShow(reason) + suspend fun showDialog(reason: Int, keyguardLocked: Boolean): Unit = coroutineScope { + logger.onShow(reason) - controller.notifyVisible(true) + controller.notifyVisible(true) - val volumeDialogComponent: VolumeDialogComponent = componentFactory.create(this) - val dialog = - volumeDialogComponent.volumeDialog().apply { - setOnDismissListener { - volumeDialogComponent.coroutineScope().cancel() - dialogVisibilityInteractor.dismissDialog(Events.DISMISS_REASON_UNKNOWN) - } + val volumeDialogComponent: VolumeDialogComponent = componentFactory.create(this) + val dialog = + volumeDialogComponent.volumeDialog().apply { + setOnDismissListener { + volumeDialogComponent.coroutineScope().cancel() + dialogVisibilityInteractor.dismissDialog(Events.DISMISS_REASON_UNKNOWN) } - launch { dialog.awaitShow() } + } + launch { dialog.awaitShow() } - Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, keyguardLocked) - } + Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, keyguardLocked) + } } /** Shows [Dialog] until suspend function is cancelled. */ -- GitLab From 14877a97c99a13e19293f68ecdee72f4c9d1b087 Mon Sep 17 00:00:00 2001 From: Jernej Virag Date: Fri, 4 Oct 2024 15:32:17 +0200 Subject: [PATCH 053/447] Cleanup register_zen_mode_content_observer_background flag Also moves the zen mode controller test to multivalent configuration. Bug: 324515627 Flag: EXEMPT removing register_zen_mode_content_observer_background Test: atest ZenModeControllerImplTest Change-Id: Ibc81c890322d2d88f0d03e8888a069358efd82e9 --- packages/SystemUI/aconfig/systemui.aconfig | 10 - .../policy/ZenModeControllerImplTest.kt | 207 ++++++++++++++++++ .../policy/ZenModeControllerImpl.java | 18 +- .../policy/ZenModeControllerImplTest.java | 201 ----------------- 4 files changed, 210 insertions(+), 226 deletions(-) create mode 100644 packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.kt delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index aaa527dead0a..f3d8bbf86b01 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -812,16 +812,6 @@ flag { } } -flag { - name: "register_zen_mode_content_observer_background" - namespace: "systemui" - description: "Decide whether to register zen mode content observers in the background thread." - bug: "324515627" - metadata { - purpose: PURPOSE_BUGFIX - } -} - flag { name: "clipboard_noninteractive_on_lockscreen" namespace: "systemui" diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.kt new file mode 100644 index 000000000000..9abdf42e735c --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.kt @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2017 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.policy + +import android.app.NotificationManager +import android.os.Handler +import android.provider.Settings +import android.service.notification.ZenModeConfig +import android.testing.TestableLooper +import android.testing.TestableLooper.RunWithLooper +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.dump.dumpManager +import com.android.systemui.kosmos.testScope +import com.android.systemui.settings.userTracker +import com.android.systemui.testKosmos +import com.android.systemui.util.settings.fakeGlobalSettings +import com.google.common.truth.Truth.assertThat +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicInteger +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers +import org.mockito.Mockito +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidJUnit4::class) +@RunWithLooper +class ZenModeControllerImplTest : SysuiTestCase() { + + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + private lateinit var testableLooper: TestableLooper + private lateinit var controller: ZenModeControllerImpl + + private val globalSettings = kosmos.fakeGlobalSettings + private val config: ZenModeConfig = mock() + private val mNm: NotificationManager = mock() + + @Before + fun setUp() { + testableLooper = TestableLooper.get(this) + mContext.addMockSystemService(NotificationManager::class.java, mNm) + whenever(mNm.zenModeConfig).thenReturn(config) + + controller = + ZenModeControllerImpl( + mContext, + Handler.createAsync(testableLooper.looper), + kosmos.broadcastDispatcher, + kosmos.dumpManager, + globalSettings, + kosmos.userTracker, + ) + } + + @Test + fun testRemoveDuringCallback() { + val callback = + object : ZenModeController.Callback { + override fun onConfigChanged(config: ZenModeConfig) { + controller.removeCallback(this) + } + } + + controller.addCallback(callback) + val mockCallback = Mockito.mock(ZenModeController.Callback::class.java) + controller.addCallback(mockCallback) + controller.fireConfigChanged(config) + Mockito.verify(mockCallback).onConfigChanged(ArgumentMatchers.eq(config)) + } + + @Test + fun testAreNotificationsHiddenInShade_zenOffShadeSuppressed() { + config.suppressedVisualEffects = + NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST + controller.updateZenMode(Settings.Global.ZEN_MODE_OFF) + controller.updateZenModeConfig() + assertThat(controller.areNotificationsHiddenInShade()).isFalse() + } + + @Test + fun testAreNotificationsHiddenInShade_zenOnShadeNotSuppressed() { + val policy = + NotificationManager.Policy( + 0, + 0, + 0, + NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR, + ) + whenever(mNm.consolidatedNotificationPolicy).thenReturn(policy) + controller.updateConsolidatedNotificationPolicy() + controller.updateZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) + assertThat(controller.areNotificationsHiddenInShade()).isFalse() + } + + @Test + fun testAreNotificationsHiddenInShade_zenOnShadeSuppressed() { + val policy = + NotificationManager.Policy( + 0, + 0, + 0, + NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST, + ) + whenever(mNm.consolidatedNotificationPolicy).thenReturn(policy) + controller.updateConsolidatedNotificationPolicy() + controller.updateZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) + assertThat(controller.areNotificationsHiddenInShade()).isTrue() + } + + @Test + fun testModeChange() = + testScope.runTest { + val states = + listOf( + Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, + Settings.Global.ZEN_MODE_NO_INTERRUPTIONS, + Settings.Global.ZEN_MODE_ALARMS, + Settings.Global.ZEN_MODE_ALARMS, + ) + + for (state in states) { + globalSettings.putInt(Settings.Global.ZEN_MODE, state) + testScope.runCurrent() + testableLooper.processAllMessages() + assertThat(controller.zen).isEqualTo(state) + } + } + + @Test + fun testModeChange_callbackNotified() = + testScope.runTest { + val currentState = AtomicInteger(-1) + + val callback: ZenModeController.Callback = + object : ZenModeController.Callback { + override fun onZenChanged(zen: Int) { + currentState.set(zen) + } + } + + controller.addCallback(callback) + + val states = + listOf( + Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, + Settings.Global.ZEN_MODE_NO_INTERRUPTIONS, + Settings.Global.ZEN_MODE_ALARMS, + Settings.Global.ZEN_MODE_ALARMS, + ) + + for (state in states) { + globalSettings.putInt(Settings.Global.ZEN_MODE, state) + testScope.runCurrent() + testableLooper.processAllMessages() + assertThat(currentState.get()).isEqualTo(state) + } + } + + @Test + fun testCallbackRemovedWhileDispatching_doesntCrash() = + testScope.runTest { + val remove = AtomicBoolean(false) + globalSettings.putInt(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF) + testableLooper.processAllMessages() + val callback: ZenModeController.Callback = + object : ZenModeController.Callback { + override fun onZenChanged(zen: Int) { + if (remove.get()) { + controller.removeCallback(this) + } + } + } + controller.addCallback(callback) + controller.addCallback(object : ZenModeController.Callback {}) + + remove.set(true) + + globalSettings.putInt( + Settings.Global.ZEN_MODE, + Settings.Global.ZEN_MODE_NO_INTERRUPTIONS, + ) + testScope.runCurrent() + testableLooper.processAllMessages() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java index e09e5777a9a3..0cba94016ffb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java @@ -16,8 +16,6 @@ package com.android.systemui.statusbar.policy; -import static com.android.systemui.Flags.registerZenModeContentObserverBackground; - import android.app.AlarmManager; import android.app.Flags; import android.app.NotificationManager; @@ -47,7 +45,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dumpable; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.settings.UserTracker; @@ -107,7 +104,6 @@ public class ZenModeControllerImpl implements ZenModeController, Dumpable { public ZenModeControllerImpl( Context context, @Main Handler handler, - @Background Handler bgHandler, BroadcastDispatcher broadcastDispatcher, DumpManager dumpManager, GlobalSettings globalSettings, @@ -138,17 +134,9 @@ public class ZenModeControllerImpl implements ZenModeController, Dumpable { } }; mNoMan = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - if (registerZenModeContentObserverBackground()) { - bgHandler.post(() -> { - globalSettings.registerContentObserverSync(Global.ZEN_MODE, modeContentObserver); - globalSettings.registerContentObserverSync(Global.ZEN_MODE_CONFIG_ETAG, - configContentObserver); - }); - } else { - globalSettings.registerContentObserverSync(Global.ZEN_MODE, modeContentObserver); - globalSettings.registerContentObserverSync(Global.ZEN_MODE_CONFIG_ETAG, - configContentObserver); - } + globalSettings.registerContentObserverAsync(Global.ZEN_MODE, modeContentObserver); + globalSettings.registerContentObserverAsync(Global.ZEN_MODE_CONFIG_ETAG, + configContentObserver); updateZenMode(getModeSettingValueFromProvider()); updateZenModeConfig(); updateConsolidatedNotificationPolicy(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java deleted file mode 100644 index 637a0f16cd5d..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2017 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.policy; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.NotificationManager; -import android.os.Handler; -import android.provider.Settings; -import android.service.notification.ZenModeConfig; -import android.testing.TestableLooper; -import android.testing.TestableLooper.RunWithLooper; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.systemui.SysuiTestCase; -import com.android.systemui.broadcast.BroadcastDispatcher; -import com.android.systemui.dump.DumpManager; -import com.android.systemui.settings.UserTracker; -import com.android.systemui.statusbar.policy.ZenModeController.Callback; -import com.android.systemui.util.settings.FakeGlobalSettings; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -@SmallTest -@RunWith(AndroidJUnit4.class) -@RunWithLooper -public class ZenModeControllerImplTest extends SysuiTestCase { - - private Callback mCallback; - @Mock - NotificationManager mNm; - @Mock - ZenModeConfig mConfig; - @Mock - BroadcastDispatcher mBroadcastDispatcher; - @Mock - DumpManager mDumpManager; - @Mock - UserTracker mUserTracker; - private ZenModeControllerImpl mController; - - private final FakeGlobalSettings mGlobalSettings = new FakeGlobalSettings(); - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext.addMockSystemService(NotificationManager.class, mNm); - when(mNm.getZenModeConfig()).thenReturn(mConfig); - - mController = new ZenModeControllerImpl( - mContext, - Handler.createAsync(TestableLooper.get(this).getLooper()), - Handler.createAsync(TestableLooper.get(this).getLooper()), - mBroadcastDispatcher, - mDumpManager, - mGlobalSettings, - mUserTracker); - } - - @Test - public void testRemoveDuringCallback() { - mCallback = new Callback() { - @Override - public void onConfigChanged(ZenModeConfig config) { - mController.removeCallback(mCallback); - } - }; - mController.addCallback(mCallback); - Callback mockCallback = mock(Callback.class); - mController.addCallback(mockCallback); - mController.fireConfigChanged(null); - verify(mockCallback).onConfigChanged(eq(null)); - } - - @Test - public void testAreNotificationsHiddenInShade_zenOffShadeSuppressed() { - mConfig.suppressedVisualEffects = - NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST; - mController.updateZenMode(Settings.Global.ZEN_MODE_OFF); - mController.updateZenModeConfig(); - - assertFalse(mController.areNotificationsHiddenInShade()); - } - - @Test - public void testAreNotificationsHiddenInShade_zenOnShadeNotSuppressed() { - NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0, - NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR); - when(mNm.getConsolidatedNotificationPolicy()).thenReturn(policy); - mController.updateConsolidatedNotificationPolicy(); - mController.updateZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS); - - assertFalse(mController.areNotificationsHiddenInShade()); - } - - @Test - public void testAreNotificationsHiddenInShade_zenOnShadeSuppressed() { - NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0, - NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST); - when(mNm.getConsolidatedNotificationPolicy()).thenReturn(policy); - mController.updateConsolidatedNotificationPolicy(); - mController.updateZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS); - - assertTrue(mController.areNotificationsHiddenInShade()); - } - - @Test - public void testModeChange() { - List states = List.of( - Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, - Settings.Global.ZEN_MODE_NO_INTERRUPTIONS, - Settings.Global.ZEN_MODE_ALARMS, - Settings.Global.ZEN_MODE_ALARMS - ); - - for (Integer state : states) { - mGlobalSettings.putInt(Settings.Global.ZEN_MODE, state); - TestableLooper.get(this).processAllMessages(); - assertEquals(state.intValue(), mController.getZen()); - } - } - - @Test - public void testModeChange_callbackNotified() { - final AtomicInteger currentState = new AtomicInteger(-1); - - ZenModeController.Callback callback = new Callback() { - @Override - public void onZenChanged(int zen) { - currentState.set(zen); - } - }; - - mController.addCallback(callback); - - List states = List.of( - Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, - Settings.Global.ZEN_MODE_NO_INTERRUPTIONS, - Settings.Global.ZEN_MODE_ALARMS, - Settings.Global.ZEN_MODE_ALARMS - ); - - for (Integer state : states) { - mGlobalSettings.putInt(Settings.Global.ZEN_MODE, state); - TestableLooper.get(this).processAllMessages(); - assertEquals(state.intValue(), currentState.get()); - } - - } - - @Test - public void testCallbackRemovedWhileDispatching_doesntCrash() { - final AtomicBoolean remove = new AtomicBoolean(false); - mGlobalSettings.putInt(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF); - TestableLooper.get(this).processAllMessages(); - final ZenModeController.Callback callback = new ZenModeController.Callback() { - @Override - public void onZenChanged(int zen) { - if (remove.get()) { - mController.removeCallback(this); - } - } - }; - mController.addCallback(callback); - mController.addCallback(new ZenModeController.Callback() {}); - - remove.set(true); - - mGlobalSettings.putInt(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_NO_INTERRUPTIONS); - TestableLooper.get(this).processAllMessages(); - } -} -- GitLab From 2f120f9039fb8288f2cecaa94bb9e5040e4234fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Kurucz?= Date: Fri, 4 Oct 2024 13:59:10 +0000 Subject: [PATCH 054/447] Dump ExpandableView clip bounds Applying a clipping bound to the notification row would be one more way to get to the "empty space in shade" state, and yet it is not included in the bugreports. Bug: 369608449 Test: dumpsysui NotificationStackScrollLayout Flag: EXEMPT changing dumps only Change-Id: I3ea395555dd0005701a3ffc71ba58dcb62fcc6e3 --- .../systemui/statusbar/notification/row/ExpandableView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java index afda4262bf9d..3a2d2795d874 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java @@ -862,8 +862,8 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro pw.println("mClipToActualHeight: " + mClipToActualHeight); pw.println("mExtraWidthForClipping: " + mExtraWidthForClipping); pw.println("mMinimumHeightForClipping: " + mMinimumHeightForClipping); - pw.println("getClipBounds(): " + getClipBounds()); } + pw.println("getClipBounds(): " + getClipBounds()); }); } -- GitLab From 173a38237569a20a12ebead102c30d50fcf1ad59 Mon Sep 17 00:00:00 2001 From: Graciela Wissen Putri Date: Fri, 27 Sep 2024 13:57:23 +0000 Subject: [PATCH 055/447] Make mUserAspectRatio final When user changes aspect ratio via Settings, the app is always killed and user will have to open it again to initialise the new setting. Since the aspect ratio will not change during the lifecycle of the activity, we make it final. Flag: EXEMPT refactor Fix: 315140179 Test: atest AppCompatAspectRatioOverridesTest atest AppCompatOrientationPolicyTest atest SizeCompatTests Change-Id: I3ed20c7473f3b142d63d1a6cd3a382004bd61d35 --- .../wm/AppCompatAspectRatioOverrides.java | 58 ++++++------------- .../server/wm/AppCompatOrientationPolicy.java | 24 +------- .../wm/DesktopAppCompatAspectRatioPolicy.java | 2 +- .../server/wm/AppCompatActivityRobot.java | 9 ++- .../wm/AppCompatAspectRatioOverridesTest.java | 20 +++---- .../wm/AppCompatOrientationPolicyTest.java | 6 +- .../DesktopModeLaunchParamsModifierTests.java | 2 +- .../android/server/wm/SizeCompatTests.java | 40 ++++++------- 8 files changed, 62 insertions(+), 99 deletions(-) diff --git a/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java index d59046f44129..1c232124e775 100644 --- a/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java +++ b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java @@ -62,8 +62,8 @@ class AppCompatAspectRatioOverrides { private final ActivityRecord mActivityRecord; @NonNull private final AppCompatConfiguration mAppCompatConfiguration; - @NonNull - private final UserAspectRatioState mUserAspectRatioState; + @PackageManager.UserMinAspectRatio + final int mUserAspectRatioType; @NonNull private final OptPropFactory.OptProp mAllowMinAspectRatioOverrideOptProp; @@ -86,7 +86,7 @@ class AppCompatAspectRatioOverrides { mActivityRecord = activityRecord; mAppCompatConfiguration = appCompatConfiguration; mAppCompatDeviceStateQuery = appCompatDeviceStateQuery; - mUserAspectRatioState = new UserAspectRatioState(); + mUserAspectRatioType = getUserMinAspectRatioOverrideType(); mAppCompatReachabilityOverrides = appCompatReachabilityOverrides; mAllowMinAspectRatioOverrideOptProp = optPropBuilder.create( PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE); @@ -122,41 +122,28 @@ class AppCompatAspectRatioOverrides { * current app. */ boolean shouldApplyUserMinAspectRatioOverride() { - if (!shouldEnableUserAspectRatioSettings()) { - return false; - } - - mUserAspectRatioState.mUserAspectRatio = getUserMinAspectRatioOverrideCode(); - - return mUserAspectRatioState.mUserAspectRatio != USER_MIN_ASPECT_RATIO_UNSET - && mUserAspectRatioState.mUserAspectRatio != USER_MIN_ASPECT_RATIO_APP_DEFAULT - && mUserAspectRatioState.mUserAspectRatio != USER_MIN_ASPECT_RATIO_FULLSCREEN; + return shouldEnableUserAspectRatioSettings() + && mUserAspectRatioType != USER_MIN_ASPECT_RATIO_UNSET + && mUserAspectRatioType != USER_MIN_ASPECT_RATIO_APP_DEFAULT + && mUserAspectRatioType != USER_MIN_ASPECT_RATIO_FULLSCREEN; } boolean shouldApplyUserFullscreenOverride() { - if (isUserFullscreenOverrideEnabled()) { - mUserAspectRatioState.mUserAspectRatio = getUserMinAspectRatioOverrideCode(); - - return mUserAspectRatioState.mUserAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN; - } - - return false; + return isUserFullscreenOverrideEnabled() + && mUserAspectRatioType == USER_MIN_ASPECT_RATIO_FULLSCREEN; } boolean isUserFullscreenOverrideEnabled() { - if (mAllowUserAspectRatioOverrideOptProp.isFalse() - || mAllowUserAspectRatioFullscreenOverrideOptProp.isFalse() - || !mAppCompatConfiguration.isUserAppAspectRatioFullscreenEnabled()) { - return false; - } - return true; + return !mAllowUserAspectRatioOverrideOptProp.isFalse() + && !mAllowUserAspectRatioFullscreenOverrideOptProp.isFalse() + && mAppCompatConfiguration.isUserAppAspectRatioFullscreenEnabled(); } boolean isSystemOverrideToFullscreenEnabled() { return isChangeEnabled(mActivityRecord, OVERRIDE_ANY_ORIENTATION_TO_USER) && !mAllowOrientationOverrideOptProp.isFalse() - && (mUserAspectRatioState.mUserAspectRatio == USER_MIN_ASPECT_RATIO_UNSET - || mUserAspectRatioState.mUserAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN); + && (mUserAspectRatioType == USER_MIN_ASPECT_RATIO_UNSET + || mUserAspectRatioType == USER_MIN_ASPECT_RATIO_FULLSCREEN); } /** @@ -173,12 +160,11 @@ class AppCompatAspectRatioOverrides { } boolean hasFullscreenOverride() { - // `mUserAspectRatio` is always initialized first in `shouldApplyUserFullscreenOverride()`. return shouldApplyUserFullscreenOverride() || isSystemOverrideToFullscreenEnabled(); } float getUserMinAspectRatio() { - switch (mUserAspectRatioState.mUserAspectRatio) { + switch (mUserAspectRatioType) { case USER_MIN_ASPECT_RATIO_DISPLAY_SIZE: return getDisplaySizeMinAspectRatio(); case USER_MIN_ASPECT_RATIO_SPLIT_SCREEN: @@ -191,7 +177,7 @@ class AppCompatAspectRatioOverrides { return 3 / 2f; default: throw new AssertionError("Unexpected user min aspect ratio override: " - + mUserAspectRatioState.mUserAspectRatio); + + mUserAspectRatioType); } } @@ -268,14 +254,15 @@ class AppCompatAspectRatioOverrides { return !mAllowUserAspectRatioOverrideOptProp.isFalse(); } - int getUserMinAspectRatioOverrideCode() { + // TODO(b/359217664): make this private. + int getUserMinAspectRatioOverrideType() { try { return mActivityRecord.mAtmService.getPackageManager() .getUserMinAspectRatio(mActivityRecord.packageName, mActivityRecord.mUserId); } catch (RemoteException e) { Slog.w(TAG, "Exception thrown retrieving aspect ratio user override " + this, e); } - return mUserAspectRatioState.mUserAspectRatio; + return USER_MIN_ASPECT_RATIO_UNSET; } private float getDefaultMinAspectRatioForUnresizableApps() { @@ -299,13 +286,6 @@ class AppCompatAspectRatioOverrides { return getDisplaySizeMinAspectRatio(); } - private static class UserAspectRatioState { - // TODO(b/315140179): Make mUserAspectRatio final - // The min aspect ratio override set by user - @PackageManager.UserMinAspectRatio - private int mUserAspectRatio = USER_MIN_ASPECT_RATIO_UNSET; - } - private Resources getResources() { return mActivityRecord.mWmService.mContext.getResources(); } diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java index f5d58eac1113..af9e1fdc64ff 100644 --- a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java +++ b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java @@ -56,11 +56,11 @@ class AppCompatOrientationPolicy { final DisplayContent displayContent = mActivityRecord.mDisplayContent; final boolean isIgnoreOrientationRequestEnabled = displayContent != null && displayContent.getIgnoreOrientationRequest(); - final boolean shouldApplyUserFullscreenOverride = mAppCompatOverrides - .getAppCompatAspectRatioOverrides().shouldApplyUserFullscreenOverride(); + final boolean hasFullscreenOverride = mAppCompatOverrides + .getAppCompatAspectRatioOverrides().hasFullscreenOverride(); final boolean shouldCameraCompatControlOrientation = AppCompatCameraPolicy.shouldCameraCompatControlOrientation(mActivityRecord); - if (shouldApplyUserFullscreenOverride && isIgnoreOrientationRequestEnabled + if (hasFullscreenOverride && isIgnoreOrientationRequestEnabled // Do not override orientation to fullscreen for camera activities. // Fixed-orientation activities are rarely tested in other orientations, and it // often results in sideways or stretched previews. As the camera compat treatment @@ -101,24 +101,6 @@ class AppCompatOrientationPolicy { return candidate; } - // mUserAspectRatio is always initialized first in shouldApplyUserFullscreenOverride(), - // which will always come first before this check as user override > device - // manufacturer override. - final boolean isSystemOverrideToFullscreenEnabled = mAppCompatOverrides - .getAppCompatAspectRatioOverrides().isSystemOverrideToFullscreenEnabled(); - if (isSystemOverrideToFullscreenEnabled && isIgnoreOrientationRequestEnabled - // Do not override orientation to fullscreen for camera activities. - // Fixed-orientation activities are rarely tested in other orientations, and it - // often results in sideways or stretched previews. As the camera compat treatment - // targets fixed-orientation activities, overriding the orientation disables the - // treatment. - && !shouldCameraCompatControlOrientation) { - Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate) - + " for " + mActivityRecord + " is overridden to " - + screenOrientationToString(SCREEN_ORIENTATION_USER)); - return SCREEN_ORIENTATION_USER; - } - final AppCompatOrientationOverrides.OrientationOverridesState capabilityState = mAppCompatOverrides.getAppCompatOrientationOverrides() .mOrientationOverridesState; diff --git a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java index c8cb62132b4c..b9db5d39a302 100644 --- a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java +++ b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java @@ -265,7 +265,7 @@ public class DesktopAppCompatAspectRatioPolicy { } final int userAspectRatioCode = mAppCompatOverrides.getAppCompatAspectRatioOverrides() - .getUserMinAspectRatioOverrideCode(); + .getUserMinAspectRatioOverrideType(); return userAspectRatioCode != USER_MIN_ASPECT_RATIO_UNSET && userAspectRatioCode != USER_MIN_ASPECT_RATIO_APP_DEFAULT diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java index c8a35598479f..049e5cfba0e6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java @@ -25,6 +25,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.server.wm.BackgroundActivityStartControllerTests.setViaReflection; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -227,7 +228,13 @@ class AppCompatActivityRobot { void setGetUserMinAspectRatioOverrideCode(@UserMinAspectRatio int overrideCode) { doReturn(overrideCode).when(mActivityStack.top().mAppCompatController - .getAppCompatAspectRatioOverrides()).getUserMinAspectRatioOverrideCode(); + .getAppCompatAspectRatioOverrides()).getUserMinAspectRatioOverrideType(); + } + + void setUserAspectRatioType(@UserMinAspectRatio int aspectRatio) { + final AppCompatAspectRatioOverrides aspectRatioOverrides = mActivityStack.top() + .mAppCompatController.getAppCompatAspectRatioOverrides(); + setViaReflection(aspectRatioOverrides, "mUserAspectRatioType", aspectRatio); } void setGetUserMinAspectRatioOverrideValue(float overrideValue) { diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java index b83911337c5c..b051aaf8a1f5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java @@ -75,7 +75,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().disable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN); + robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_FULLSCREEN); robot.checkShouldApplyUserFullscreenOverride(/* expected */ false); }); @@ -88,7 +88,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().disable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN); + robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_FULLSCREEN); robot.checkShouldApplyUserFullscreenOverride(/* expected */ false); }); } @@ -100,7 +100,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.conf().enableUserAppAspectRatioFullscreen(/* enabled */ true); robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.activity().createActivityWithComponent(); - robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN); + robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_FULLSCREEN); robot.checkShouldApplyUserFullscreenOverride(/* expected */ true); }); @@ -113,7 +113,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().disable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldEnableUserAspectRatioSettings(/* expected */ false); }); @@ -126,7 +126,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().enable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldEnableUserAspectRatioSettings(/* expected */ true); }); @@ -139,7 +139,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().enable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldEnableUserAspectRatioSettings(/* expected */ false); }); @@ -152,7 +152,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().disable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldEnableUserAspectRatioSettings(/* expected */ false); }); @@ -175,7 +175,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.conf().enableUserAppAspectRatioSettings(/* enabled */ true); robot.activity().setIgnoreOrientationRequest(/* enabled */ false); robot.activity().createActivityWithComponent(); - robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldApplyUserMinAspectRatioOverride(/* expected */ false); }); @@ -187,7 +187,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.conf().enableUserAppAspectRatioSettings(/* enabled */ true); robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.activity().createActivityWithComponent(); - robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldApplyUserMinAspectRatioOverride(/* expected */ true); }); @@ -199,7 +199,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.conf().enableUserAppAspectRatioSettings(/* enabled */ false); robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.activity().createActivityWithComponent(); - robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldApplyUserMinAspectRatioOverride(/* expected */ false); }); diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java index 76101d51f931..fa2eca57ea22 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java @@ -118,7 +118,7 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase { robot.applyOnActivity((a) -> { a.createActivityWithComponent(); a.setIgnoreOrientationRequest(true); - a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN); + a.setUserAspectRatioType(USER_MIN_ASPECT_RATIO_FULLSCREEN); }); robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT, @@ -135,7 +135,7 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase { robot.applyOnActivity((a) -> { a.createActivityWithComponent(); a.setIgnoreOrientationRequest(true); - a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN); + a.setUserAspectRatioType(USER_MIN_ASPECT_RATIO_FULLSCREEN); }); robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT, @@ -164,7 +164,7 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase { robot.applyOnActivity((a) -> { a.createActivityWithComponent(); a.setIgnoreOrientationRequest(true); - a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); + a.setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); }); robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT, diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java index 6d508eabcd52..3c0d83b75e08 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java @@ -1322,7 +1322,7 @@ public class DesktopModeLaunchParamsModifierTests extends spyOn(appCompatAspectRatioOverrides); doReturn(overrideValue).when(appCompatAspectRatioOverrides).getUserMinAspectRatio(); doReturn(overrideCode).when(appCompatAspectRatioOverrides) - .getUserMinAspectRatioOverrideCode(); + .getUserMinAspectRatioOverrideType(); } private TestDisplayContent createDisplayContent(int orientation, Rect displayBounds) { diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index 72f4fa9158fb..c2ef6eaa1728 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -63,9 +63,10 @@ import static com.android.server.wm.ActivityRecord.State.PAUSED; import static com.android.server.wm.ActivityRecord.State.RESTARTING_PROCESS; import static com.android.server.wm.ActivityRecord.State.RESUMED; import static com.android.server.wm.ActivityRecord.State.STOPPED; +import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_POSITION_MULTIPLIER_CENTER; import static com.android.server.wm.AppCompatUtils.computeAspectRatio; +import static com.android.server.wm.BackgroundActivityStartControllerTests.setViaReflection; import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; -import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_POSITION_MULTIPLIER_CENTER; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.google.common.truth.Truth.assertThat; @@ -95,13 +96,11 @@ import android.compat.testing.PlatformCompatChangeRule; import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.ScreenOrientation; -import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Insets; import android.graphics.Rect; import android.os.Binder; -import android.os.RemoteException; import android.os.UserHandle; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; @@ -1087,9 +1086,7 @@ public class SizeCompatTests extends WindowTestsBase { spyOn(activity.mAppCompatController.getAppCompatAspectRatioOverrides()); doReturn(true).when(activity.mWmService.mAppCompatConfiguration) .isUserAppAspectRatioFullscreenEnabled(); - doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN) - .when(activity.mAppCompatController.getAppCompatAspectRatioOverrides()) - .getUserMinAspectRatioOverrideCode(); + setUserAspectRatioType(activity, USER_MIN_ASPECT_RATIO_FULLSCREEN); assertFalse(activity.shouldCreateAppCompatDisplayInsets()); } @@ -2210,11 +2207,9 @@ public class SizeCompatTests extends WindowTestsBase { doReturn(true).when(mActivity.mWmService.mAppCompatConfiguration) .isUserAppAspectRatioFullscreenEnabled(); - // Set user aspect ratio override + // Set user aspect ratio override. spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()); - doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN) - .when(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()) - .getUserMinAspectRatioOverrideCode(); + setUserAspectRatioType(mActivity, USER_MIN_ASPECT_RATIO_FULLSCREEN); prepareMinAspectRatio(mActivity, 16 / 9f, SCREEN_ORIENTATION_PORTRAIT); @@ -2237,10 +2232,7 @@ public class SizeCompatTests extends WindowTestsBase { // Set user aspect ratio override spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()); - doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN) - .when(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()) - .getUserMinAspectRatioOverrideCode(); - + setUserAspectRatioType(mActivity, USER_MIN_ASPECT_RATIO_FULLSCREEN); prepareMinAspectRatio(mActivity, 16 / 9f, SCREEN_ORIENTATION_LANDSCAPE); final Rect bounds = mActivity.getBounds(); @@ -2423,7 +2415,7 @@ public class SizeCompatTests extends WindowTestsBase { true); } - private void testUserOverrideAspectRatio(boolean isUnresizable, int screenOrientation, + private void testUserOverrideAspectRatio(boolean isUnresizeable, int screenOrientation, float expectedAspectRatio, @PackageManager.UserMinAspectRatio int aspectRatio, boolean enabled) { final ActivityRecord activity = getActivityBuilderWithoutTask().build(); @@ -2437,15 +2429,10 @@ public class SizeCompatTests extends WindowTestsBase { spyOn(activity.mWmService.mAppCompatConfiguration); doReturn(enabled).when(activity.mWmService.mAppCompatConfiguration) .isUserAppAspectRatioSettingsEnabled(); - // Set user aspect ratio override - final IPackageManager pm = mAtm.getPackageManager(); - try { - doReturn(aspectRatio).when(pm) - .getUserMinAspectRatio(activity.packageName, activity.mUserId); - } catch (RemoteException ignored) { - } + // Set user aspect ratio override. + setUserAspectRatioType(activity, aspectRatio); - prepareLimitedBounds(activity, screenOrientation, isUnresizable); + prepareLimitedBounds(activity, screenOrientation, isUnresizeable); final Rect afterBounds = activity.getBounds(); final int width = afterBounds.width(); @@ -5202,4 +5189,11 @@ public class SizeCompatTests extends WindowTestsBase { DeviceConfig.setProperty(NAMESPACE_CONSTRAIN_DISPLAY_APIS, CONFIG_ALWAYS_CONSTRAIN_DISPLAY_APIS, value, makeDefault); } + + private void setUserAspectRatioType(ActivityRecord activity, + @PackageManager.UserMinAspectRatio int aspectRatio) { + final AppCompatAspectRatioOverrides aspectRatioOverrides = activity.mAppCompatController + .getAppCompatAspectRatioOverrides(); + setViaReflection(aspectRatioOverrides, "mUserAspectRatioType", aspectRatio); + } } -- GitLab From 50dc71796c4ab64bf98645dc9ef9539b62e2ab6c Mon Sep 17 00:00:00 2001 From: Matt Casey Date: Thu, 3 Oct 2024 19:19:51 +0000 Subject: [PATCH 056/447] Make insets and bounds immutable. Bug: 370798587 Flag: EXEMPT minor refactor Test: atest com.android.systemui.screenshot Change-Id: Ibbc7131b1b6a0094cfef20fb325178cca3d250cd --- .../LegacyScreenshotController.java | 18 +++++++++--------- .../screenshot/ScreenshotController.kt | 19 +++++++++++-------- .../systemui/screenshot/ScreenshotData.kt | 12 ++++++------ .../policy/PolicyRequestProcessor.kt | 4 ++-- .../systemui/screenshot/ScreenshotDataTest.kt | 4 ++-- .../policy/PolicyRequestProcessorTest.kt | 4 ++-- 6 files changed, 32 insertions(+), 29 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotController.java index e58960072454..3920d585734e 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotController.java @@ -255,11 +255,11 @@ public class LegacyScreenshotController implements InteractiveScreenshotHandler Assert.isMainThread(); mCurrentRequestCallback = requestCallback; + Rect bounds = screenshot.getOriginalScreenBounds(); if (screenshot.getType() == WindowManager.TAKE_SCREENSHOT_FULLSCREEN && screenshot.getBitmap() == null) { - Rect bounds = getFullScreenRect(); + bounds = getFullScreenRect(); screenshot.setBitmap(mImageCapture.captureDisplay(mDisplay.getDisplayId(), bounds)); - screenshot.setScreenBounds(bounds); } if (screenshot.getBitmap() == null) { @@ -325,22 +325,22 @@ public class LegacyScreenshotController implements InteractiveScreenshotHandler boolean showFlash; if (screenshot.getType() == WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE) { - if (screenshot.getScreenBounds() != null - && aspectRatiosMatch(screenshot.getBitmap(), screenshot.getInsets(), - screenshot.getScreenBounds())) { + if (bounds != null + && aspectRatiosMatch(screenshot.getBitmap(), screenshot.getOriginalInsets(), + bounds)) { showFlash = false; } else { showFlash = true; - screenshot.setInsets(Insets.NONE); - screenshot.setScreenBounds(new Rect(0, 0, screenshot.getBitmap().getWidth(), - screenshot.getBitmap().getHeight())); + bounds = new Rect(0, 0, screenshot.getBitmap().getWidth(), + screenshot.getBitmap().getHeight()); } } else { showFlash = true; } + final Rect animationBounds = bounds; mViewProxy.prepareEntranceAnimation( - () -> startAnimation(screenshot.getScreenBounds(), showFlash, + () -> startAnimation(animationBounds, showFlash, () -> mMessageContainerController.onScreenshotTaken(screenshot))); mViewProxy.setScreenshot(screenshot); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt index 0806be8d6bb2..2a63564b1d55 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt @@ -174,7 +174,6 @@ internal constructor( if (screenshot.type == TAKE_SCREENSHOT_FULLSCREEN && screenshot.bitmap == null) { val bounds = fullScreenRect screenshot.bitmap = imageCapture.captureDisplay(display.displayId, bounds) - screenshot.screenBounds = bounds } val currentBitmap = screenshot.bitmap @@ -235,23 +234,27 @@ internal constructor( window.attachWindow() + var bounds = + screenshot.originalScreenBounds ?: Rect(0, 0, currentBitmap.width, currentBitmap.height) + val showFlash: Boolean if (screenshot.type == TAKE_SCREENSHOT_PROVIDED_IMAGE) { - if (aspectRatiosMatch(currentBitmap, screenshot.insets, screenshot.screenBounds)) { + if ( + aspectRatiosMatch( + currentBitmap, + screenshot.originalInsets, + screenshot.originalScreenBounds, + ) + ) { showFlash = false } else { showFlash = true - screenshot.insets = Insets.NONE - screenshot.screenBounds = Rect(0, 0, currentBitmap.width, currentBitmap.height) + bounds = Rect(0, 0, currentBitmap.width, currentBitmap.height) } } else { showFlash = true } - // screenshot.screenBounds is expected to be non-null in all cases at this point - val bounds = - screenshot.screenBounds ?: Rect(0, 0, currentBitmap.width, currentBitmap.height) - viewProxy.prepareEntranceAnimation { startAnimation(bounds, showFlash) { messageContainerController.onScreenshotTaken(screenshot) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotData.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotData.kt index 2df1e8aa2e68..c390e71d3701 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotData.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotData.kt @@ -21,9 +21,9 @@ data class ScreenshotData( val userHandle: UserHandle, /** ComponentName of the top-most app in the screenshot. */ val topComponent: ComponentName?, - var screenBounds: Rect?, val taskId: Int, - var insets: Insets, + val originalScreenBounds: Rect?, + val originalInsets: Insets, var bitmap: Bitmap?, val displayId: Int, ) { @@ -42,9 +42,9 @@ data class ScreenshotData( source = request.source, userHandle = UserHandle.of(request.userId), topComponent = request.topComponent, - screenBounds = request.boundsInScreen, + originalScreenBounds = request.boundsInScreen, taskId = request.taskId, - insets = request.insets, + originalInsets = request.insets, bitmap = request.bitmap, displayId = displayId, ) @@ -61,9 +61,9 @@ data class ScreenshotData( source = source, userHandle = userHandle, topComponent = topComponent, - screenBounds = null, + originalScreenBounds = null, taskId = 0, - insets = Insets.NONE, + originalInsets = Insets.NONE, bitmap = bitmap, displayId = Display.DEFAULT_DISPLAY, ) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/policy/PolicyRequestProcessor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/policy/PolicyRequestProcessor.kt index b67ad8a2b947..a94393b774a1 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/policy/PolicyRequestProcessor.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/policy/PolicyRequestProcessor.kt @@ -141,7 +141,7 @@ class PolicyRequestProcessor( userHandle = owner, taskId = taskId, topComponent = componentName, - screenBounds = taskBounds, + originalScreenBounds = taskBounds, ) } @@ -159,7 +159,7 @@ class PolicyRequestProcessor( bitmap = screenshot, userHandle = owner, topComponent = componentName, - screenBounds = Rect(0, 0, screenshot?.width ?: 0, screenshot?.height ?: 0), + originalScreenBounds = Rect(0, 0, screenshot?.width ?: 0, screenshot?.height ?: 0), taskId = taskId ?: -1, ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt index 1d74e8b3002c..4ede90ec4466 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt @@ -53,8 +53,8 @@ class ScreenshotDataTest { assertThat(data.source).isEqualTo(source) assertThat(data.type).isEqualTo(type) - assertThat(data.screenBounds).isEqualTo(bounds) - assertThat(data.insets).isEqualTo(insets) + assertThat(data.originalScreenBounds).isEqualTo(bounds) + assertThat(data.originalInsets).isEqualTo(insets) assertThat(data.taskId).isEqualTo(taskId) assertThat(data.userHandle).isEqualTo(UserHandle.of(userId)) assertThat(data.topComponent).isEqualTo(component) diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt index 2fcacb9880dd..e4329a513772 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt @@ -60,9 +60,9 @@ class PolicyRequestProcessorTest { SCREENSHOT_KEY_CHORD, UserHandle.CURRENT, topComponent = null, - screenBounds = Rect(0, 0, 1, 1), + originalScreenBounds = Rect(0, 0, 1, 1), taskId = -1, - insets = Insets.NONE, + originalInsets = Insets.NONE, bitmap = null, displayId = DEFAULT_DISPLAY, ) -- GitLab From 4c3a7c431c9eaee32e04c0b50ce7037be21f5909 Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Fri, 4 Oct 2024 10:13:19 -0400 Subject: [PATCH 057/447] Add resize functionality to CommunalEditModeviewModel When a widget is resized, we also allow them to be re-ordered within the same function call. This ensures that the resizing and the re-ordering happen within the same database transaction, to ensure they stay in sync. Bug: 368056517 Test: CommunalInteractorTest Test: CommunalWidgetRepositoryImplTest Flag: com.android.systemui.communal_widget_resizing Change-Id: I467663c1f7e34d93bf14413506ef43411c9a4385 --- .../CommunalWidgetRepositoryImplTest.kt | 19 +++- .../interactor/CommunalInteractorTest.kt | 104 ++++++++++++++++++ .../communal/data/db/CommunalWidgetDao.kt | 13 ++- .../repository/CommunalWidgetRepository.kt | 20 ++-- .../domain/interactor/CommunalInteractor.kt | 6 + .../domain/model/CommunalContentModel.kt | 9 +- .../model/CommunalWidgetContentModel.kt | 5 +- .../ui/viewmodel/BaseCommunalViewModel.kt | 28 ++--- .../ui/viewmodel/CommunalEditModeViewModel.kt | 30 ++--- .../FakeCommunalWidgetRepository.kt | 56 ++++++++-- 10 files changed, 232 insertions(+), 58 deletions(-) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt index 3d30eccc4572..8ae9d2e8f7e8 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt @@ -25,8 +25,10 @@ import android.content.applicationContext import android.graphics.Bitmap import android.os.UserHandle import android.os.userManager +import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.systemui.Flags.FLAG_COMMUNAL_WIDGET_RESIZING import com.android.systemui.SysuiTestCase import com.android.systemui.common.data.repository.fakePackageChangeRepository import com.android.systemui.common.shared.model.PackageInstallSession @@ -156,6 +158,7 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { appWidgetId = communalWidgetItemEntry.widgetId, providerInfo = providerInfoA, rank = communalItemRankEntry.rank, + spanY = communalWidgetItemEntry.spanY, ) ) @@ -188,11 +191,13 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { appWidgetId = 1, providerInfo = providerInfoA, rank = 1, + spanY = 3, ), CommunalWidgetContentModel.Available( appWidgetId = 2, providerInfo = providerInfoB, rank = 2, + spanY = 3, ), ) } @@ -219,11 +224,13 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { appWidgetId = 1, providerInfo = providerInfoA, rank = 1, + spanY = 3, ), CommunalWidgetContentModel.Available( appWidgetId = 2, providerInfo = providerInfoB, rank = 2, + spanY = 3, ), ) @@ -238,11 +245,13 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { // Verify that provider info updated providerInfo = providerInfoC, rank = 1, + spanY = 3, ), CommunalWidgetContentModel.Available( appWidgetId = 2, providerInfo = providerInfoB, rank = 2, + spanY = 3, ), ) } @@ -681,6 +690,7 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { appWidgetId = 1, providerInfo = providerInfoA, rank = 1, + spanY = 3, ), CommunalWidgetContentModel.Pending( appWidgetId = 2, @@ -688,6 +698,7 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { componentName = ComponentName("pk_2", "cls_2"), icon = fakeIcon, user = mainUser, + spanY = 3, ), ) } @@ -723,6 +734,7 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { componentName = ComponentName("pk_1", "cls_1"), icon = fakeIcon, user = mainUser, + spanY = 3, ) ) @@ -740,20 +752,23 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() { appWidgetId = 1, providerInfo = providerInfoA, rank = 1, + spanY = 3, ) ) } @Test + @EnableFlags(FLAG_COMMUNAL_WIDGET_RESIZING) fun updateWidgetSpanY_updatesWidgetInDaoAndRequestsBackup() = testScope.runTest { val widgetId = 1 val newSpanY = 6 + val widgetIdToRankMap = emptyMap() - underTest.updateWidgetSpanY(widgetId, newSpanY) + underTest.resizeWidget(widgetId, newSpanY, widgetIdToRankMap) runCurrent() - verify(communalWidgetDao).updateWidgetSpanY(widgetId, newSpanY) + verify(communalWidgetDao).resizeWidget(widgetId, newSpanY, widgetIdToRankMap) verify(backupManager).dataChanged() } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt index b96e40f43318..611a61a6282c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt @@ -24,6 +24,7 @@ import android.content.pm.UserInfo import android.os.UserHandle import android.os.UserManager import android.os.userManager +import android.platform.test.annotations.EnableFlags import android.provider.Settings import android.provider.Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED import android.widget.RemoteViews @@ -31,6 +32,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.Flags.FLAG_COMMUNAL_HUB +import com.android.systemui.Flags.FLAG_COMMUNAL_WIDGET_RESIZING import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.broadcastDispatcher import com.android.systemui.communal.data.model.CommunalSmartspaceTimer @@ -1078,6 +1080,108 @@ class CommunalInteractorTest : SysuiTestCase() { assertThat(managedProfileController.isWorkModeEnabled()).isTrue() } + @Test + @EnableFlags(FLAG_COMMUNAL_WIDGET_RESIZING) + fun resizeWidget_withoutUpdatingOrder() = + testScope.runTest { + val userInfos = listOf(MAIN_USER_INFO) + userRepository.setUserInfos(userInfos) + userTracker.set(userInfos = userInfos, selectedUserIndex = 0) + runCurrent() + + // Widgets available. + widgetRepository.addWidget( + appWidgetId = 1, + userId = MAIN_USER_INFO.id, + rank = 0, + spanY = CommunalContentSize.HALF.span, + ) + widgetRepository.addWidget( + appWidgetId = 2, + userId = MAIN_USER_INFO.id, + rank = 1, + spanY = CommunalContentSize.HALF.span, + ) + widgetRepository.addWidget( + appWidgetId = 3, + userId = MAIN_USER_INFO.id, + rank = 2, + spanY = CommunalContentSize.HALF.span, + ) + + val widgetContent by collectLastValue(underTest.widgetContent) + + assertThat(widgetContent?.map { it.appWidgetId to it.size }) + .containsExactly( + 1 to CommunalContentSize.HALF, + 2 to CommunalContentSize.HALF, + 3 to CommunalContentSize.HALF, + ) + .inOrder() + + underTest.resizeWidget(2, CommunalContentSize.FULL.span, emptyMap()) + + // Widget 2 should have been resized to FULL + assertThat(widgetContent?.map { it.appWidgetId to it.size }) + .containsExactly( + 1 to CommunalContentSize.HALF, + 2 to CommunalContentSize.FULL, + 3 to CommunalContentSize.HALF, + ) + .inOrder() + } + + @Test + @EnableFlags(FLAG_COMMUNAL_WIDGET_RESIZING) + fun resizeWidget_andUpdateOrder() = + testScope.runTest { + val userInfos = listOf(MAIN_USER_INFO) + userRepository.setUserInfos(userInfos) + userTracker.set(userInfos = userInfos, selectedUserIndex = 0) + runCurrent() + + // Widgets available. + widgetRepository.addWidget( + appWidgetId = 1, + userId = MAIN_USER_INFO.id, + rank = 0, + spanY = CommunalContentSize.HALF.span, + ) + widgetRepository.addWidget( + appWidgetId = 2, + userId = MAIN_USER_INFO.id, + rank = 1, + spanY = CommunalContentSize.HALF.span, + ) + widgetRepository.addWidget( + appWidgetId = 3, + userId = MAIN_USER_INFO.id, + rank = 2, + spanY = CommunalContentSize.HALF.span, + ) + + val widgetContent by collectLastValue(underTest.widgetContent) + + assertThat(widgetContent?.map { it.appWidgetId to it.size }) + .containsExactly( + 1 to CommunalContentSize.HALF, + 2 to CommunalContentSize.HALF, + 3 to CommunalContentSize.HALF, + ) + .inOrder() + + underTest.resizeWidget(2, CommunalContentSize.FULL.span, mapOf(2 to 0, 1 to 1)) + + // Widget 2 should have been resized to FULL and moved to the front of the list + assertThat(widgetContent?.map { it.appWidgetId to it.size }) + .containsExactly( + 2 to CommunalContentSize.FULL, + 1 to CommunalContentSize.HALF, + 3 to CommunalContentSize.HALF, + ) + .inOrder() + } + private fun setKeyguardFeaturesDisabled(user: UserInfo, disabledFlags: Int) { whenever(kosmos.devicePolicyManager.getKeyguardDisabledFeatures(nullable(), eq(user.id))) .thenReturn(disabledFlags) diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt b/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt index 5dd4c1cb7f72..02bf9dbab373 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/data/db/CommunalWidgetDao.kt @@ -23,6 +23,7 @@ import androidx.room.Delete import androidx.room.Query import androidx.room.RoomDatabase import androidx.room.Transaction +import androidx.room.Update import androidx.sqlite.db.SupportSQLiteDatabase import com.android.systemui.communal.nano.CommunalHubState import com.android.systemui.communal.shared.model.CommunalContentSize @@ -171,8 +172,7 @@ interface CommunalWidgetDao { @Query("UPDATE communal_item_rank_table SET rank = :order WHERE uid = :itemUid") fun updateItemRank(itemUid: Long, order: Int) - @Query("UPDATE communal_widget_table SET span_y = :spanY WHERE widget_id = :widgetId") - fun updateWidgetSpanY(widgetId: Int, spanY: Int) + @Update fun updateWidget(widget: CommunalWidgetItem) @Query("DELETE FROM communal_widget_table") fun clearCommunalWidgetsTable() @@ -188,6 +188,15 @@ interface CommunalWidgetDao { } } + @Transaction + fun resizeWidget(appWidgetId: Int, spanY: Int, widgetIdToRankMap: Map) { + val widget = getWidgetByIdNow(appWidgetId) + if (widget != null) { + updateWidget(widget.copy(spanY = spanY)) + } + updateWidgetOrder(widgetIdToRankMap) + } + @Transaction fun addWidget( widgetId: Int, diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt index 3312f3cac64b..0e9428970a13 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt @@ -21,6 +21,7 @@ import android.appwidget.AppWidgetProviderInfo import android.content.ComponentName import android.os.UserHandle import android.os.UserManager +import com.android.systemui.Flags.communalWidgetResizing import com.android.systemui.common.data.repository.PackageChangeRepository import com.android.systemui.common.shared.model.PackageInstallSession import com.android.systemui.communal.data.backup.CommunalBackupUtils @@ -82,7 +83,7 @@ interface CommunalWidgetRepository { * * @param widgetIdToRankMap mapping of the widget ids to the rank of the widget. */ - fun updateWidgetOrder(widgetIdToRankMap: Map) {} + fun updateWidgetOrder(widgetIdToRankMap: Map) /** * Restores the database by reading a state file from disk and updating the widget ids according @@ -96,10 +97,13 @@ interface CommunalWidgetRepository { /** * Update the spanY of a widget in the database. * - * @param widgetId id of the widget to update. + * @param appWidgetId id of the widget to update. * @param spanY new spanY value for the widget. + * @param widgetIdToRankMap mapping of the widget ids to its rank. Allows re-ordering widgets + * alongside the resize, in case resizing also requires re-ordering. This ensures the + * re-ordering is done in the same database transaction as the resize. */ - fun updateWidgetSpanY(widgetId: Int, spanY: Int) + fun resizeWidget(appWidgetId: Int, spanY: Int, widgetIdToRankMap: Map) } @SysUISingleton @@ -135,15 +139,17 @@ constructor( componentName = widget.componentName, rank = rank.rank, providerInfo = providers[widget.widgetId], + spanY = widget.spanY, ) } } - override fun updateWidgetSpanY(widgetId: Int, spanY: Int) { + override fun resizeWidget(appWidgetId: Int, spanY: Int, widgetIdToRankMap: Map) { + if (!communalWidgetResizing()) return bgScope.launch { - communalWidgetDao.updateWidgetSpanY(widgetId, spanY) + communalWidgetDao.resizeWidget(appWidgetId, spanY, widgetIdToRankMap) logger.i({ "Updated spanY of widget $int1 to $int2." }) { - int1 = widgetId + int1 = appWidgetId int2 = spanY } backupManager.dataChanged() @@ -445,7 +451,7 @@ constructor( val appWidgetId: Int, val componentName: String, val rank: Int, + val spanY: Int, var providerInfo: AppWidgetProviderInfo? = null, - var spanY: Int = 3, ) } diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt index a687734ff499..3a04d026ee84 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt @@ -399,6 +399,10 @@ constructor( fun updateWidgetOrder(widgetIdToRankMap: Map) = widgetRepository.updateWidgetOrder(widgetIdToRankMap) + fun resizeWidget(appWidgetId: Int, spanY: Int, widgetIdToRankMap: Map) { + widgetRepository.resizeWidget(appWidgetId, spanY, widgetIdToRankMap) + } + /** Request to unpause work profile that is currently in quiet mode. */ fun unpauseWorkProfile() { managedProfileController.setWorkModeEnabled(true) @@ -449,6 +453,7 @@ constructor( providerInfo = widget.providerInfo, appWidgetHost = appWidgetHost, inQuietMode = isQuietModeEnabled(widget.providerInfo.profile), + size = CommunalContentSize.toSize(widget.spanY), ) } is CommunalWidgetContentModel.Pending -> { @@ -457,6 +462,7 @@ constructor( rank = widget.rank, componentName = widget.componentName, icon = widget.icon, + size = CommunalContentSize.toSize(widget.spanY), ) } } diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt index c2f6e85a33e4..4c2c094a4aea 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt @@ -62,11 +62,10 @@ sealed interface CommunalContentModel { val providerInfo: AppWidgetProviderInfo, val appWidgetHost: CommunalAppWidgetHost, val inQuietMode: Boolean, + override val size: CommunalContentSize, ) : WidgetContent { override val key = KEY.widget(appWidgetId) override val componentName: ComponentName = providerInfo.provider - // Widget size is always half. - override val size = CommunalContentSize.HALF /** Whether this widget can be reconfigured after it has already been added. */ val reconfigurable: Boolean @@ -79,11 +78,10 @@ sealed interface CommunalContentModel { override val appWidgetId: Int, override val rank: Int, val providerInfo: AppWidgetProviderInfo, + override val size: CommunalContentSize, ) : WidgetContent { override val key = KEY.disabledWidget(appWidgetId) override val componentName: ComponentName = providerInfo.provider - // Widget size is always half. - override val size = CommunalContentSize.HALF val appInfo: ApplicationInfo? get() = providerInfo.providerInfo?.applicationInfo @@ -93,11 +91,10 @@ sealed interface CommunalContentModel { override val appWidgetId: Int, override val rank: Int, override val componentName: ComponentName, + override val size: CommunalContentSize, val icon: Bitmap? = null, ) : WidgetContent { override val key = KEY.pendingWidget(appWidgetId) - // Widget size is always half. - override val size = CommunalContentSize.HALF } } diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalWidgetContentModel.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalWidgetContentModel.kt index bcbc8f65ce36..0c9ea789f3d1 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalWidgetContentModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalWidgetContentModel.kt @@ -25,13 +25,14 @@ import android.os.UserHandle sealed interface CommunalWidgetContentModel { val appWidgetId: Int val rank: Int + val spanY: Int /** Widget is ready to display */ data class Available( override val appWidgetId: Int, val providerInfo: AppWidgetProviderInfo, override val rank: Int, - val spanY: Int = 3, + override val spanY: Int, ) : CommunalWidgetContentModel /** Widget is pending installation */ @@ -41,6 +42,6 @@ sealed interface CommunalWidgetContentModel { val componentName: ComponentName, val icon: Bitmap?, val user: UserHandle, - val spanY: Int = 3, + override val spanY: Int, ) : CommunalWidgetContentModel } diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt index 0929d3e1bda9..e25ea4cbfb25 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt @@ -105,7 +105,7 @@ abstract class BaseCommunalViewModel( scene: SceneKey, loggingReason: String, transitionKey: TransitionKey? = null, - keyguardState: KeyguardState? = null + keyguardState: KeyguardState? = null, ) { communalSceneInteractor.changeScene(scene, loggingReason, transitionKey, keyguardState) } @@ -155,17 +155,10 @@ abstract class BaseCommunalViewModel( ) {} /** Called as the UI requests deleting a widget. */ - open fun onDeleteWidget( - id: Int, - componentName: ComponentName, - rank: Int, - ) {} + open fun onDeleteWidget(id: Int, componentName: ComponentName, rank: Int) {} /** Called as the UI detects a tap event on the widget. */ - open fun onTapWidget( - componentName: ComponentName, - rank: Int, - ) {} + open fun onTapWidget(componentName: ComponentName, rank: Int) {} /** * Called as the UI requests reordering widgets. @@ -176,10 +169,19 @@ abstract class BaseCommunalViewModel( */ open fun onReorderWidgets(widgetIdToRankMap: Map) {} + /** + * Called as the UI requests resizing a widget. + * + * @param appWidgetId The id of the widget being resized. + * @param spanY The new size of the widget, in grid spans. + * @param widgetIdToRankMap Mapping of the widget ids to its rank. Allows re-ordering widgets + * alongside the resize, in case resizing also requires re-ordering. This ensures the + * re-ordering is done in the same database transaction as the resize. + */ + open fun onResizeWidget(appWidgetId: Int, spanY: Int, widgetIdToRankMap: Map) {} + /** Called as the UI requests opening the widget editor with an optional preselected widget. */ - open fun onOpenWidgetEditor( - shouldOpenWidgetPickerOnStart: Boolean = false, - ) {} + open fun onOpenWidgetEditor(shouldOpenWidgetPickerOnStart: Boolean = false) {} /** Called as the UI requests to dismiss the CTA tile. */ open fun onDismissCtaTile() {} diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt index 65f0679c4266..3ae9250b2938 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt @@ -107,9 +107,9 @@ constructor( allOf( keyguardTransitionInteractor.isFinishedIn( scene = Scenes.Gone, - stateWithoutSceneContainer = KeyguardState.GONE + stateWithoutSceneContainer = KeyguardState.GONE, ), - communalInteractor.editModeOpen + communalInteractor.editModeOpen, ) .filter { it } @@ -128,17 +128,13 @@ constructor( componentName: ComponentName, user: UserHandle, rank: Int?, - configurator: WidgetConfigurator? + configurator: WidgetConfigurator?, ) { communalInteractor.addWidget(componentName, user, rank, configurator) metricsLogger.logAddWidget(componentName.flattenToString(), rank) } - override fun onDeleteWidget( - id: Int, - componentName: ComponentName, - rank: Int, - ) { + override fun onDeleteWidget(id: Int, componentName: ComponentName, rank: Int) { communalInteractor.deleteWidget(id) metricsLogger.logRemoveWidget(componentName.flattenToString(), rank) } @@ -146,6 +142,10 @@ constructor( override fun onReorderWidgets(widgetIdToRankMap: Map) = communalInteractor.updateWidgetOrder(widgetIdToRankMap) + override fun onResizeWidget(appWidgetId: Int, spanY: Int, widgetIdToRankMap: Map) { + communalInteractor.resizeWidget(appWidgetId, spanY, widgetIdToRankMap) + } + override fun onReorderWidgetStart() { // Clear selection status setSelectedKey(null) @@ -173,7 +173,7 @@ constructor( val announcementText = context.getString( R.string.accessibility_announcement_communal_widget_added, - widgetLabel + widgetLabel, ) accessibilityManager.sendAccessibilityEvent( AccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT).apply { @@ -187,7 +187,7 @@ constructor( /** Launch the widget picker activity using the given {@link ActivityResultLauncher}. */ suspend fun onOpenWidgetPicker( resources: Resources, - activityLauncher: ActivityResultLauncher + activityLauncher: ActivityResultLauncher, ): Boolean = withContext(backgroundDispatcher) { val widgets = communalInteractor.widgetContent.first() @@ -210,21 +210,21 @@ constructor( private fun getWidgetPickerActivityIntent( resources: Resources, - excludeList: ArrayList + excludeList: ArrayList, ): Intent? { return Intent(Intent.ACTION_PICK).apply { setPackage(launcherPackage) putExtra( EXTRA_DESIRED_WIDGET_WIDTH, - resources.getDimensionPixelSize(R.dimen.communal_widget_picker_desired_width) + resources.getDimensionPixelSize(R.dimen.communal_widget_picker_desired_width), ) putExtra( EXTRA_DESIRED_WIDGET_HEIGHT, - resources.getDimensionPixelSize(R.dimen.communal_widget_picker_desired_height) + resources.getDimensionPixelSize(R.dimen.communal_widget_picker_desired_height), ) putExtra( AppWidgetManager.EXTRA_CATEGORY_FILTER, - CommunalWidgetCategories.defaultCategories + CommunalWidgetCategories.defaultCategories, ) communalSettingsInteractor.workProfileUserDisallowedByDevicePolicy.value?.let { @@ -234,7 +234,7 @@ constructor( putExtra(EXTRA_PICKER_TITLE, resources.getString(R.string.communal_widget_picker_title)) putExtra( EXTRA_PICKER_DESCRIPTION, - resources.getString(R.string.communal_widget_picker_description) + resources.getString(R.string.communal_widget_picker_description), ) putParcelableArrayListExtra(EXTRA_ADDED_APP_WIDGETS_KEY, excludeList) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt index 1302faaf82ca..62d221dd9790 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt @@ -6,6 +6,7 @@ import android.content.pm.ActivityInfo import android.content.pm.ApplicationInfo import android.graphics.Bitmap import android.os.UserHandle +import com.android.systemui.communal.shared.model.CommunalContentSize import com.android.systemui.communal.shared.model.CommunalWidgetContentModel import com.android.systemui.communal.widgets.WidgetConfigurator import kotlinx.coroutines.CoroutineScope @@ -23,6 +24,10 @@ class FakeCommunalWidgetRepository(private val coroutineScope: CoroutineScope) : private var nextWidgetId = 1 + private fun updateListFromDatabase() { + _communalWidgets.value = fakeDatabase.values.sortedWith(compareBy { it.rank }).toList() + } + fun setCommunalWidgets(inventory: List) { _communalWidgets.value = inventory } @@ -49,6 +54,7 @@ class FakeCommunalWidgetRepository(private val coroutineScope: CoroutineScope) : rank: Int = 0, category: Int = AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD, userId: Int = 0, + spanY: Int = CommunalContentSize.HALF.span, ) { fakeDatabase[appWidgetId] = CommunalWidgetContentModel.Available( @@ -66,8 +72,9 @@ class FakeCommunalWidgetRepository(private val coroutineScope: CoroutineScope) : } } }, + spanY = spanY, ) - _communalWidgets.value = fakeDatabase.values.toList() + updateListFromDatabase() } fun addPendingWidget( @@ -84,8 +91,9 @@ class FakeCommunalWidgetRepository(private val coroutineScope: CoroutineScope) : componentName = ComponentName.unflattenFromString(componentName)!!, icon = icon, user = UserHandle(userId), + spanY = CommunalContentSize.HALF.span, ) - _communalWidgets.value = fakeDatabase.values.toList() + updateListFromDatabase() } override fun deleteWidget(widgetId: Int) { @@ -93,28 +101,54 @@ class FakeCommunalWidgetRepository(private val coroutineScope: CoroutineScope) : _communalWidgets.value = fakeDatabase.values.toList() } - override fun updateWidgetSpanY(widgetId: Int, spanY: Int) { - coroutineScope.launch { - fakeDatabase[widgetId]?.let { widget -> + private fun reorderDatabase(widgetIdToRankMap: Map) { + for ((id, rank) in widgetIdToRankMap) { + val widget = fakeDatabase[id] ?: continue + fakeDatabase[id] = when (widget) { is CommunalWidgetContentModel.Available -> { - fakeDatabase[widgetId] = widget.copy(spanY = spanY) + widget.copy(rank = rank) } is CommunalWidgetContentModel.Pending -> { - fakeDatabase[widgetId] = widget.copy(spanY = spanY) + widget.copy(rank = rank) } } - _communalWidgets.value = fakeDatabase.values.toList() - } } } + override fun updateWidgetOrder(widgetIdToRankMap: Map) { + reorderDatabase(widgetIdToRankMap) + updateListFromDatabase() + } + + override fun resizeWidget(appWidgetId: Int, spanY: Int, widgetIdToRankMap: Map) { + val widget = fakeDatabase[appWidgetId] ?: return + + fakeDatabase[appWidgetId] = + when (widget) { + is CommunalWidgetContentModel.Available -> { + widget.copy(spanY = spanY) + } + is CommunalWidgetContentModel.Pending -> { + widget.copy(spanY = spanY) + } + } + reorderDatabase(widgetIdToRankMap) + updateListFromDatabase() + } + override fun restoreWidgets(oldToNewWidgetIdMap: Map) {} override fun abortRestoreWidgets() {} private fun onConfigured(id: Int, providerInfo: AppWidgetProviderInfo, rank: Int) { - _communalWidgets.value += - listOf(CommunalWidgetContentModel.Available(id, providerInfo, rank)) + fakeDatabase[id] = + CommunalWidgetContentModel.Available( + appWidgetId = id, + providerInfo = providerInfo, + rank = rank, + spanY = CommunalContentSize.HALF.span, + ) + updateListFromDatabase() } } -- GitLab From de6a2867d9c2cdfe869897f26b8375b5ea50f632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Kozynski?= Date: Fri, 4 Oct 2024 08:54:53 -0400 Subject: [PATCH 058/447] Remove observing offset in composition Instead, use derived state as it can cause extra unneeded recompositions Test: manual Test: PagerDotsScreenshotTest Flag: com.android.systemui.qs_ui_refactor_compose_fragment Bug: 369156081 Change-Id: Id298c00f1943954e99c7362e1913d6b28f4af374 --- .../qs/panels/ui/compose/PagerDots.kt | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PagerDots.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PagerDots.kt index 331aabb532a5..0dedfe125d6f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PagerDots.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PagerDots.kt @@ -46,6 +46,8 @@ import androidx.compose.ui.unit.dp import kotlin.math.absoluteValue import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import platform.test.motion.compose.values.MotionTestValueKey +import platform.test.motion.compose.values.motionTestValues @Composable fun PagerDots( @@ -93,13 +95,22 @@ fun PagerDots( } Row( - modifier = modifier.wrapContentWidth().pagerDotsSemantics(pagerState, coroutineScope), + modifier = + modifier + .motionTestValues { activeMarkerWidth exportAs PagerDotsMotionKeys.indicatorWidth } + .wrapContentWidth() + .pagerDotsSemantics(pagerState, coroutineScope), horizontalArrangement = spacedBy(spaceSize), verticalAlignment = Alignment.CenterVertically, ) { // This means that the active rounded rect has to be drawn between the current page // and the previous one (as we are animating back), or the current one if not transitioning - val withPrevious = pagerState.currentPageOffsetFraction <= 0 || pagerState.isOverscrolling() + val withPrevious by + remember(pagerState) { + derivedStateOf { + pagerState.currentPageOffsetFraction <= 0 || pagerState.isOverscrolling() + } + } repeat(pagerState.pageCount) { page -> Canvas(Modifier.size(dotSize)) { val rtl = layoutDirection == LayoutDirection.Rtl @@ -127,6 +138,10 @@ fun PagerDots( } } +object PagerDotsMotionKeys { + val indicatorWidth = MotionTestValueKey("indicatorWidth") +} + private fun Modifier.pagerDotsSemantics( pagerState: PagerState, coroutineScope: CoroutineScope, -- GitLab From 4f0aee421c78eff716106cb42c4da7a570906ed5 Mon Sep 17 00:00:00 2001 From: Merissa Mitchell Date: Tue, 1 Oct 2024 18:09:46 -0700 Subject: [PATCH 059/447] [PIP2] Hook up expand icon to PipScheduler#scheduleExitPipViaExpand. Recall: http://recall/clips/52077335-9939-4ec1-a46e-830b59863d72 Bug: 322548939 Test: Launch PiP and test expand button manually. Flag: com.android.wm.shell.enable_pip2 Change-Id: I84244b34dab4757ccb3b96efcc52916617818841 --- .../src/com/android/wm/shell/pip2/phone/PipMotionHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java index 0324fdba0fbf..268c3a20a41a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java @@ -336,7 +336,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, } cancelPhysicsAnimation(); mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */); - // mPipTaskOrganizer.exitPip(skipAnimation ? 0 : LEAVE_PIP_DURATION, enterSplit); + mPipScheduler.scheduleExitPipViaExpand(); } /** -- GitLab From a5e8b705e335ce1000632ce30fe2f335913eadad Mon Sep 17 00:00:00 2001 From: Vladimir Komsiyski Date: Fri, 6 Sep 2024 16:55:41 +0200 Subject: [PATCH 060/447] API for setting the power state of a virtual device. Equivalent to a "virtual power button". "Pressing" it will turn all of the device's displays on/off, which will affect the relevant power groups and virtual display states. Only applied to trusted non-mirror displays, as they should be in the default power group. Bug: 285020111 Test: CTS Flag: android.companion.virtualdevice.flags.device_aware_display_power Change-Id: I083c48c5e773fb2f17f7bcea3df30a76aac65e97 --- core/api/system-current.txt | 2 + .../companion/virtual/IVirtualDevice.aidl | 12 ++++ .../virtual/VirtualDeviceInternal.java | 18 +++++ .../virtual/VirtualDeviceManager.java | 39 ++++++++++ .../companion/virtual/VirtualDeviceImpl.java | 72 +++++++++++++++++-- 5 files changed, 139 insertions(+), 4 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 4b6c62ecb032..93e592db9b1f 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3510,6 +3510,7 @@ package android.companion.virtual { method public int getDeviceId(); method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") @Nullable public String getPersistentDeviceId(); method @NonNull public java.util.List getVirtualSensorList(); + method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void goToSleep(); method public void launchPendingIntent(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer); method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void registerIntentInterceptor(@NonNull android.content.IntentFilter, @NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback); method public void removeActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener); @@ -3521,6 +3522,7 @@ package android.companion.virtual { method @FlaggedApi("android.companion.virtual.flags.vdm_custom_ime") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setDisplayImePolicy(int, int); method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setShowPointerIcon(boolean); method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void unregisterIntentInterceptor(@NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback); + method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void wakeUp(); } public final class VirtualDeviceParams implements android.os.Parcelable { diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl index 6fe0a7342216..7487396e9e82 100644 --- a/core/java/android/companion/virtual/IVirtualDevice.aidl +++ b/core/java/android/companion/virtual/IVirtualDevice.aidl @@ -93,6 +93,18 @@ interface IVirtualDevice { */ boolean canCreateMirrorDisplays(); + /* + * Turns off all trusted non-mirror displays of the virtual device. + */ + @EnforcePermission("CREATE_VIRTUAL_DEVICE") + void goToSleep(); + + /** + * Turns on all trusted non-mirror displays of the virtual device. + */ + @EnforcePermission("CREATE_VIRTUAL_DEVICE") + void wakeUp(); + /** * Closes the virtual device and frees all associated resources. */ diff --git a/core/java/android/companion/virtual/VirtualDeviceInternal.java b/core/java/android/companion/virtual/VirtualDeviceInternal.java index de20a68e52cb..053c7954b2a4 100644 --- a/core/java/android/companion/virtual/VirtualDeviceInternal.java +++ b/core/java/android/companion/virtual/VirtualDeviceInternal.java @@ -251,6 +251,24 @@ public class VirtualDeviceInternal { } } + @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) + void goToSleep() { + try { + mVirtualDevice.goToSleep(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) + void wakeUp() { + try { + mVirtualDevice.wakeUp(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + void launchPendingIntent( int displayId, @NonNull PendingIntent pendingIntent, diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java index 473ab27ee560..37d644aeef18 100644 --- a/core/java/android/companion/virtual/VirtualDeviceManager.java +++ b/core/java/android/companion/virtual/VirtualDeviceManager.java @@ -619,6 +619,45 @@ public final class VirtualDeviceManager { return mVirtualDeviceInternal.getVirtualSensorList(); } + /** + * Forces all trusted non-mirror displays of the virtual device to turn off. + * + *

    After this action, if all displays across all devices, including the default one, are + * off, then the physical device will be put to sleep. If the displays of this virtual + * device are already off, then nothing will happen.

    + * + *

    Overrides all the wake locks that are held. This is equivalent to pressing a "virtual + * power key" to turn off the screen.

    + * + * @see #wakeUp() + * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED + * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY + */ + @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) + @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) + public void goToSleep() { + mVirtualDeviceInternal.goToSleep(); + } + + /** + * Forces all trusted non-mirror displays of the virtual device to turn on. + * + *

    If the displays of this virtual device are turned off, then they will be turned on. + * Additionally, if the device is asleep it will be awoken. If the displays of this virtual + * device are already on, then nothing will happen.

    + * + *

    This is equivalent to pressing a "virtual power key" to turn on the screen.

    + * + * @see #goToSleep() + * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED + * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY + */ + @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) + @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) + public void wakeUp() { + mVirtualDeviceInternal.wakeUp(); + } + /** * Launches a given pending intent on the give display ID. * diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index 81ae717ca959..807e14e8c677 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -99,6 +99,7 @@ import android.os.PermissionEnforcer; import android.os.PowerManager; import android.os.RemoteException; import android.os.ResultReceiver; +import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; @@ -203,6 +204,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub private IVirtualDeviceSoundEffectListener mSoundEffectListener; private final DisplayManagerGlobal mDisplayManager; private final DisplayManagerInternal mDisplayManagerInternal; + private final PowerManager mPowerManager; @GuardedBy("mVirtualDeviceLock") private final Map mIntentInterceptors = new ArrayMap<>(); @NonNull @@ -418,6 +420,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mDevicePolicies = params.getDevicePolicies(); mDisplayManager = displayManager; mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); + mPowerManager = context.getSystemService(PowerManager.class); if (inputController == null) { mInputController = new InputController( context.getMainThreadHandler(), @@ -575,6 +578,52 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub : mAssociationInfo.getId(); } + @Override // Binder call + @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) + public void goToSleep() { + super.goToSleep_enforcePermission(); + final long now = SystemClock.uptimeMillis(); + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mVirtualDeviceLock) { + for (int i = 0; i < mVirtualDisplays.size(); i++) { + VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); + if (!wrapper.isTrusted() || wrapper.isMirror()) { + continue; + } + int displayId = mVirtualDisplays.keyAt(i); + mPowerManager.goToSleep(displayId, now, + PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, /* flags= */ 0); + } + } + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override // Binder call + @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) + public void wakeUp() { + super.wakeUp_enforcePermission(); + final long now = SystemClock.uptimeMillis(); + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mVirtualDeviceLock) { + for (int i = 0; i < mVirtualDisplays.size(); i++) { + VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); + if (!wrapper.isTrusted() || wrapper.isMirror()) { + continue; + } + int displayId = mVirtualDisplays.keyAt(i); + mPowerManager.wakeUp(now, PowerManager.WAKE_REASON_POWER_BUTTON, + "android.server.companion.virtual:DEVICE_ON", displayId); + } + } + } finally { + Binder.restoreCallingIdentity(ident); + } + } + @Override // Binder call public void launchPendingIntent(int displayId, PendingIntent pendingIntent, ResultReceiver resultReceiver) { @@ -1423,6 +1472,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub boolean isMirrorDisplay = mDisplayManagerInternal.getDisplayIdToMirror(displayId) != Display.INVALID_DISPLAY; gwpc.setDisplayId(displayId, isMirrorDisplay); + boolean isTrustedDisplay = + (mDisplayManagerInternal.getDisplayInfo(displayId).flags & Display.FLAG_TRUSTED) + == Display.FLAG_TRUSTED; boolean showPointer; synchronized (mVirtualDeviceLock) { @@ -1433,7 +1485,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } PowerManager.WakeLock wakeLock = createAndAcquireWakeLockForDisplay(displayId); - mVirtualDisplays.put(displayId, new VirtualDisplayWrapper(callback, gwpc, wakeLock)); + mVirtualDisplays.put(displayId, new VirtualDisplayWrapper(callback, gwpc, wakeLock, + isTrustedDisplay, isMirrorDisplay)); showPointer = mDefaultShowPointerIcon; } @@ -1444,8 +1497,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mInputController.setDisplayEligibilityForPointerCapture(/* isEligible= */ false, displayId); // WM throws a SecurityException if the display is untrusted. - if ((mDisplayManagerInternal.getDisplayInfo(displayId).flags & Display.FLAG_TRUSTED) - == Display.FLAG_TRUSTED) { + if (isTrustedDisplay) { mInputController.setDisplayImePolicy(displayId, WindowManager.DISPLAY_IME_POLICY_LOCAL); } @@ -1732,13 +1784,17 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub private final IVirtualDisplayCallback mToken; private final GenericWindowPolicyController mWindowPolicyController; private final PowerManager.WakeLock mWakeLock; + private final boolean mIsTrusted; + private final boolean mIsMirror; VirtualDisplayWrapper(@NonNull IVirtualDisplayCallback token, @NonNull GenericWindowPolicyController windowPolicyController, - @NonNull PowerManager.WakeLock wakeLock) { + @NonNull PowerManager.WakeLock wakeLock, boolean isTrusted, boolean isMirror) { mToken = Objects.requireNonNull(token); mWindowPolicyController = Objects.requireNonNull(windowPolicyController); mWakeLock = Objects.requireNonNull(wakeLock); + mIsTrusted = isTrusted; + mIsMirror = isMirror; } GenericWindowPolicyController getWindowPolicyController() { @@ -1749,6 +1805,14 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub return mWakeLock; } + boolean isTrusted() { + return mIsTrusted; + } + + boolean isMirror() { + return mIsMirror; + } + IVirtualDisplayCallback getToken() { return mToken; } -- GitLab From e7e595de7f59ed273401e4e941fbb24e22be9a57 Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Fri, 4 Oct 2024 11:18:37 -0400 Subject: [PATCH 061/447] Address some issues with ResizeableItemFrame 1. Use rememberUpdatedState to remember the resize callback, and ensure we always use the latest one in the event of recomposition. 2. Make sure we clear anchors when the layout info becomes unknown, such as when the item is scrolled out-of-view. 3. Instead of using the index, use a key to locate items. The index may change if the item is moved as part of resizing, which will cause a recomposition. However, the key should remain stable. Bug: 368056517 Test: atest ResizeableItemFrameViewModelTest Flag: EXEMPT component is not yet used anywhere Change-Id: I17d4fc1180866d18bfb61f8de739e794e80da886 --- .../ui/compose/ResizeableItemFrame.kt | 25 +++++++++++-------- .../ResizeableItemFrameViewModelTest.kt | 21 ++++++++++++++-- .../viewmodel/ResizeableItemFrameViewModel.kt | 23 ++++++++++------- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResizeableItemFrame.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResizeableItemFrame.kt index fda46b855a65..ef62eb726e2b 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResizeableItemFrame.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResizeableItemFrame.kt @@ -30,6 +30,8 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.grid.LazyGridState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -52,12 +54,11 @@ import com.android.systemui.communal.ui.viewmodel.ResizeableItemFrameViewModel import com.android.systemui.lifecycle.rememberViewModel import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.filterNotNull @Composable private fun UpdateGridLayoutInfo( viewModel: ResizeableItemFrameViewModel, - index: Int, + key: String, gridState: LazyGridState, minItemSpan: Int, gridContentPadding: PaddingValues, @@ -67,7 +68,7 @@ private fun UpdateGridLayoutInfo( LaunchedEffect( density, viewModel, - index, + key, gridState, minItemSpan, gridContentPadding, @@ -85,9 +86,8 @@ private fun UpdateGridLayoutInfo( snapshotFlow { gridState.layoutInfo.maxSpan }, snapshotFlow { gridState.layoutInfo.viewportSize.height }, snapshotFlow { - gridState.layoutInfo.visibleItemsInfo.firstOrNull { it.index == index } - } - .filterNotNull(), + gridState.layoutInfo.visibleItemsInfo.firstOrNull { it.key == key } + }, ::Triple, ) .collectLatest { (maxItemSpan, viewportHeightPx, itemInfo) -> @@ -97,8 +97,8 @@ private fun UpdateGridLayoutInfo( viewportHeightPx, maxItemSpan, minItemSpan, - itemInfo.row, - itemInfo.span, + itemInfo?.row, + itemInfo?.span, ) } } @@ -161,7 +161,7 @@ private fun BoxScope.DragHandle( */ @Composable fun ResizableItemFrame( - index: Int, + key: String, gridState: LazyGridState, minItemSpan: Int, gridContentPadding: PaddingValues, @@ -177,6 +177,7 @@ fun ResizableItemFrame( content: @Composable () -> Unit, ) { val brush = SolidColor(outlineColor) + val onResizeUpdated by rememberUpdatedState(onResize) val viewModel = rememberViewModel(traceName = "ResizeableItemFrame.viewModel") { ResizeableItemFrameViewModel() @@ -230,13 +231,15 @@ fun ResizableItemFrame( UpdateGridLayoutInfo( viewModel, - index, + key, gridState, minItemSpan, gridContentPadding, verticalArrangement, ) - LaunchedEffect(viewModel) { viewModel.resizeInfo.collectLatest(onResize) } + LaunchedEffect(viewModel) { + viewModel.resizeInfo.collectLatest { info -> onResizeUpdated(info) } + } } } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt index e1946fc7bc6f..f0d88ab41ad4 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt @@ -254,6 +254,23 @@ class ResizeableItemFrameViewModelTest : SysuiTestCase() { assertThat(resizeInfo).isEqualTo(ResizeInfo(-1, DragHandle.BOTTOM)) } + @Test + fun testRowInfoBecomesNull_revertsBackToDefault() = + testScope.runTest { + val gridLayout = singleSpanGrid.copy(maxItemSpan = 3, currentRow = 1) + updateGridLayout(gridLayout) + + val topState = underTest.topDragState + assertThat(topState.anchors.toList()).containsExactly(0 to 0f, -1 to -30f) + + val bottomState = underTest.bottomDragState + assertThat(bottomState.anchors.toList()).containsExactly(0 to 0f, 1 to 30f) + + updateGridLayout(gridLayout.copy(currentRow = null)) + assertThat(topState.anchors.toList()).containsExactly(0 to 0f) + assertThat(bottomState.anchors.toList()).containsExactly(0 to 0f) + } + @Test(expected = IllegalArgumentException::class) fun testIllegalState_maxSpanSmallerThanMinSpan() = testScope.runTest { @@ -317,7 +334,7 @@ class ResizeableItemFrameViewModelTest : SysuiTestCase() { val viewportHeightPx: Int, val maxItemSpan: Int, val minItemSpan: Int, - val currentRow: Int, - val currentSpan: Int, + val currentRow: Int?, + val currentSpan: Int?, ) } diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModel.kt index 7aad33da97b6..87fcdd7b97ee 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModel.kt @@ -25,8 +25,7 @@ import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.dropWhile -import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge @@ -45,7 +44,10 @@ data class ResizeInfo( val spans: Int, /** The drag handle which was used to resize the element. */ val fromHandle: DragHandle, -) +) { + /** Whether we are expanding. If false, then we are shrinking. */ + val isExpanding = spans > 0 +} class ResizeableItemFrameViewModel : ExclusiveActivatable() { private data class GridLayoutInfo( @@ -73,7 +75,7 @@ class ResizeableItemFrameViewModel : ExclusiveActivatable() { snapshotFlow { bottomDragState.settledValue } .map { ResizeInfo(it, DragHandle.BOTTOM) }, ) - .dropWhile { it.spans == 0 } + .filter { it.spans != 0 } .distinctUntilChanged() /** @@ -86,9 +88,13 @@ class ResizeableItemFrameViewModel : ExclusiveActivatable() { viewportHeightPx: Int, maxItemSpan: Int, minItemSpan: Int, - currentRow: Int, - currentSpan: Int, + currentRow: Int?, + currentSpan: Int?, ) { + if (currentSpan == null || currentRow == null) { + gridLayoutInfo.value = null + return + } require(maxItemSpan >= minItemSpan) { "Maximum item span of $maxItemSpan cannot be less than the minimum span of $minItemSpan" } @@ -114,10 +120,10 @@ class ResizeableItemFrameViewModel : ExclusiveActivatable() { private fun calculateAnchorsForHandle( handle: DragHandle, - layoutInfo: GridLayoutInfo, + layoutInfo: GridLayoutInfo?, ): DraggableAnchors { - if (!isDragAllowed(handle, layoutInfo)) { + if (layoutInfo == null || !isDragAllowed(handle, layoutInfo)) { return DraggableAnchors { 0 at 0f } } @@ -188,7 +194,6 @@ class ResizeableItemFrameViewModel : ExclusiveActivatable() { override suspend fun onActivated(): Nothing { coroutineScope("ResizeableItemFrameViewModel.onActivated") { gridLayoutInfo - .filterNotNull() .onEach { layoutInfo -> topDragState.updateAnchors( calculateAnchorsForHandle(DragHandle.TOP, layoutInfo) -- GitLab From 2b1db2d744fbf1992cc5f235b131fa653af3bbc0 Mon Sep 17 00:00:00 2001 From: Mina Granic Date: Fri, 4 Oct 2024 14:26:02 +0000 Subject: [PATCH 062/447] Create Robot for Desktop Windowing testing. Flag: EXEMPT tests only Bug: 350460645 Test: atest WmTests:AppCompatCameraPolicyTest Test: atest WmTests:AppCompatOrientationPolicyTest Change-Id: Ia06537f494ef4334f4004535ddb86c3d5e2644ed --- .../server/wm/AppCompatCameraPolicyTest.java | 28 +++++++------------ .../wm/AppCompatOrientationPolicyTest.java | 10 +------ .../android/server/wm/AppCompatRobotBase.java | 8 ++++++ .../server/wm/DesktopWindowingRobot.java | 28 +++++++++++++++++++ 4 files changed, 47 insertions(+), 27 deletions(-) create mode 100644 services/tests/wmtests/src/com/android/server/wm/DesktopWindowingRobot.java diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java index 9b9040b439c7..cb5afd830619 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java @@ -18,7 +18,6 @@ package com.android.server.wm; import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.wm.AppCompatCameraPolicy.isTreatmentEnabledForActivity; import static com.android.server.wm.AppCompatCameraPolicy.shouldOverrideMinAspectRatioForCamera; @@ -26,7 +25,6 @@ import static com.android.window.flags.Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKT import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; import android.compat.testing.PlatformCompatChangeRule; import android.platform.test.annotations.DisableFlags; @@ -90,7 +88,7 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase { @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING) public void testCameraCompatFreeformPolicy_presentWhenEnabledAndDW() { runTestScenario((robot) -> { - robot.allowEnterDesktopMode(/* isAllowed= */ true); + robot.dw().allowEnterDesktopMode(/* isAllowed= */ true); robot.activity().createActivityWithComponentInNewTaskAndDisplay(); robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ true); }); @@ -100,7 +98,7 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase { @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING) public void testCameraCompatFreeformPolicy_notPresentWhenNoDW() { runTestScenario((robot) -> { - robot.allowEnterDesktopMode(/* isAllowed= */ false); + robot.dw().allowEnterDesktopMode(/* isAllowed= */ false); robot.activity().createActivityWithComponentInNewTaskAndDisplay(); robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ false); }); @@ -110,7 +108,7 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase { @DisableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING) public void testCameraCompatFreeformPolicy_notPresentWhenNoFlag() { runTestScenario((robot) -> { - robot.allowEnterDesktopMode(/* isAllowed= */ true); + robot.dw().allowEnterDesktopMode(/* isAllowed= */ true); robot.activity().createActivityWithComponentInNewTaskAndDisplay(); robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ false); }); @@ -120,7 +118,7 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase { @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING) public void testCameraCompatFreeformPolicy_notPresentWhenNoFlagAndNoDW() { runTestScenario((robot) -> { - robot.allowEnterDesktopMode(/* isAllowed= */ false); + robot.dw().allowEnterDesktopMode(/* isAllowed= */ false); robot.activity().createActivityWithComponentInNewTaskAndDisplay(); robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ false); }); @@ -130,7 +128,7 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase { @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING) public void testCameraCompatFreeformPolicy_startedWhenEnabledAndDW() { runTestScenario((robot) -> { - robot.allowEnterDesktopMode(/* isAllowed= */ true); + robot.dw().allowEnterDesktopMode(/* isAllowed= */ true); robot.activity().createActivityWithComponentInNewTaskAndDisplay(); robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ true); robot.checkTopActivityCameraCompatFreeformPolicyIsRunning(); @@ -141,7 +139,7 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase { @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING) public void testCameraStateManager_existsWhenCameraCompatFreeformExists() { runTestScenario((robot) -> { - robot.allowEnterDesktopMode(true); + robot.dw().allowEnterDesktopMode(true); robot.activity().createActivityWithComponentInNewTaskAndDisplay(); robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ true); robot.checkTopActivityHasCameraStateMonitor(/* exists= */ true); @@ -152,7 +150,7 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase { @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING) public void testCameraStateManager_startedWhenCameraCompatFreeformExists() { runTestScenario((robot) -> { - robot.allowEnterDesktopMode(true); + robot.dw().allowEnterDesktopMode(true); robot.activity().createActivityWithComponentInNewTaskAndDisplay(); robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ true); robot.checkTopActivityHasCameraStateMonitor(/* exists= */ true); @@ -224,7 +222,7 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase { public void testShouldOverrideMinAspectRatioForCamera_whenCameraIsNotRunning() { runTestScenario((robot) -> { robot.applyOnActivity((a)-> { - robot.allowEnterDesktopMode(true); + robot.dw().allowEnterDesktopMode(true); robot.conf().enableCameraCompatTreatmentAtBuildTime(/* enabled= */ true); a.createActivityWithComponentInNewTaskAndDisplay(); a.setIsCameraRunningAndWindowingModeEligibleFullscreen(/* enabled */ false); @@ -239,7 +237,7 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase { public void testShouldOverrideMinAspectRatioForCamera_whenCameraIsRunning_overrideDisabled() { runTestScenario((robot) -> { robot.applyOnActivity((a)-> { - robot.allowEnterDesktopMode(true); + robot.dw().allowEnterDesktopMode(true); robot.conf().enableCameraCompatTreatmentAtBuildTime(/* enabled= */ true); a.createActivityWithComponentInNewTaskAndDisplay(); a.setIsCameraRunningAndWindowingModeEligibleFullscreen(/* active */ true); @@ -270,7 +268,7 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase { public void testShouldOverrideMinAspectRatioForCameraFreeform_cameraRunning_overrideEnabled() { runTestScenario((robot) -> { robot.applyOnActivity((a)-> { - robot.allowEnterDesktopMode(true); + robot.dw().allowEnterDesktopMode(true); a.createActivityWithComponentInNewTaskAndDisplay(); a.setIsCameraRunningAndWindowingModeEligibleFreeform(/* active */ true); }); @@ -346,11 +344,5 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase { void checkShouldOverrideMinAspectRatioForCamera(boolean expected) { assertEquals(expected, shouldOverrideMinAspectRatioForCamera(activity().top())); } - - // TODO(b/350460645): Create Desktop Windowing Robot to reuse common functionalities. - void allowEnterDesktopMode(boolean isAllowed) { - doReturn(isAllowed).when(() -> - DesktopModeHelper.canEnterDesktopMode(any())); - } } } diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java index 76101d51f931..09ed9baba096 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java @@ -37,12 +37,10 @@ import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERR import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE; import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.window.flags.Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING; import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import android.compat.testing.PlatformCompatChangeRule; @@ -338,7 +336,7 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase { public void testOverrideOrientationIfNeeded_fullscrOverrideFreeform_cameraActivity_unchanged() { runTestScenario((robot) -> { robot.applyOnActivity((a) -> { - robot.allowEnterDesktopMode(true); + robot.dw().allowEnterDesktopMode(true); a.createActivityWithComponentInNewTaskAndDisplay(); a.setIsCameraRunningAndWindowingModeEligibleFreeform(false); }); @@ -610,11 +608,5 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase { private AppCompatOrientationPolicy getTopAppCompatOrientationPolicy() { return activity().top().mAppCompatController.getOrientationPolicy(); } - - // TODO(b/350460645): Create Desktop Windowing Robot to reuse common functionalities. - void allowEnterDesktopMode(boolean isAllowed) { - doReturn(isAllowed).when(() -> - DesktopModeHelper.canEnterDesktopMode(any())); - } } } diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java index 5f2a63aa9eab..0d929abeb34a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java @@ -39,6 +39,8 @@ abstract class AppCompatRobotBase { private final AppCompatComponentPropRobot mOptPropRobot; @NonNull private final AppCompatResourcesRobot mResourcesRobot; + @NonNull + private final DesktopWindowingRobot mDesktopWindowingRobot; AppCompatRobotBase(@NonNull WindowManagerService wm, @NonNull ActivityTaskManagerService atm, @@ -51,6 +53,7 @@ abstract class AppCompatRobotBase { new AppCompatConfigurationRobot(wm.mAppCompatConfiguration); mOptPropRobot = new AppCompatComponentPropRobot(wm); mResourcesRobot = new AppCompatResourcesRobot(wm.mContext.getResources()); + mDesktopWindowingRobot = new DesktopWindowingRobot(); } AppCompatRobotBase(@NonNull WindowManagerService wm, @@ -111,6 +114,11 @@ abstract class AppCompatRobotBase { return mResourcesRobot; } + @NonNull + DesktopWindowingRobot dw() { + return mDesktopWindowingRobot; + } + void applyOnResources(@NonNull Consumer consumer) { consumer.accept(mResourcesRobot); } diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopWindowingRobot.java b/services/tests/wmtests/src/com/android/server/wm/DesktopWindowingRobot.java new file mode 100644 index 000000000000..285a5e246e0c --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/DesktopWindowingRobot.java @@ -0,0 +1,28 @@ +/* + * 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.wm; + +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; + +import static org.mockito.ArgumentMatchers.any; + +/** Robot for changing desktop windowing properties. */ +class DesktopWindowingRobot { + void allowEnterDesktopMode(boolean isAllowed) { + doReturn(isAllowed).when(() -> DesktopModeHelper.canEnterDesktopMode(any())); + } +} -- GitLab From b81782302015210c1e1383738c0c1cd0b14f239d Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Fri, 4 Oct 2024 11:56:27 -0400 Subject: [PATCH 063/447] Allow widgets to be resized on glanceable hub Adds resize frame around the widget content of the hub in edit mode, and implements resize logic in ContentListState Bug: 368056517 Test: manually on device by expanding and shrinking widgets Flag: com.android.systemui.communal_widget_resizing Change-Id: I3ecba4418fa726dc438134db87cfd2dea0b1041f --- .../communal/ui/compose/CommunalHub.kt | 105 +++++++++++++----- .../communal/ui/compose/ContentListState.kt | 45 ++++++-- .../communal/ui/compose/GridDragDropState.kt | 26 +++-- 3 files changed, 134 insertions(+), 42 deletions(-) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt index bcd333710497..7fb4c537641b 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt @@ -148,6 +148,7 @@ import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp @@ -165,6 +166,7 @@ import com.android.compose.ui.graphics.painter.rememberDrawablePainter import com.android.internal.R.dimen.system_app_widget_background_radius import com.android.systemui.Flags import com.android.systemui.Flags.communalTimerFlickerFix +import com.android.systemui.Flags.communalWidgetResizing import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.shared.model.CommunalContentSize import com.android.systemui.communal.shared.model.CommunalScenes @@ -176,6 +178,7 @@ import com.android.systemui.communal.ui.view.layout.sections.CommunalAppWidgetSe import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel import com.android.systemui.communal.ui.viewmodel.CommunalViewModel +import com.android.systemui.communal.ui.viewmodel.ResizeInfo import com.android.systemui.communal.util.DensityUtils.Companion.adjustedDp import com.android.systemui.communal.widgets.SmartspaceAppWidgetHostView import com.android.systemui.communal.widgets.WidgetConfigurator @@ -639,6 +642,38 @@ private fun ObserveNewWidgetAddedEffect( } } +@Composable +private fun ResizableItemFrameWrapper( + key: String, + gridState: LazyGridState, + minItemSpan: Int, + gridContentPadding: PaddingValues, + verticalArrangement: Arrangement.Vertical, + enabled: Boolean, + modifier: Modifier = Modifier, + alpha: () -> Float = { 1f }, + onResize: (info: ResizeInfo) -> Unit = {}, + content: @Composable (modifier: Modifier) -> Unit, +) { + if (!communalWidgetResizing()) { + content(modifier) + } else { + ResizableItemFrame( + key = key, + gridState = gridState, + minItemSpan = minItemSpan, + gridContentPadding = gridContentPadding, + verticalArrangement = verticalArrangement, + enabled = enabled, + alpha = alpha, + modifier = modifier, + onResize = onResize, + ) { + content(Modifier) + } + } +} + @OptIn(ExperimentalFoundationApi::class) @Composable private fun BoxScope.CommunalHubLazyGrid( @@ -695,13 +730,14 @@ private fun BoxScope.CommunalHubLazyGrid( gridModifier = gridModifier.height(hubDimensions.GridHeight) } + val itemArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing) LazyHorizontalGrid( modifier = gridModifier, state = gridState, rows = GridCells.Fixed(CommunalContentSize.FULL.span), contentPadding = contentPadding, - horizontalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing), - verticalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing), + horizontalArrangement = itemArrangement, + verticalArrangement = itemArrangement, ) { itemsIndexed( items = list, @@ -710,35 +746,54 @@ private fun BoxScope.CommunalHubLazyGrid( span = { _, item -> GridItemSpan(item.size.span) }, ) { index, item -> val size = SizeF(Dimensions.CardWidth.value, item.size.dp().value) - val cardModifier = Modifier.requiredSize(width = size.width.dp, height = size.height.dp) + val selected = item.key == selectedKey.value + val dpSize = DpSize(size.width.dp, size.height.dp) + if (viewModel.isEditMode && dragDropState != null) { - val selected = item.key == selectedKey.value - DraggableItem( + val outlineAlpha by + animateFloatAsState( + targetValue = if (selected) 1f else 0f, + animationSpec = spring(stiffness = Spring.StiffnessMediumLow), + label = "Widget resizing outline alpha", + ) + ResizableItemFrameWrapper( + key = item.key, + gridState = gridState, + minItemSpan = CommunalContentSize.HALF.span, + gridContentPadding = contentPadding, + verticalArrangement = itemArrangement, + enabled = selected, + alpha = { outlineAlpha }, modifier = - if (dragDropState.draggingItemIndex == index) { - Modifier - } else { + Modifier.requiredSize(dpSize).thenIf( + dragDropState.draggingItemIndex != index + ) { Modifier.animateItem( placementSpec = spring(stiffness = Spring.StiffnessMediumLow) ) }, - dragDropState = dragDropState, - selected = selected, - enabled = item.isWidgetContent(), - index = index, - ) { isDragging -> - CommunalContent( - modifier = cardModifier, - model = item, - viewModel = viewModel, - size = size, - selected = selected && !isDragging, - widgetConfigurator = widgetConfigurator, + onResize = { resizeInfo -> contentListState.resize(index, resizeInfo) }, + ) { modifier -> + DraggableItem( + modifier = modifier, + dragDropState = dragDropState, + selected = selected, + enabled = item.isWidgetContent(), index = index, - contentListState = contentListState, - interactionHandler = interactionHandler, - widgetSection = widgetSection, - ) + ) { isDragging -> + CommunalContent( + modifier = Modifier.fillMaxSize(), + model = item, + viewModel = viewModel, + size = size, + selected = selected && !isDragging, + widgetConfigurator = widgetConfigurator, + index = index, + contentListState = contentListState, + interactionHandler = interactionHandler, + widgetSection = widgetSection, + ) + } } } else { CommunalContent( @@ -746,7 +801,7 @@ private fun BoxScope.CommunalHubLazyGrid( viewModel = viewModel, size = size, selected = false, - modifier = cardModifier.animateItem(), + modifier = Modifier.requiredSize(dpSize).animateItem(), index = index, contentListState = contentListState, interactionHandler = interactionHandler, diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt index 11373577eedb..6e30575a684d 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt @@ -21,8 +21,12 @@ import android.os.UserHandle import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.runtime.toMutableStateList +import com.android.systemui.Flags.communalWidgetResizing import com.android.systemui.communal.domain.model.CommunalContentModel +import com.android.systemui.communal.shared.model.CommunalContentSize import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel +import com.android.systemui.communal.ui.viewmodel.DragHandle +import com.android.systemui.communal.ui.viewmodel.ResizeInfo import com.android.systemui.communal.widgets.WidgetConfigurator @Composable @@ -35,15 +39,11 @@ fun rememberContentListState( ContentListState( communalContent, { componentName, user, rank -> - viewModel.onAddWidget( - componentName, - user, - rank, - widgetConfigurator, - ) + viewModel.onAddWidget(componentName, user, rank, widgetConfigurator) }, viewModel::onDeleteWidget, viewModel::onReorderWidgets, + viewModel::onResizeWidget, ) } } @@ -59,6 +59,7 @@ internal constructor( private val onAddWidget: (componentName: ComponentName, user: UserHandle, rank: Int) -> Unit, private val onDeleteWidget: (id: Int, componentName: ComponentName, rank: Int) -> Unit, private val onReorderWidgets: (widgetIdToRankMap: Map) -> Unit, + private val onResizeWidget: (id: Int, spanY: Int, widgetIdToRankMap: Map) -> Unit, ) { var list = communalContent.toMutableStateList() private set @@ -77,6 +78,36 @@ internal constructor( } } + /** Resize a widget, possibly re-ordering widgets if needed. */ + fun resize(index: Int, resizeInfo: ResizeInfo) { + val item = list[index] + val currentSpan = item.size.span + val newSpan = currentSpan + resizeInfo.spans + // Only widgets can be resized + if ( + !communalWidgetResizing() || + currentSpan == newSpan || + item !is CommunalContentModel.WidgetContent.Widget + ) { + return + } + list[index] = item.copy(size = CommunalContentSize.toSize(newSpan)) + val prevItem = list.getOrNull(index - 1) + // Check if we have to update indices of items to accommodate the resize. + val widgetIdToRankMap: Map = + if ( + resizeInfo.isExpanding && + resizeInfo.fromHandle == DragHandle.TOP && + prevItem is CommunalContentModel.WidgetContent.Widget + ) { + onMove(index - 1, index) + mapOf(prevItem.appWidgetId to index, item.appWidgetId to index - 1) + } else { + emptyMap() + } + onResizeWidget(item.appWidgetId, newSpan, widgetIdToRankMap) + } + /** * Persists the new order with all the movements happened during drag operations & the new * widget drop (if applicable). @@ -91,7 +122,7 @@ internal constructor( fun onSaveList( newItemComponentName: ComponentName? = null, newItemUser: UserHandle? = null, - newItemIndex: Int? = null + newItemIndex: Int? = null, ) { // New widget added to the grid. Other widgets are shifted as needed at the database level. if (newItemComponentName != null && newItemUser != null && newItemIndex != null) { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt index 20ee13166c08..101385f88825 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt @@ -42,6 +42,7 @@ import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.toOffset import androidx.compose.ui.unit.toSize +import com.android.systemui.Flags.communalWidgetResizing import com.android.systemui.communal.ui.compose.extensions.firstItemAtOffset import com.android.systemui.communal.ui.compose.extensions.plus import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel @@ -65,7 +66,7 @@ fun rememberGridDragDropState( state = gridState, contentListState = contentListState, scope = scope, - updateDragPositionForRemove = updateDragPositionForRemove + updateDragPositionForRemove = updateDragPositionForRemove, ) } LaunchedEffect(state) { @@ -90,7 +91,7 @@ internal constructor( private val state: LazyGridState, private val contentListState: ContentListState, private val scope: CoroutineScope, - private val updateDragPositionForRemove: (offset: Offset) -> Boolean + private val updateDragPositionForRemove: (offset: Offset) -> Boolean, ) { var draggingItemIndex by mutableStateOf(null) private set @@ -122,12 +123,12 @@ internal constructor( offset: Offset, screenWidth: Int, layoutDirection: LayoutDirection, - contentOffset: Offset + contentOffset: Offset, ): Boolean { val normalizedOffset = Offset( if (layoutDirection == LayoutDirection.Ltr) offset.x else screenWidth - offset.x, - offset.y + offset.y, ) state.layoutInfo.visibleItemsInfo .filter { item -> contentListState.isItemEditable(item.index) } @@ -248,7 +249,7 @@ fun Modifier.dragContainer( offset, screenWidth, layoutDirection, - contentOffset + contentOffset, ) ) { viewModel.onReorderWidgetStart() @@ -261,7 +262,7 @@ fun Modifier.dragContainer( onDragCancel = { dragDropState.onDragInterrupted() viewModel.onReorderWidgetCancel() - } + }, ) } ) @@ -276,7 +277,7 @@ fun LazyGridItemScope.DraggableItem( enabled: Boolean, selected: Boolean, modifier: Modifier = Modifier, - content: @Composable (isDragging: Boolean) -> Unit + content: @Composable (isDragging: Boolean) -> Unit, ) { if (!enabled) { return content(false) @@ -286,7 +287,7 @@ fun LazyGridItemScope.DraggableItem( val itemAlpha: Float by animateFloatAsState( targetValue = if (dragDropState.isDraggingToRemove) 0.5f else 1f, - label = "DraggableItemAlpha" + label = "DraggableItemAlpha", ) val direction = LocalLayoutDirection.current val draggingModifier = @@ -303,12 +304,17 @@ fun LazyGridItemScope.DraggableItem( // Animate the highlight alpha manually as alpha modifier (and AnimatedVisibility) clips the // widget to bounds, which cuts off the highlight as we are drawing outside the widget bounds. + val highlightSelected = !communalWidgetResizing() && selected val alpha by animateFloatAsState( targetValue = - if ((dragging || selected) && !dragDropState.isDraggingToRemove) 1f else 0f, + if ((dragging || highlightSelected) && !dragDropState.isDraggingToRemove) { + 1f + } else { + 0f + }, animationSpec = spring(stiffness = Spring.StiffnessMediumLow), - label = "Widget outline alpha" + label = "Widget outline alpha", ) Box(modifier) { -- GitLab From fd40803f5f5c574e60a5dbc4bfea9fd9f16eb2fe Mon Sep 17 00:00:00 2001 From: Marcelo Arteiro Date: Fri, 4 Oct 2024 13:45:49 +0000 Subject: [PATCH 064/447] Fixes issue that would switch dark mode off when in scheduled mode Bug: 324548844 Flag: EXEMPT bugfix Test: Manual Change-Id: Ie13a88f114112dfeb22fb6928892ae6d36fbb6e5 --- .../java/com/android/server/UiModeManagerService.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index 7daf15821047..f8857d3e152a 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -2064,12 +2064,14 @@ final class UiModeManagerService extends SystemService { private void updateComputedNightModeLocked(boolean activate) { boolean newComputedValue = activate; + boolean appliedOverrides = false; if (mNightMode.get() != MODE_NIGHT_YES && mNightMode.get() != UiModeManager.MODE_NIGHT_NO) { if (mOverrideNightModeOn && !newComputedValue) { newComputedValue = true; } else if (mOverrideNightModeOff && newComputedValue) { newComputedValue = false; } + appliedOverrides = true; } if (modesApi()) { @@ -2079,8 +2081,10 @@ final class UiModeManagerService extends SystemService { case (UiModeManager.MODE_ATTENTION_THEME_OVERLAY_DAY) -> false; default -> newComputedValue; // case OFF }; - } else { - mComputedNightMode = newComputedValue; + } + + if (appliedOverrides) { + return; } if (mNightMode.get() != MODE_NIGHT_AUTO || (mTwilightManager != null -- GitLab From 85b26324b3a6d35a7ef1c61257879004ffed9bc6 Mon Sep 17 00:00:00 2001 From: Matt Casey Date: Fri, 4 Oct 2024 15:56:18 +0000 Subject: [PATCH 065/447] Always instantiate sound controller There is only ever one screenshotcontroller (regardless of flags), so we should always instantiate the sound controller. Bug: 371564464 Flag: EXEMPT minor bugfix Test: Manual build/test Change-Id: Ibca0c83504d24b7e1cd84e7e9db6e3822b478b71 --- .../screenshot/ScreenshotController.kt | 27 +++---------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt index 0806be8d6bb2..fca29e1122d0 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.kt @@ -60,7 +60,6 @@ import java.util.concurrent.Executor import java.util.concurrent.ExecutorService import java.util.concurrent.Executors import java.util.function.Consumer -import javax.inject.Provider import kotlin.math.abs /** Controls the state and flow for screenshots. */ @@ -73,7 +72,7 @@ internal constructor( screenshotNotificationsControllerFactory: ScreenshotNotificationsController.Factory, screenshotActionsControllerFactory: ScreenshotActionsController.Factory, actionExecutorFactory: ActionExecutor.Factory, - screenshotSoundControllerProvider: Provider, + private val screenshotSoundController: ScreenshotSoundController, private val uiEventLogger: UiEventLogger, private val imageExporter: ImageExporter, private val imageCapture: ImageCapture, @@ -98,7 +97,6 @@ internal constructor( private val actionExecutor: ActionExecutor private val copyBroadcastReceiver: BroadcastReceiver - private var screenshotSoundController: ScreenshotSoundController? = null private var screenBitmap: Bitmap? = null private var screenshotTakenInPortrait = false private var screenshotAnimation: Animator? = null @@ -137,14 +135,6 @@ internal constructor( actionExecutor = actionExecutorFactory.create(window.window, viewProxy) { finishDismiss() } actionsController = screenshotActionsControllerFactory.getController(actionExecutor) - // Sound is only reproduced from the controller of the default display. - screenshotSoundController = - if (display.displayId == Display.DEFAULT_DISPLAY) { - screenshotSoundControllerProvider.get() - } else { - null - } - copyBroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { @@ -302,7 +292,7 @@ internal constructor( // Any cleanup needed when the service is being destroyed. override fun onDestroy() { removeWindow() - releaseMediaPlayer() + screenshotSoundController.releaseScreenshotSoundAsync() releaseContext() bgExecutor.shutdown() } @@ -313,10 +303,6 @@ internal constructor( context.release() } - private fun releaseMediaPlayer() { - screenshotSoundController?.releaseScreenshotSoundAsync() - } - /** Update resources on configuration change. Reinflate for theme/color changes. */ private fun reloadAssets() { if (LogConfig.DEBUG_UI) { @@ -442,18 +428,13 @@ internal constructor( viewProxy.stopInputListening() } - private fun playCameraSoundIfNeeded() { - // the controller is not-null only on the default display controller - screenshotSoundController?.playScreenshotSoundAsync() - } - /** * Save the bitmap but don't show the normal screenshot UI.. just a toast (or notification on * failure). */ private fun saveScreenshotAndToast(screenshot: ScreenshotData, finisher: Consumer) { // Play the shutter sound to notify that we've taken a screenshot - playCameraSoundIfNeeded() + screenshotSoundController.playScreenshotSoundAsync() saveScreenshotInBackground(screenshot, UUID.randomUUID(), finisher) { result: ImageExporter.Result -> @@ -482,7 +463,7 @@ internal constructor( viewProxy.createScreenshotDropInAnimation(screenRect, showFlash).apply { doOnEnd { onAnimationComplete?.run() } // Play the shutter sound to notify that we've taken a screenshot - playCameraSoundIfNeeded() + screenshotSoundController.playScreenshotSoundAsync() if (LogConfig.DEBUG_ANIM) { Log.d(TAG, "starting post-screenshot animation") } -- GitLab From da522df80568c158fe30896f9a571d05556ee51a Mon Sep 17 00:00:00 2001 From: Pavel Grafov Date: Fri, 4 Oct 2024 17:05:01 +0100 Subject: [PATCH 066/447] Allow uninstalling DMRH when not used for management Bug: 360807442 Test: btest a.d.c.DevicePolicyManagementRoleHolderTest Change-Id: I023f78cef11fb7e8e9a92e2896cf94c9fcd1113b Merged-In: I9fd8bed4a8203f3dbfa8dc4ea1388e7c8d136d9a --- .../server/pm/PackageManagerService.java | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index cac96e544432..84f0057757dd 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -60,6 +60,7 @@ import android.app.ApplicationExitInfo; import android.app.ApplicationPackageManager; import android.app.BroadcastOptions; import android.app.IActivityManager; +import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.IDevicePolicyManager; import android.app.admin.SecurityLog; import android.app.backup.IBackupManager; @@ -3371,8 +3372,10 @@ public class PackageManagerService implements PackageSender, TestUtilityService // TODO(b/261957226): centralise this logic in DPM boolean isPackageDeviceAdmin(String packageName, int userId) { final IDevicePolicyManager dpm = getDevicePolicyManager(); + final DevicePolicyManagerInternal dpmi = + mInjector.getLocalService(DevicePolicyManagerInternal.class); try { - if (dpm != null) { + if (dpm != null && dpmi != null) { final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( /* callingUserOnly =*/ false); final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null @@ -3385,17 +3388,31 @@ public class PackageManagerService implements PackageSender, TestUtilityService return true; } // Does it contain a device admin for any user? - int[] users; + int[] allUsers = mUserManager.getUserIds(); + int[] targetUsers; if (userId == UserHandle.USER_ALL) { - users = mUserManager.getUserIds(); + targetUsers = allUsers; } else { - users = new int[]{userId}; + targetUsers = new int[]{userId}; } - for (int i = 0; i < users.length; ++i) { - if (dpm.packageHasActiveAdmins(packageName, users[i])) { + + for (int i = 0; i < targetUsers.length; ++i) { + if (dpm.packageHasActiveAdmins(packageName, targetUsers[i])) { return true; } - if (isDeviceManagementRoleHolder(packageName, users[i])) { + } + + // If a package is DMRH on a managed user, it should also be treated as an admin on + // that user. If that package is also a system package, it should also be protected + // on other users otherwise "uninstall updates" on an unmanaged user may break + // management on other users because apk version is shared between all users. + var packageState = snapshotComputer().getPackageStateInternal(packageName); + if (packageState == null) { + return false; + } + for (int user : packageState.isSystem() ? allUsers : targetUsers) { + if (isDeviceManagementRoleHolder(packageName, user) + && dpmi.isUserOrganizationManaged(user)) { return true; } } -- GitLab From 761f72e9368fc93d5ed02851c97f1227c3735261 Mon Sep 17 00:00:00 2001 From: Ben Lin Date: Thu, 5 Sep 2024 16:20:14 -0700 Subject: [PATCH 067/447] WindowContainerTransaction: add KeyguardState. This adds a HOP.KeyguardState class that keyguard related transitions can pass to wct to communicate to core. Currently, it does nothing (all the variables are default values), and Core does not really handle it (it just no-ops), and is only set on the most simple case (Simple unlock via swipe up). Subsequent changes will address the TODOs. Bug: 364930619 Test: Manually swipe up to make sure nothing breaks Flag: EXEMPT no-op at the moment Change-Id: I5e5890d8e82a1a3d1d9b930071fbd968f2c437bb --- core/java/android/window/KeyguardState.aidl | 22 +++ core/java/android/window/KeyguardState.java | 160 ++++++++++++++++++ .../window/WindowContainerTransaction.java | 43 +++++ .../server/wm/WindowOrganizerController.java | 19 +++ 4 files changed, 244 insertions(+) create mode 100644 core/java/android/window/KeyguardState.aidl create mode 100644 core/java/android/window/KeyguardState.java diff --git a/core/java/android/window/KeyguardState.aidl b/core/java/android/window/KeyguardState.aidl new file mode 100644 index 000000000000..9612d9590056 --- /dev/null +++ b/core/java/android/window/KeyguardState.aidl @@ -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 android.window; + +/** + * @hide + */ +parcelable KeyguardState; diff --git a/core/java/android/window/KeyguardState.java b/core/java/android/window/KeyguardState.java new file mode 100644 index 000000000000..6584d30cdaed --- /dev/null +++ b/core/java/android/window/KeyguardState.java @@ -0,0 +1,160 @@ +/* + * 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.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * Data object of params for Keyguard related {@link WindowContainerTransaction} operation. + * + * @hide + */ +public final class KeyguardState implements Parcelable { + + private final int mDisplayId; + + private final boolean mKeyguardShowing; + + private final boolean mAodShowing; + + + private KeyguardState(int displayId, boolean keyguardShowing, boolean aodShowing) { + mDisplayId = displayId; + mKeyguardShowing = keyguardShowing; + mAodShowing = aodShowing; + } + + private KeyguardState(Parcel in) { + mDisplayId = in.readInt(); + mKeyguardShowing = in.readBoolean(); + mAodShowing = in.readBoolean(); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mDisplayId); + dest.writeBoolean(mKeyguardShowing); + dest.writeBoolean(mAodShowing); + } + + @NonNull + public static final Creator CREATOR = + new Creator() { + @Override + public KeyguardState createFromParcel(Parcel in) { + return new KeyguardState(in); + } + + @Override + public KeyguardState[] newArray(int size) { + return new KeyguardState[size]; + } + }; + + /** + * Gets the display id of this {@link KeyguardState}. + */ + public int getDisplayId() { + return mDisplayId; + } + + /** Returns the keyguard showing value. */ + public boolean getKeyguardShowing() { + return mKeyguardShowing; + } + + /** Returns the aod showing value. */ + public boolean getAodShowing() { + return mAodShowing; + } + + @Override + public String toString() { + return "KeyguardState{ displayId=" + mDisplayId + + ", keyguardShowing=" + mKeyguardShowing + + ", aodShowing=" + mAodShowing + + '}'; + } + + @Override + public int hashCode() { + return Objects.hash(mDisplayId, mKeyguardShowing, mAodShowing); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (!(obj instanceof KeyguardState other)) { + return false; + } + return mDisplayId == other.mDisplayId + && mKeyguardShowing == other.mKeyguardShowing + && mAodShowing == other.mAodShowing; + } + + @Override + public int describeContents() { + return 0; + } + + /** Builder to construct the {@link KeyguardState}. */ + public static final class Builder { + + private final int mDisplayId; + + private boolean mKeyguardShowing; + + private boolean mAodShowing; + + /** + * @param displayId the display of this {@link KeyguardState}. + */ + public Builder(int displayId) { + mDisplayId = displayId; + } + + /** + * Sets the boolean value for this operation. + */ + @NonNull + public Builder setKeyguardShowing(boolean keyguardShowing) { + mKeyguardShowing = keyguardShowing; + return this; + } + + /** + * Sets the boolean value for this operation. + */ + @NonNull + public Builder setAodShowing(boolean aodShowing) { + mAodShowing = aodShowing; + return this; + } + + /** + * Constructs the {@link KeyguardState}. + */ + @NonNull + public KeyguardState build() { + return new KeyguardState(mDisplayId, mKeyguardShowing, mAodShowing); + } + } +} diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index 0dc9263e990d..8e495ec1dc40 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -868,6 +868,24 @@ public final class WindowContainerTransaction implements Parcelable { return this; } + /** + * Adds a {@link KeyguardState} to apply to the given displays. + * + * @hide + */ + @NonNull + public WindowContainerTransaction addKeyguardState( + @NonNull KeyguardState keyguardState) { + Objects.requireNonNull(keyguardState); + final HierarchyOp hierarchyOp = + new HierarchyOp.Builder( + HierarchyOp.HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE) + .setKeyguardState(keyguardState) + .build(); + mHierarchyOps.add(hierarchyOp); + return this; + } + /** * Sets/removes the always on top flag for this {@code windowContainer}. See * {@link com.android.server.wm.ConfigurationContainer#setAlwaysOnTop(boolean)}. @@ -1469,6 +1487,7 @@ public final class WindowContainerTransaction implements Parcelable { public static final int HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE = 19; public static final int HIERARCHY_OP_TYPE_RESTORE_BACK_NAVIGATION = 20; public static final int HIERARCHY_OP_TYPE_SET_EXCLUDE_INSETS_TYPES = 21; + public static final int HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE = 22; // The following key(s) are for use with mLaunchOptions: // When launching a task (eg. from recents), this is the taskId to be launched. @@ -1515,6 +1534,9 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private TaskFragmentOperation mTaskFragmentOperation; + @Nullable + private KeyguardState mKeyguardState; + @Nullable private PendingIntent mPendingIntent; @@ -1666,6 +1688,7 @@ public final class WindowContainerTransaction implements Parcelable { mLaunchOptions = copy.mLaunchOptions; mActivityIntent = copy.mActivityIntent; mTaskFragmentOperation = copy.mTaskFragmentOperation; + mKeyguardState = copy.mKeyguardState; mPendingIntent = copy.mPendingIntent; mShortcutInfo = copy.mShortcutInfo; mAlwaysOnTop = copy.mAlwaysOnTop; @@ -1689,6 +1712,7 @@ public final class WindowContainerTransaction implements Parcelable { mLaunchOptions = in.readBundle(); mActivityIntent = in.readTypedObject(Intent.CREATOR); mTaskFragmentOperation = in.readTypedObject(TaskFragmentOperation.CREATOR); + mKeyguardState = in.readTypedObject(KeyguardState.CREATOR); mPendingIntent = in.readTypedObject(PendingIntent.CREATOR); mShortcutInfo = in.readTypedObject(ShortcutInfo.CREATOR); mAlwaysOnTop = in.readBoolean(); @@ -1769,6 +1793,11 @@ public final class WindowContainerTransaction implements Parcelable { return mTaskFragmentOperation; } + @Nullable + public KeyguardState getKeyguardState() { + return mKeyguardState; + } + @Nullable public PendingIntent getPendingIntent() { return mPendingIntent; @@ -1902,6 +1931,9 @@ public final class WindowContainerTransaction implements Parcelable { .append(" mExcludeInsetsTypes= ") .append(WindowInsets.Type.toString(mExcludeInsetsTypes)); break; + case HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE: + sb.append("KeyguardState= ").append(mKeyguardState); + break; case HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE: sb.append("container= ").append(mContainer) .append(" isTrimmable= ") @@ -1932,6 +1964,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeBundle(mLaunchOptions); dest.writeTypedObject(mActivityIntent, flags); dest.writeTypedObject(mTaskFragmentOperation, flags); + dest.writeTypedObject(mKeyguardState, flags); dest.writeTypedObject(mPendingIntent, flags); dest.writeTypedObject(mShortcutInfo, flags); dest.writeBoolean(mAlwaysOnTop); @@ -1992,6 +2025,9 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private TaskFragmentOperation mTaskFragmentOperation; + @Nullable + private KeyguardState mKeyguardState; + @Nullable private PendingIntent mPendingIntent; @@ -2081,6 +2117,12 @@ public final class WindowContainerTransaction implements Parcelable { return this; } + Builder setKeyguardState( + @Nullable KeyguardState keyguardState) { + mKeyguardState = keyguardState; + return this; + } + Builder setReparentLeafTaskIfRelaunch(boolean reparentLeafTaskIfRelaunch) { mReparentLeafTaskIfRelaunch = reparentLeafTaskIfRelaunch; return this; @@ -2130,6 +2172,7 @@ public final class WindowContainerTransaction implements Parcelable { hierarchyOp.mPendingIntent = mPendingIntent; hierarchyOp.mAlwaysOnTop = mAlwaysOnTop; hierarchyOp.mTaskFragmentOperation = mTaskFragmentOperation; + hierarchyOp.mKeyguardState = mKeyguardState; hierarchyOp.mShortcutInfo = mShortcutInfo; hierarchyOp.mBounds = mBounds; hierarchyOp.mIncludingParents = mIncludingParents; diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index f8d0bc252b0f..8a7eefab6445 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -51,6 +51,7 @@ import static android.window.WindowContainerTransaction.Change.CHANGE_FOCUSABLE; import static android.window.WindowContainerTransaction.Change.CHANGE_FORCE_TRANSLUCENT; import static android.window.WindowContainerTransaction.Change.CHANGE_HIDDEN; import static android.window.WindowContainerTransaction.Change.CHANGE_RELATIVE_BOUNDS; +import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT; @@ -121,6 +122,7 @@ import android.window.ITransitionMetricsReporter; import android.window.ITransitionPlayer; import android.window.IWindowContainerTransactionCallback; import android.window.IWindowOrganizerController; +import android.window.KeyguardState; import android.window.RemoteTransition; import android.window.TaskFragmentAnimationParams; import android.window.TaskFragmentCreationParams; @@ -1253,6 +1255,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub caller, errorCallbackToken, organizer); break; } + case HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE: { + effects |= applyKeyguardState(hop); + break; + } case HIERARCHY_OP_TYPE_PENDING_INTENT: { final Bundle launchOpts = hop.getLaunchOptions(); ActivityOptions activityOptions = launchOpts != null @@ -1788,6 +1794,19 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub return effects; } + private int applyKeyguardState(@NonNull WindowContainerTransaction.HierarchyOp hop) { + int effects = TRANSACT_EFFECTS_NONE; + + final KeyguardState keyguardState = hop.getKeyguardState(); + if (keyguardState != null) { + int displayId = keyguardState.getDisplayId(); + boolean keyguardShowing = keyguardState.getKeyguardShowing(); + boolean aodShowing = keyguardState.getAodShowing(); + } + // TODO: At the moment, this does nothing. + return effects; + } + /** * Executes the provided {@code runnable} after the {@code transition}. If the * {@code transition} is {@code null}, the {@code runnable} is executed immediately. -- GitLab From 4342a725ad939b69d0153e5c42fe72edf78d5478 Mon Sep 17 00:00:00 2001 From: 0 Date: Thu, 3 Oct 2024 15:44:54 -0700 Subject: [PATCH 068/447] [flexiglass] Inflate QS when SceneContainer is composed Avoids the problem of QS height not populating fast enough during initial shade expansion after reboot. We now inflate before shade scene ever composes, and use the measuredHeight of qqs, so that the notification scrim is placed correctly. Bug: 369644622 Test: Verified with logging that QS height is correct during first shade expansion Flag: com.android.systemui.scene_container Change-Id: I527619c1d4d96b06cd286369ae64f0faf0ae7bea --- .../qs/ui/composable/QuickSettings.kt | 2 +- .../scene/ui/composable/SceneContainer.kt | 26 +++++++++++++++++ .../android/systemui/qs/QSContainerImpl.java | 3 +- .../scene/ui/view/SceneWindowRootView.kt | 13 ++++----- .../ui/view/SceneWindowRootViewBinder.kt | 6 ++++ .../ui/viewmodel/SceneContainerViewModel.kt | 2 ++ .../systemui/shade/ShadeViewProviderModule.kt | 29 +++++++++---------- 7 files changed, 56 insertions(+), 25 deletions(-) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt index e9c5c0333fe5..edc4cba2d53f 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt @@ -199,7 +199,7 @@ private fun QuickSettingsContent( QuickSettingsTheme { val context = LocalContext.current - LaunchedEffect(key1 = context) { + LaunchedEffect(context) { if (qsView == null) { qsSceneAdapter.inflate(context) } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt index 56de096effce..4a7bf2e222d0 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt @@ -24,6 +24,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -31,6 +32,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentKey import com.android.compose.animation.scene.MutableSceneTransitionLayoutState import com.android.compose.animation.scene.OverlayKey @@ -39,9 +42,13 @@ import com.android.compose.animation.scene.SceneTransitionLayout import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.compose.animation.scene.observableTransitionState +import com.android.systemui.qs.ui.adapter.QSSceneAdapter +import com.android.systemui.qs.ui.composable.QuickSettingsTheme import com.android.systemui.ribbon.ui.composable.BottomRightCornerRibbon import com.android.systemui.scene.shared.model.SceneDataSourceDelegator +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel +import javax.inject.Provider import kotlinx.coroutines.flow.collectLatest /** @@ -73,6 +80,7 @@ fun SceneContainer( overlayByKey: Map, initialSceneKey: SceneKey, dataSourceDelegator: SceneDataSourceDelegator, + qsSceneAdapter: Provider, modifier: Modifier = Modifier, ) { val coroutineScope = rememberCoroutineScope() @@ -119,6 +127,24 @@ fun SceneContainer( } } + // Inflate qsView here so that shade has the correct qqs height in the first measure pass after + // rebooting + if ( + viewModel.allContentKeys.contains(Scenes.QuickSettings) || + viewModel.allContentKeys.contains(Scenes.Shade) + ) { + val qsAdapter = qsSceneAdapter.get() + QuickSettingsTheme { + val context = LocalContext.current + val qsView by qsAdapter.qsView.collectAsStateWithLifecycle() + LaunchedEffect(context) { + if (qsView == null) { + qsAdapter.inflate(context) + } + } + } + } + Box( modifier = Modifier.fillMaxSize().pointerInput(Unit) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index 1511f31a3f92..fa987ddbe266 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -255,7 +255,8 @@ public class QSContainerImpl extends FrameLayout implements Dumpable { * @return size in pixels of QQS */ public int getQqsHeight() { - return mHeader.getHeight(); + SceneContainerFlag.assertInNewMode(); + return mHeader.getMeasuredHeight(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt index 8a2e2745264e..cd38ca6cadef 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt @@ -6,6 +6,7 @@ import android.view.MotionEvent import android.view.View import android.view.WindowInsets import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerDependencies +import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.scene.shared.model.SceneContainerConfig import com.android.systemui.scene.shared.model.SceneDataSourceDelegator import com.android.systemui.scene.ui.composable.Overlay @@ -13,19 +14,13 @@ import com.android.systemui.scene.ui.composable.Scene import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel import com.android.systemui.shade.TouchLogger import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer +import javax.inject.Provider import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow /** A root view of the main SysUI window that supports scenes. */ @ExperimentalCoroutinesApi -class SceneWindowRootView( - context: Context, - attrs: AttributeSet?, -) : - WindowRootView( - context, - attrs, - ) { +class SceneWindowRootView(context: Context, attrs: AttributeSet?) : WindowRootView(context, attrs) { private var motionEventHandler: SceneContainerViewModel.MotionEventHandler? = null // TODO(b/298525212): remove once Compose exposes window inset bounds. @@ -39,6 +34,7 @@ class SceneWindowRootView( overlays: Set, layoutInsetController: LayoutInsetsController, sceneDataSourceDelegator: SceneDataSourceDelegator, + qsSceneAdapter: Provider, alternateBouncerDependencies: AlternateBouncerDependencies, ) { setLayoutInsetsController(layoutInsetController) @@ -57,6 +53,7 @@ class SceneWindowRootView( super.setVisibility(if (isVisible) View.VISIBLE else View.INVISIBLE) }, dataSourceDelegator = sceneDataSourceDelegator, + qsSceneAdapter = qsSceneAdapter, alternateBouncerDependencies = alternateBouncerDependencies, ) } diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt index a8be5804d04a..4cd0730642fd 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt @@ -42,6 +42,7 @@ import com.android.systemui.lifecycle.WindowLifecycleState import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.lifecycle.setSnapshotBinding import com.android.systemui.lifecycle.viewModel +import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.SceneContainerConfig @@ -51,6 +52,7 @@ import com.android.systemui.scene.ui.composable.Scene import com.android.systemui.scene.ui.composable.SceneContainer import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer +import javax.inject.Provider import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.awaitCancellation @@ -74,6 +76,7 @@ object SceneWindowRootViewBinder { overlays: Set, onVisibilityChangedInternal: (isVisible: Boolean) -> Unit, dataSourceDelegator: SceneDataSourceDelegator, + qsSceneAdapter: Provider, alternateBouncerDependencies: AlternateBouncerDependencies, ) { val unsortedSceneByKey: Map = scenes.associateBy { scene -> scene.key } @@ -138,6 +141,7 @@ object SceneWindowRootViewBinder { sceneByKey = sortedSceneByKey, overlayByKey = sortedOverlayByKey, dataSourceDelegator = dataSourceDelegator, + qsSceneAdapter = qsSceneAdapter, containerConfig = containerConfig, ) .also { it.id = R.id.scene_container_root_composable } @@ -183,6 +187,7 @@ object SceneWindowRootViewBinder { sceneByKey: Map, overlayByKey: Map, dataSourceDelegator: SceneDataSourceDelegator, + qsSceneAdapter: Provider, containerConfig: SceneContainerConfig, ): View { return ComposeView(context).apply { @@ -198,6 +203,7 @@ object SceneWindowRootViewBinder { overlayByKey = overlayByKey, initialSceneKey = containerConfig.initialSceneKey, dataSourceDelegator = dataSourceDelegator, + qsSceneAdapter = qsSceneAdapter, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt index f5053853846c..a3e238f5e2fc 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt @@ -76,6 +76,8 @@ constructor( /** Whether the container is visible. */ val isVisible: Boolean by hydrator.hydratedStateOf("isVisible", sceneInteractor.isVisible) + val allContentKeys: List = sceneInteractor.allContentKeys + private val hapticsViewModel = hapticsViewModelFactory.create(view) /** diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt index fc8a59395b14..5afc5398d401 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt @@ -35,6 +35,7 @@ import com.android.systemui.flags.FeatureFlags import com.android.systemui.keyguard.ui.view.KeyguardRootView import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerDependencies import com.android.systemui.privacy.OngoingPrivacyChip +import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.SceneContainerConfig @@ -89,6 +90,7 @@ abstract class ShadeViewProviderModule { overlaysProvider: Provider>, layoutInsetController: NotificationInsetsController, sceneDataSourceDelegator: Provider, + qsSceneAdapter: Provider, alternateBouncerDependencies: Provider, ): WindowRootView { return if (SceneContainerFlag.isEnabled) { @@ -104,6 +106,7 @@ abstract class ShadeViewProviderModule { overlays = overlaysProvider.get(), layoutInsetController = layoutInsetController, sceneDataSourceDelegator = sceneDataSourceDelegator.get(), + qsSceneAdapter = qsSceneAdapter, alternateBouncerDependencies = alternateBouncerDependencies.get(), ) sceneWindowRootView @@ -119,9 +122,7 @@ abstract class ShadeViewProviderModule { // {@link NotificationShadeWindowViewController} can inject this view. @Provides @SysUISingleton - fun providesNotificationShadeWindowView( - root: WindowRootView, - ): NotificationShadeWindowView { + fun providesNotificationShadeWindowView(root: WindowRootView): NotificationShadeWindowView { if (SceneContainerFlag.isEnabled) { return root.requireViewById(R.id.legacy_window_root) } @@ -133,7 +134,7 @@ abstract class ShadeViewProviderModule { @Provides @SysUISingleton fun providesNotificationStackScrollLayout( - notificationShadeWindowView: NotificationShadeWindowView, + notificationShadeWindowView: NotificationShadeWindowView ): NotificationStackScrollLayout { return notificationShadeWindowView.requireViewById(R.id.notification_stack_scroller) } @@ -142,7 +143,7 @@ abstract class ShadeViewProviderModule { @Provides @SysUISingleton fun providesNotificationPanelView( - notificationShadeWindowView: NotificationShadeWindowView, + notificationShadeWindowView: NotificationShadeWindowView ): NotificationPanelView { return notificationShadeWindowView.requireViewById(R.id.notification_panel) } @@ -178,7 +179,7 @@ abstract class ShadeViewProviderModule { @Provides @SysUISingleton fun providesKeyguardRootView( - notificationShadeWindowView: NotificationShadeWindowView, + notificationShadeWindowView: NotificationShadeWindowView ): KeyguardRootView { return notificationShadeWindowView.requireViewById(R.id.keyguard_root_view) } @@ -186,7 +187,7 @@ abstract class ShadeViewProviderModule { @Provides @SysUISingleton fun providesSharedNotificationContainer( - notificationShadeWindowView: NotificationShadeWindowView, + notificationShadeWindowView: NotificationShadeWindowView ): SharedNotificationContainer { return notificationShadeWindowView.requireViewById(R.id.shared_notification_container) } @@ -195,7 +196,7 @@ abstract class ShadeViewProviderModule { @Provides @SysUISingleton fun providesAuthRippleView( - notificationShadeWindowView: NotificationShadeWindowView, + notificationShadeWindowView: NotificationShadeWindowView ): AuthRippleView? { return notificationShadeWindowView.requireViewById(R.id.auth_ripple) } @@ -203,9 +204,7 @@ abstract class ShadeViewProviderModule { // TODO(b/277762009): Only allow this view's controller to inject the view. See above. @Provides @SysUISingleton - fun providesTapAgainView( - notificationPanelView: NotificationPanelView, - ): TapAgainView { + fun providesTapAgainView(notificationPanelView: NotificationPanelView): TapAgainView { return notificationPanelView.requireViewById(R.id.shade_falsing_tap_again) } @@ -213,7 +212,7 @@ abstract class ShadeViewProviderModule { @Provides @SysUISingleton fun providesNotificationsQuickSettingsContainer( - notificationShadeWindowView: NotificationShadeWindowView, + notificationShadeWindowView: NotificationShadeWindowView ): NotificationsQuickSettingsContainer { return notificationShadeWindowView.requireViewById(R.id.notification_container_parent) } @@ -223,7 +222,7 @@ abstract class ShadeViewProviderModule { @SysUISingleton @Named(SHADE_HEADER) fun providesShadeHeaderView( - notificationShadeWindowView: NotificationShadeWindowView, + notificationShadeWindowView: NotificationShadeWindowView ): MotionLayout { val stub = notificationShadeWindowView.requireViewById(R.id.qs_header_stub) val layoutId = R.layout.combined_qs_header @@ -275,7 +274,7 @@ abstract class ShadeViewProviderModule { @SysUISingleton @Named(SHADE_HEADER) fun providesOngoingPrivacyChip( - @Named(SHADE_HEADER) header: MotionLayout, + @Named(SHADE_HEADER) header: MotionLayout ): OngoingPrivacyChip { return header.requireViewById(R.id.privacy_chip) } @@ -284,7 +283,7 @@ abstract class ShadeViewProviderModule { @SysUISingleton @Named(SHADE_HEADER) fun providesStatusIconContainer( - @Named(SHADE_HEADER) header: MotionLayout, + @Named(SHADE_HEADER) header: MotionLayout ): StatusIconContainer { return header.requireViewById(R.id.statusIcons) } -- GitLab From b8f42c5d7bc2276ec24192f0670513dfdab1cc85 Mon Sep 17 00:00:00 2001 From: Sally Qi Date: Mon, 26 Aug 2024 11:40:39 -0700 Subject: [PATCH 069/447] [Lut API] Introduce LUT java interface. - Add OverlayProperties#getLutProperties - Add SurfaceControl#setLuts - Introduce LutProperties and DisplayLuts java class - DisplayLuts is a class that allows developers to provide customized Lut(s) for the SurfaceControl instance. Bug: 349667978 Test: builds Flag: NONE new added apis are all hidden right now Change-Id: I0182896cea926b5af3a1d6fe5b385012b8e3fd1a --- core/java/android/hardware/DisplayLuts.java | 131 ++++++++++++++++++ core/java/android/hardware/LutProperties.java | 94 +++++++++++++ .../android/hardware/OverlayProperties.java | 19 ++- core/java/android/view/SurfaceControl.java | 16 ++- .../android_hardware_OverlayProperties.cpp | 43 ++++++ core/jni/android_view_SurfaceControl.cpp | 62 +++++++++ 6 files changed, 362 insertions(+), 3 deletions(-) create mode 100644 core/java/android/hardware/DisplayLuts.java create mode 100644 core/java/android/hardware/LutProperties.java diff --git a/core/java/android/hardware/DisplayLuts.java b/core/java/android/hardware/DisplayLuts.java new file mode 100644 index 000000000000..b162ad6e2d15 --- /dev/null +++ b/core/java/android/hardware/DisplayLuts.java @@ -0,0 +1,131 @@ +/* + * 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.hardware; + +import android.annotation.NonNull; +import android.util.IntArray; + +import java.util.ArrayList; +import java.util.List; + +/** + * @hide + */ +public final class DisplayLuts { + private IntArray mOffsets; + private int mTotalLength; + + private List mLutBuffers; + private IntArray mLutDimensions; + private IntArray mLutSizes; + private IntArray mLutSamplingKeys; + private static final int LUT_LENGTH_LIMIT = 100000; + + public DisplayLuts() { + mOffsets = new IntArray(); + mTotalLength = 0; + + mLutBuffers = new ArrayList<>(); + mLutDimensions = new IntArray(); + mLutSizes = new IntArray(); + mLutSamplingKeys = new IntArray(); + } + + /** + * Add the lut to be applied. + * + * @param buffer + * @param dimension either 1D or 3D + * @param size + * @param samplingKey + */ + public void addLut(@NonNull float[] buffer, @LutProperties.Dimension int dimension, + int size, @LutProperties.SamplingKey int samplingKey) { + + int lutLength = 0; + if (dimension == LutProperties.ONE_DIMENSION) { + lutLength = size; + } else if (dimension == LutProperties.THREE_DIMENSION) { + lutLength = size * size * size; + } else { + clear(); + throw new IllegalArgumentException("The dimension is either 1D or 3D!"); + } + + if (lutLength >= LUT_LENGTH_LIMIT) { + clear(); + throw new IllegalArgumentException("The lut length is too big to handle!"); + } + + mOffsets.add(mTotalLength); + mTotalLength += lutLength; + + mLutBuffers.add(buffer); + mLutDimensions.add(dimension); + mLutSizes.add(size); + mLutSamplingKeys.add(samplingKey); + } + + private void clear() { + mTotalLength = 0; + mOffsets.clear(); + mLutBuffers.clear(); + mLutDimensions.clear(); + mLutSamplingKeys.clear(); + } + + /** + * @return the array of Lut buffers + */ + public float[] getLutBuffers() { + float[] buffer = new float[mTotalLength]; + + for (int i = 0; i < mLutBuffers.size(); i++) { + float[] lutBuffer = mLutBuffers.get(i); + System.arraycopy(lutBuffer, 0, buffer, mOffsets.get(i), lutBuffer.length); + } + return buffer; + } + + /** + * @return the starting point of each lut memory region of the lut buffer + */ + public int[] getOffsets() { + return mOffsets.toArray(); + } + + /** + * @return the array of Lut size + */ + public int[] getLutSizes() { + return mLutSizes.toArray(); + } + + /** + * @return the array of Lut dimension + */ + public int[] getLutDimensions() { + return mLutDimensions.toArray(); + } + + /** + * @return the array of sampling key + */ + public int[] getLutSamplingKeys() { + return mLutSamplingKeys.toArray(); + } +} diff --git a/core/java/android/hardware/LutProperties.java b/core/java/android/hardware/LutProperties.java new file mode 100644 index 000000000000..57f8a4ece304 --- /dev/null +++ b/core/java/android/hardware/LutProperties.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware; + +import android.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Lut properties class. + * + * A Lut (Look-Up Table) is a pre-calculated table for color transformation. + * + * @hide + */ +public final class LutProperties { + private final @Dimension int mDimension; + private final long mSize; + private final @SamplingKey int[] mSamplingKeys; + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SAMPLING_KEY_"}, value = { + SAMPLING_KEY_RGB, + SAMPLING_KEY_MAX_RGB + }) + public @interface SamplingKey { + } + + /** use r,g,b channel as the gain value of a Lut */ + public static final int SAMPLING_KEY_RGB = 0; + + /** use max of r,g,b channel as the gain value of a Lut */ + public static final int SAMPLING_KEY_MAX_RGB = 1; + + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + ONE_DIMENSION, + THREE_DIMENSION + }) + public @interface Dimension { + } + + /** The Lut is one dimensional */ + public static final int ONE_DIMENSION = 1; + + /** The Lut is three dimensional */ + public static final int THREE_DIMENSION = 3; + + public @Dimension int getDimension() { + return mDimension; + } + + /** + * @return the size of the Lut. + */ + public long getSize() { + return mSize; + } + + /** + * @return the list of sampling keys + */ + public @SamplingKey int[] getSamplingKeys() { + if (mSamplingKeys.length == 0) { + throw new IllegalStateException("no sampling key!"); + } + return mSamplingKeys; + } + + /* use in the native code */ + private LutProperties(@Dimension int dimension, long size, @SamplingKey int[] samplingKeys) { + if (dimension != ONE_DIMENSION || dimension != THREE_DIMENSION) { + throw new IllegalArgumentException("The dimension is either 1 or 3!"); + } + mDimension = dimension; + mSize = size; + mSamplingKeys = samplingKeys; + } +} diff --git a/core/java/android/hardware/OverlayProperties.java b/core/java/android/hardware/OverlayProperties.java index 7b452a8e0857..24cfc1b53e00 100644 --- a/core/java/android/hardware/OverlayProperties.java +++ b/core/java/android/hardware/OverlayProperties.java @@ -50,6 +50,8 @@ public final class OverlayProperties implements Parcelable { // Invoked on destruction private Runnable mCloser; + private LutProperties[] mLutProperties; + private OverlayProperties(long nativeObject) { if (nativeObject != 0) { mCloser = sRegistry.registerNativeAllocation(this, nativeObject); @@ -69,6 +71,20 @@ public final class OverlayProperties implements Parcelable { return sDefaultOverlayProperties; } + /** + * Gets the lut properties of the display. + * @hide + */ + public LutProperties[] getLutProperties() { + if (mNativeObject == 0) { + return null; + } + if (mLutProperties == null) { + mLutProperties = nGetLutProperties(mNativeObject); + } + return mLutProperties; + } + /** * Indicates that hardware composition of a buffer encoded with the provided {@link DataSpace} * and {@link HardwareBuffer.Format} is supported on the device. @@ -140,4 +156,5 @@ public final class OverlayProperties implements Parcelable { long nativeObject, int dataspace, int format); private static native void nWriteOverlayPropertiesToParcel(long nativeObject, Parcel dest); private static native long nReadOverlayPropertiesFromParcel(Parcel in); -} + private static native LutProperties[] nGetLutProperties(long nativeObject); +} \ No newline at end of file diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 2dda835436bc..7e3486ff93d5 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -49,6 +49,7 @@ import android.gui.DropInputMode; import android.gui.StalledTransactionInfo; import android.gui.TrustedOverlay; import android.hardware.DataSpace; +import android.hardware.DisplayLuts; import android.hardware.HardwareBuffer; import android.hardware.OverlayProperties; import android.hardware.SyncFence; @@ -305,9 +306,9 @@ public final class SurfaceControl implements Parcelable { private static native StalledTransactionInfo nativeGetStalledTransactionInfo(int pid); private static native void nativeSetDesiredPresentTimeNanos(long transactionObj, long desiredPresentTimeNanos); - private static native void nativeSetFrameTimeline(long transactionObj, - long vsyncId); private static native void nativeNotifyShutdown(); + private static native void nativeSetLuts(long transactionObj, long nativeObject, + float[] buffers, int[] slots, int[] dimensions, int[] sizes, int[] samplingKeys); /** * Transforms that can be applied to buffers as they are displayed to a window. @@ -4374,6 +4375,17 @@ public final class SurfaceControl implements Parcelable { return this; } + /** @hide */ + public @NonNull Transaction setLuts(@NonNull SurfaceControl sc, + @NonNull DisplayLuts displayLuts) { + checkPreconditions(sc); + + nativeSetLuts(mNativeObject, sc.mNativeObject, displayLuts.getLutBuffers(), + displayLuts.getOffsets(), displayLuts.getLutDimensions(), + displayLuts.getLutSizes(), displayLuts.getLutSamplingKeys()); + return this; + } + /** * Sets the caching hint for the layer. By default, the caching hint is * {@link CACHING_ENABLED}. diff --git a/core/jni/android_hardware_OverlayProperties.cpp b/core/jni/android_hardware_OverlayProperties.cpp index 96494b16cc21..63de1950f2a5 100644 --- a/core/jni/android_hardware_OverlayProperties.cpp +++ b/core/jni/android_hardware_OverlayProperties.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "OverlayProperties" // #define LOG_NDEBUG 0 +#include #include #include #include @@ -35,6 +36,12 @@ static struct { jclass clazz; jmethodID ctor; } gOverlayPropertiesClassInfo; + +static struct { + jclass clazz; + jmethodID ctor; +} gLutPropertiesClassInfo; + // ---------------------------------------------------------------------------- // OverlayProperties lifecycle // ---------------------------------------------------------------------------- @@ -95,6 +102,36 @@ static jlong android_hardware_OverlayProperties_createDefault(JNIEnv* env, jobje return reinterpret_cast(overlayProperties); } +static jobjectArray android_hardware_OverlayProperties_getLutProperties(JNIEnv* env, jobject thiz, + jlong nativeObject) { + gui::OverlayProperties* overlayProperties = + reinterpret_cast(nativeObject); + if (overlayProperties->lutProperties.has_value()) { + return NULL; + } + auto& lutProperties = overlayProperties->lutProperties.value(); + if (lutProperties.empty()) { + return NULL; + } + int32_t size = static_cast(lutProperties.size()); + jobjectArray nativeLutProperties = + env->NewObjectArray(size, gLutPropertiesClassInfo.clazz, NULL); + if (nativeLutProperties == NULL) { + return NULL; + } + for (int32_t i = 0; i < size; i++) { + if (lutProperties[i].has_value()) { + auto& item = lutProperties[i].value(); + jobject properties = + env->NewObject(gLutPropertiesClassInfo.clazz, gLutPropertiesClassInfo.ctor, + static_cast(item.dimension), item.size, + item.samplingKeys.data()); + env->SetObjectArrayElement(nativeLutProperties, i, properties); + } + } + return nativeLutProperties; +} + // ---------------------------------------------------------------------------- // Serialization // ---------------------------------------------------------------------------- @@ -161,6 +198,8 @@ static const JNINativeMethod gMethods[] = { { "nReadOverlayPropertiesFromParcel", "(Landroid/os/Parcel;)J", (void*) android_hardware_OverlayProperties_read }, {"nCreateDefault", "()J", (void*) android_hardware_OverlayProperties_createDefault }, + {"nGetLutProperties", "(J)[Landroid/hardware/LutProperties;", + (void*) android_hardware_OverlayProperties_getLutProperties }, }; // clang-format on @@ -171,5 +210,9 @@ int register_android_hardware_OverlayProperties(JNIEnv* env) { gOverlayPropertiesClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); gOverlayPropertiesClassInfo.ctor = GetMethodIDOrDie(env, gOverlayPropertiesClassInfo.clazz, "", "(J)V"); + clazz = FindClassOrDie(env, "android/hardware/LutProperties"); + gLutPropertiesClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); + gLutPropertiesClassInfo.ctor = + GetMethodIDOrDie(env, gLutPropertiesClassInfo.clazz, "", "(IJ[I)V"); return err; } diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 17c89f88b441..134e51cfeabd 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -33,11 +33,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -735,6 +737,65 @@ static void nativeSetDesiredHdrHeadroom(JNIEnv* env, jclass clazz, jlong transac transaction->setDesiredHdrHeadroom(ctrl, desiredRatio); } +static void nativeSetLuts(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, + jfloatArray jbufferArray, jintArray joffsetArray, + jintArray jdimensionArray, jintArray jsizeArray, + jintArray jsamplingKeyArray) { + auto transaction = reinterpret_cast(transactionObj); + SurfaceControl* const ctrl = reinterpret_cast(nativeObject); + + ScopedIntArrayRW joffsets(env, joffsetArray); + if (joffsets.get() == nullptr) { + jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from joffsetArray"); + return; + } + ScopedIntArrayRW jdimensions(env, jdimensionArray); + if (jdimensions.get() == nullptr) { + jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jdimensionArray"); + return; + } + ScopedIntArrayRW jsizes(env, jsizeArray); + if (jsizes.get() == nullptr) { + jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jsizeArray"); + return; + } + ScopedIntArrayRW jsamplingKeys(env, jsamplingKeyArray); + if (jsamplingKeys.get() == nullptr) { + jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jsamplingKeyArray"); + return; + } + + jsize numLuts = env->GetArrayLength(jdimensionArray); + std::vector offsets(joffsets.get(), joffsets.get() + numLuts); + std::vector dimensions(jdimensions.get(), jdimensions.get() + numLuts); + std::vector sizes(jsizes.get(), jsizes.get() + numLuts); + std::vector samplingKeys(jsamplingKeys.get(), jsamplingKeys.get() + numLuts); + + ScopedFloatArrayRW jbuffers(env, jbufferArray); + if (jbuffers.get() == nullptr) { + jniThrowRuntimeException(env, "Failed to get ScopedFloatArrayRW from jbufferArray"); + return; + } + + // create the shared memory and copy jbuffers + size_t bufferSize = jbuffers.size() * sizeof(float); + int32_t fd = ashmem_create_region("lut_shread_mem", bufferSize); + if (fd < 0) { + jniThrowRuntimeException(env, "ashmem_create_region() failed"); + return; + } + void* ptr = mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (ptr == MAP_FAILED) { + jniThrowRuntimeException(env, "Failed to map the shared memory"); + return; + } + memcpy(ptr, jbuffers.get(), bufferSize); + // unmap + munmap(ptr, bufferSize); + + transaction->setLuts(ctrl, base::unique_fd(fd), offsets, dimensions, sizes, samplingKeys); +} + static void nativeSetCachingHint(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, jint cachingHint) { auto transaction = reinterpret_cast(transactionObj); @@ -2529,6 +2590,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*) nativeSetDesiredPresentTimeNanos }, {"nativeNotifyShutdown", "()V", (void*)nativeNotifyShutdown }, + {"nativeSetLuts", "(JJ[F[I[I[I[I)V", (void*)nativeSetLuts }, // clang-format on }; -- GitLab From 4923b58a1adeb19498059ecba60bd1c52c336736 Mon Sep 17 00:00:00 2001 From: Nan Wu Date: Thu, 5 Sep 2024 19:40:22 +0000 Subject: [PATCH 070/447] Generate CreatorToken Collect extra intent keys on the client side and generated CreatorToken on the system server side Bug: 363016571 Test: ActivityManagerService#testAddCreatorToken Flag: android.security.prevent_intent_redirect Change-Id: Ibc6d461e74d96b12a9af990d8653f66fcfa26c14 --- .../android/app/ActivityManagerInternal.java | 8 ++ core/java/android/app/PendingIntent.java | 3 + core/java/android/content/ClipData.java | 2 +- core/java/android/content/Intent.java | 19 +++- core/java/android/content/IntentSender.java | 3 + .../server/am/ActivityManagerService.java | 89 ++++++++++++++++++- .../server/wm/ActivityClientController.java | 2 + .../server/wm/ActivityTaskManagerService.java | 11 +++ .../com/android/server/wm/AppTaskImpl.java | 1 + .../server/am/ActivityManagerServiceTest.java | 40 +++++++++ 10 files changed, 172 insertions(+), 6 deletions(-) diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index d31881265064..3bd121a4a19b 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -1323,4 +1323,12 @@ public abstract class ActivityManagerInternal { */ public abstract void killApplicationSync(String pkgName, int appId, int userId, String reason, int exitInfoReason); + + /** + * Add a creator token for all embedded intents (stored as extra) of the given intent. + * + * @param intent The given intent + * @hide + */ + public abstract void addCreatorToken(Intent intent); } diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 3714e5de23ca..393ec8c1d66d 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -1094,6 +1094,9 @@ public final class PendingIntent implements Parcelable { @Nullable String requiredPermission, @Nullable Bundle options) throws CanceledException { try { + if (intent != null) { + intent.collectExtraIntentKeys(); + } String resolvedType = intent != null ? intent.resolveTypeIfNeeded(context.getContentResolver()) : null; diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java index b42133939f28..ff0bb25bbccc 100644 --- a/core/java/android/content/ClipData.java +++ b/core/java/android/content/ClipData.java @@ -1149,7 +1149,7 @@ public class ClipData implements Parcelable { for (int i = 0; i < size; i++) { final Item item = mItems.get(i); if (item.mIntent != null) { - item.mIntent.prepareToLeaveProcess(leavingPackage); + item.mIntent.prepareToLeaveProcess(leavingPackage, false); } if (item.mUri != null && leavingPackage) { if (StrictMode.vmFileUriExposureEnabled()) { diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 044178c4f6aa..c23bcabf77ba 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -12227,6 +12227,8 @@ public class Intent implements Parcelable, Cloneable { /** * Collects keys in the extra bundle whose value are intents. + * With these keys collected on the client side, the system server would only unparcel values + * of these keys and create IntentCreatorToken for them. * @hide */ public void collectExtraIntentKeys() { @@ -12589,22 +12591,29 @@ public class Intent implements Parcelable, Cloneable { */ @android.ravenwood.annotation.RavenwoodThrow public void prepareToLeaveProcess(boolean leavingPackage) { + prepareToLeaveProcess(leavingPackage, true); + } + + /** + * @hide + */ + void prepareToLeaveProcess(boolean leavingPackage, boolean isTopLevel) { setAllowFds(false); if (mSelector != null) { - mSelector.prepareToLeaveProcess(leavingPackage); + mSelector.prepareToLeaveProcess(leavingPackage, false); } if (mClipData != null) { mClipData.prepareToLeaveProcess(leavingPackage, getFlags()); } if (mOriginalIntent != null) { - mOriginalIntent.prepareToLeaveProcess(leavingPackage); + mOriginalIntent.prepareToLeaveProcess(leavingPackage, false); } if (mExtras != null && !mExtras.isParcelled()) { final Object intent = mExtras.get(Intent.EXTRA_INTENT); if (intent instanceof Intent) { - ((Intent) intent).prepareToLeaveProcess(leavingPackage); + ((Intent) intent).prepareToLeaveProcess(leavingPackage, false); } } @@ -12678,6 +12687,10 @@ public class Intent implements Parcelable, Cloneable { StrictMode.onUnsafeIntentLaunch(this); } } + + if (isTopLevel) { + collectExtraIntentKeys(); + } } /** diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java index ca6d86ae2dd8..f406927b62a5 100644 --- a/core/java/android/content/IntentSender.java +++ b/core/java/android/content/IntentSender.java @@ -288,6 +288,9 @@ public class IntentSender implements Parcelable { @Nullable Executor executor, @Nullable OnFinished onFinished) throws SendIntentException { try { + if (intent != null) { + intent.collectExtraIntentKeys(); + } String resolvedType = intent != null ? intent.resolveTypeIfNeeded(context.getContentResolver()) : null; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 35323d6cb391..5ca72ab998a4 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -130,6 +130,7 @@ import static android.os.Process.setThreadScheduler; import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES; import static android.provider.Settings.Global.DEBUG_APP; import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER; +import static android.security.Flags.preventIntentRedirect; import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS; import static android.view.Display.INVALID_DISPLAY; @@ -420,6 +421,7 @@ import com.android.internal.util.FastPrintWriter; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.MemInfoReader; import com.android.internal.util.Preconditions; +import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.AlarmManagerInternal; import com.android.server.BootReceiver; import com.android.server.DeviceIdleInternal; @@ -2420,6 +2422,7 @@ public class ActivityManagerService extends IActivityManager.Stub mBroadcastController = new BroadcastController(mContext, this, mBroadcastQueue); mComponentAliasResolver = new ComponentAliasResolver(this); mApplicationSharedMemoryReadOnlyFd = null; + sCreatorTokenCacheCleaner = new Handler(mHandlerThread.getLooper()); } // Note: This method is invoked on the main thread but may need to attach various @@ -2526,6 +2529,7 @@ public class ActivityManagerService extends IActivityManager.Stub mPendingStartActivityUids = new PendingStartActivityUids(); mTraceErrorLogger = new TraceErrorLogger(); mComponentAliasResolver = new ComponentAliasResolver(this); + sCreatorTokenCacheCleaner = new Handler(mHandlerThread.getLooper()); try { mApplicationSharedMemoryReadOnlyFd = ApplicationSharedMemory.getInstance().getReadOnlyFileDescriptor(); @@ -5532,6 +5536,7 @@ public class ActivityManagerService extends IActivityManager.Stub public int sendIntentSender(IApplicationThread caller, IIntentSender target, IBinder allowlistToken, int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { + addCreatorToken(intent); if (target instanceof PendingIntentRecord) { final PendingIntentRecord originalRecord = (PendingIntentRecord) target; @@ -13610,6 +13615,7 @@ public class ActivityManagerService extends IActivityManager.Stub throws TransactionTooLargeException { enforceNotIsolatedCaller("startService"); enforceAllowedToStartOrBindServiceIfSdkSandbox(service); + addCreatorToken(service); if (service != null) { // Refuse possible leaked file descriptors if (service.hasFileDescriptors()) { @@ -13871,6 +13877,7 @@ public class ActivityManagerService extends IActivityManager.Stub validateServiceInstanceName(instanceName); + addCreatorToken(service); try { if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) { final ComponentName cn = service.getComponent(); @@ -17148,6 +17155,7 @@ public class ActivityManagerService extends IActivityManager.Stub Slog.v(TAG_SERVICE, "startServiceInPackage: " + service + " type=" + resolvedType); } + addCreatorToken(service); final long origId = Binder.clearCallingIdentity(); ComponentName res; try { @@ -17973,6 +17981,11 @@ public class ActivityManagerService extends IActivityManager.Stub userId, reason, exitInfoReason); } } + + @Override + public void addCreatorToken(Intent intent) { + ActivityManagerService.this.addCreatorToken(intent); + } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, TimeoutRecord timeoutRecord) { @@ -19105,6 +19118,7 @@ public class ActivityManagerService extends IActivityManager.Stub private static final Map> sIntentCreatorTokenCache = new ConcurrentHashMap<>(); + private static Handler sCreatorTokenCacheCleaner; /** * A binder token used to keep track of which app created the intent. This token can be used to * defend against intent redirect attacks. It stores uid of the intent creator and key fields of @@ -19112,13 +19126,16 @@ public class ActivityManagerService extends IActivityManager.Stub * * @hide */ + @VisibleForTesting public static final class IntentCreatorToken extends Binder { @NonNull private final Key mKeyFields; + private final WeakReference mRef; public IntentCreatorToken(int creatorUid, Intent intent) { super(); this.mKeyFields = new Key(creatorUid, intent); + mRef = new WeakReference<>(this); } public int getCreatorUid() { @@ -19136,6 +19153,26 @@ public class ActivityManagerService extends IActivityManager.Stub new Key(token.mKeyFields.mCreatorUid, intent)); } + @Override + protected void finalize() throws Throwable { + try { + sCreatorTokenCacheCleaner.sendMessage(PooledLambda.obtainMessage( + IntentCreatorToken::completeFinalize, this)); + } finally { + super.finalize(); + } + } + + private void completeFinalize() { + synchronized (sIntentCreatorTokenCache) { + WeakReference current = sIntentCreatorTokenCache.get( + mKeyFields); + if (current == mRef) { + sIntentCreatorTokenCache.remove(mKeyFields); + } + } + } + private static class Key { private Key(int creatorUid, Intent intent) { this.mCreatorUid = creatorUid; @@ -19178,9 +19215,57 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public int hashCode() { return Objects.hash(mCreatorUid, mAction, mData, mType, mPackage, mComponent, - mFlags, - mClipDataUris); + mFlags, mClipDataUris); + } + } + } + + /** + * Add a creator token for all embedded intents (stored as extra) of the given intent. + * + * @param intent The given intent + * @hide + */ + public void addCreatorToken(@Nullable Intent intent) { + if (!preventIntentRedirect()) return; + + if (intent == null || intent.getExtraIntentKeys() == null) return; + for (String key : intent.getExtraIntentKeys()) { + try { + Intent extraIntent = intent.getParcelableExtra(key, Intent.class); + if (extraIntent == null) { + Slog.w(TAG, "The key {" + key + + "} does not correspond to an intent in the extra bundle."); + continue; + } + Slog.wtf(TAG, "A creator token is added to an intent."); + IBinder creatorToken = createIntentCreatorToken(extraIntent); + if (creatorToken != null) { + extraIntent.setCreatorToken(creatorToken); + } + } catch (Exception e) { + Slog.wtf(TAG, + "Something went wrong when trying to add creator token for embedded " + + "intents of intent: ." + + intent, e); + } + } + } + + private IBinder createIntentCreatorToken(Intent intent) { + if (IntentCreatorToken.isValid(intent)) return null; + int creatorUid = getCallingUid(); + IntentCreatorToken.Key key = new IntentCreatorToken.Key(creatorUid, intent); + IntentCreatorToken token; + synchronized (sIntentCreatorTokenCache) { + WeakReference ref = sIntentCreatorTokenCache.get(key); + if (ref == null || ref.get() == null) { + token = new IntentCreatorToken(creatorUid, intent); + sIntentCreatorTokenCache.put(key, token.mRef); + } else { + token = ref.get(); } } + return token; } } diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index c1e859ddcccf..a6b650fea2d2 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -442,6 +442,8 @@ class ActivityClientController extends IActivityClientController.Stub { throw new IllegalArgumentException("File descriptors passed in Intent"); } + mService.mAmInternal.addCreatorToken(resultData); + final ActivityRecord r; synchronized (mGlobalLock) { r = ActivityRecord.isInRootTaskLocked(token); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index de95d1bfb5c3..93f428b27440 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -1228,6 +1228,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { + mAmInternal.addCreatorToken(intent); return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); @@ -1240,6 +1241,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { assertPackageMatchesCallingUid(callingPackage); final String reason = "startActivities"; enforceNotIsolatedCaller(reason); + if (intents != null) { + for (Intent intent : intents) { + mAmInternal.addCreatorToken(intent); + } + } userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason); // TODO: Switch to user app stacks here. return getActivityStartController().startActivities(caller, -1, 0, -1, callingPackage, @@ -1269,6 +1275,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Nullable String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { + mAmInternal.addCreatorToken(intent); final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions); assertPackageMatchesCallingUid(callingPackage); @@ -1323,6 +1330,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } // Remove existing mismatch flag so it can be properly updated later fillInIntent.removeExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH); + mAmInternal.addCreatorToken(fillInIntent); } if (!(target instanceof PendingIntentRecord)) { @@ -1352,6 +1360,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (intent != null && intent.hasFileDescriptors()) { throw new IllegalArgumentException("File descriptors passed in Intent"); } + + mAmInternal.addCreatorToken(intent); + SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions); synchronized (mGlobalLock) { diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java index d699af872c7f..4d17ed24e734 100644 --- a/services/core/java/com/android/server/wm/AppTaskImpl.java +++ b/services/core/java/com/android/server/wm/AppTaskImpl.java @@ -160,6 +160,7 @@ class AppTaskImpl extends IAppTask.Stub { Intent intent, String resolvedType, Bundle bOptions) { checkCallerOrSystemOrRoot(); mService.assertPackageMatchesCallingUid(callingPackage); + mService.mAmInternal.addCreatorToken(intent); int callingUser = UserHandle.getCallingUserId(); Task task; diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java index 809e13c65225..6ccc03709b4f 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java @@ -29,6 +29,7 @@ import static android.app.ActivityManager.PROCESS_STATE_TOP; import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; import static android.content.ContentResolver.SCHEME_CONTENT; +import static android.content.Intent.FILL_IN_ACTION; import static android.os.PowerExemptionManager.REASON_DENIED; import static android.os.UserHandle.USER_ALL; import static android.util.DebugUtils.valueToString; @@ -1300,6 +1301,45 @@ public class ActivityManagerServiceTest { .containsExactly(new Pair<>(USER_ID, 42)); } + @Test + @RequiresFlagsEnabled(android.security.Flags.FLAG_PREVENT_INTENT_REDIRECT) + public void testAddCreatorToken() { + Intent intent = new Intent(); + Intent extraIntent = new Intent("EXTRA_INTENT_ACTION"); + intent.putExtra("EXTRA_INTENT0", extraIntent); + + intent.collectExtraIntentKeys(); + mAms.addCreatorToken(intent); + + ActivityManagerService.IntentCreatorToken token = + (ActivityManagerService.IntentCreatorToken) extraIntent.getCreatorToken(); + assertThat(token).isNotNull(); + assertThat(token.getCreatorUid()).isEqualTo(mInjector.getCallingUid()); + } + + @Test + @RequiresFlagsEnabled(android.security.Flags.FLAG_PREVENT_INTENT_REDIRECT) + public void testAddCreatorTokenForFillingIntent() { + Intent intent = new Intent(); + Intent extraIntent = new Intent("EXTRA_INTENT_ACTION"); + intent.putExtra("EXTRA_INTENT0", extraIntent); + Intent fillinIntent = new Intent(); + Intent fillinExtraIntent = new Intent("FILLIN_EXTRA_INTENT_ACTION"); + fillinIntent.putExtra("FILLIN_EXTRA_INTENT0", fillinExtraIntent); + + fillinIntent.collectExtraIntentKeys(); + intent.fillIn(fillinIntent, FILL_IN_ACTION); + + mAms.addCreatorToken(fillinIntent); + + fillinExtraIntent = intent.getParcelableExtra("FILLIN_EXTRA_INTENT0", Intent.class); + + ActivityManagerService.IntentCreatorToken token = + (ActivityManagerService.IntentCreatorToken) fillinExtraIntent.getCreatorToken(); + assertThat(token).isNotNull(); + assertThat(token.getCreatorUid()).isEqualTo(mInjector.getCallingUid()); + } + private void verifyWaitingForNetworkStateUpdate(long curProcStateSeq, long lastNetworkUpdatedProcStateSeq, final long procStateSeqToWait, boolean expectWait) throws Exception { -- GitLab From 31ce2795a8fa161920ac4e153fb62a37cb20cf2c Mon Sep 17 00:00:00 2001 From: Sandeep Bandaru Date: Fri, 4 Oct 2024 00:09:38 +0000 Subject: [PATCH 071/447] Extend service permission list only accessible from SystemUid. As noted in b/185746653 - for isolated_compute_app, we do not want even the holding app for the isolated-process to be able to bind to it. This was implemented specifically for HOTWORD usecase previously and missed for few other usecases. Similar to hotword service, we are extending the same permission check to wearablesensingservice and ondeviceintelligence service which also run as isolated_compute_app and require this enforcement in framework. Change-Id: I6bbe1a48de15243ace803e08c2ab7550c3612eb1 Bug: 369871251 Flag: EXEMPT bugfix Test: added CTS in topic --- services/core/java/com/android/server/am/ActiveServices.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 36665240c16b..f9197e3c5c42 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -5077,7 +5077,10 @@ public final class ActiveServices { + " requires " + r.permission); return new ServiceLookupResult(r.permission); } else if ((Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE.equals(r.permission) - || Manifest.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE.equals(r.permission)) + || Manifest.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE.equals(r.permission) + || Manifest.permission.BIND_WEARABLE_SENSING_SERVICE.equals(r.permission) + || Manifest.permission.BIND_ON_DEVICE_SANDBOXED_INFERENCE_SERVICE.equals( + r.permission)) && callingUid != Process.SYSTEM_UID) { // Hotword detection and visual query detection must run in its own sandbox, and we // don't even trust its enclosing application to bind to it - only the system. -- GitLab From a55c0b07197815c5ab3b5eb81bf97abf873c40b1 Mon Sep 17 00:00:00 2001 From: Vlad Popa Date: Fri, 4 Oct 2024 11:30:22 -0700 Subject: [PATCH 072/447] Fix VolumeHelperTest on automotive On automotive platforms the hardening enforcer is blocking a lot of set/adjust stream volume calls. Skipping those tests. Also added some minor improvements regarding the assertEqual checking order. Flag: TEST_ONLY Test: atest VolumeHelperTest Bug: 369155290 Change-Id: I4eebedadbbdb367123938f6c67283a986bad0518 --- .../server/audio/VolumeHelperTest.java | 54 +++++++++++-------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java b/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java index beed0a3d413c..f9479f332cb9 100644 --- a/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java +++ b/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java @@ -289,6 +289,9 @@ public class VolumeHelperTest { // --------------- Volume Stream APIs --------------- @Test public void setStreamVolume_callsASSetStreamVolumeIndex() throws Exception { + assumeFalse("Skipping setStreamVolume_callsASSetStreamVolumeIndex on automotive", + mIsAutomotive); + int newIndex = circularNoMinMaxIncrementVolume(STREAM_MUSIC); mAudioService.setDeviceForStream(STREAM_MUSIC, DEVICE_OUT_USB_DEVICE); @@ -312,6 +315,9 @@ public class VolumeHelperTest { @Test public void adjustStreamVolume_callsASSetStreamVolumeIndex() throws Exception { + assumeFalse("Skipping adjustStreamVolume_callsASSetStreamVolumeIndex on automotive", + mIsAutomotive); + mAudioService.setDeviceForStream(STREAM_MUSIC, DEVICE_OUT_USB_DEVICE); mAudioService.adjustStreamVolume(STREAM_MUSIC, ADJUST_LOWER, /*flags=*/0, mContext.getOpPackageName()); @@ -323,6 +329,9 @@ public class VolumeHelperTest { @Test public void handleVolumeKey_callsASSetStreamVolumeIndex() throws Exception { + assumeFalse("Skipping handleVolumeKey_callsASSetStreamVolumeIndex on automotive", + mIsAutomotive); + final KeyEvent keyEvent = new KeyEvent(ACTION_DOWN, KEYCODE_VOLUME_UP); mAudioService.setDeviceForStream(STREAM_MUSIC, DEVICE_OUT_USB_DEVICE); @@ -338,6 +347,9 @@ public class VolumeHelperTest { @Test public void setVolumeGroupVolumeIndex_callsASSetVolumeIndexForAttributes() throws Exception { + assumeFalse( + "Skipping setVolumeGroupVolumeIndex_callsASSetVolumeIndexForAttributes on " + + "automotive", mIsAutomotive); assumeNotNull(mAudioMusicVolumeGroup); mAudioService.setDeviceForStream(STREAM_MUSIC, DEVICE_OUT_USB_DEVICE); @@ -346,8 +358,8 @@ public class VolumeHelperTest { mContext.getOpPackageName(), /*attributionTag*/null); mTestLooper.dispatchAll(); - verify(mSpyAudioSystem).setVolumeIndexForAttributes( - any(), anyInt(), eq(DEVICE_OUT_USB_DEVICE)); + verify(mSpyAudioSystem).setVolumeIndexForAttributes(any(), anyInt(), + eq(DEVICE_OUT_USB_DEVICE)); } @Test @@ -365,6 +377,7 @@ public class VolumeHelperTest { @Test public void check_getVolumeGroupVolumeIndex() throws Exception { + assumeFalse("Skipping check_getVolumeGroupVolumeIndex on automotive", mIsAutomotive); assumeNotNull(mAudioMusicVolumeGroup); int newIndex = circularNoMinMaxIncrementVolume(STREAM_MUSIC); @@ -373,10 +386,9 @@ public class VolumeHelperTest { newIndex, /*flags=*/0, mContext.getOpPackageName(), /*attributionTag*/null); mTestLooper.dispatchAll(); - assertEquals(mAudioService.getVolumeGroupVolumeIndex(mAudioMusicVolumeGroup.getId()), - newIndex); - assertEquals(mAudioService.getStreamVolume(STREAM_MUSIC), - newIndex); + assertEquals(newIndex, + mAudioService.getVolumeGroupVolumeIndex(mAudioMusicVolumeGroup.getId())); + assertEquals(newIndex, mAudioService.getStreamVolume(STREAM_MUSIC)); } @Test @@ -431,6 +443,7 @@ public class VolumeHelperTest { @Test public void flagAbsVolume_onBtDevice_changesVolume() throws Exception { + assumeFalse("Skipping flagAbsVolume_onBtDevice_changesVolume on automotive", mIsAutomotive); mAudioService.setDeviceForStream(STREAM_NOTIFICATION, DEVICE_OUT_BLE_SPEAKER); int newIndex = circularNoMinMaxIncrementVolume(STREAM_NOTIFICATION); @@ -493,7 +506,7 @@ public class VolumeHelperTest { mContext.getOpPackageName()); mTestLooper.dispatchAll(); - assertEquals(mAudioService.getRingerModeInternal(), RINGER_MODE_VIBRATE); + assertEquals(RINGER_MODE_VIBRATE, mAudioService.getRingerModeInternal()); } // --------------------- Permission tests --------------------- @@ -537,6 +550,7 @@ public class VolumeHelperTest { // ----------------- AudioDeviceVolumeManager ----------------- @Test public void setDeviceVolume_checkIndex() { + assumeFalse("Skipping setDeviceVolume_checkIndex on automotive", mIsAutomotive); final int minIndex = mAm.getStreamMinVolume(STREAM_MUSIC); final int maxIndex = mAm.getStreamMaxVolume(STREAM_MUSIC); final int midIndex = (minIndex + maxIndex) / 2; @@ -552,21 +566,17 @@ public class VolumeHelperTest { mAudioService.setDeviceVolume(volMin, usbDevice, mContext.getOpPackageName()); mTestLooper.dispatchAll(); - if (!mIsAutomotive) { - // there is a min/max index mismatch in automotive - assertEquals(mAudioService.getDeviceVolume(volMin, usbDevice, - mContext.getOpPackageName()), volMin); - } + // there is a min/max index mismatch in automotive + assertEquals(volMin, mAudioService.getDeviceVolume(volMin, usbDevice, + mContext.getOpPackageName())); verify(mSpyAudioSystem, atLeast(1)).setStreamVolumeIndexAS( eq(STREAM_MUSIC), anyInt(), eq(AudioSystem.DEVICE_OUT_USB_DEVICE)); mAudioService.setDeviceVolume(volMid, usbDevice, mContext.getOpPackageName()); mTestLooper.dispatchAll(); - if (!mIsAutomotive) { - // there is a min/max index mismatch in automotive - assertEquals(mAudioService.getDeviceVolume(volMid, usbDevice, - mContext.getOpPackageName()), volMid); - } + // there is a min/max index mismatch in automotive + assertEquals(volMid, mAudioService.getDeviceVolume(volMid, usbDevice, + mContext.getOpPackageName())); verify(mSpyAudioSystem, atLeast(1)).setStreamVolumeIndexAS( eq(STREAM_MUSIC), anyInt(), eq(AudioSystem.DEVICE_OUT_USB_DEVICE)); } @@ -602,9 +612,8 @@ public class VolumeHelperTest { mAudioService.setDeviceVolume(volCur, bleDevice, mContext.getOpPackageName()); mTestLooper.dispatchAll(); - assertEquals( - mAudioService.getDeviceVolume(volCur, bleDevice, mContext.getOpPackageName()), - volCur); + assertEquals(volCur, + mAudioService.getDeviceVolume(volCur, bleDevice, mContext.getOpPackageName())); // Stream volume changes verify(mSpyAudioSystem, atLeast(1)).setStreamVolumeIndexAS( STREAM_MUSIC, targetIndex, @@ -617,9 +626,8 @@ public class VolumeHelperTest { mAudioService.setDeviceVolume(volIndex4, bleDevice, mContext.getOpPackageName()); mTestLooper.dispatchAll(); - assertEquals( - mAudioService.getDeviceVolume(volIndex4, bleDevice, mContext.getOpPackageName()), - volIndex4); + assertEquals(volIndex4, + mAudioService.getDeviceVolume(volIndex4, bleDevice, mContext.getOpPackageName())); verify(mSpyAudioSystem, atLeast(1)).setStreamVolumeIndexAS( STREAM_MUSIC, maxIndex, AudioSystem.DEVICE_OUT_BLE_HEADSET); -- GitLab From ef3ecd5096d8f4a4c92dd19e0d9ae09320455ba9 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Tue, 24 Sep 2024 21:00:32 +0000 Subject: [PATCH 073/447] Add metrics for TextureView dataspace changes Bug: 329475035 Flag: EXEMPT logging only Test: builds Test: GraphicsAtomTests Change-Id: Ia65ceb3bf205e3050b182aa6d170a453076bdc4c --- libs/hwui/DeferredLayerUpdater.cpp | 24 ++++++++++++++++++++++++ libs/hwui/DeferredLayerUpdater.h | 9 +++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp index b763a96e8e8a..c0160705fd47 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -19,6 +19,7 @@ #include // TODO: Use public SurfaceTexture APIs once available and include public NDK header file instead. +#include #include #include "AutoBackendTextureRelease.h" @@ -50,6 +51,14 @@ DeferredLayerUpdater::~DeferredLayerUpdater() { setTransform(nullptr); mRenderState.removeContextCallback(this); destroyLayer(); + if (mFirstTimeForDataspace > std::chrono::steady_clock::time_point::min()) { + auto currentTime = std::chrono::steady_clock::now(); + stats_write(stats::TEXTURE_VIEW_EVENT, static_cast(getuid()), + static_cast(std::chrono::duration_cast( + currentTime - mFirstTimeForDataspace) + .count()), + mDataspace); + } } void DeferredLayerUpdater::setSurfaceTexture(AutoTextureRelease&& consumer) { @@ -195,6 +204,21 @@ void DeferredLayerUpdater::apply() { updateLayer(forceFilter, layerImage, outTransform, currentCropRect, maxLuminanceNits); } + + if (dataspace != mDataspace || + mFirstTimeForDataspace == std::chrono::steady_clock::time_point::min()) { + auto currentTime = std::chrono::steady_clock::now(); + if (mFirstTimeForDataspace > std::chrono::steady_clock::time_point::min()) { + stats_write(stats::TEXTURE_VIEW_EVENT, static_cast(getuid()), + static_cast( + std::chrono::duration_cast( + currentTime - mFirstTimeForDataspace) + .count()), + mDataspace); + } + mFirstTimeForDataspace = currentTime; + mDataspace = dataspace; + } } } diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index a7f8f6189a8e..3abb47ca92d1 100644 --- a/libs/hwui/DeferredLayerUpdater.h +++ b/libs/hwui/DeferredLayerUpdater.h @@ -16,6 +16,8 @@ #pragma once +#include +#include #include #include #include @@ -24,9 +26,9 @@ #include #include #include +#include -#include -#include +#include #include #include @@ -154,6 +156,9 @@ private: bool mGLContextAttached; bool mUpdateTexImage; int mCurrentSlot = -1; + android_dataspace mDataspace = HAL_DATASPACE_UNKNOWN; + std::chrono::steady_clock::time_point mFirstTimeForDataspace = + std::chrono::steady_clock::time_point::min(); Layer* mLayer; }; -- GitLab From 3586871bd060cce0278d468515557be8b3035feb Mon Sep 17 00:00:00 2001 From: Yining Liu Date: Thu, 3 Oct 2024 18:49:31 +0000 Subject: [PATCH 074/447] Fix transparent content view when opening the shade during bubble fly out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix transparent content view issue when opening the shade during bubble fly out animation. Old codepath uses setHideSensitive to reset the alpha , which is not preferred because we didn’t change the hideSensitive, but rely on calling it to reset the alpha. Fix: 366027702 Flag: com.android.systemui.notification_content_alpha_optimization Test: SystemUITest Change-Id: I8b1215b09c44f79b2bd367a41c939e0d65ae17db --- .../row/ExpandableNotificationRow.java | 2 +- .../stack/NotificationStackScrollLayout.java | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 5003a6af5c4c..57529f263771 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -3218,7 +3218,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } @Override - protected void resetAllContentAlphas() { + public void resetAllContentAlphas() { mLogger.logResetAllContentAlphas(getEntry()); mPrivateLayout.setAlpha(1f); mPrivateLayout.setLayerType(LAYER_TYPE_NONE, null); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index b466bf02387f..452db5cbaf35 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -113,6 +113,7 @@ import com.android.systemui.statusbar.notification.row.ActivatableNotificationVi import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.notification.row.StackScrollerDecorView; +import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization; import com.android.systemui.statusbar.notification.shared.NotificationHeadsUpCycling; import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun; import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation; @@ -4363,6 +4364,16 @@ public class NotificationStackScrollLayout } } + private void resetChildAlpha() { + for (int i = 0; i < getChildCount(); i++) { + ExpandableView child = getChildAtIndex(i); + if (child instanceof ExpandableNotificationRow row) { + if (row.isExpandAnimationRunning()) continue; + row.resetAllContentAlphas(); + } + } + } + private void logTransientNotificationRowTraversalCleaned( ExpandableNotificationRow transientView, String reason @@ -4406,6 +4417,9 @@ public class NotificationStackScrollLayout if (SceneContainerFlag.isEnabled()) { setHeadsUpAnimatingAway(false); } + if (NotificationContentAlphaOptimization.isEnabled()) { + resetChildAlpha(); + } } else { mGroupExpansionManager.collapseGroups(); mExpandHelper.cancelImmediately(); -- GitLab From a814c2dfbe7b4e50a609f0b85bc26d0f265c03a0 Mon Sep 17 00:00:00 2001 From: Atneya Nair Date: Fri, 4 Oct 2024 20:56:46 +0000 Subject: [PATCH 075/447] audio: Addtl logging in PlaybackActivity Add package name to new player events, for easier debugging. Change-Id: Ia7cbb617781eb312043d1ca39b982b8b89f10faa Test: Compiles Bug: TRIVIAL Flag: EXEMPT TRIVIAL --- .../server/audio/PlaybackActivityMonitor.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java index 88268cd19a38..a734e73d213b 100644 --- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java +++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java @@ -253,7 +253,11 @@ public final class PlaybackActivityMonitor updateAllowedCapturePolicy(apc, mAllowedCapturePolicies.get(uid)); } } - sEventLogger.enqueue(new NewPlayerEvent(apc)); + var packages = mContext.getPackageManager().getPackagesForUid(apc.getClientUid()); + sEventLogger.enqueue(new NewPlayerEvent( + apc, + packages != null && packages.length > 0 ? packages[0] : null + )); synchronized(mPlayerLock) { mPlayers.put(newPiid, apc); maybeMutePlayerAwaitingConnection(apc); @@ -1402,14 +1406,16 @@ public final class PlaybackActivityMonitor private final int mPlayerIId; private final int mPlayerType; private final int mClientUid; + private final String mClientPackageName; private final int mClientPid; private final AudioAttributes mPlayerAttr; private final int mSessionId; - NewPlayerEvent(AudioPlaybackConfiguration apc) { + NewPlayerEvent(AudioPlaybackConfiguration apc, String packageName) { mPlayerIId = apc.getPlayerInterfaceId(); mPlayerType = apc.getPlayerType(); mClientUid = apc.getClientUid(); + mClientPackageName = packageName; mClientPid = apc.getClientPid(); mPlayerAttr = apc.getAudioAttributes(); mSessionId = apc.getSessionId(); @@ -1418,7 +1424,7 @@ public final class PlaybackActivityMonitor @Override public String eventToString() { return new String("new player piid:" + mPlayerIId + " uid/pid:" + mClientUid + "/" - + mClientPid + " type:" + + mClientPid + " package:" + mClientPackageName + " type:" + AudioPlaybackConfiguration.toLogFriendlyPlayerType(mPlayerType) + " attr:" + mPlayerAttr + " session:" + mSessionId); -- GitLab From 439eee0b509523c99126906a5cc35776f8983ebf Mon Sep 17 00:00:00 2001 From: Josh Tsuji Date: Thu, 3 Oct 2024 18:26:00 -0400 Subject: [PATCH 076/447] Add sendTransitionStepsOnStartTransition. Currently, calls to startTransition are recorded/spied on so that we can verify that someone asked to start a transition. However, as our interactors become more complicated, calls to startTransition sometimes are guarded by checking previous TransitionSteps. This requires us to send the appropriate fake transition steps prior to triggering the startTransition call we're looking for. To improve this, and also test more live code, this adds support for sending STARTED/RUNNING/FINISHED steps in response to startTransition calls from the real interactors. Also, adds FromLockscreenTransitionInteractor tests as promised in the previous CL. Bug: 370177430 Test: atest SystemUITests Flag: EXEMPT tests Change-Id: Iab04c8799978b54568a1069c8d7ce425bbe02a93 --- ...lternateBouncerTransitionInteractorTest.kt | 20 +++---- .../FromAodTransitionInteractorTest.kt | 24 ++++----- .../FromDozingTransitionInteractorTest.kt | 7 +-- .../FromDreamingTransitionInteractorTest.kt | 14 +++-- .../FromGoneTransitionInteractorTest.kt | 19 +++---- .../FromLockscreenTransitionInteractorTest.kt | 54 +++++++++++++++++-- .../FromOccludedTransitionInteractorTest.kt | 21 +++----- ...mPrimaryBouncerTransitionInteractorTest.kt | 38 ++++++------- .../KeyguardTransitionScenariosTest.kt | 9 ++-- .../HeadsUpNotificationInteractorTest.kt | 2 +- .../FakeKeyguardTransitionRepository.kt | 33 ++++++++++-- .../KeyguardTransitionRepositoryKosmos.kt | 7 ++- .../FromAodTransitionInteractorKosmos.kt | 4 +- .../FromGoneTransitionInteractorKosmos.kt | 4 +- 14 files changed, 159 insertions(+), 97 deletions(-) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt index 17e3006812ca..047d8c2b31a9 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt @@ -42,7 +42,8 @@ import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepositor import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository -import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy +import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat import com.android.systemui.kosmos.testScope @@ -57,7 +58,6 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mockito import org.mockito.Mockito.reset @ExperimentalCoroutinesApi @@ -66,7 +66,7 @@ import org.mockito.Mockito.reset class FromAlternateBouncerTransitionInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().apply { - this.fakeKeyguardTransitionRepository = Mockito.spy(FakeKeyguardTransitionRepository()) + this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } private val testScope = kosmos.testScope private lateinit var underTest: FromAlternateBouncerTransitionInteractor @@ -74,7 +74,7 @@ class FromAlternateBouncerTransitionInteractorTest : SysuiTestCase() { @Before fun setup() { - transitionRepository = kosmos.fakeKeyguardTransitionRepository + transitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy underTest = kosmos.fromAlternateBouncerTransitionInteractor underTest.start() } @@ -86,7 +86,7 @@ class FromAlternateBouncerTransitionInteractorTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.OCCLUDED, to = KeyguardState.ALTERNATE_BOUNCER, - testScope + testScope, ) reset(transitionRepository) @@ -111,7 +111,7 @@ class FromAlternateBouncerTransitionInteractorTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.OCCLUDED, to = KeyguardState.ALTERNATE_BOUNCER, - testScope + testScope, ) reset(transitionRepository) @@ -129,7 +129,7 @@ class FromAlternateBouncerTransitionInteractorTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.OCCLUDED, to = KeyguardState.ALTERNATE_BOUNCER, - testScope + testScope, ) reset(transitionRepository) @@ -158,7 +158,7 @@ class FromAlternateBouncerTransitionInteractorTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.OCCLUDED, to = KeyguardState.ALTERNATE_BOUNCER, - testScope + testScope, ) reset(transitionRepository) @@ -168,7 +168,7 @@ class FromAlternateBouncerTransitionInteractorTest : SysuiTestCase() { assertThat(transitionRepository) .startedTransition( from = KeyguardState.ALTERNATE_BOUNCER, - to = KeyguardState.OCCLUDED + to = KeyguardState.OCCLUDED, ) } @@ -183,7 +183,7 @@ class FromAlternateBouncerTransitionInteractorTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.GLANCEABLE_HUB, to = KeyguardState.ALTERNATE_BOUNCER, - testScope + testScope, ) reset(transitionRepository) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt index 33f3cd4ac167..930096463354 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt @@ -42,8 +42,9 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository -import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository +import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.GONE @@ -69,7 +70,6 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.reset -import org.mockito.Mockito.spy @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @@ -77,7 +77,7 @@ import org.mockito.Mockito.spy class FromAodTransitionInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().apply { - this.fakeKeyguardTransitionRepository = spy(FakeKeyguardTransitionRepository()) + this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } private val testScope = kosmos.testScope @@ -89,7 +89,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { @Before fun setup() { powerInteractor = kosmos.powerInteractor - transitionRepository = kosmos.fakeKeyguardTransitionRepository + transitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy underTest = kosmos.fromAodTransitionInteractor underTest.start() @@ -101,7 +101,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.AOD, - testScope + testScope, ) kosmos.fakeKeyguardRepository.setBiometricUnlockState(BiometricUnlockMode.NONE) reset(transitionRepository) @@ -117,10 +117,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { // Under default conditions, we should transition to LOCKSCREEN when waking up. assertThat(transitionRepository) - .startedTransition( - from = KeyguardState.AOD, - to = KeyguardState.LOCKSCREEN, - ) + .startedTransition(from = KeyguardState.AOD, to = KeyguardState.LOCKSCREEN) } @Test @@ -133,10 +130,7 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { // Waking with a SHOW_WHEN_LOCKED activity on top should transition to OCCLUDED. assertThat(transitionRepository) - .startedTransition( - from = KeyguardState.AOD, - to = KeyguardState.OCCLUDED, - ) + .startedTransition(from = KeyguardState.AOD, to = KeyguardState.OCCLUDED) } @Test @@ -363,13 +357,13 @@ class FromAodTransitionInteractorTest : SysuiTestCase() { from = KeyguardState.GONE, to = KeyguardState.AOD, transitionState = TransitionState.STARTED, - value = 0f + value = 0f, ), TransitionStep( from = KeyguardState.GONE, to = KeyguardState.AOD, transitionState = TransitionState.RUNNING, - value = 0.1f + value = 0.1f, ), ), testScope = testScope, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt index ff0a4a16fe2a..3b6e5d09a37c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt @@ -36,8 +36,9 @@ import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository -import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository +import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.GONE @@ -79,7 +80,7 @@ import platform.test.runner.parameterized.Parameters class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiTestCase() { private val kosmos = testKosmos().apply { - this.fakeKeyguardTransitionRepository = spy(FakeKeyguardTransitionRepository()) + this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy this.fakeCommunalSceneRepository = spy(FakeCommunalSceneRepository(applicationScope = applicationCoroutineScope)) } @@ -105,7 +106,7 @@ class FromDozingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiT @Before fun setup() { powerInteractor = kosmos.powerInteractor - transitionRepository = kosmos.fakeKeyguardTransitionRepository + transitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy underTest = kosmos.fromDozingTransitionInteractor underTest.start() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt index fa304c99ecc9..9ca3ce6929b0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt @@ -32,7 +32,9 @@ import com.android.systemui.flags.andSceneContainer import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository +import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat @@ -53,7 +55,6 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.reset -import org.mockito.Mockito.spy import org.mockito.kotlin.whenever import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @@ -77,14 +78,21 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu private val kosmos = testKosmos().apply { - this.fakeKeyguardTransitionRepository = spy(FakeKeyguardTransitionRepository()) + this.fakeKeyguardTransitionRepository = + FakeKeyguardTransitionRepository( + // This test sends transition steps manually in the test cases. + sendTransitionStepsOnStartTransition = false, + testScope = testScope, + ) + + this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } private val testScope = kosmos.testScope private val underTest by lazy { kosmos.fromDreamingTransitionInteractor } private val powerInteractor = kosmos.powerInteractor - private val transitionRepository = kosmos.fakeKeyguardTransitionRepository + private val transitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy @Before fun setup() { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorTest.kt index af76b088787e..57b12990fb97 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorTest.kt @@ -23,10 +23,10 @@ import androidx.test.filters.SmallTest import com.android.internal.widget.LockPatternUtils import com.android.systemui.Flags import com.android.systemui.SysuiTestCase -import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository -import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy +import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.keyguard.shared.model.AuthenticationFlags import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionState @@ -41,18 +41,17 @@ import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.reset -import org.mockito.Mockito.spy @SmallTest @RunWith(AndroidJUnit4::class) class FromGoneTransitionInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().apply { - fakeKeyguardTransitionRepository = spy(FakeKeyguardTransitionRepository()) + this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } private val testScope = kosmos.testScope private val underTest = kosmos.fromGoneTransitionInteractor - private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository + private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy @Before fun setUp() { @@ -101,9 +100,7 @@ class FromGoneTransitionInteractorTest : SysuiTestCase() { // We're in the middle of a GONE -> LOCKSCREEN transition. assertThat(keyguardTransitionRepository) - .startedTransition( - to = KeyguardState.LOCKSCREEN, - ) + .startedTransition(to = KeyguardState.LOCKSCREEN) } @Test @@ -121,15 +118,13 @@ class FromGoneTransitionInteractorTest : SysuiTestCase() { kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags( AuthenticationFlags( 0, - LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN + LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN, ) ) runCurrent() // We're in the middle of a GONE -> LOCKSCREEN transition. assertThat(keyguardTransitionRepository) - .startedTransition( - to = KeyguardState.LOCKSCREEN, - ) + .startedTransition(to = KeyguardState.LOCKSCREEN) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt index 4d81317b7755..9c2e6313a1f0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt @@ -27,9 +27,11 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository -import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository +import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.model.StatusBarState.KEYGUARD import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep @@ -42,10 +44,10 @@ import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.reset -import org.mockito.Mockito.spy @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @@ -53,15 +55,20 @@ import org.mockito.Mockito.spy class FromLockscreenTransitionInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().apply { - fakeKeyguardTransitionRepository = spy(FakeKeyguardTransitionRepository()) + this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } private val testScope = kosmos.testScope private val underTest = kosmos.fromLockscreenTransitionInteractor - private val transitionRepository = kosmos.fakeKeyguardTransitionRepository + private lateinit var transitionRepository: FakeKeyguardTransitionRepository private val shadeRepository = kosmos.fakeShadeRepository private val keyguardRepository = kosmos.fakeKeyguardRepository + @Before + fun setup() { + transitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy + } + @Test fun testSurfaceBehindVisibility() = testScope.runTest { @@ -256,4 +263,43 @@ class FromLockscreenTransitionInteractorTest : SysuiTestCase() { assertThatRepository(transitionRepository) .startedTransition(from = KeyguardState.LOCKSCREEN, to = KeyguardState.DREAMING) } + + @Test + fun testTransitionsBackToOccluded_ifOccluded_andCanceledSwipe() = + testScope.runTest { + underTest.start() + keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) + keyguardRepository.setKeyguardDismissible(false) + keyguardRepository.setKeyguardOccluded(false) + runCurrent() + + reset(transitionRepository) + + shadeRepository.setLegacyShadeTracking(true) + runCurrent() + shadeRepository.setLegacyShadeExpansion(0.5f) + runCurrent() + + assertThatRepository(transitionRepository) + .startedTransition( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.PRIMARY_BOUNCER, + ) + reset(transitionRepository) + + runCurrent() + + shadeRepository.setLegacyShadeExpansion(0.6f) + shadeRepository.setLegacyShadeExpansion(0.7f) + runCurrent() + + shadeRepository.setLegacyShadeExpansion(1f) + runCurrent() + + assertThatRepository(transitionRepository) + .startedTransition( + from = KeyguardState.PRIMARY_BOUNCER, + to = KeyguardState.LOCKSCREEN, + ) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt index 74243208cd98..4a90722274bd 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt @@ -42,9 +42,9 @@ import com.android.systemui.Flags.FLAG_COMMUNAL_SCENE_KTF_REFACTOR import com.android.systemui.SysuiTestCase import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository import com.android.systemui.communal.shared.model.CommunalScenes -import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository -import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository +import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat import com.android.systemui.kosmos.testScope @@ -60,7 +60,6 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.reset -import org.mockito.Mockito.spy @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @@ -68,14 +67,14 @@ import org.mockito.Mockito.spy class FromOccludedTransitionInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().apply { - this.fakeKeyguardTransitionRepository = spy(FakeKeyguardTransitionRepository()) + this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } private val testScope = kosmos.testScope private val underTest = kosmos.fromOccludedTransitionInteractor private val powerInteractor = kosmos.powerInteractor - private val transitionRepository = kosmos.fakeKeyguardTransitionRepository + private val transitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy @Before fun setup() { @@ -88,7 +87,7 @@ class FromOccludedTransitionInteractorTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.OCCLUDED, - testScope + testScope, ) reset(transitionRepository) } @@ -102,10 +101,7 @@ class FromOccludedTransitionInteractorTest : SysuiTestCase() { runCurrent() assertThat(transitionRepository) - .startedTransition( - from = KeyguardState.OCCLUDED, - to = KeyguardState.LOCKSCREEN, - ) + .startedTransition(from = KeyguardState.OCCLUDED, to = KeyguardState.LOCKSCREEN) } @Test @@ -122,9 +118,6 @@ class FromOccludedTransitionInteractorTest : SysuiTestCase() { runCurrent() assertThat(transitionRepository) - .startedTransition( - from = KeyguardState.OCCLUDED, - to = KeyguardState.GLANCEABLE_HUB, - ) + .startedTransition(from = KeyguardState.OCCLUDED, to = KeyguardState.GLANCEABLE_HUB) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt index 14f2d654a031..a7da23065dec 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt @@ -26,9 +26,9 @@ import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepositor import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.coroutines.collectValues -import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository -import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository +import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep @@ -44,20 +44,19 @@ import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.reset -import org.mockito.Mockito.spy @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() { - val kosmos = + private val kosmos = testKosmos().apply { - this.fakeKeyguardTransitionRepository = spy(FakeKeyguardTransitionRepository()) + this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } val underTest = kosmos.fromPrimaryBouncerTransitionInteractor val testScope = kosmos.testScope val selectedUserInteractor = kosmos.selectedUserInteractor - val transitionRepository = kosmos.fakeKeyguardTransitionRepository + val transitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy val bouncerRepository = kosmos.fakeKeyguardBouncerRepository @Test @@ -67,12 +66,7 @@ class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() { runCurrent() // Transition-specific surface visibility should be null ("don't care") initially. - assertEquals( - listOf( - null, - ), - values - ) + assertEquals(listOf(null), values) transitionRepository.sendTransitionStep( TransitionStep( @@ -86,9 +80,9 @@ class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() { assertEquals( listOf( - null, // PRIMARY_BOUNCER -> LOCKSCREEN does not have any specific visibility. + null // PRIMARY_BOUNCER -> LOCKSCREEN does not have any specific visibility. ), - values + values, ) transitionRepository.sendTransitionStep( @@ -117,7 +111,7 @@ class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() { null, false, // Surface is only made visible once the bouncer UI animates out. ), - values + values, ) transitionRepository.sendTransitionStep( @@ -137,7 +131,7 @@ class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() { false, true, // Surface should eventually be visible. ), - values + values, ) } @@ -150,7 +144,7 @@ class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.PRIMARY_BOUNCER, - testScope + testScope, ) reset(transitionRepository) @@ -161,7 +155,7 @@ class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() { assertThat(transitionRepository) .startedTransition( from = KeyguardState.PRIMARY_BOUNCER, - to = KeyguardState.LOCKSCREEN + to = KeyguardState.LOCKSCREEN, ) } @@ -177,7 +171,7 @@ class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.PRIMARY_BOUNCER, - testScope + testScope, ) reset(transitionRepository) @@ -188,7 +182,7 @@ class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() { assertThat(transitionRepository) .startedTransition( from = KeyguardState.PRIMARY_BOUNCER, - to = KeyguardState.GLANCEABLE_HUB + to = KeyguardState.GLANCEABLE_HUB, ) } @@ -201,7 +195,7 @@ class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.PRIMARY_BOUNCER, - testScope + testScope, ) reset(transitionRepository) @@ -218,7 +212,7 @@ class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() { assertThat(transitionRepository) .startedTransition( from = KeyguardState.PRIMARY_BOUNCER, - to = KeyguardState.OCCLUDED + to = KeyguardState.OCCLUDED, ) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt index a617484d7d94..8f3d54961483 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt @@ -41,9 +41,9 @@ import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED import com.android.systemui.flags.andSceneContainer import com.android.systemui.flags.fakeFeatureFlagsClassic -import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository -import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy +import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.keyguard.shared.model.BiometricUnlockMode import com.android.systemui.keyguard.shared.model.DozeStateModel import com.android.systemui.keyguard.shared.model.DozeTransitionModel @@ -76,7 +76,6 @@ import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.reset -import org.mockito.Mockito.spy import org.mockito.MockitoAnnotations import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @@ -91,7 +90,7 @@ import platform.test.runner.parameterized.Parameters class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTestCase() { private val kosmos = testKosmos().apply { - fakeKeyguardTransitionRepository = spy(FakeKeyguardTransitionRepository()) + this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } private val testScope = kosmos.testScope @@ -99,7 +98,7 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest private val keyguardInteractor by lazy { kosmos.keyguardInteractor } private val bouncerRepository by lazy { kosmos.fakeKeyguardBouncerRepository } private val shadeTestUtil by lazy { kosmos.shadeTestUtil } - private val transitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository } + private val transitionRepository by lazy { kosmos.fakeKeyguardTransitionRepositorySpy } private lateinit var featureFlags: FakeFeatureFlags // Used to verify transition requests for test output diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt index eb1bcc7fe147..d717fe4c1e04 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt @@ -48,7 +48,7 @@ class HeadsUpNotificationInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().apply { fakeKeyguardTransitionRepository = - FakeKeyguardTransitionRepository(initInLockscreen = false) + FakeKeyguardTransitionRepository(initInLockscreen = false, testScope = testScope) } private val testScope = kosmos.testScope private val faceAuthRepository by lazy { kosmos.fakeDeviceEntryFaceAuthRepository } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt index 4d0e603aadd6..70b4f79131a7 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt @@ -48,13 +48,35 @@ import kotlinx.coroutines.test.runCurrent * with OFF -> GONE. Construct with initInLockscreen = false if your test requires this behavior. */ @SysUISingleton -class FakeKeyguardTransitionRepository(private val initInLockscreen: Boolean = true) : - KeyguardTransitionRepository { +class FakeKeyguardTransitionRepository( + private val initInLockscreen: Boolean = true, + + /** + * If true, calls to [startTransition] will automatically emit STARTED, RUNNING, and FINISHED + * transition steps from/to the given states. + * + * [startTransition] is what the From*TransitionInteractors call, so this more closely emulates + * the behavior of the real KeyguardTransitionRepository, and reduces the work needed to + * manually set up the repository state in each test. For example, setting dreaming=true will + * automatically cause FromDreamingTransitionInteractor to call startTransition(DREAMING), and + * then we'll send STARTED/RUNNING/FINISHED DREAMING TransitionSteps. + * + * If your test needs to make assertions at specific points between STARTED/FINISHED, or if it's + * difficult to set up all of the conditions to make the transition interactors actually call + * startTransition, then construct a FakeKeyguardTransitionRepository with this value false. + */ + private val sendTransitionStepsOnStartTransition: Boolean = true, + private val testScope: TestScope, +) : KeyguardTransitionRepository { + private val _transitions = MutableSharedFlow(replay = 3, onBufferOverflow = BufferOverflow.DROP_OLDEST) override val transitions: SharedFlow = _transitions - @Inject constructor() : this(initInLockscreen = true) + @Inject + constructor( + testScope: TestScope + ) : this(initInLockscreen = true, sendTransitionStepsOnStartTransition = true, testScope) private val _currentTransitionInfo: MutableStateFlow = MutableStateFlow( @@ -287,6 +309,11 @@ class FakeKeyguardTransitionRepository(private val initInLockscreen: Boolean = t override suspend fun startTransition(info: TransitionInfo): UUID? { _currentTransitionInfo.value = info + + if (sendTransitionStepsOnStartTransition) { + sendTransitionSteps(from = info.from, to = info.to, testScope = testScope) + } + return if (info.animator == null) UUID.randomUUID() else null } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryKosmos.kt index 3e69e875cd0d..e9eea83d54df 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryKosmos.kt @@ -18,9 +18,14 @@ package com.android.systemui.keyguard.data.repository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.kosmos.testScope +import org.mockito.Mockito.spy var Kosmos.keyguardTransitionRepository: KeyguardTransitionRepository by Kosmos.Fixture { fakeKeyguardTransitionRepository } -var Kosmos.fakeKeyguardTransitionRepository by Kosmos.Fixture { FakeKeyguardTransitionRepository() } +var Kosmos.fakeKeyguardTransitionRepository by + Kosmos.Fixture { FakeKeyguardTransitionRepository(testScope = testScope) } +var Kosmos.fakeKeyguardTransitionRepositorySpy: FakeKeyguardTransitionRepository by + Kosmos.Fixture { spy(fakeKeyguardTransitionRepository) } var Kosmos.realKeyguardTransitionRepository: KeyguardTransitionRepository by Kosmos.Fixture { KeyguardTransitionRepositoryImpl(testDispatcher) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt index ef789d1b29ff..93a59eb8ca0c 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt @@ -17,7 +17,7 @@ package com.android.systemui.keyguard.domain.interactor import com.android.systemui.deviceentry.data.repository.deviceEntryRepository -import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +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 @@ -27,7 +27,7 @@ import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInterac val Kosmos.fromAodTransitionInteractor by Kosmos.Fixture { FromAodTransitionInteractor( - transitionRepository = fakeKeyguardTransitionRepository, + transitionRepository = keyguardTransitionRepository, transitionInteractor = keyguardTransitionInteractor, internalTransitionInteractor = internalKeyguardTransitionInteractor, scope = applicationCoroutineScope, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt index c694114a0f47..700d7e9c5608 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt @@ -18,8 +18,8 @@ package com.android.systemui.keyguard.domain.interactor import com.android.systemui.communal.domain.interactor.communalSceneInteractor import com.android.systemui.keyguard.data.repository.biometricSettingsRepository -import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository 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 @@ -29,7 +29,7 @@ import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInterac val Kosmos.fromGoneTransitionInteractor by Kosmos.Fixture { FromGoneTransitionInteractor( - transitionRepository = fakeKeyguardTransitionRepository, + transitionRepository = keyguardTransitionRepository, transitionInteractor = keyguardTransitionInteractor, internalTransitionInteractor = internalKeyguardTransitionInteractor, scope = applicationCoroutineScope, -- GitLab From 331bbabf05c5701b1783a14b382d57bfbb54dc38 Mon Sep 17 00:00:00 2001 From: Chandru S Date: Fri, 4 Oct 2024 03:19:34 +0000 Subject: [PATCH 077/447] Fixes the issue of UDFPS icon background being white when the device is in DOZE_PULSING state Test: manually 1. Disable dark theme and AOD 2. Enroll fingerprint on a udfps device 3. Go to lockscreen, keep the phone on a table. 4. Press power button to force Lockscreen -> Dozing transition 5. move the phone around on the table to switch from dozing to doze_pulsing 6. Fingerprint icon background should not be visible now (black) Fixes: 366100470 Flag: EXEMPT bugfix Change-Id: I6e962ff0b3bd1184e453b5b1ea247e5efb6f4cec --- .../DeviceEntryBackgroundViewModelTest.kt | 90 +++++++++++++++++++ .../DeviceEntryBackgroundViewModel.kt | 5 +- .../LockscreenToDozingTransitionViewModel.kt | 8 +- .../DeviceEntryBackgroundViewModelKosmos.kt | 53 +++++++++++ 4 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt new file mode 100644 index 000000000000..22677b2f8e3e --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyguard.ui.viewmodel + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.shared.model.KeyguardState +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.shared.model.TransitionStep +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith + +@ExperimentalCoroutinesApi +@SmallTest +@RunWith(AndroidJUnit4::class) +class DeviceEntryBackgroundViewModelTest : SysuiTestCase() { + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + private val underTest: DeviceEntryBackgroundViewModel by lazy { + kosmos.deviceEntryBackgroundViewModel + } + + @Test + fun lockscreenToDozingTransitionChangesBackgroundViewAlphaToZero() = + testScope.runTest { + kosmos.fingerprintPropertyRepository.supportsUdfps() + val alpha by collectLastValue(underTest.alpha) + + kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps( + listOf(dozingToLockscreen(0f, STARTED), dozingToLockscreen(0.1f)), + testScope, + ) + runCurrent() + assertThat(alpha).isEqualTo(1.0f) + + kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps( + listOf(lockscreenToDozing(0f, STARTED)), + testScope, + ) + runCurrent() + + assertThat(alpha).isEqualTo(0.0f) + } + + private fun lockscreenToDozing(value: Float, state: TransitionState = RUNNING): TransitionStep { + return TransitionStep( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.DOZING, + value = value, + transitionState = state, + ownerName = "DeviceEntryBackgroundViewModelTest", + ) + } + + private fun dozingToLockscreen(value: Float, state: TransitionState = RUNNING): TransitionStep { + return TransitionStep( + from = KeyguardState.DOZING, + to = KeyguardState.LOCKSCREEN, + value = value, + transitionState = state, + ownerName = "DeviceEntryBackgroundViewModelTest", + ) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt index ca1a8006c6bb..68244d842046 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt @@ -60,6 +60,7 @@ constructor( primaryBouncerToAodTransitionViewModel: PrimaryBouncerToAodTransitionViewModel, primaryBouncerToDozingTransitionViewModel: PrimaryBouncerToDozingTransitionViewModel, primaryBouncerToLockscreenTransitionViewModel: PrimaryBouncerToLockscreenTransitionViewModel, + lockscreenToDozingTransitionViewModel: LockscreenToDozingTransitionViewModel, ) { val color: Flow = deviceEntryIconViewModel.useBackgroundProtection.flatMapLatest { useBackground -> @@ -103,7 +104,9 @@ constructor( offToLockscreenTransitionViewModel.deviceEntryBackgroundViewAlpha, primaryBouncerToAodTransitionViewModel.deviceEntryBackgroundViewAlpha, primaryBouncerToDozingTransitionViewModel.deviceEntryBackgroundViewAlpha, - primaryBouncerToLockscreenTransitionViewModel.deviceEntryBackgroundViewAlpha, + primaryBouncerToLockscreenTransitionViewModel + .deviceEntryBackgroundViewAlpha, + lockscreenToDozingTransitionViewModel.deviceEntryBackgroundViewAlpha, ) .merge() .onStart { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt index d3eefca67037..7abf35de5dae 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt @@ -55,16 +55,16 @@ constructor( onCancel = { 1f }, ) + val deviceEntryBackgroundViewAlpha: Flow = + transitionAnimation.immediatelyTransitionTo(0f) + override val deviceEntryParentViewAlpha: Flow = deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest { isUdfpsEnrolledAndEnabled -> if (isUdfpsEnrolledAndEnabled) { transitionAnimation.immediatelyTransitionTo(1f) } else { - transitionAnimation.sharedFlow( - duration = 250.milliseconds, - onStep = { 1f - it }, - ) + transitionAnimation.sharedFlow(duration = 250.milliseconds, onStep = { 1f - it }) } } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt new file mode 100644 index 000000000000..fc4f3a553d51 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyguard.ui.viewmodel + +import android.content.applicationContext +import com.android.systemui.common.ui.domain.interactor.configurationInteractor +import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import kotlinx.coroutines.ExperimentalCoroutinesApi + +@ExperimentalCoroutinesApi +val Kosmos.deviceEntryBackgroundViewModel by Fixture { + DeviceEntryBackgroundViewModel( + context = applicationContext, + deviceEntryIconViewModel = deviceEntryIconViewModel, + configurationInteractor = configurationInteractor, + keyguardTransitionInteractor = keyguardTransitionInteractor, + alternateBouncerToAodTransitionViewModel = alternateBouncerToAodTransitionViewModel, + alternateBouncerToDozingTransitionViewModel = alternateBouncerToDozingTransitionViewModel, + aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel, + dozingToLockscreenTransitionViewModel = dozingToLockscreenTransitionViewModel, + dreamingToAodTransitionViewModel = dreamingToAodTransitionViewModel, + dreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel, + goneToAodTransitionViewModel = goneToAodTransitionViewModel, + goneToDozingTransitionViewModel = goneToDozingTransitionViewModel, + goneToLockscreenTransitionViewModel = goneToLockscreenTransitionViewModel, + lockscreenToAodTransitionViewModel = lockscreenToAodTransitionViewModel, + occludedToAodTransitionViewModel = occludedToAodTransitionViewModel, + occludedToDozingTransitionViewModel = occludedToDozingTransitionViewModel, + occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel, + offToLockscreenTransitionViewModel = offToLockscreenTransitionViewModel, + primaryBouncerToAodTransitionViewModel = primaryBouncerToAodTransitionViewModel, + primaryBouncerToDozingTransitionViewModel = primaryBouncerToDozingTransitionViewModel, + primaryBouncerToLockscreenTransitionViewModel = + primaryBouncerToLockscreenTransitionViewModel, + lockscreenToDozingTransitionViewModel = lockscreenToDozingTransitionViewModel, + ) +} -- GitLab From f524115011cb60783d6b4bfeacee037fa0c229d8 Mon Sep 17 00:00:00 2001 From: John Wu Date: Fri, 4 Oct 2024 21:43:40 +0000 Subject: [PATCH 078/447] [Ravenwood] Make sure Mockito actually works Bug: 292141694 Flag: EXEMPT host test change only Test: atest RavenwoodCoreTest Change-Id: I58fd0f7a319780163ef0dc7edb312f19ca47c446 --- .../coretest/RavenwoodMockitoTest.java | 15 +++++++++++++++ .../test/ravenwood/ravenizer/Ravenizer.kt | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodMockitoTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodMockitoTest.java index dd6d259d5a34..31884b6bfc57 100644 --- a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodMockitoTest.java +++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodMockitoTest.java @@ -16,11 +16,19 @@ package com.android.ravenwoodtest.coretest; import static org.junit.Assert.assertThrows; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; import org.junit.Test; public class RavenwoodMockitoTest { + private static class MockClass { + void foo() { + throw new RuntimeException("Unsupported!!"); + } + } + @Test public void checkMockitoClasses() { // DexMaker should not exist @@ -32,4 +40,11 @@ public class RavenwoodMockitoTest { ClassNotFoundException.class, () -> Class.forName("org.mockito.Matchers")); } + + @Test + public void checkMockitoActuallyWorks() { + var mock = mock(MockClass.class); + doNothing().when(mock).foo(); + mock.foo(); + } } diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt index 49f0b599762f..e67c730df069 100644 --- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt +++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt @@ -127,7 +127,7 @@ class Ravenizer { } } if (includeUnsupportedMockito(allClasses)) { - log.w("Unsupported Mockito detected in $inJar}!") + log.w("Unsupported Mockito detected in $inJar!") } stats.totalProcessTime = log.vTime("$executableName processing $inJar") { -- GitLab From ff180674e7b92349e580fdbd47f538f537db2a1d Mon Sep 17 00:00:00 2001 From: Matthew Reynolds Date: Fri, 4 Oct 2024 18:05:39 +0000 Subject: [PATCH 079/447] Robolectric Mass Migration: statusbar tests Bug: 369884473 Test: tested with atest Flag: TEST_ONLY Change-Id: Icfcb77eee2bec88dbf3d895c1237a52b3205bf90 --- .../src/com/android/systemui/statusbar/BlurUtilsTest.kt | 0 .../src/com/android/systemui/statusbar/DragDownHelperTest.kt | 0 .../statusbar/KeyguardIndicationControllerBaseTest.java | 0 .../android/systemui/statusbar/LSShadeTransitionLoggerTest.kt | 0 .../statusbar/LockscreenShadeQsTransitionControllerTest.kt | 0 .../android/systemui/statusbar/NotificationListenerTest.java | 0 .../systemui/statusbar/NotificationRemoteInputManagerTest.java | 0 .../systemui/statusbar/NotificationShadeDepthControllerTest.kt | 0 .../systemui/statusbar/NotificationUiAdjustmentTest.java | 0 .../android/systemui/statusbar/PulseExpansionHandlerTest.kt | 0 .../statusbar/RemoteInputNotificationRebuilderTest.java | 0 .../statusbar/SingleShadeLockScreenOverScrollerTest.kt | 0 .../android/systemui/statusbar/SmartReplyControllerTest.java | 0 .../com/android/systemui/statusbar/StatusBarIconViewTest.java | 0 .../com/android/systemui/statusbar/StatusBarStateEventTest.kt | 0 .../src/com/android/systemui/statusbar/VibratorHelperTest.kt | 0 .../statusbar/chips/ui/view/ChipBackgroundContainerTest.kt | 0 .../systemui/statusbar/chips/ui/view/ChipChronometerTest.kt | 0 .../android/systemui/statusbar/commandline/ParametersTest.kt | 0 .../systemui/statusbar/commandline/ParseableCommandTest.kt | 0 .../android/systemui/statusbar/commandline/ValueParserTest.kt | 0 .../statusbar/connectivity/AccessPointControllerImplTest.kt | 0 .../statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt | 0 .../statusbar/connectivity/NetworkTypeResIdCacheTest.kt | 0 .../statusbar/connectivity/ui/MobileContextProviderTest.kt | 0 .../systemui/statusbar/core/CommandQueueInitializerTest.kt | 0 .../systemui/statusbar/core/StatusBarInitializerTest.kt | 0 .../systemui/statusbar/core/StatusBarOrchestratorTest.kt | 0 .../data/repository/KeyguardStatusBarRepositoryImplTest.kt | 0 .../data/repository/StatusBarModeRepositoryImplTest.kt | 0 .../systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt | 0 .../systemui/statusbar/disableflags/DisableStateTrackerTest.kt | 0 .../disableflags/data/repository/DisableFlagsRepositoryTest.kt | 0 .../com/android/systemui/statusbar/events/FakeStatusEvent.kt | 0 .../statusbar/events/SystemEventChipAnimationControllerTest.kt | 0 .../systemui/statusbar/events/SystemEventCoordinatorTest.kt | 0 .../statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt | 0 .../statusbar/notification/DynamicChildBindControllerTest.java | 0 .../statusbar/notification/DynamicPrivacyControllerTest.java | 0 .../notification/NotificationWakeUpCoordinatorLoggerTest.kt | 0 .../notification/NotificationWakeUpCoordinatorTest.kt | 0 .../notification/collection/HighPriorityProviderTest.java | 0 .../statusbar/notification/collection/NoManSimulator.java | 0 .../statusbar/notification/collection/NotifLiveDataImplTest.kt | 0 .../notification/collection/NotifLiveDataStoreImplTest.kt | 0 .../notification/collection/NotifLiveDataStoreMocks.kt | 0 .../notification/collection/NotifPipelineChoreographerTest.kt | 0 .../notification/collection/SectionStyleProviderTest.kt | 0 .../notification/collection/coalescer/GroupCoalescerTest.java | 0 .../collection/coordinator/ColorizedFgsCoordinatorTest.java | 0 .../coordinator/DeviceProvisionedCoordinatorTest.java | 0 .../collection/coordinator/DismissibilityCoordinatorTest.kt | 0 .../collection/coordinator/DreamCoordinatorTest.kt | 0 .../collection/coordinator/GroupCountCoordinatorTest.kt | 0 .../collection/coordinator/GroupWhenCoordinatorTest.kt | 0 .../notification/collection/coordinator/GutsCoordinatorTest.kt | 0 .../collection/coordinator/HeadsUpCoordinatorTest.kt | 0 .../coordinator/HideNotifsForOtherUsersCoordinatorTest.java | 0 .../collection/coordinator/KeyguardCoordinatorTest.kt | 0 .../collection/coordinator/MediaCoordinatorTest.java | 0 .../coordinator/NotificationStatsLoggerCoordinatorTest.kt | 0 .../collection/coordinator/PreparationCoordinatorTest.java | 0 .../collection/coordinator/RankingCoordinatorTest.java | 0 .../collection/coordinator/RemoteInputCoordinatorTest.kt | 0 .../collection/coordinator/RowAlertTimeCoordinatorTest.kt | 0 .../collection/coordinator/SensitiveContentCoordinatorTest.kt | 0 .../coordinator/SmartspaceDedupingCoordinatorTest.kt | 0 .../collection/inflation/NotifUiAdjustmentProviderTest.kt | 0 .../notification/collection/listbuilder/SemiStableSortTest.kt | 0 .../collection/listbuilder/ShadeListBuilderHelperTest.kt | 0 .../notifcollection/NotifCollectionInconsistencyTrackerTest.kt | 0 .../notifcollection/SelfTrackingLifetimeExtenderTest.kt | 0 .../collection/provider/VisualStabilityProviderTest.kt | 0 .../notification/collection/render/FakeNodeController.kt | 0 .../notification/collection/render/NodeSpecBuilderTest.kt | 0 .../notification/collection/render/RenderStageManagerTest.kt | 0 .../notification/collection/render/ShadeViewDifferTest.kt | 0 .../domain/interactor/NotificationAlertsInteractorTest.kt | 0 .../interactor/NotificationLaunchAnimationInteractorTest.kt | 0 .../domain/interactor/NotificationsKeyguardInteractorTest.kt | 0 .../domain/interactor/RenderNotificationsListInteractorTest.kt | 0 .../notification/footer/ui/viewmodel/FooterViewModelTest.kt | 0 .../icon/domain/interactor/NotificationIconsInteractorTest.kt | 0 .../NotificationIconContainerAlwaysOnDisplayViewModelTest.kt | 0 .../notification/interruption/HeadsUpViewBinderTest.java | 0 .../KeyguardNotificationVisibilityProviderTest.java | 0 .../interruption/VisualInterruptionDecisionProviderTestBase.kt | 0 .../interruption/VisualInterruptionDecisionProviderTestUtil.kt | 0 .../notification/logging/ExpansionStateLoggerTest.java | 0 .../notification/logging/NotificationPanelLoggerFake.java | 0 .../notification/row/ActivatableNotificationViewTest.kt | 0 .../row/ExpandableNotificationRowControllerTest.kt | 0 .../systemui/statusbar/notification/row/FeedbackInfoTest.java | 0 .../statusbar/notification/row/HeadsUpStyleProviderImplTest.kt | 0 .../statusbar/notification/row/NotifBindPipelineTest.java | 0 .../notification/row/NotifInflationErrorManagerTest.kt | 0 .../notification/row/NotifRemoteViewCacheImplTest.java | 0 .../statusbar/notification/row/NotificationGutsTest.kt | 0 .../statusbar/notification/row/NotificationInfoTest.java | 0 .../notification/row/NotificationInlineImageResolverTest.java | 0 .../notification/row/PartialConversationInfoTest.java | 0 .../statusbar/notification/row/RowContentBindStageTest.java | 0 .../row/ui/viewmodel/ActivatableNotificationViewModelTest.kt | 0 .../row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt | 0 .../notification/shared/TestActiveNotificationModel.kt | 0 .../shelf/domain/interactor/NotificationShelfInteractorTest.kt | 0 .../shelf/ui/viewmodel/NotificationShelfViewModelTest.kt | 0 .../systemui/statusbar/notification/stack/AmbientStateTest.kt | 0 .../stack/DisplaySwitchNotificationsHiderTrackerTest.kt | 0 .../statusbar/notification/stack/MediaContainerViewTest.kt | 0 .../statusbar/notification/stack/NotificationShelfTest.kt | 0 .../notification/stack/NotificationStackSizeCalculatorTest.kt | 0 .../notification/stack/NotificationSwipeHelperTest.java | 0 .../statusbar/notification/stack/StackScrollAlgorithmTest.kt | 0 .../statusbar/notification/stack/StackStateAnimatorTest.kt | 0 .../systemui/statusbar/notification/stack/ViewStateTest.kt | 0 .../stack/domain/interactor/HideNotificationsInteractorTest.kt | 0 .../stack/domain/interactor/NotificationStackInteractorTest.kt | 0 .../stack/ui/viewmodel/NotificationLoggerViewModelTest.kt | 0 .../statusbar/phone/BiometricsUnlockControllerTest.java | 0 .../phone/CentralSurfacesCommandQueueCallbacksTest.java | 0 .../statusbar/phone/ConfigurationControllerImplTest.kt | 0 .../android/systemui/statusbar/phone/DozeParametersTest.java | 0 .../systemui/statusbar/phone/DozeScrimControllerTest.java | 0 .../systemui/statusbar/phone/KeyguardBypassControllerTest.kt | 0 .../systemui/statusbar/phone/KeyguardDismissUtilTest.java | 0 .../statusbar/phone/KeyguardIndicationTextViewTest.java | 0 .../statusbar/phone/LegacyLightsOutNotifControllerTest.java | 0 .../statusbar/phone/LetterboxAppearanceCalculatorTest.kt | 0 .../statusbar/phone/LetterboxBackgroundProviderTest.kt | 0 .../systemui/statusbar/phone/LightBarControllerTest.java | 0 .../statusbar/phone/ManagedProfileControllerImplTest.kt | 0 .../systemui/statusbar/phone/NotificationGroupTestHelper.java | 0 .../systemui/statusbar/phone/NotificationIconContainerTest.kt | 0 .../systemui/statusbar/phone/NotificationTapHelperTest.java | 0 .../statusbar/phone/StatusBarNotificationPresenterTest.java | 0 .../statusbar/phone/StatusBarRemoteInputCallbackTest.java | 0 .../statusbar/phone/StatusBarTouchableRegionManagerTest.kt | 0 .../systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt | 0 .../phone/domain/interactor/LightsOutInteractorTest.kt | 0 .../phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt | 0 .../statusbar/phone/fragment/StatusBarVisibilityModelTest.kt | 0 .../phone/ongoingcall/OngoingCallControllerViaListenerTest.kt | 0 .../phone/ongoingcall/OngoingCallControllerViaRepoTest.kt | 0 .../ongoingcall/data/repository/OngoingCallRepositoryTest.kt | 0 .../com/android/systemui/statusbar/phone/ui/IconManagerTest.kt | 0 .../statusbar/phone/ui/StatusBarIconControllerImplTest.kt | 0 .../statusbar/phone/ui/StatusBarIconControllerTest.java | 0 .../systemui/statusbar/phone/ui/StatusBarIconListTest.java | 0 .../airplane/data/repository/AirplaneModeRepositoryImplTest.kt | 0 .../airplane/domain/interactor/AirplaneModeInteractorTest.kt | 0 .../pipeline/ethernet/domain/EthernetInteractorTest.kt | 0 .../repository/demo/DemoMobileConnectionParameterizedTest.kt | 0 .../repository/demo/DemoMobileConnectionsRepositoryTest.kt | 0 .../repository/prod/CarrierMergedConnectionRepositoryTest.kt | 0 .../mobile/domain/interactor/MobileIconInteractorTest.kt | 0 .../mobile/domain/interactor/MobileIconsInteractorTest.kt | 0 .../statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt | 0 .../mobile/ui/model/SignalIconModelParameterizedTest.kt | 0 .../ui/viewmodel/LocationBasedMobileIconViewModelTest.kt | 0 .../pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt | 0 .../pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt | 0 .../data/DeviceBasedSatelliteRepositorySwitcherTest.kt | 0 .../data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt | 0 .../satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt | 0 .../domain/interactor/DeviceBasedSatelliteInteractorTest.kt | 0 .../ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt | 0 .../ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt | 0 .../pipeline/shared/data/model/DefaultConnectionModelTest.kt | 0 .../domain/interactor/CollapsedStatusBarInteractorTest.kt | 3 +++ .../pipeline/shared/ui/view/ModernStatusBarViewTest.kt | 0 .../shared/ui/view/SingleBindableStatusBarIconViewTest.kt | 0 .../shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt | 0 .../shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt | 0 .../pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt | 0 .../systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt | 0 .../systemui/statusbar/policy/BlockingQueueIntentReceiver.java | 0 .../systemui/statusbar/policy/BluetoothControllerImplTest.java | 2 +- .../systemui/statusbar/policy/CastControllerImplTest.java | 0 .../src/com/android/systemui/statusbar/policy/ClockTest.kt | 0 .../statusbar/policy/DevicePostureControllerImplTest.kt | 0 .../statusbar/policy/DeviceProvisionedControllerImplTest.kt | 0 .../systemui/statusbar/policy/ExtensionControllerImplTest.java | 0 .../systemui/statusbar/policy/HotspotControllerImplTest.java | 0 .../statusbar/policy/KeyguardQsUserSwitchControllerTest.kt | 0 .../systemui/statusbar/policy/KeyguardStateControllerTest.java | 0 .../statusbar/policy/KeyguardUserSwitcherAdapterTest.kt | 0 .../statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt | 0 .../android/systemui/statusbar/policy/SafetyControllerTest.kt | 0 .../systemui/statusbar/policy/SmartReplyConstantsTest.java | 0 .../statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt | 0 .../statusbar/policy/bluetooth/FakeBluetoothRepository.kt | 0 .../data/repository/DeviceProvisioningRepositoryImplTest.kt | 0 .../statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt | 0 .../statusbar/window/StatusBarWindowStateControllerTest.kt | 0 .../repository/StatusBarWindowStatePerDisplayRepositoryTest.kt | 3 +++ .../data/repository/StatusBarWindowStateRepositoryStoreTest.kt | 3 +++ 197 files changed, 10 insertions(+), 1 deletion(-) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/BlurUtilsTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/DragDownHelperTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/NotificationListenerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/SmartReplyControllerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/StatusBarIconViewTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/VibratorHelperTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/commandline/ParametersTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/core/CommandQueueInitializerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/core/StatusBarOrchestratorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreMocks.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/render/FakeNodeController.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLoggerFake.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolverTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLoggerViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/DozeParametersTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/phone/ui/StatusBarIconListTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractorTest.kt (96%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/BlockingQueueIntentReceiver.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java (99%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/ClockTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt (100%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStatePerDisplayRepositoryTest.kt (97%) rename packages/SystemUI/{tests => multivalentTests}/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStateRepositoryStoreTest.kt (97%) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/BlurUtilsTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/BlurUtilsTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/DragDownHelperTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/DragDownHelperTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationListenerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationListenerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/VibratorHelperTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/VibratorHelperTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/MobileIconCarrierIdOverridesFake.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/core/CommandQueueInitializerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/CommandQueueInitializerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/core/CommandQueueInitializerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/CommandQueueInitializerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/core/StatusBarOrchestratorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarOrchestratorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/core/StatusBarOrchestratorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarOrchestratorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreMocks.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreMocks.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreMocks.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreMocks.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/FakeNodeController.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/FakeNodeController.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/FakeNodeController.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/FakeNodeController.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLoggerFake.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLoggerFake.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLoggerFake.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLoggerFake.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolverTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolverTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolverTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolverTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shared/TestActiveNotificationModel.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLoggerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLoggerViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLoggerViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLoggerViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/IconManagerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconListTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconListTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconListTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconListTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/FakeDeviceBasedSatelliteViewModel.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractorTest.kt similarity index 96% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractorTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractorTest.kt index 5036e775211e..46f822aae7b8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/domain/interactor/CollapsedStatusBarInteractorTest.kt @@ -21,6 +21,7 @@ import android.app.StatusBarManager.DISABLE_CLOCK import android.app.StatusBarManager.DISABLE_NONE import android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS import android.app.StatusBarManager.DISABLE_SYSTEM_INFO +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue @@ -31,8 +32,10 @@ import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.test.Test import kotlinx.coroutines.test.runTest +import org.junit.runner.RunWith; @SmallTest +@RunWith(AndroidJUnit4::class) class CollapsedStatusBarInteractorTest : SysuiTestCase() { val kosmos = testKosmos() val testScope = kosmos.testScope diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewBinder.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BlockingQueueIntentReceiver.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BlockingQueueIntentReceiver.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BlockingQueueIntentReceiver.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BlockingQueueIntentReceiver.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java similarity index 99% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java index 2588f1f4fe3f..e3bd88523e8e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java @@ -61,7 +61,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) @RunWithLooper @SmallTest public class BluetoothControllerImplTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ClockTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ClockTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt similarity index 100% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStatePerDisplayRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStatePerDisplayRepositoryTest.kt similarity index 97% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStatePerDisplayRepositoryTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStatePerDisplayRepositoryTest.kt index 0c27e58fd369..c7c7fdc40acb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStatePerDisplayRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStatePerDisplayRepositoryTest.kt @@ -21,6 +21,7 @@ import android.app.StatusBarManager.WINDOW_STATE_HIDDEN import android.app.StatusBarManager.WINDOW_STATE_HIDING import android.app.StatusBarManager.WINDOW_STATE_SHOWING import android.app.StatusBarManager.WINDOW_STATUS_BAR +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue @@ -34,11 +35,13 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Test +import org.junit.runner.RunWith import org.mockito.Mockito.verify import org.mockito.kotlin.argumentCaptor @SmallTest @OptIn(ExperimentalCoroutinesApi::class) +@RunWith(AndroidJUnit4::class) class StatusBarWindowStatePerDisplayRepositoryTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStateRepositoryStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStateRepositoryStoreTest.kt similarity index 97% rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStateRepositoryStoreTest.kt rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStateRepositoryStoreTest.kt index b6a3f367fe33..e23e88cc2e4a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStateRepositoryStoreTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStateRepositoryStoreTest.kt @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.window.data.repository import android.app.StatusBarManager.WINDOW_STATE_HIDDEN import android.app.StatusBarManager.WINDOW_STATE_SHOWING import android.app.StatusBarManager.WINDOW_STATUS_BAR +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue @@ -33,12 +34,14 @@ import kotlin.test.Test import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest +import org.junit.runner.RunWith import org.mockito.Mockito.verify import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.reset @SmallTest @OptIn(ExperimentalCoroutinesApi::class) +@RunWith(AndroidJUnit4::class) class StatusBarWindowStateRepositoryStoreTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope -- GitLab From 875547e9266e92e0e94cdfb61df2e0e3306645e8 Mon Sep 17 00:00:00 2001 From: Merissa Mitchell Date: Fri, 4 Oct 2024 14:22:43 -0700 Subject: [PATCH 080/447] [PIP2] Hide PiP menu when PiP is moved or resized. Recall: http://recall/clips/a108d098-fea6-4fb7-b5e5-5acf0b0392be Bug: 322548939 Test: Launch PiP and manually verify menu is hidden when PiP is moved or resized. Flag: com.android.wm.shell.enable_pip2 Change-Id: I14b726e9c96a31822e3baf5a3f06b1c7d9462739 --- .../wm/shell/pip2/phone/PhonePipMenuController.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java index 02e6670470d7..8c1e5e6a3e84 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java @@ -598,6 +598,13 @@ public class PhonePipMenuController implements PipMenuController, break; case PipTransitionState.CHANGED_PIP_BOUNDS: updateMenuLayout(mPipBoundsState.getBounds()); + hideMenu(); + break; + case PipTransitionState.CHANGING_PIP_BOUNDS: + hideMenu(); + break; + case PipTransitionState.SCHEDULED_BOUNDS_CHANGE: + hideMenu(); break; } } -- GitLab From 115905881811f1c638d9ab95fec54280a9dc87bc Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Fri, 4 Oct 2024 16:39:08 -0400 Subject: [PATCH 081/447] [sb] remove StatusBarLocationPublisher (rip) This was no longer used; I'm fairly certain it preceded the StatusBarContentInsetsProvider class which is far more powerful. Test: atest SystemUITests Bug: 364360986 Flag: EXEMPT deleting unused code Change-Id: I3355744016dd41233495f01193086cad4e424ded --- .../phone/StatusBarLocationPublisher.kt | 83 ------------------- .../fragment/CollapsedStatusBarFragment.java | 22 ----- .../CollapsedStatusBarFragmentTest.java | 4 - 3 files changed, 109 deletions(-) delete mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt deleted file mode 100644 index 4e5ecfe3f623..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.phone - -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.statusbar.policy.CallbackController -import java.lang.ref.WeakReference -import javax.inject.Inject - -/** - * Publishes updates to the status bar's margins. - * - * While the status bar view consumes the entire width of the device, the status bar - * contents are laid out with margins for rounded corners, padding from the absolute - * edges, and potentially display cutouts in the corner. - */ -@SysUISingleton -class StatusBarLocationPublisher @Inject constructor() -: CallbackController { - private val listeners = mutableSetOf>() - - var marginLeft: Int = 0 - private set - var marginRight: Int = 0 - private set - - override fun addCallback(listener: StatusBarMarginUpdatedListener) { - listeners.add(WeakReference(listener)) - } - - override fun removeCallback(listener: StatusBarMarginUpdatedListener) { - var toRemove: WeakReference? = null - for (l in listeners) { - if (l.get() == listener) { - toRemove = l - } - } - - if (toRemove != null) { - listeners.remove(toRemove) - } - } - - fun updateStatusBarMargin(left: Int, right: Int) { - marginLeft = left - marginRight = right - - notifyListeners() - } - - private fun notifyListeners() { - var listenerList: List> - synchronized(this) { - listenerList = listeners.toList() - } - - listenerList.forEach { wrapper -> - if (wrapper.get() == null) { - listeners.remove(wrapper) - } - - wrapper.get()?.onStatusBarMarginUpdated(marginLeft, marginRight) - } - } -} - -interface StatusBarMarginUpdatedListener { - fun onStatusBarMarginUpdated(marginLeft: Int, marginRight: Int) -} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java index a8b4728bc982..c258095510c6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java @@ -65,7 +65,6 @@ import com.android.systemui.statusbar.phone.NotificationIconContainer; import com.android.systemui.statusbar.phone.PhoneStatusBarView; import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager; import com.android.systemui.statusbar.phone.StatusBarLocation; -import com.android.systemui.statusbar.phone.StatusBarLocationPublisher; import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent; import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent.Startable; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; @@ -140,7 +139,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private final OperatorNameViewController.Factory mOperatorNameViewControllerFactory; private final OngoingCallController mOngoingCallController; private final SystemStatusAnimationScheduler mAnimationScheduler; - private final StatusBarLocationPublisher mLocationPublisher; private final ShadeExpansionStateManager mShadeExpansionStateManager; private final StatusBarIconController mStatusBarIconController; private final CarrierConfigTracker mCarrierConfigTracker; @@ -243,7 +241,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue StatusBarFragmentComponent.Factory statusBarFragmentComponentFactory, OngoingCallController ongoingCallController, SystemStatusAnimationScheduler animationScheduler, - StatusBarLocationPublisher locationPublisher, ShadeExpansionStateManager shadeExpansionStateManager, StatusBarIconController statusBarIconController, DarkIconManager.Factory darkIconManagerFactory, @@ -267,7 +264,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mStatusBarFragmentComponentFactory = statusBarFragmentComponentFactory; mOngoingCallController = ongoingCallController; mAnimationScheduler = animationScheduler; - mLocationPublisher = locationPublisher; mShadeExpansionStateManager = shadeExpansionStateManager; mStatusBarIconController = statusBarIconController; mCollapsedStatusBarViewModel = collapsedStatusBarViewModel; @@ -349,9 +345,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue } mStatusBar = (PhoneStatusBarView) view; - View contents = mStatusBar.findViewById(R.id.status_bar_contents); - contents.addOnLayoutChangeListener(mStatusBarLayoutListener); - updateStatusBarLocation(contents.getLeft(), contents.getRight()); if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_PANEL_STATE)) { mStatusBar.restoreHierarchyState( savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE)); @@ -977,13 +970,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue }, /*isAnimationRunning*/ false); } - private void updateStatusBarLocation(int left, int right) { - int leftMargin = left - mStatusBar.getLeft(); - int rightMargin = mStatusBar.getRight() - right; - - mLocationPublisher.updateStatusBarMargin(leftMargin, rightMargin); - } - private final ContentObserver mVolumeSettingObserver = new ContentObserver(null) { @Override public void onChange(boolean selfChange) { @@ -991,14 +977,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue } }; - // Listen for view end changes of PhoneStatusBarView and publish that to the privacy dot - private View.OnLayoutChangeListener mStatusBarLayoutListener = - (view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { - if (left != oldLeft || right != oldRight) { - updateStatusBarLocation(left, right); - } - }; - @Override public void dump(PrintWriter printWriter, String[] args) { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, /* singleIndent= */" "); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java index 63a560ffd2c1..e57e8d108529 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java @@ -66,7 +66,6 @@ import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder; import com.android.systemui.statusbar.phone.HeadsUpAppearanceController; import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager; -import com.android.systemui.statusbar.phone.StatusBarLocationPublisher; import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.phone.ui.DarkIconManager; @@ -98,7 +97,6 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { private ShadeExpansionStateManager mShadeExpansionStateManager; private OngoingCallController mOngoingCallController; private SystemStatusAnimationScheduler mAnimationScheduler; - private StatusBarLocationPublisher mLocationPublisher; // Set in instantiate() private StatusBarIconController mStatusBarIconController; private KeyguardStateController mKeyguardStateController; @@ -1181,7 +1179,6 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { setUpDaggerComponent(); mOngoingCallController = mock(OngoingCallController.class); mAnimationScheduler = mock(SystemStatusAnimationScheduler.class); - mLocationPublisher = mock(StatusBarLocationPublisher.class); mStatusBarIconController = mock(StatusBarIconController.class); mStatusBarStateController = mock(StatusBarStateController.class); mKeyguardStateController = mock(KeyguardStateController.class); @@ -1200,7 +1197,6 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { mStatusBarFragmentComponentFactory, mOngoingCallController, mAnimationScheduler, - mLocationPublisher, mShadeExpansionStateManager, mStatusBarIconController, mIconManagerFactory, -- GitLab From dcf939f76f2a2c35b17e1a15d66c9d9df0909466 Mon Sep 17 00:00:00 2001 From: Rahul Banerjee Date: Fri, 4 Oct 2024 15:22:15 -0700 Subject: [PATCH 082/447] Remove defunct sysprop in preparation for multi-display bootanim. Bug: 335406617 Test: Manual (build, flash, reboot) Change-Id: Id82aa1448a097bbc7dd32952a78f1a64ef1693a0 --- cmds/bootanimation/BootAnimation.cpp | 59 ++-------------------------- 1 file changed, 4 insertions(+), 55 deletions(-) diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index c2f6e3072507..87c9fa4dbe28 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -106,7 +106,6 @@ static const int TEXT_CENTER_VALUE = INT_MAX; static const int TEXT_MISSING_VALUE = INT_MIN; static const char EXIT_PROP_NAME[] = "service.bootanim.exit"; static const char PROGRESS_PROP_NAME[] = "service.bootanim.progress"; -static const char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays"; static const char CLOCK_ENABLED_PROP_NAME[] = "persist.sys.bootanim.clock.enabled"; static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1; static const int MAX_CHECK_EXIT_INTERVAL_US = 50000; @@ -514,50 +513,9 @@ status_t BootAnimation::readyToRun() { return NAME_NOT_FOUND; } - // this system property specifies multi-display IDs to show the boot animation - // multiple ids can be set with comma (,) as separator, for example: - // setprop persist.boot.animation.displays 19260422155234049,19261083906282754 - Vector physicalDisplayIds; - char displayValue[PROPERTY_VALUE_MAX] = ""; - property_get(DISPLAYS_PROP_NAME, displayValue, ""); - bool isValid = displayValue[0] != '\0'; - if (isValid) { - char *p = displayValue; - while (*p) { - if (!isdigit(*p) && *p != ',') { - isValid = false; - break; - } - p ++; - } - if (!isValid) - SLOGE("Invalid syntax for the value of system prop: %s", DISPLAYS_PROP_NAME); - } - if (isValid) { - std::istringstream stream(displayValue); - for (PhysicalDisplayId id; stream >> id.value; ) { - physicalDisplayIds.add(id); - if (stream.peek() == ',') - stream.ignore(); - } - - // the first specified display id is used to retrieve mDisplayToken - for (const auto id : physicalDisplayIds) { - if (std::find(ids.begin(), ids.end(), id) != ids.end()) { - if (const auto token = SurfaceComposerClient::getPhysicalDisplayToken(id)) { - mDisplayToken = token; - break; - } - } - } - } - - // If the system property is not present or invalid, display 0 is used + mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front()); if (mDisplayToken == nullptr) { - mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front()); - if (mDisplayToken == nullptr) { - return NAME_NOT_FOUND; - } + return NAME_NOT_FOUND; } DisplayMode displayMode; @@ -577,17 +535,8 @@ status_t BootAnimation::readyToRun() { ISurfaceComposerClient::eOpaque); SurfaceComposerClient::Transaction t; - if (isValid) { - // In the case of multi-display, boot animation shows on the specified displays - for (const auto id : physicalDisplayIds) { - if (std::find(ids.begin(), ids.end(), id) != ids.end()) { - if (const auto token = SurfaceComposerClient::getPhysicalDisplayToken(id)) { - t.setDisplayLayerStack(token, ui::DEFAULT_LAYER_STACK); - } - } - } - t.setLayerStack(control, ui::DEFAULT_LAYER_STACK); - } + t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK); + t.setLayerStack(control, ui::DEFAULT_LAYER_STACK); t.setLayer(control, 0x40000000) .apply(); -- GitLab From e4d7b622a25b5f5063fd3e003f704ba0ab6b7b12 Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Thu, 3 Oct 2024 18:19:33 +0000 Subject: [PATCH 083/447] Remove hidden API usages backed by VcnTransportInfo VCN will be moved to a mainline module and #getWifiInfo will no longer be accessible. Also VcnTransportInfo will be a final class. This patch updates SystemUI to use VcnUtils to get the WifiInfo and use a Builder to construct a VcnTransportInfo instance for testing. Bug: 369710077 Test: atest SystemUITests:MobileConnectionsRepositoryTest && atest SystemUITests:ConnectivityRepositoryImplTest Flag: EXEMPT pure refactoring Change-Id: I255548e1d1c26e465657d8006272a689fc8a5de4 --- .../data/repository/ConnectivityRepository.kt | 19 ++-- .../NetworkControllerWifiTest.java | 2 +- .../prod/MobileConnectionsRepositoryTest.kt | 28 +++++- .../ConnectivityRepositoryImplTest.kt | 97 ++++++++++++++----- 4 files changed, 114 insertions(+), 32 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt index f5cfc8c5b307..e0bf00fbe431 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt @@ -26,6 +26,7 @@ import android.net.NetworkCapabilities.TRANSPORT_CELLULAR import android.net.NetworkCapabilities.TRANSPORT_ETHERNET import android.net.NetworkCapabilities.TRANSPORT_WIFI import android.net.vcn.VcnTransportInfo +import android.net.vcn.VcnUtils import android.net.wifi.WifiInfo import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import androidx.annotation.ArrayRes @@ -161,7 +162,9 @@ constructor( defaultNetworkCapabilities .map { networkCapabilities -> networkCapabilities?.run { - val subId = (transportInfo as? VcnTransportInfo)?.subId + val subId = + VcnUtils.getSubIdFromVcnCaps(connectivityManager, networkCapabilities) + // Never return an INVALID_SUBSCRIPTION_ID (-1) if (subId != INVALID_SUBSCRIPTION_ID) { subId @@ -245,9 +248,9 @@ constructor( * info. */ fun NetworkCapabilities.getMainOrUnderlyingWifiInfo( - connectivityManager: ConnectivityManager, + connectivityManager: ConnectivityManager ): WifiInfo? { - val mainWifiInfo = this.getMainWifiInfo() + val mainWifiInfo = this.getMainWifiInfo(connectivityManager) if (mainWifiInfo != null) { return mainWifiInfo } @@ -264,7 +267,9 @@ constructor( // eventually traced to a wifi or carrier merged connection. So, check those underlying // networks for possible wifi information as well. See b/225902574. return this.underlyingNetworks?.firstNotNullOfOrNull { underlyingNetwork -> - connectivityManager.getNetworkCapabilities(underlyingNetwork)?.getMainWifiInfo() + connectivityManager + .getNetworkCapabilities(underlyingNetwork) + ?.getMainWifiInfo(connectivityManager) } } @@ -272,7 +277,9 @@ constructor( * Checks the network capabilities for wifi info, but does *not* check the underlying * networks. See [getMainOrUnderlyingWifiInfo]. */ - private fun NetworkCapabilities.getMainWifiInfo(): WifiInfo? { + private fun NetworkCapabilities.getMainWifiInfo( + connectivityManager: ConnectivityManager + ): WifiInfo? { // Wifi info can either come from a WIFI Transport, or from a CELLULAR transport for // virtual networks like VCN. val canHaveWifiInfo = @@ -286,7 +293,7 @@ constructor( // [com.android.settingslib.Utils.tryGetWifiInfoForVcn]. It's copied instead of // re-used because it makes the logic here clearer, and because the method will be // removed once this pipeline is fully launched. - is VcnTransportInfo -> currentTransportInfo.wifiInfo + is VcnTransportInfo -> VcnUtils.getWifiInfoFromVcnCaps(connectivityManager, this) is WifiInfo -> currentTransportInfo else -> null } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java index 6c80a97625a7..234ea8ffd368 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java @@ -57,7 +57,7 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest { private static final int MIN_RSSI = -100; private static final int MAX_RSSI = -55; private WifiInfo mWifiInfo = mock(WifiInfo.class); - private VcnTransportInfo mVcnTransportInfo = mock(VcnTransportInfo.class); + private VcnTransportInfo mVcnTransportInfo = new VcnTransportInfo.Builder().build(); @Before public void setUp() throws Exception { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt index 4b6e31303f79..ec9f157a7ec6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt @@ -134,6 +134,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { private val wifiLogBuffer = LogBuffer("wifi", maxSize = 100, logcatEchoTracker = mock()) private val wifiPickerTrackerCallback = argumentCaptor() + private val vcnTransportInfo = VcnTransportInfo.Builder().build() private val testDispatcher = StandardTestDispatcher() private val testScope = TestScope(testDispatcher) @@ -1018,6 +1019,18 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { assertThat(latest).isTrue() } + private fun newWifiNetwork(wifiInfo: WifiInfo): Network { + val network = mock() + val capabilities = + mock().also { + whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true) + whenever(it.transportInfo).thenReturn(wifiInfo) + } + whenever(connectivityManager.getNetworkCapabilities(network)).thenReturn(capabilities) + + return network + } + /** Regression test for b/272586234. */ @Test fun hasCarrierMergedConnection_carrierMergedViaWifiWithVcnTransport_isTrue() = @@ -1027,10 +1040,12 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { whenever(this.isCarrierMerged).thenReturn(true) whenever(this.isPrimary).thenReturn(true) } + val underlyingWifi = newWifiNetwork(carrierMergedInfo) val caps = mock().also { whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true) - whenever(it.transportInfo).thenReturn(VcnTransportInfo(carrierMergedInfo)) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(underlyingWifi)) } val latest by collectLastValue(underTest.hasCarrierMergedConnection) @@ -1049,10 +1064,12 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { whenever(this.isCarrierMerged).thenReturn(true) whenever(this.isPrimary).thenReturn(true) } + val underlyingWifi = newWifiNetwork(carrierMergedInfo) val caps = mock().also { whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(it.transportInfo).thenReturn(VcnTransportInfo(carrierMergedInfo)) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(underlyingWifi)) } val latest by collectLastValue(underTest.hasCarrierMergedConnection) @@ -1109,10 +1126,15 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { whenever(this.isCarrierMerged).thenReturn(true) whenever(this.isPrimary).thenReturn(true) } + + // The Wifi network that is under the VCN network + val physicalWifiNetwork = newWifiNetwork(carrierMergedInfo) + val underlyingCapabilities = mock().also { whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(it.transportInfo).thenReturn(VcnTransportInfo(carrierMergedInfo)) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(physicalWifiNetwork)) } whenever(connectivityManager.getNetworkCapabilities(underlyingCarrierMergedNetwork)) .thenReturn(underlyingCapabilities) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt index 0945742fb325..88f262bec123 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt @@ -23,6 +23,7 @@ import android.net.NetworkCapabilities.TRANSPORT_CELLULAR import android.net.NetworkCapabilities.TRANSPORT_ETHERNET import android.net.NetworkCapabilities.TRANSPORT_VPN import android.net.NetworkCapabilities.TRANSPORT_WIFI +import android.net.TelephonyNetworkSpecifier import android.net.VpnTransportInfo import android.net.vcn.VcnTransportInfo import android.net.wifi.WifiInfo @@ -74,6 +75,8 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { private val testScope = kosmos.testScope private val tunerService = mock() + private val vcnTransportInfo = VcnTransportInfo.Builder().build() + @Before fun setUp() { createAndSetRepo() @@ -343,6 +346,30 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { assertThat(latest!!.wifi.isDefault).isTrue() } + private fun newWifiNetwork(wifiInfo: WifiInfo): Network { + val network = mock() + val capabilities = + mock().also { + whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true) + whenever(it.transportInfo).thenReturn(wifiInfo) + } + whenever(connectivityManager.getNetworkCapabilities(network)).thenReturn(capabilities) + + return network + } + + private fun newCellNetwork(subId: Int): Network { + val network = mock() + val capabilities = + mock().also { + whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) + whenever(it.networkSpecifier).thenReturn(TelephonyNetworkSpecifier(subId)) + } + whenever(connectivityManager.getNetworkCapabilities(network)).thenReturn(capabilities) + + return network + } + @Test fun defaultConnections_carrierMergedViaWifiWithVcnTransport_wifiAndCarrierMergedDefault() = testScope.runTest { @@ -350,10 +377,12 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { val carrierMergedInfo = mock().apply { whenever(this.isCarrierMerged).thenReturn(true) } + val underlyingWifi = newWifiNetwork(carrierMergedInfo) val capabilities = mock().also { whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true) - whenever(it.transportInfo).thenReturn(VcnTransportInfo(carrierMergedInfo)) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(underlyingWifi)) whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(false) whenever(it.hasTransport(TRANSPORT_ETHERNET)).thenReturn(false) } @@ -373,10 +402,12 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { val carrierMergedInfo = mock().apply { whenever(this.isCarrierMerged).thenReturn(true) } + val underlyingWifi = newWifiNetwork(carrierMergedInfo) val capabilities = mock().also { whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(it.transportInfo).thenReturn(VcnTransportInfo(carrierMergedInfo)) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(underlyingWifi)) whenever(it.hasTransport(TRANSPORT_ETHERNET)).thenReturn(false) whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(false) } @@ -561,10 +592,12 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { val underlyingCarrierMergedNetwork = mock() val carrierMergedInfo = mock().apply { whenever(this.isCarrierMerged).thenReturn(true) } + val underlyingWifi = newWifiNetwork(carrierMergedInfo) val underlyingCapabilities = mock().also { whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(it.transportInfo).thenReturn(VcnTransportInfo(carrierMergedInfo)) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(underlyingWifi)) } whenever(connectivityManager.getNetworkCapabilities(underlyingCarrierMergedNetwork)) .thenReturn(underlyingCapabilities) @@ -645,14 +678,15 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { @Test fun vcnSubId_tracksVcnTransportInfo() = testScope.runTest { - val vcnInfo = VcnTransportInfo(SUB_1_ID) + val underlyingCell = newCellNetwork(SUB_1_ID) val latest by collectLastValue(underTest.vcnSubId) val capabilities = mock().also { whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(it.transportInfo).thenReturn(vcnInfo) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(underlyingCell)) } getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) @@ -663,14 +697,15 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { @Test fun vcnSubId_filersOutInvalid() = testScope.runTest { - val vcnInfo = VcnTransportInfo(INVALID_SUBSCRIPTION_ID) + val underlyingCell = newCellNetwork(INVALID_SUBSCRIPTION_ID) val latest by collectLastValue(underTest.vcnSubId) val capabilities = mock().also { whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(it.transportInfo).thenReturn(vcnInfo) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(underlyingCell)) } getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) @@ -703,11 +738,12 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { val latest by collectLastValue(underTest.vcnSubId) val wifiInfo = mock() - val vcnInfo = VcnTransportInfo(wifiInfo) + val underlyingWifi = newWifiNetwork(wifiInfo) val capabilities = mock().also { whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(it.transportInfo).thenReturn(vcnInfo) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(underlyingWifi)) } getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) @@ -721,14 +757,15 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { val latest by collectLastValue(underTest.vcnSubId) val wifiInfo = mock() - val wifiVcnInfo = VcnTransportInfo(wifiInfo) - val sub1VcnInfo = VcnTransportInfo(SUB_1_ID) - val sub2VcnInfo = VcnTransportInfo(SUB_2_ID) + val underlyingWifi = newWifiNetwork(wifiInfo) + val underlyingCell1 = newCellNetwork(SUB_1_ID) + val underlyingCell2 = newCellNetwork(SUB_2_ID) val capabilities = mock().also { whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true) - whenever(it.transportInfo).thenReturn(wifiVcnInfo) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(underlyingWifi)) } // WIFI VCN info @@ -738,14 +775,16 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { // Cellular VCN info with subId 1 whenever(capabilities.hasTransport(eq(TRANSPORT_CELLULAR))).thenReturn(true) - whenever(capabilities.transportInfo).thenReturn(sub1VcnInfo) + whenever(capabilities.transportInfo).thenReturn(vcnTransportInfo) + whenever(capabilities.underlyingNetworks).thenReturn(listOf(underlyingCell1)) getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) assertThat(latest).isEqualTo(SUB_1_ID) // Cellular VCN info with subId 2 - whenever(capabilities.transportInfo).thenReturn(sub2VcnInfo) + whenever(capabilities.transportInfo).thenReturn(vcnTransportInfo) + whenever(capabilities.underlyingNetworks).thenReturn(listOf(underlyingCell2)) getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities) @@ -776,11 +815,12 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { @Test fun getMainOrUnderlyingWifiInfo_vcnWithWifi_hasInfo() { val wifiInfo = mock() - val vcnInfo = VcnTransportInfo(wifiInfo) + val underlyingWifi = newWifiNetwork(wifiInfo) val capabilities = mock().also { whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true) - whenever(it.transportInfo).thenReturn(vcnInfo) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(underlyingWifi)) } val result = capabilities.getMainOrUnderlyingWifiInfo(connectivityManager) @@ -860,11 +900,15 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { fun getMainOrUnderlyingWifiInfo_cellular_underlyingVcnWithWifi_hasInfo() { val wifiInfo = mock() val underlyingNetwork = mock() - val underlyingVcnInfo = VcnTransportInfo(wifiInfo) + + // The Wifi network that is under the VCN network + val physicalWifiNetwork = newWifiNetwork(wifiInfo) + val underlyingWifiCapabilities = mock().also { whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true) - whenever(it.transportInfo).thenReturn(underlyingVcnInfo) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(physicalWifiNetwork)) } whenever(connectivityManager.getNetworkCapabilities(underlyingNetwork)) .thenReturn(underlyingWifiCapabilities) @@ -887,11 +931,15 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { @DisableFlags(FLAG_STATUS_BAR_ALWAYS_CHECK_UNDERLYING_NETWORKS) fun getMainOrUnderlyingWifiInfo_notCellular_underlyingVcnWithWifi_noInfo() { val underlyingNetwork = mock() - val underlyingVcnInfo = VcnTransportInfo(mock()) + + // The Wifi network that is under the VCN network + val physicalWifiNetwork = newWifiNetwork(mock()) + val underlyingWifiCapabilities = mock().also { whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true) - whenever(it.transportInfo).thenReturn(underlyingVcnInfo) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(physicalWifiNetwork)) } whenever(connectivityManager.getNetworkCapabilities(underlyingNetwork)) .thenReturn(underlyingWifiCapabilities) @@ -917,10 +965,15 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() { val underlyingCarrierMergedNetwork = mock() val carrierMergedInfo = mock().apply { whenever(this.isCarrierMerged).thenReturn(true) } + + // The Wifi network that is under the VCN network + val physicalWifiNetwork = newWifiNetwork(carrierMergedInfo) + val underlyingCapabilities = mock().also { whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true) - whenever(it.transportInfo).thenReturn(VcnTransportInfo(carrierMergedInfo)) + whenever(it.transportInfo).thenReturn(vcnTransportInfo) + whenever(it.underlyingNetworks).thenReturn(listOf(physicalWifiNetwork)) } whenever(connectivityManager.getNetworkCapabilities(underlyingCarrierMergedNetwork)) .thenReturn(underlyingCapabilities) -- GitLab From 4405d63344696b6cccdb00637adda2d1c62a5e39 Mon Sep 17 00:00:00 2001 From: Lee Shombert Date: Fri, 4 Oct 2024 17:51:23 -0700 Subject: [PATCH 084/447] Set owners for PIC files The performance team owns PropertyInvalidatedCache files. Flag: EXEMPT owners-only Bug: 360897450 Test: presubmit Change-Id: Ic38f33c4e36e3d212c44d12d6a604e67c5b16a23 --- core/jni/OWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/core/jni/OWNERS b/core/jni/OWNERS index af106235bd77..af393fdc5ad4 100644 --- a/core/jni/OWNERS +++ b/core/jni/OWNERS @@ -119,3 +119,4 @@ per-file android_tracing_Perfetto* = file:platform/development:/tools/winscope/O # ApplicationSharedMemory per-file *ApplicationSharedMemory* = file:/PERFORMANCE_OWNERS +per-file *PropertyInvalidatedCache* = file:/PERFORMANCE_OWNERS -- GitLab From fc279a45c67ee6bb0020574cb46023e26193995e Mon Sep 17 00:00:00 2001 From: Jorge Gil Date: Thu, 3 Oct 2024 22:52:43 +0000 Subject: [PATCH 085/447] Exit desktop-immersive when app unrequests immersive Resizes the app back to maximized bounds when it stops requesting immersive mode. Flag: com.android.window.flags.enable_fully_immersive_in_desktop Bug: 369443574 Test: enter desktop immersive with YT Music, exit using app UI, verify app resizes back into maximized size Change-Id: I937ffe7b61b0246358d3c63a978ca0eb64ae6b43 --- .../wm/shell/dagger/WMShellModule.java | 4 ++- .../desktopmode/DesktopTasksController.kt | 12 +++++++++ .../shell/freeform/FreeformTaskListener.java | 5 ++++ .../desktopmode/DesktopTasksControllerTest.kt | 27 +++++++++++++++++++ .../freeform/FreeformTaskListenerTests.java | 16 +++++++++++ 5 files changed, 63 insertions(+), 1 deletion(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index b7d967709123..c5fa814b904c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -354,6 +354,7 @@ public abstract class WMShellModule { ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, Optional desktopRepository, + Optional desktopTasksController, LaunchAdjacentController launchAdjacentController, WindowDecorViewModel windowDecorViewModel) { // TODO(b/238217847): Temporarily add this check here until we can remove the dynamic @@ -362,7 +363,8 @@ public abstract class WMShellModule { ? shellInit : null; return new FreeformTaskListener(context, init, shellTaskOrganizer, - desktopRepository, launchAdjacentController, windowDecorViewModel); + desktopRepository, desktopTasksController, launchAdjacentController, + windowDecorViewModel); } @WMSingleton diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt index 4e548a691907..5b9d2fed2701 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt @@ -110,6 +110,7 @@ import com.android.wm.shell.windowdecor.OnTaskRepositionAnimationListener import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener import com.android.wm.shell.windowdecor.extension.isFullscreen import com.android.wm.shell.windowdecor.extension.isMultiWindow +import com.android.wm.shell.windowdecor.extension.requestingImmersive import java.io.PrintWriter import java.util.Optional import java.util.concurrent.Executor @@ -1844,6 +1845,17 @@ class DesktopTasksController( userId = newUserId } + /** Called when a task's info changes. */ + fun onTaskInfoChanged(taskInfo: RunningTaskInfo) { + if (!Flags.enableFullyImmersiveInDesktop()) return + val inImmersive = taskRepository.isTaskInFullImmersiveState(taskInfo.taskId) + val requestingImmersive = taskInfo.requestingImmersive + if (inImmersive && !requestingImmersive) { + // Exit immersive if the app is no longer requesting it. + exitDesktopTaskFromFullImmersive(taskInfo) + } + } + private fun dump(pw: PrintWriter, prefix: String) { val innerPrefix = "$prefix " pw.println("${prefix}DesktopTasksController") diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java index 73f70118b07d..fbd3c10368f7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java @@ -30,6 +30,7 @@ import com.android.internal.protolog.ProtoLog; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.LaunchAdjacentController; import com.android.wm.shell.desktopmode.DesktopRepository; +import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; import com.android.wm.shell.sysui.ShellInit; @@ -50,6 +51,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener, private final Context mContext; private final ShellTaskOrganizer mShellTaskOrganizer; private final Optional mDesktopRepository; + private final Optional mDesktopTasksController; private final WindowDecorViewModel mWindowDecorationViewModel; private final LaunchAdjacentController mLaunchAdjacentController; @@ -65,12 +67,14 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, Optional desktopRepository, + Optional desktopTasksController, LaunchAdjacentController launchAdjacentController, WindowDecorViewModel windowDecorationViewModel) { mContext = context; mShellTaskOrganizer = shellTaskOrganizer; mWindowDecorationViewModel = windowDecorationViewModel; mDesktopRepository = desktopRepository; + mDesktopTasksController = desktopTasksController; mLaunchAdjacentController = launchAdjacentController; if (shellInit != null) { shellInit.addInitCallback(this::onInit, this); @@ -147,6 +151,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener, ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Freeform Task Info Changed: #%d", taskInfo.taskId); + mDesktopTasksController.ifPresent(c -> c.onTaskInfoChanged(taskInfo)); mWindowDecorationViewModel.onTaskInfoChanged(taskInfo); state.mTaskInfo = taskInfo; if (DesktopModeStatus.canEnterDesktopMode(mContext)) { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt index 9e5c1a66b823..ae4772eba5b0 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt @@ -50,6 +50,7 @@ import android.view.Display.DEFAULT_DISPLAY import android.view.DragEvent import android.view.Gravity import android.view.SurfaceControl +import android.view.WindowInsets import android.view.WindowManager import android.view.WindowManager.TRANSIT_CHANGE import android.view.WindowManager.TRANSIT_CLOSE @@ -75,6 +76,7 @@ import com.android.dx.mockito.inline.extended.StaticMockitoSession import com.android.internal.jank.InteractionJankMonitor import com.android.window.flags.Flags import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE +import com.android.window.flags.Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP import com.android.wm.shell.MockToken import com.android.wm.shell.R import com.android.wm.shell.RootTaskDisplayAreaOrganizer @@ -142,6 +144,7 @@ import org.mockito.Mockito import org.mockito.Mockito.anyInt import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.mock +import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.verify import org.mockito.Mockito.times @@ -3151,6 +3154,30 @@ class DesktopTasksControllerTest : ShellTestCase() { }) } + @Test + @EnableFlags(FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP) + fun onTaskInfoChanged_inImmersiveUnrequestsImmersive_exits() { + val task = setUpFreeformTask(DEFAULT_DISPLAY) + taskRepository.setTaskInFullImmersiveState(DEFAULT_DISPLAY, task.taskId, immersive = true) + + task.requestedVisibleTypes = WindowInsets.Type.statusBars() + controller.onTaskInfoChanged(task) + + verify(mockDesktopFullImmersiveTransitionHandler).exitImmersive(eq(task), any()) + } + + @Test + @EnableFlags(FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP) + fun onTaskInfoChanged_notInImmersiveUnrequestsImmersive_noReExit() { + val task = setUpFreeformTask(DEFAULT_DISPLAY) + taskRepository.setTaskInFullImmersiveState(DEFAULT_DISPLAY, task.taskId, immersive = false) + + task.requestedVisibleTypes = WindowInsets.Type.statusBars() + controller.onTaskInfoChanged(task) + + verify(mockDesktopFullImmersiveTransitionHandler, never()).exitImmersive(eq(task), any()) + } + /** * Assert that an unhandled drag event launches a PendingIntent with the * windowing mode and bounds we are expecting. diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java index 956ef14bf2ee..36e0427a7e22 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java @@ -42,6 +42,7 @@ import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.TestRunningTaskInfoBuilder; import com.android.wm.shell.common.LaunchAdjacentController; import com.android.wm.shell.desktopmode.DesktopRepository; +import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.windowdecor.WindowDecorViewModel; @@ -75,6 +76,8 @@ public final class FreeformTaskListenerTests extends ShellTestCase { @Mock private DesktopRepository mDesktopRepository; @Mock + private DesktopTasksController mDesktopTasksController; + @Mock private LaunchAdjacentController mLaunchAdjacentController; private FreeformTaskListener mFreeformTaskListener; private StaticMockitoSession mMockitoSession; @@ -90,6 +93,7 @@ public final class FreeformTaskListenerTests extends ShellTestCase { mShellInit, mTaskOrganizer, Optional.of(mDesktopRepository), + Optional.of(mDesktopTasksController), mLaunchAdjacentController, mWindowDecorViewModel); } @@ -177,6 +181,18 @@ public final class FreeformTaskListenerTests extends ShellTestCase { verify(mDesktopRepository).removeFreeformTask(task.displayId, task.taskId); } + @Test + public void onTaskInfoChanged_withDesktopController_forwards() { + ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder() + .setWindowingMode(WINDOWING_MODE_FREEFORM).build(); + task.isVisible = true; + mFreeformTaskListener.onTaskAppeared(task, mMockSurfaceControl); + + mFreeformTaskListener.onTaskInfoChanged(task); + + verify(mDesktopTasksController).onTaskInfoChanged(task); + } + @After public void tearDown() { mMockitoSession.finishMocking(); -- GitLab From 795e61c4c671202a7b92cf75316cd0df99af9dfd Mon Sep 17 00:00:00 2001 From: Chandru S Date: Sat, 5 Oct 2024 02:45:11 +0000 Subject: [PATCH 086/447] Update the face auth locked out state only if face auth is enrolled, When fingerprint is locked out for user A and we switch from another user to user A, the following happens: 1. we use FingerprintManager#getLockoutModeForUser(...) to get the lockout mode for the current user and store it in KeyguardUpdateMonitor this returns BIOMETRIC_LOCKOUT_PERMANENT 2. we use faceManager#getLockoutModeForUser(...) to get the lockout mode for the current user and store it in DeviceEntryFaceAuthRepository this also returns BIOMETRIC_LOCKOUT_PERMANENT (even though face is not enrolled) 3. once we unlock the phone by entering the PIN/pattern/password, we receive a call through FingerprintManager.LockoutResetCallback#onLockoutReset this resets the state stored in KeyguardUpdateMonitor 4. we don't receive a call on FaceManager.LockoutResetCallback#onLockoutReset so that state in DeviceEntryFaceAuthRepository never gets reset. 5. face auth remains locked out, when we lock the device again we assume fingerprint is not allowed because face auth is strong and is locked out. Bug: 365629896 Fixes: 348456150 Flag: EXEMPT bugfix Test: atest Test: verified manually, 1. create 2 users, user A and B 2. enroll fingerprint for both users 3. lockout fingerprint for user A 4. switch to user B 5. switch back to user A 6. "Face unlock unavailable" message should not be shown on lock screen 7. unlock the device using pin/pattern/password 8. lock the device again 9. udfps should be available. Change-Id: I9983f37075cb2638127b2fac6c1785e2496473cc --- .../DeviceEntryFaceAuthInteractorTest.kt | 18 ++++++++++-------- .../SystemUIDeviceEntryFaceAuthInteractor.kt | 15 +++++++++------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt index 40b2a0864a8c..a0c56b4a27a6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt @@ -139,7 +139,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { TransitionStep( KeyguardState.OFF, KeyguardState.LOCKSCREEN, - transitionState = TransitionState.STARTED + transitionState = TransitionState.STARTED, ) ) @@ -181,7 +181,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { TransitionStep( KeyguardState.AOD, KeyguardState.LOCKSCREEN, - transitionState = TransitionState.STARTED + transitionState = TransitionState.STARTED, ) ) @@ -206,7 +206,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { TransitionStep( KeyguardState.DOZING, KeyguardState.LOCKSCREEN, - transitionState = TransitionState.STARTED + transitionState = TransitionState.STARTED, ) ) @@ -229,7 +229,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { TransitionStep( KeyguardState.DOZING, KeyguardState.LOCKSCREEN, - transitionState = TransitionState.STARTED + transitionState = TransitionState.STARTED, ) ) @@ -244,12 +244,14 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { fun faceAuthLockedOutStateIsUpdatedAfterUserSwitch() = testScope.runTest { underTest.start() + runCurrent() + fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true) // User switching has started fakeUserRepository.setSelectedUserInfo(primaryUser, SelectionStatus.SELECTION_COMPLETE) fakeUserRepository.setSelectedUserInfo( primaryUser, - SelectionStatus.SELECTION_IN_PROGRESS + SelectionStatus.SELECTION_IN_PROGRESS, ) runCurrent() @@ -258,7 +260,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { facePropertyRepository.setLockoutMode(secondaryUser.id, LockoutMode.NONE) fakeUserRepository.setSelectedUserInfo( secondaryUser, - SelectionStatus.SELECTION_COMPLETE + SelectionStatus.SELECTION_COMPLETE, ) runCurrent() @@ -316,7 +318,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { .isEqualTo( Pair( FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN, - false + false, ) ) } @@ -600,7 +602,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { faceAuthRepository.requestAuthenticate( FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED, - true + true, ) facePropertyRepository.setCameraIno(CameraInfo("0", "1", null)) 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 3b5d5a8f0598..b19b2d9ece02 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 @@ -114,7 +114,7 @@ constructor( faceAuthenticationLogger.bouncerVisibilityChanged() runFaceAuth( FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN, - fallbackToDetect = false + fallbackToDetect = false, ) } .launchIn(applicationScope) @@ -125,7 +125,7 @@ constructor( faceAuthenticationLogger.alternateBouncerVisibilityChanged() runFaceAuth( FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN, - fallbackToDetect = false + fallbackToDetect = false, ) } .launchIn(applicationScope) @@ -153,7 +153,7 @@ constructor( it.lastWakeReason.powerManagerWakeReason runFaceAuth( FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED, - fallbackToDetect = true + fallbackToDetect = true, ) } .launchIn(applicationScope) @@ -193,13 +193,16 @@ constructor( .map { (_, curr) -> curr.userInfo.id } .sample(isBouncerVisible, ::Pair) .onEach { (userId, isBouncerCurrentlyVisible) -> + if (!isFaceAuthEnabledAndEnrolled()) { + return@onEach + } resetLockedOutState(userId) yield() runFaceAuth( FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING, // Fallback to detection if bouncer is not showing so that we can detect a // face and then show the bouncer to the user if face auth can't run - fallbackToDetect = !isBouncerCurrentlyVisible + fallbackToDetect = !isBouncerCurrentlyVisible, ) } .launchIn(applicationScope) @@ -210,7 +213,7 @@ constructor( repository.cancel() runFaceAuth( FaceAuthUiEvent.FACE_AUTH_CAMERA_AVAILABLE_CHANGED, - fallbackToDetect = true + fallbackToDetect = true, ) } } @@ -321,7 +324,7 @@ constructor( faceAuthenticationStatusOverride.value = ErrorFaceAuthenticationStatus( BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT, - context.resources.getString(R.string.keyguard_face_unlock_unavailable) + context.resources.getString(R.string.keyguard_face_unlock_unavailable), ) } else { faceAuthenticationStatusOverride.value = null -- GitLab From bc9b371f5fb303cb09098db478089e6af2d23216 Mon Sep 17 00:00:00 2001 From: Vladimir Komsiyski Date: Sat, 5 Oct 2024 07:09:42 +0000 Subject: [PATCH 087/447] Revert^2 "Per-display group PowerManager APIs by default" 95daecabe8c3576d96712f849a83a49285b1c5cc Change-Id: I1da85e9d1981866b2b0df2f3baaf235ac9dd3349 --- .../display/DisplayManagerInternal.java | 5 +- core/java/android/os/IPowerManager.aidl | 2 + core/java/android/os/PowerManager.java | 10 ++ .../server/display/DisplayManagerService.java | 5 +- .../server/power/PowerManagerService.java | 25 +++- .../power/LowPowerStandbyControllerTest.java | 3 + .../server/power/PowerManagerServiceTest.java | 113 +++++++++++++++++- 7 files changed, 146 insertions(+), 17 deletions(-) diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index e5980972d590..5a5090728620 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -92,9 +92,10 @@ public abstract class DisplayManagerInternal { boolean waitForNegativeProximity); /** - * Returns {@code true} if the proximity sensor screen-off function is available. + * Returns {@code true} if the proximity sensor screen-off function is available for the given + * display. */ - public abstract boolean isProximitySensorAvailable(); + public abstract boolean isProximitySensorAvailable(int displayId); /** * Registers a display group listener which will be informed of the addition, removal, or change diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 5f62b8be45a3..e85e58039828 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -42,7 +42,9 @@ interface IPowerManager void updateWakeLockWorkSource(IBinder lock, in WorkSource ws, String historyTag); void updateWakeLockCallback(IBinder lock, IWakeLockCallback callback); + @UnsupportedAppUsage boolean isWakeLockLevelSupported(int level); + boolean isWakeLockLevelSupportedWithDisplayId(int level, int displayId); void userActivity(int displayId, long time, int event, int flags); void wakeUp(long time, int reason, String details, String opPackageName); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index b9bae5b9f737..32db3bea7686 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -1344,6 +1344,9 @@ public final class PowerManager { * @see #ON_AFTER_RELEASE */ public WakeLock newWakeLock(int levelAndFlags, String tag) { + if (android.companion.virtualdevice.flags.Flags.displayPowerManagerApis()) { + return newWakeLock(levelAndFlags, tag, mContext.getDisplayId()); + } validateWakeLockParameters(levelAndFlags, tag); return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName(), Display.INVALID_DISPLAY); @@ -1734,6 +1737,10 @@ public final class PowerManager { */ public boolean isWakeLockLevelSupported(int level) { try { + if (android.companion.virtualdevice.flags.Flags.displayPowerManagerApis()) { + return mService.isWakeLockLevelSupportedWithDisplayId( + level, mContext.getDisplayId()); + } return mService.isWakeLockLevelSupported(level); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1797,6 +1804,9 @@ public final class PowerManager { * @see android.content.Intent#ACTION_SCREEN_OFF */ public boolean isInteractive() { + if (android.companion.virtualdevice.flags.Flags.displayPowerManagerApis()) { + return isInteractive(mContext.getDisplayId()); + } return mInteractiveCache.query(null); } diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 99a7743323ff..442d0c8b0373 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -5233,10 +5233,9 @@ public final class DisplayManagerService extends SystemService { } @Override - public boolean isProximitySensorAvailable() { + public boolean isProximitySensorAvailable(int displayId) { synchronized (mSyncRoot) { - return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) - .isProximitySensorAvailable(); + return mDisplayPowerControllers.get(displayId).isProximitySensorAvailable(); } } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 21ab7812e604..65f22416a535 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -743,6 +743,7 @@ public final class PowerManagerService extends SystemService int reason, int uid, int opUid, String opPackageName, String details) { mWakefulnessChanging = true; mDirty |= DIRTY_WAKEFULNESS; + mInjector.invalidateIsInteractiveCaches(); if (wakefulness == WAKEFULNESS_AWAKE) { // Kick user activity to prevent newly awake group from timing out instantly. // The dream may end without user activity if the dream app crashes / is updated, @@ -2035,7 +2036,7 @@ public final class PowerManagerService extends SystemService } @SuppressWarnings("deprecation") - private boolean isWakeLockLevelSupportedInternal(int level) { + private boolean isWakeLockLevelSupportedInternal(int level, int displayId) { synchronized (mLock) { switch (level) { case PowerManager.PARTIAL_WAKE_LOCK: @@ -2047,7 +2048,8 @@ public final class PowerManagerService extends SystemService return true; case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: - return mSystemReady && mDisplayManagerInternal.isProximitySensorAvailable(); + return mSystemReady + && mDisplayManagerInternal.isProximitySensorAvailable(displayId); case PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK: return mSystemReady && mFeatureFlags.isEarlyScreenTimeoutDetectorEnabled() && mScreenTimeoutOverridePolicy != null; @@ -2264,7 +2266,6 @@ public final class PowerManagerService extends SystemService int opUid, String opPackageName, String details) { mPowerGroups.get(groupId).setWakefulnessLocked(wakefulness, eventTime, uid, reason, opUid, opPackageName, details); - mInjector.invalidateIsInteractiveCaches(); } @SuppressWarnings("deprecation") @@ -2329,8 +2330,6 @@ public final class PowerManagerService extends SystemService Trace.traceBegin(Trace.TRACE_TAG_POWER, traceMethodName); try { // Phase 2: Handle wakefulness change and bookkeeping. - // Under lock, invalidate before set ensures caches won't return stale values. - mInjector.invalidateIsInteractiveCaches(); mWakefulnessRaw = newWakefulness; mWakefulnessChanging = true; mDirty |= DIRTY_WAKEFULNESS; @@ -2428,6 +2427,7 @@ public final class PowerManagerService extends SystemService void onPowerGroupEventLocked(int event, PowerGroup powerGroup) { mWakefulnessChanging = true; mDirty |= DIRTY_WAKEFULNESS; + mInjector.invalidateIsInteractiveCaches(); final int groupId = powerGroup.getGroupId(); if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED) { mPowerGroups.delete(groupId); @@ -3975,6 +3975,9 @@ public final class PowerManagerService extends SystemService private boolean isInteractiveInternal(int displayId, int uid) { synchronized (mLock) { + if (!mSystemReady) { + return isGloballyInteractiveInternal(); + } DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(displayId); if (displayInfo == null) { Slog.w(TAG, "Did not find DisplayInfo for displayId " + displayId); @@ -5975,7 +5978,17 @@ public final class PowerManagerService extends SystemService public boolean isWakeLockLevelSupported(int level) { final long ident = Binder.clearCallingIdentity(); try { - return isWakeLockLevelSupportedInternal(level); + return isWakeLockLevelSupportedInternal(level, Display.DEFAULT_DISPLAY); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override // Binder call + public boolean isWakeLockLevelSupportedWithDisplayId(int level, int displayId) { + final long ident = Binder.clearCallingIdentity(); + try { + return isWakeLockLevelSupportedInternal(level, displayId); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java b/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java index 0e815d0eab95..3e731a322d4e 100644 --- a/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java +++ b/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java @@ -163,6 +163,7 @@ public class LowPowerStandbyControllerTest { addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock); when(mIPowerManagerMock.isInteractive()).thenReturn(true); + when(mIPowerManagerMock.isDisplayInteractive(anyInt())).thenReturn(true); when(mDeviceConfigWrapperMock.enableCustomPolicy()).thenReturn(true); when(mDeviceConfigWrapperMock.enableStandbyPorts()).thenReturn(true); @@ -899,11 +900,13 @@ public class LowPowerStandbyControllerTest { private void setInteractive() throws Exception { when(mIPowerManagerMock.isInteractive()).thenReturn(true); + when(mIPowerManagerMock.isDisplayInteractive(anyInt())).thenReturn(true); mContextSpy.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON)); } private void setNonInteractive() throws Exception { when(mIPowerManagerMock.isInteractive()).thenReturn(false); + when(mIPowerManagerMock.isDisplayInteractive(anyInt())).thenReturn(false); mContextSpy.sendBroadcast(new Intent(Intent.ACTION_SCREEN_OFF)); } diff --git a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java index 54a02cf3cda3..e9e21dee16a8 100644 --- a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java +++ b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java @@ -1658,6 +1658,64 @@ public class PowerManagerServiceTest { assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); } + @Test + public void testIsWakeLockLevelSupported_returnsCorrectValue() { + createService(); + startSystem(); + PowerManagerService.BinderService service = mService.getBinderServiceInstance(); + assertThat(service.isWakeLockLevelSupported(PowerManager.PARTIAL_WAKE_LOCK)).isTrue(); + assertThat(service.isWakeLockLevelSupported(PowerManager.SCREEN_BRIGHT_WAKE_LOCK)).isTrue(); + assertThat(service.isWakeLockLevelSupported(PowerManager.FULL_WAKE_LOCK)).isTrue(); + assertThat(service.isWakeLockLevelSupported(PowerManager.DOZE_WAKE_LOCK)).isTrue(); + assertThat(service.isWakeLockLevelSupported(PowerManager.DRAW_WAKE_LOCK)).isTrue(); + + when(mDisplayManagerInternalMock.isProximitySensorAvailable(eq(Display.DEFAULT_DISPLAY))) + .thenReturn(true); + assertThat(service.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) + .isTrue(); + + when(mDisplayManagerInternalMock.isProximitySensorAvailable(eq(Display.DEFAULT_DISPLAY))) + .thenReturn(false); + assertThat(service.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) + .isFalse(); + } + + @Test + public void testIsWakeLockLevelSupportedWithDisplayId_nonDefaultDisplay_returnsCorrectValue() { + createService(); + startSystem(); + int displayId = Display.DEFAULT_DISPLAY + 1; + PowerManagerService.BinderService service = mService.getBinderServiceInstance(); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.PARTIAL_WAKE_LOCK, displayId)) + .isTrue(); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.SCREEN_BRIGHT_WAKE_LOCK, displayId)) + .isTrue(); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.FULL_WAKE_LOCK, displayId)) + .isTrue(); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.DOZE_WAKE_LOCK, displayId)) + .isTrue(); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.DRAW_WAKE_LOCK, displayId)) + .isTrue(); + + when(mDisplayManagerInternalMock.isProximitySensorAvailable(eq(displayId))) + .thenReturn(true); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, displayId)) + .isTrue(); + + when(mDisplayManagerInternalMock.isProximitySensorAvailable(eq(displayId))) + .thenReturn(false); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, displayId)) + .isFalse(); + } + + @Test public void testWakeLock_affectsProperDisplayGroup() { final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; @@ -1698,6 +1756,47 @@ public class PowerManagerServiceTest { WAKEFULNESS_DOZING); } + @Test + public void testWakeLock_nonDefaultDisplay_affectsProperDisplayGroup() { + final int nonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1; + final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; + final AtomicReference listener = + new AtomicReference<>(); + doAnswer((Answer) invocation -> { + listener.set(invocation.getArgument(0)); + return null; + }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any()); + final DisplayInfo info = new DisplayInfo(); + info.displayGroupId = nonDefaultDisplayGroupId; + when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplayId)).thenReturn(info); + + final String pkg = mContextSpy.getOpPackageName(); + final Binder token = new Binder(); + final String tag = "testWakeLock_nonDefaultDisplay_affectsProperDisplayGroup"; + + setMinimumScreenOffTimeoutConfig(5); + createService(); + startSystem(); + listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); + + mService.getBinderServiceInstance().acquireWakeLock(token, + PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg, + null /* workSource */, null /* historyTag */, nonDefaultDisplayId, null); + + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo( + WAKEFULNESS_AWAKE); + assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo( + WAKEFULNESS_AWAKE); + + advanceTime(15000); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo( + WAKEFULNESS_ASLEEP); + assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo( + WAKEFULNESS_AWAKE); + } + @Test public void testInvalidDisplayGroupWakeLock_affectsAllDisplayGroups() { final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; @@ -2590,14 +2689,15 @@ public class PowerManagerServiceTest { when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(info); createService(); startSystem(); - listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); - verify(mInvalidateInteractiveCachesMock).call(); + listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); + verify(mInvalidateInteractiveCachesMock, times(2)).call(); + mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, mClock.now(), 0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null); - verify(mInvalidateInteractiveCachesMock, times(2)).call(); + verify(mInvalidateInteractiveCachesMock, times(3)).call(); } @Test @@ -2616,14 +2716,15 @@ public class PowerManagerServiceTest { when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(info); createService(); startSystem(); - listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); - verify(mInvalidateInteractiveCachesMock).call(); + listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); + verify(mInvalidateInteractiveCachesMock, times(2)).call(); + mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, mClock.now(), 0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null); - verify(mInvalidateInteractiveCachesMock, times(2)).call(); + verify(mInvalidateInteractiveCachesMock, times(3)).call(); } @Test -- GitLab From c17b99d13d5c5e2318c58903708af91d143179be Mon Sep 17 00:00:00 2001 From: Ahmad Khalil Date: Fri, 4 Oct 2024 21:47:31 +0000 Subject: [PATCH 088/447] Renaming Frequency Profile APIs To prepare for the implementation of PWLE v2, which requires a new FrequencyProfile, we're renaming the existing profile to avoid naming conflicts: - VibratorFrequencyProfile -> VibratorFrequencyProfileLegacy - VibratorInfo.FrequencyProfile -> VibratorInfo.FrequencyProfileLegacy The legacy APIs were never made part of the public API, so this renaming should not affect external developers. Bug: 347034419 Flag: android.os.vibrator.normalized_pwle_effects Test: atest FrameworksVibratorCoreTests Change-Id: I57bd2768d1253537a4a7cfeef00f111fa3989457 --- core/api/test-current.txt | 4 +- core/java/android/os/VibrationEffect.java | 5 +- core/java/android/os/Vibrator.java | 11 ++-- core/java/android/os/VibratorInfo.java | 64 +++++++++---------- .../os/vibrator/MultiVibratorInfo.java | 20 +++--- ...va => VibratorFrequencyProfileLegacy.java} | 13 +++- .../src/android/os/VibratorInfoTest.java | 64 ++++++++++--------- .../os/vibrator/MultiVibratorInfoTest.java | 60 ++++++++--------- .../ClippingAmplitudeAndFrequencyAdapter.java | 8 +-- ...oid_server_vibrator_VibratorController.cpp | 32 ++++++---- .../vibrator/RampToStepAdapterTest.java | 6 +- .../vibrator/SplitSegmentsAdapterTest.java | 8 +-- .../vibrator/StepToRampAdapterTest.java | 6 +- .../vibrator/VibratorControllerTest.java | 5 +- .../FakeVibratorControllerProvider.java | 2 +- 15 files changed, 165 insertions(+), 143 deletions(-) rename core/java/android/os/vibrator/{VibratorFrequencyProfile.java => VibratorFrequencyProfileLegacy.java} (89%) diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 9bcdf959a6a7..76e9ca060547 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2603,7 +2603,7 @@ package android.os { public abstract class Vibrator { method public int getDefaultVibrationIntensity(int); - method @Nullable public android.os.vibrator.VibratorFrequencyProfile getFrequencyProfile(); + method @Nullable public android.os.vibrator.VibratorFrequencyProfileLegacy getFrequencyProfileLegacy(); method public boolean hasFrequencyControl(); field public static final int VIBRATION_INTENSITY_HIGH = 3; // 0x3 field public static final int VIBRATION_INTENSITY_LOW = 1; // 0x1 @@ -2793,7 +2793,7 @@ package android.os.vibrator { field @NonNull public static final android.os.Parcelable.Creator CREATOR; } - public final class VibratorFrequencyProfile { + public final class VibratorFrequencyProfileLegacy { method public float getMaxAmplitudeMeasurementInterval(); method @FloatRange(from=0, to=1) @NonNull public float[] getMaxAmplitudeMeasurements(); method public float getMaxFrequency(); diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java index 64a2dbcb6a83..ffc58c537f2a 100644 --- a/core/java/android/os/VibrationEffect.java +++ b/core/java/android/os/VibrationEffect.java @@ -40,6 +40,7 @@ import android.os.vibrator.PrimitiveSegment; import android.os.vibrator.RampSegment; import android.os.vibrator.StepSegment; import android.os.vibrator.VibrationEffectSegment; +import android.os.vibrator.VibratorFrequencyProfileLegacy; import android.util.MathUtils; import com.android.internal.util.Preconditions; @@ -1761,7 +1762,7 @@ public abstract class VibrationEffect implements Parcelable { * new value as fast as possible. * *

    Vibration parameter values will be truncated to conform to the device capabilities - * according to the {@link android.os.vibrator.VibratorFrequencyProfile}. + * according to the {@link VibratorFrequencyProfileLegacy}. * * @param duration The length of time this transition should take. Value must be * non-negative and will be truncated to milliseconds. @@ -1792,7 +1793,7 @@ public abstract class VibrationEffect implements Parcelable { * new values as fast as possible. * *

    Vibration parameters values will be truncated to conform to the device capabilities - * according to the {@link android.os.vibrator.VibratorFrequencyProfile}. + * according to the {@link VibratorFrequencyProfileLegacy}. * * @param duration The length of time this transition should take. Value must be * non-negative and will be truncated to milliseconds. diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java index 84325b7c2874..7327630bca39 100644 --- a/core/java/android/os/Vibrator.java +++ b/core/java/android/os/Vibrator.java @@ -22,6 +22,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; @@ -33,7 +34,7 @@ import android.hardware.vibrator.IVibrator; import android.media.AudioAttributes; import android.os.vibrator.Flags; import android.os.vibrator.VibrationConfig; -import android.os.vibrator.VibratorFrequencyProfile; +import android.os.vibrator.VibratorFrequencyProfileLegacy; import android.util.Log; import android.view.HapticFeedbackConstants; @@ -290,13 +291,15 @@ public abstract class Vibrator { * @hide */ @TestApi + @SuppressLint("UnflaggedApi") @Nullable - public VibratorFrequencyProfile getFrequencyProfile() { - VibratorInfo.FrequencyProfile frequencyProfile = getInfo().getFrequencyProfile(); + public VibratorFrequencyProfileLegacy getFrequencyProfileLegacy() { + VibratorInfo.FrequencyProfileLegacy frequencyProfile = + getInfo().getFrequencyProfileLegacy(); if (frequencyProfile.isEmpty()) { return null; } - return new VibratorFrequencyProfile(frequencyProfile); + return new VibratorFrequencyProfileLegacy(frequencyProfile); } /** diff --git a/core/java/android/os/VibratorInfo.java b/core/java/android/os/VibratorInfo.java index 5378295e3720..f7fff391147b 100644 --- a/core/java/android/os/VibratorInfo.java +++ b/core/java/android/os/VibratorInfo.java @@ -59,7 +59,7 @@ public class VibratorInfo implements Parcelable { private final int mPwlePrimitiveDurationMax; private final int mPwleSizeMax; private final float mQFactor; - private final FrequencyProfile mFrequencyProfile; + private final FrequencyProfileLegacy mFrequencyProfileLegacy; private final int mMaxEnvelopeEffectSize; private final int mMinEnvelopeEffectControlPointDurationMillis; private final int mMaxEnvelopeEffectControlPointDurationMillis; @@ -75,7 +75,7 @@ public class VibratorInfo implements Parcelable { mPwlePrimitiveDurationMax = in.readInt(); mPwleSizeMax = in.readInt(); mQFactor = in.readFloat(); - mFrequencyProfile = FrequencyProfile.CREATOR.createFromParcel(in); + mFrequencyProfileLegacy = FrequencyProfileLegacy.CREATOR.createFromParcel(in); mMaxEnvelopeEffectSize = in.readInt(); mMinEnvelopeEffectControlPointDurationMillis = in.readInt(); mMaxEnvelopeEffectControlPointDurationMillis = in.readInt(); @@ -86,7 +86,7 @@ public class VibratorInfo implements Parcelable { baseVibratorInfo.mSupportedBraking, baseVibratorInfo.mSupportedPrimitives, baseVibratorInfo.mPrimitiveDelayMax, baseVibratorInfo.mCompositionSizeMax, baseVibratorInfo.mPwlePrimitiveDurationMax, baseVibratorInfo.mPwleSizeMax, - baseVibratorInfo.mQFactor, baseVibratorInfo.mFrequencyProfile, + baseVibratorInfo.mQFactor, baseVibratorInfo.mFrequencyProfileLegacy, baseVibratorInfo.mMaxEnvelopeEffectSize, baseVibratorInfo.mMinEnvelopeEffectControlPointDurationMillis, baseVibratorInfo.mMaxEnvelopeEffectControlPointDurationMillis); @@ -112,7 +112,7 @@ public class VibratorInfo implements Parcelable { * @param pwleSizeMax The maximum number of primitives supported by a PWLE * composition. * @param qFactor The vibrator quality factor. - * @param frequencyProfile The description of the vibrator supported frequencies and max + * @param frequencyProfileLegacy The description of the vibrator supported frequencies and max * amplitude mappings. * @hide */ @@ -120,11 +120,11 @@ public class VibratorInfo implements Parcelable { @Nullable SparseBooleanArray supportedBraking, @NonNull SparseIntArray supportedPrimitives, int primitiveDelayMax, int compositionSizeMax, int pwlePrimitiveDurationMax, int pwleSizeMax, - float qFactor, @NonNull FrequencyProfile frequencyProfile, + float qFactor, @NonNull FrequencyProfileLegacy frequencyProfileLegacy, int maxEnvelopeEffectSize, int minEnvelopeEffectControlPointDurationMillis, int maxEnvelopeEffectControlPointDurationMillis) { Preconditions.checkNotNull(supportedPrimitives); - Preconditions.checkNotNull(frequencyProfile); + Preconditions.checkNotNull(frequencyProfileLegacy); mId = id; mCapabilities = capabilities; mSupportedEffects = supportedEffects == null ? null : supportedEffects.clone(); @@ -135,7 +135,7 @@ public class VibratorInfo implements Parcelable { mPwlePrimitiveDurationMax = pwlePrimitiveDurationMax; mPwleSizeMax = pwleSizeMax; mQFactor = qFactor; - mFrequencyProfile = frequencyProfile; + mFrequencyProfileLegacy = frequencyProfileLegacy; mMaxEnvelopeEffectSize = maxEnvelopeEffectSize; mMinEnvelopeEffectControlPointDurationMillis = minEnvelopeEffectControlPointDurationMillis; @@ -155,7 +155,7 @@ public class VibratorInfo implements Parcelable { dest.writeInt(mPwlePrimitiveDurationMax); dest.writeInt(mPwleSizeMax); dest.writeFloat(mQFactor); - mFrequencyProfile.writeToParcel(dest, flags); + mFrequencyProfileLegacy.writeToParcel(dest, flags); dest.writeInt(mMaxEnvelopeEffectSize); dest.writeInt(mMinEnvelopeEffectControlPointDurationMillis); dest.writeInt(mMaxEnvelopeEffectControlPointDurationMillis); @@ -205,7 +205,7 @@ public class VibratorInfo implements Parcelable { && Objects.equals(mSupportedEffects, that.mSupportedEffects) && Objects.equals(mSupportedBraking, that.mSupportedBraking) && Objects.equals(mQFactor, that.mQFactor) - && Objects.equals(mFrequencyProfile, that.mFrequencyProfile) + && Objects.equals(mFrequencyProfileLegacy, that.mFrequencyProfileLegacy) && mMaxEnvelopeEffectSize == that.mMaxEnvelopeEffectSize && mMinEnvelopeEffectControlPointDurationMillis == that.mMinEnvelopeEffectControlPointDurationMillis @@ -216,7 +216,7 @@ public class VibratorInfo implements Parcelable { @Override public int hashCode() { int hashCode = Objects.hash(mId, mCapabilities, mSupportedEffects, mSupportedBraking, - mQFactor, mFrequencyProfile); + mQFactor, mFrequencyProfileLegacy); for (int i = 0; i < mSupportedPrimitives.size(); i++) { hashCode = 31 * hashCode + mSupportedPrimitives.keyAt(i); hashCode = 31 * hashCode + mSupportedPrimitives.valueAt(i); @@ -238,7 +238,7 @@ public class VibratorInfo implements Parcelable { + ", mPwlePrimitiveDurationMax=" + mPwlePrimitiveDurationMax + ", mPwleSizeMax=" + mPwleSizeMax + ", mQFactor=" + mQFactor - + ", mFrequencyProfile=" + mFrequencyProfile + + ", mFrequencyProfileLegacy=" + mFrequencyProfileLegacy + ", mMaxEnvelopeEffectSize=" + mMaxEnvelopeEffectSize + ", mMinEnvelopeEffectControlPointDurationMillis=" + mMinEnvelopeEffectControlPointDurationMillis @@ -262,7 +262,7 @@ public class VibratorInfo implements Parcelable { pw.println("pwlePrimitiveDurationMax = " + mPwlePrimitiveDurationMax); pw.println("pwleSizeMax = " + mPwleSizeMax); pw.println("q-factor = " + mQFactor); - pw.println("frequencyProfile = " + mFrequencyProfile); + pw.println("frequencyProfileLegacy = " + mFrequencyProfileLegacy); pw.println("mMaxEnvelopeEffectSize = " + mMaxEnvelopeEffectSize); pw.println("mMinEnvelopeEffectControlPointDurationMillis = " + mMinEnvelopeEffectControlPointDurationMillis); @@ -517,7 +517,7 @@ public class VibratorInfo implements Parcelable { * this vibrator is a composite of multiple physical devices. */ public float getResonantFrequencyHz() { - return mFrequencyProfile.mResonantFrequencyHz; + return mFrequencyProfileLegacy.mResonantFrequencyHz; } /** @@ -537,8 +537,8 @@ public class VibratorInfo implements Parcelable { *

    If the devices does not have frequency control then the profile should be empty. */ @NonNull - public FrequencyProfile getFrequencyProfile() { - return mFrequencyProfile; + public FrequencyProfileLegacy getFrequencyProfileLegacy() { + return mFrequencyProfileLegacy; } /** Returns a single int representing all the capabilities of the vibrator. */ @@ -640,7 +640,7 @@ public class VibratorInfo implements Parcelable { * * @hide */ - public static final class FrequencyProfile implements Parcelable { + public static final class FrequencyProfileLegacy implements Parcelable { @Nullable private final Range mFrequencyRangeHz; private final float mMinFrequencyHz; @@ -648,7 +648,7 @@ public class VibratorInfo implements Parcelable { private final float mFrequencyResolutionHz; private final float[] mMaxAmplitudes; - FrequencyProfile(Parcel in) { + FrequencyProfileLegacy(Parcel in) { this(in.readFloat(), in.readFloat(), in.readFloat(), in.createFloatArray()); } @@ -664,7 +664,7 @@ public class VibratorInfo implements Parcelable { * resolution. * @hide */ - public FrequencyProfile(float resonantFrequencyHz, float minFrequencyHz, + public FrequencyProfileLegacy(float resonantFrequencyHz, float minFrequencyHz, float frequencyResolutionHz, float[] maxAmplitudes) { mMinFrequencyHz = minFrequencyHz; mResonantFrequencyHz = resonantFrequencyHz; @@ -776,10 +776,10 @@ public class VibratorInfo implements Parcelable { if (this == o) { return true; } - if (!(o instanceof FrequencyProfile)) { + if (!(o instanceof FrequencyProfileLegacy)) { return false; } - FrequencyProfile that = (FrequencyProfile) o; + FrequencyProfileLegacy that = (FrequencyProfileLegacy) o; return Float.compare(mMinFrequencyHz, that.mMinFrequencyHz) == 0 && Float.compare(mResonantFrequencyHz, that.mResonantFrequencyHz) == 0 && Float.compare(mFrequencyResolutionHz, that.mFrequencyResolutionHz) == 0 @@ -796,7 +796,7 @@ public class VibratorInfo implements Parcelable { @Override public String toString() { - return "FrequencyProfile{" + return "FrequencyProfileLegacy{" + "mFrequencyRange=" + mFrequencyRangeHz + ", mMinFrequency=" + mMinFrequencyHz + ", mResonantFrequency=" + mResonantFrequencyHz @@ -806,16 +806,16 @@ public class VibratorInfo implements Parcelable { } @NonNull - public static final Creator CREATOR = - new Creator() { + public static final Creator CREATOR = + new Creator() { @Override - public FrequencyProfile createFromParcel(Parcel in) { - return new FrequencyProfile(in); + public FrequencyProfileLegacy createFromParcel(Parcel in) { + return new FrequencyProfileLegacy(in); } @Override - public FrequencyProfile[] newArray(int size) { - return new FrequencyProfile[size]; + public FrequencyProfileLegacy[] newArray(int size) { + return new FrequencyProfileLegacy[size]; } }; } @@ -832,8 +832,8 @@ public class VibratorInfo implements Parcelable { private int mPwlePrimitiveDurationMax; private int mPwleSizeMax; private float mQFactor = Float.NaN; - private FrequencyProfile mFrequencyProfile = - new FrequencyProfile(Float.NaN, Float.NaN, Float.NaN, null); + private FrequencyProfileLegacy mFrequencyProfileLegacy = + new FrequencyProfileLegacy(Float.NaN, Float.NaN, Float.NaN, null); private int mMaxEnvelopeEffectSize; private int mMinEnvelopeEffectControlPointDurationMillis; private int mMaxEnvelopeEffectControlPointDurationMillis; @@ -908,8 +908,8 @@ public class VibratorInfo implements Parcelable { /** Configure the vibrator frequency information like resonant frequency and bandwidth. */ @NonNull - public Builder setFrequencyProfile(@NonNull FrequencyProfile frequencyProfile) { - mFrequencyProfile = frequencyProfile; + public Builder setFrequencyProfileLegacy(@NonNull FrequencyProfileLegacy frequencyProfile) { + mFrequencyProfileLegacy = frequencyProfile; return this; } @@ -950,7 +950,7 @@ public class VibratorInfo implements Parcelable { public VibratorInfo build() { return new VibratorInfo(mId, mCapabilities, mSupportedEffects, mSupportedBraking, mSupportedPrimitives, mPrimitiveDelayMax, mCompositionSizeMax, - mPwlePrimitiveDurationMax, mPwleSizeMax, mQFactor, mFrequencyProfile, + mPwlePrimitiveDurationMax, mPwleSizeMax, mQFactor, mFrequencyProfileLegacy, mMaxEnvelopeEffectSize, mMinEnvelopeEffectControlPointDurationMillis, mMaxEnvelopeEffectControlPointDurationMillis); } diff --git a/core/java/android/os/vibrator/MultiVibratorInfo.java b/core/java/android/os/vibrator/MultiVibratorInfo.java index 9c2b9782ffb3..37dae56abc6d 100644 --- a/core/java/android/os/vibrator/MultiVibratorInfo.java +++ b/core/java/android/os/vibrator/MultiVibratorInfo.java @@ -48,7 +48,7 @@ public final class MultiVibratorInfo extends VibratorInfo { } private MultiVibratorInfo( - int id, VibratorInfo[] vibrators, VibratorInfo.FrequencyProfile mergedProfile) { + int id, VibratorInfo[] vibrators, FrequencyProfileLegacy mergedProfile) { super(id, capabilitiesIntersection(vibrators, mergedProfile.isEmpty()), supportedEffectsIntersection(vibrators), @@ -209,15 +209,15 @@ public final class MultiVibratorInfo extends VibratorInfo { } @NonNull - private static FrequencyProfile frequencyProfileIntersection(VibratorInfo[] infos) { + private static FrequencyProfileLegacy frequencyProfileIntersection(VibratorInfo[] infos) { float freqResolution = floatPropertyIntersection(infos, - info -> info.getFrequencyProfile().getFrequencyResolutionHz()); + info -> info.getFrequencyProfileLegacy().getFrequencyResolutionHz()); float resonantFreq = floatPropertyIntersection(infos, VibratorInfo::getResonantFrequencyHz); Range freqRange = frequencyRangeIntersection(infos, freqResolution); if ((freqRange == null) || Float.isNaN(freqResolution)) { - return new FrequencyProfile(resonantFreq, Float.NaN, freqResolution, null); + return new FrequencyProfileLegacy(resonantFreq, Float.NaN, freqResolution, null); } int amplitudeCount = @@ -230,8 +230,8 @@ public final class MultiVibratorInfo extends VibratorInfo { Arrays.fill(maxAmplitudes, Float.MAX_VALUE); for (VibratorInfo info : infos) { - Range vibratorFreqRange = info.getFrequencyProfile().getFrequencyRangeHz(); - float[] vibratorMaxAmplitudes = info.getFrequencyProfile().getMaxAmplitudes(); + Range vibratorFreqRange = info.getFrequencyProfileLegacy().getFrequencyRangeHz(); + float[] vibratorMaxAmplitudes = info.getFrequencyProfileLegacy().getMaxAmplitudes(); int vibratorStartIdx = Math.round( (freqRange.getLower() - vibratorFreqRange.getLower()) / freqResolution); int vibratorEndIdx = vibratorStartIdx + maxAmplitudes.length - 1; @@ -240,7 +240,7 @@ public final class MultiVibratorInfo extends VibratorInfo { Slog.w(TAG, "Error calculating the intersection of vibrator frequency" + " profiles: attempted to fetch from vibrator " + info.getId() + " max amplitude with bad index " + vibratorStartIdx); - return new FrequencyProfile(resonantFreq, Float.NaN, Float.NaN, null); + return new FrequencyProfileLegacy(resonantFreq, Float.NaN, Float.NaN, null); } for (int i = 0; i < maxAmplitudes.length; i++) { @@ -249,14 +249,14 @@ public final class MultiVibratorInfo extends VibratorInfo { } } - return new FrequencyProfile(resonantFreq, freqRange.getLower(), + return new FrequencyProfileLegacy(resonantFreq, freqRange.getLower(), freqResolution, maxAmplitudes); } @Nullable private static Range frequencyRangeIntersection(VibratorInfo[] infos, float frequencyResolution) { - Range firstRange = infos[0].getFrequencyProfile().getFrequencyRangeHz(); + Range firstRange = infos[0].getFrequencyProfileLegacy().getFrequencyRangeHz(); if (firstRange == null) { // If one vibrator is undefined then the intersection is undefined. return null; @@ -268,7 +268,7 @@ public final class MultiVibratorInfo extends VibratorInfo { // min supported frequencies are aligned w.r.t. the frequency resolution. for (int i = 1; i < infos.length; i++) { - Range vibratorRange = infos[i].getFrequencyProfile().getFrequencyRangeHz(); + Range vibratorRange = infos[i].getFrequencyProfileLegacy().getFrequencyRangeHz(); if (vibratorRange == null) { // If one vibrator is undefined then the intersection is undefined. return null; diff --git a/core/java/android/os/vibrator/VibratorFrequencyProfile.java b/core/java/android/os/vibrator/VibratorFrequencyProfileLegacy.java similarity index 89% rename from core/java/android/os/vibrator/VibratorFrequencyProfile.java rename to core/java/android/os/vibrator/VibratorFrequencyProfileLegacy.java index 8392940010e3..5c3e785550d3 100644 --- a/core/java/android/os/vibrator/VibratorFrequencyProfile.java +++ b/core/java/android/os/vibrator/VibratorFrequencyProfileLegacy.java @@ -18,6 +18,7 @@ package android.os.vibrator; import android.annotation.FloatRange; import android.annotation.NonNull; +import android.annotation.SuppressLint; import android.annotation.TestApi; import android.os.VibratorInfo; @@ -42,12 +43,14 @@ import com.android.internal.util.Preconditions; * @hide */ @TestApi -public final class VibratorFrequencyProfile { +@SuppressLint("UnflaggedApi") +public final class VibratorFrequencyProfileLegacy { - private final VibratorInfo.FrequencyProfile mFrequencyProfile; + private final VibratorInfo.FrequencyProfileLegacy mFrequencyProfile; /** @hide */ - public VibratorFrequencyProfile(@NonNull VibratorInfo.FrequencyProfile frequencyProfile) { + public VibratorFrequencyProfileLegacy( + @NonNull VibratorInfo.FrequencyProfileLegacy frequencyProfile) { Preconditions.checkArgument(!frequencyProfile.isEmpty(), "Frequency profile must have a non-empty frequency range"); mFrequencyProfile = frequencyProfile; @@ -68,6 +71,7 @@ public final class VibratorFrequencyProfile { * @hide */ @TestApi + @SuppressLint("UnflaggedApi") @NonNull @FloatRange(from = 0, to = 1) public float[] getMaxAmplitudeMeasurements() { @@ -82,6 +86,7 @@ public final class VibratorFrequencyProfile { * @hide */ @TestApi + @SuppressLint("UnflaggedApi") public float getMaxAmplitudeMeasurementInterval() { return mFrequencyProfile.getFrequencyResolutionHz(); } @@ -93,6 +98,7 @@ public final class VibratorFrequencyProfile { * @hide */ @TestApi + @SuppressLint("UnflaggedApi") public float getMinFrequency() { return mFrequencyProfile.getFrequencyRangeHz().getLower(); } @@ -104,6 +110,7 @@ public final class VibratorFrequencyProfile { * @hide */ @TestApi + @SuppressLint("UnflaggedApi") public float getMaxFrequency() { return mFrequencyProfile.getFrequencyRangeHz().getUpper(); } diff --git a/core/tests/vibrator/src/android/os/VibratorInfoTest.java b/core/tests/vibrator/src/android/os/VibratorInfoTest.java index c81081075859..47d01c4452f6 100644 --- a/core/tests/vibrator/src/android/os/VibratorInfoTest.java +++ b/core/tests/vibrator/src/android/os/VibratorInfoTest.java @@ -40,10 +40,10 @@ public class VibratorInfoTest { private static final float[] TEST_AMPLITUDE_MAP = new float[]{ /* 50Hz= */ 0.1f, 0.2f, 0.4f, 0.8f, /* 150Hz= */ 1f, 0.9f, /* 200Hz= */ 0.8f}; - private static final VibratorInfo.FrequencyProfile EMPTY_FREQUENCY_PROFILE = - new VibratorInfo.FrequencyProfile(Float.NaN, Float.NaN, Float.NaN, null); - private static final VibratorInfo.FrequencyProfile TEST_FREQUENCY_PROFILE = - new VibratorInfo.FrequencyProfile(TEST_RESONANT_FREQUENCY, TEST_MIN_FREQUENCY, + private static final VibratorInfo.FrequencyProfileLegacy EMPTY_FREQUENCY_PROFILE = + new VibratorInfo.FrequencyProfileLegacy(Float.NaN, Float.NaN, Float.NaN, null); + private static final VibratorInfo.FrequencyProfileLegacy TEST_FREQUENCY_PROFILE_LEGACY = + new VibratorInfo.FrequencyProfileLegacy(TEST_RESONANT_FREQUENCY, TEST_MIN_FREQUENCY, TEST_FREQUENCY_RESOLUTION, TEST_AMPLITUDE_MAP); @Test @@ -179,53 +179,57 @@ public class VibratorInfoTest { } @Test - public void testGetFrequencyProfile_unsetProfileIsEmpty() { - assertTrue( - new VibratorInfo.Builder(TEST_VIBRATOR_ID).build().getFrequencyProfile().isEmpty()); + public void testGetFrequencyProfileLegacy_unsetProfileIsEmpty() { + assertTrue(new VibratorInfo.Builder( + TEST_VIBRATOR_ID).build().getFrequencyProfileLegacy().isEmpty()); } @Test public void testFrequencyProfile_invalidValuesCreatesEmptyProfile() { // Invalid, contains NaN values or empty array. - assertTrue(new VibratorInfo.FrequencyProfile( + assertTrue(new VibratorInfo.FrequencyProfileLegacy( Float.NaN, 50, 25, TEST_AMPLITUDE_MAP).isEmpty()); - assertTrue(new VibratorInfo.FrequencyProfile( + assertTrue(new VibratorInfo.FrequencyProfileLegacy( 150, Float.NaN, 25, TEST_AMPLITUDE_MAP).isEmpty()); - assertTrue(new VibratorInfo.FrequencyProfile( + assertTrue(new VibratorInfo.FrequencyProfileLegacy( 150, 50, Float.NaN, TEST_AMPLITUDE_MAP).isEmpty()); - assertTrue(new VibratorInfo.FrequencyProfile(150, 50, 25, null).isEmpty()); + assertTrue(new VibratorInfo.FrequencyProfileLegacy(150, 50, 25, null).isEmpty()); // Invalid, contains zero or negative frequency values. - assertTrue(new VibratorInfo.FrequencyProfile(-1, 50, 25, TEST_AMPLITUDE_MAP).isEmpty()); - assertTrue(new VibratorInfo.FrequencyProfile(150, 0, 25, TEST_AMPLITUDE_MAP).isEmpty()); - assertTrue(new VibratorInfo.FrequencyProfile(150, 50, -2, TEST_AMPLITUDE_MAP).isEmpty()); + assertTrue( + new VibratorInfo.FrequencyProfileLegacy(-1, 50, 25, TEST_AMPLITUDE_MAP).isEmpty()); + assertTrue( + new VibratorInfo.FrequencyProfileLegacy(150, 0, 25, TEST_AMPLITUDE_MAP).isEmpty()); + assertTrue( + new VibratorInfo.FrequencyProfileLegacy(150, 50, -2, TEST_AMPLITUDE_MAP).isEmpty()); // Invalid max amplitude entries. - assertTrue(new VibratorInfo.FrequencyProfile( + assertTrue(new VibratorInfo.FrequencyProfileLegacy( 150, 50, 50, new float[] { -1, 0, 1, 1, 0 }).isEmpty()); - assertTrue(new VibratorInfo.FrequencyProfile( + assertTrue(new VibratorInfo.FrequencyProfileLegacy( 150, 50, 50, new float[] { 0, 1, 2, 1, 0 }).isEmpty()); // Invalid, minFrequency > resonantFrequency - assertTrue(new VibratorInfo.FrequencyProfile( + assertTrue(new VibratorInfo.FrequencyProfileLegacy( /* resonantFrequencyHz= */ 150, /* minFrequencyHz= */ 250, 25, TEST_AMPLITUDE_MAP) .isEmpty()); // Invalid, maxFrequency < resonantFrequency by changing resolution. - assertTrue(new VibratorInfo.FrequencyProfile( + assertTrue(new VibratorInfo.FrequencyProfileLegacy( 150, 50, /* frequencyResolutionHz= */ 10, TEST_AMPLITUDE_MAP).isEmpty()); } @Test public void testGetFrequencyRangeHz_emptyProfileReturnsNull() { - assertNull(new VibratorInfo.FrequencyProfile( + assertNull(new VibratorInfo.FrequencyProfileLegacy( Float.NaN, 50, 25, TEST_AMPLITUDE_MAP).getFrequencyRangeHz()); - assertNull(new VibratorInfo.FrequencyProfile( + assertNull(new VibratorInfo.FrequencyProfileLegacy( 150, Float.NaN, 25, TEST_AMPLITUDE_MAP).getFrequencyRangeHz()); - assertNull(new VibratorInfo.FrequencyProfile( + assertNull(new VibratorInfo.FrequencyProfileLegacy( 150, 50, Float.NaN, TEST_AMPLITUDE_MAP).getFrequencyRangeHz()); - assertNull(new VibratorInfo.FrequencyProfile(150, 50, 25, null).getFrequencyRangeHz()); + assertNull( + new VibratorInfo.FrequencyProfileLegacy(150, 50, 25, null).getFrequencyRangeHz()); } @Test public void testGetFrequencyRangeHz_validProfileReturnsMappedValues() { - VibratorInfo.FrequencyProfile profile = new VibratorInfo.FrequencyProfile( + VibratorInfo.FrequencyProfileLegacy profile = new VibratorInfo.FrequencyProfileLegacy( /* resonantFrequencyHz= */ 150, /* minFrequencyHz= */ 50, /* frequencyResolutionHz= */ 25, @@ -239,12 +243,12 @@ public class VibratorInfoTest { @Test public void testGetMaxAmplitude_emptyProfileReturnsAlwaysZero() { - VibratorInfo.FrequencyProfile profile = EMPTY_FREQUENCY_PROFILE; + VibratorInfo.FrequencyProfileLegacy profile = EMPTY_FREQUENCY_PROFILE; assertEquals(0f, profile.getMaxAmplitude(Float.NaN), TEST_TOLERANCE); assertEquals(0f, profile.getMaxAmplitude(100f), TEST_TOLERANCE); assertEquals(0f, profile.getMaxAmplitude(200f), TEST_TOLERANCE); - profile = new VibratorInfo.FrequencyProfile( + profile = new VibratorInfo.FrequencyProfileLegacy( /* resonantFrequencyHz= */ 150, /* minFrequencyHz= */ Float.NaN, /* frequencyResolutionHz= */ Float.NaN, @@ -257,7 +261,7 @@ public class VibratorInfoTest { @Test public void testGetMaxAmplitude_validProfileReturnsMappedValues() { - VibratorInfo.FrequencyProfile profile = new VibratorInfo.FrequencyProfile( + VibratorInfo.FrequencyProfileLegacy profile = new VibratorInfo.FrequencyProfileLegacy( /* resonantFrequencyHz= */ 150, /* minFrequencyHz= */ 50, /* frequencyResolutionHz= */ 25, @@ -301,7 +305,7 @@ public class VibratorInfoTest { .setPwlePrimitiveDurationMax(50) .setPwleSizeMax(20) .setQFactor(2f) - .setFrequencyProfile(TEST_FREQUENCY_PROFILE) + .setFrequencyProfileLegacy(TEST_FREQUENCY_PROFILE_LEGACY) .setMaxEnvelopeEffectSize(16) .setMinEnvelopeEffectControlPointDurationMillis(20) .setMaxEnvelopeEffectControlPointDurationMillis(1_000); @@ -344,7 +348,7 @@ public class VibratorInfoTest { assertFalse(complete.equalContent(completeWithDifferentPrimitiveDuration)); VibratorInfo completeWithDifferentFrequencyProfile = completeBuilder - .setFrequencyProfile(new VibratorInfo.FrequencyProfile( + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy( TEST_RESONANT_FREQUENCY + 20, TEST_MIN_FREQUENCY + 10, TEST_FREQUENCY_RESOLUTION + 5, @@ -354,7 +358,7 @@ public class VibratorInfoTest { assertFalse(complete.equalContent(completeWithDifferentFrequencyProfile)); VibratorInfo completeWithEmptyFrequencyProfile = completeBuilder - .setFrequencyProfile(EMPTY_FREQUENCY_PROFILE) + .setFrequencyProfileLegacy(EMPTY_FREQUENCY_PROFILE) .build(); assertNotEquals(complete, completeWithEmptyFrequencyProfile); assertFalse(complete.equalContent(completeWithEmptyFrequencyProfile)); @@ -391,7 +395,7 @@ public class VibratorInfoTest { .setSupportedEffects(VibrationEffect.EFFECT_CLICK) .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 20) .setQFactor(Float.NaN) - .setFrequencyProfile(TEST_FREQUENCY_PROFILE) + .setFrequencyProfileLegacy(TEST_FREQUENCY_PROFILE_LEGACY) .build(); Parcel parcel = Parcel.obtain(); diff --git a/core/tests/vibrator/src/android/os/vibrator/MultiVibratorInfoTest.java b/core/tests/vibrator/src/android/os/vibrator/MultiVibratorInfoTest.java index fc31ac44b362..f192b896e1db 100644 --- a/core/tests/vibrator/src/android/os/vibrator/MultiVibratorInfoTest.java +++ b/core/tests/vibrator/src/android/os/vibrator/MultiVibratorInfoTest.java @@ -161,12 +161,12 @@ public class MultiVibratorInfoTest { VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) .setQFactor(1f) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1, null)) + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(1, 1, 1, null)) .build(); VibratorInfo secondInfo = new VibratorInfo.Builder(/* id= */ 2) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) .setQFactor(2f) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(2, 2, 2, null)) + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(2, 2, 2, null)) .build(); VibratorInfo info = new MultiVibratorInfo(/* id= */ 1, @@ -191,13 +191,13 @@ public class MultiVibratorInfoTest { VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) .setQFactor(10f) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile( + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy( /* resonantFrequencyHz= */ 11, 10, 0.5f, null)) .build(); VibratorInfo secondInfo = new VibratorInfo.Builder(/* id= */ 2) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) .setQFactor(10f) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile( + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy( /* resonantFrequencyHz= */ 11, 5, 1, null)) .build(); @@ -207,20 +207,20 @@ public class MultiVibratorInfoTest { assertEquals(10f, info.getQFactor(), TEST_TOLERANCE); assertEquals(11f, info.getResonantFrequencyHz(), TEST_TOLERANCE); // No frequency range defined. - assertTrue(info.getFrequencyProfile().isEmpty()); + assertTrue(info.getFrequencyProfileLegacy().isEmpty()); assertEquals(false, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL)); } @Test - public void testGetFrequencyProfile_differentResonantFrequencyOrResolutions_returnsEmpty() { + public void testGetFrequencyProfileLegacy_differentResonantFreqOrResolutions_returnsEmpty() { VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(1, 1, 1, new float[] { 0, 1 })) .build(); VibratorInfo differentResonantFrequency = new VibratorInfo.Builder(/* id= */ 2) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(2, 1, 1, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(2, 1, 1, new float[] { 0, 1 })) .build(); VibratorInfo info = new MultiVibratorInfo(/* id= */ 1, @@ -230,7 +230,7 @@ public class MultiVibratorInfoTest { VibratorInfo differentFrequencyResolution = new VibratorInfo.Builder(/* id= */ 2) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 2, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(1, 1, 2, new float[] { 0, 1 })) .build(); info = new MultiVibratorInfo(/* id= */ 1, @@ -240,15 +240,15 @@ public class MultiVibratorInfoTest { } @Test - public void testGetFrequencyProfile_missingValues_returnsEmpty() { + public void testGetFrequencyProfileLegacy_missingValues_returnsEmpty() { VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(1, 1, 1, new float[] { 0, 1 })) .build(); VibratorInfo missingResonantFrequency = new VibratorInfo.Builder(/* id= */ 2) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(Float.NaN, 1, 1, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(Float.NaN, 1, 1, new float[] { 0, 1 })) .build(); @@ -259,7 +259,7 @@ public class MultiVibratorInfoTest { VibratorInfo missingMinFrequency = new VibratorInfo.Builder(/* id= */ 2) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, Float.NaN, 1, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(1, Float.NaN, 1, new float[] { 0, 1 })) .build(); info = new MultiVibratorInfo(/* id= */ 1, @@ -269,7 +269,7 @@ public class MultiVibratorInfoTest { VibratorInfo missingFrequencyResolution = new VibratorInfo.Builder(/* id= */ 2) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, Float.NaN, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(1, 1, Float.NaN, new float[] { 0, 1 })) .build(); info = new MultiVibratorInfo(/* id= */ 1, @@ -279,7 +279,7 @@ public class MultiVibratorInfoTest { VibratorInfo missingMaxAmplitudes = new VibratorInfo.Builder(/* id= */ 2) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1, null)) + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(1, 1, 1, null)) .build(); info = new MultiVibratorInfo(/* id= */ 1, new VibratorInfo[]{firstInfo, missingMaxAmplitudes}); @@ -288,20 +288,20 @@ public class MultiVibratorInfoTest { } @Test - public void testGetFrequencyProfile_unalignedMaxAmplitudes_returnsEmpty() { + public void testGetFrequencyProfileLegacy_unalignedMaxAmplitudes_returnsEmpty() { VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10, 0.5f, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(11, 10, 0.5f, new float[] { 0, 1, 1, 0 })) .build(); VibratorInfo unalignedMinFrequency = new VibratorInfo.Builder(/* id= */ 2) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.1f, 0.5f, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(11, 10.1f, 0.5f, new float[] { 0, 1, 1, 0 })) .build(); VibratorInfo thirdVibrator = new VibratorInfo.Builder(/* id= */ 2) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(11, 10.5f, 0.5f, new float[] { 0, 1, 1, 0 })) .build(); @@ -312,20 +312,20 @@ public class MultiVibratorInfoTest { } @Test - public void testGetFrequencyProfile_alignedProfiles_returnsIntersection() { + public void testGetFrequencyProfileLegacy_alignedProfiles_returnsIntersection() { VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10, 0.5f, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(11, 10, 0.5f, new float[] { 0.5f, 1, 1, 0.5f })) .build(); VibratorInfo secondInfo = new VibratorInfo.Builder(/* id= */ 2) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(11, 10.5f, 0.5f, new float[] { 1, 1, 1 })) .build(); VibratorInfo thirdVibrator = new VibratorInfo.Builder(/* id= */ 3) .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(11, 10.5f, 0.5f, new float[] { 0.8f, 1, 0.8f, 0.5f })) .build(); @@ -333,21 +333,23 @@ public class MultiVibratorInfoTest { new VibratorInfo[]{firstInfo, secondInfo, thirdVibrator}); assertEquals( - new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f, new float[] { 0.8f, 1, 0.5f }), - info.getFrequencyProfile()); + new VibratorInfo.FrequencyProfileLegacy(11, 10.5f, 0.5f, + new float[]{0.8f, 1, 0.5f}), + info.getFrequencyProfileLegacy()); assertEquals(true, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL)); // Third vibrator without frequency control capability. thirdVibrator = new VibratorInfo.Builder(/* id= */ 3) - .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f, + .setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy(11, 10.5f, 0.5f, new float[] { 0.8f, 1, 0.8f, 0.5f })) .build(); info = new MultiVibratorInfo(/* id= */ 1, new VibratorInfo[]{firstInfo, secondInfo, thirdVibrator}); assertEquals( - new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f, new float[] { 0.8f, 1, 0.5f }), - info.getFrequencyProfile()); + new VibratorInfo.FrequencyProfileLegacy(11, 10.5f, 0.5f, + new float[]{0.8f, 1, 0.5f}), + info.getFrequencyProfileLegacy()); assertEquals(false, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL)); } @@ -355,7 +357,7 @@ public class MultiVibratorInfoTest { * Asserts that the frequency profile is empty, and therefore frequency control isn't supported. */ private void assertEmptyFrequencyProfileAndControl(VibratorInfo info) { - assertTrue(info.getFrequencyProfile().isEmpty()); + assertTrue(info.getFrequencyProfileLegacy().isEmpty()); assertEquals(false, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL)); } } diff --git a/services/core/java/com/android/server/vibrator/ClippingAmplitudeAndFrequencyAdapter.java b/services/core/java/com/android/server/vibrator/ClippingAmplitudeAndFrequencyAdapter.java index 111e075a7374..245d9020d5a2 100644 --- a/services/core/java/com/android/server/vibrator/ClippingAmplitudeAndFrequencyAdapter.java +++ b/services/core/java/com/android/server/vibrator/ClippingAmplitudeAndFrequencyAdapter.java @@ -26,10 +26,10 @@ import java.util.List; /** * Adapter that clips frequency values to the supported range specified by - * {@link VibratorInfo.FrequencyProfile}, then clips amplitude values to the max supported one at + * {@link VibratorInfo.FrequencyProfileLegacy}, then clips amplitude values to the max supported one at * each frequency. * - *

    The {@link VibratorInfo.FrequencyProfile} is only applicable to PWLE compositions. This + *

    The {@link VibratorInfo.FrequencyProfileLegacy} is only applicable to PWLE compositions. This * adapter is only applied to {@link RampSegment} and all other segments will remain unchanged. */ final class ClippingAmplitudeAndFrequencyAdapter implements VibrationSegmentsAdapter { @@ -59,7 +59,7 @@ final class ClippingAmplitudeAndFrequencyAdapter implements VibrationSegmentsAda } private float clampFrequency(VibratorInfo info, float frequencyHz) { - Range frequencyRangeHz = info.getFrequencyProfile().getFrequencyRangeHz(); + Range frequencyRangeHz = info.getFrequencyProfileLegacy().getFrequencyRangeHz(); if (frequencyHz == 0 || frequencyRangeHz == null) { return Float.isNaN(info.getResonantFrequencyHz()) ? 0 : info.getResonantFrequencyHz(); } @@ -67,7 +67,7 @@ final class ClippingAmplitudeAndFrequencyAdapter implements VibrationSegmentsAda } private float clampAmplitude(VibratorInfo info, float frequencyHz, float amplitude) { - VibratorInfo.FrequencyProfile mapping = info.getFrequencyProfile(); + VibratorInfo.FrequencyProfileLegacy mapping = info.getFrequencyProfileLegacy(); if (mapping.isEmpty()) { // No frequency mapping was specified so leave amplitude unchanged. // The frequency will be clamped to the device's resonant frequency. diff --git a/services/core/jni/com_android_server_vibrator_VibratorController.cpp b/services/core/jni/com_android_server_vibrator_VibratorController.cpp index 39c0c3ef1847..bcd0b94b6877 100644 --- a/services/core/jni/com_android_server_vibrator_VibratorController.cpp +++ b/services/core/jni/com_android_server_vibrator_VibratorController.cpp @@ -41,8 +41,8 @@ namespace android { static JavaVM* sJvm = nullptr; static jmethodID sMethodIdOnComplete; -static jclass sFrequencyProfileClass; -static jmethodID sFrequencyProfileCtor; +static jclass sFrequencyProfileLegacyClass; +static jmethodID sFrequencyProfileLegacyCtor; static struct { jmethodID setCapabilities; jmethodID setSupportedEffects; @@ -53,7 +53,7 @@ static struct { jmethodID setPrimitiveDelayMax; jmethodID setCompositionSizeMax; jmethodID setQFactor; - jmethodID setFrequencyProfile; + jmethodID setFrequencyProfileLegacy; jmethodID setMaxEnvelopeEffectSize; jmethodID setMinEnvelopeEffectControlPointDurationMillis; jmethodID setMaxEnvelopeEffectControlPointDurationMillis; @@ -517,11 +517,12 @@ static jboolean vibratorGetInfo(JNIEnv* env, jclass /* clazz */, jlong ptr, env->SetFloatArrayRegion(maxAmplitudes, 0, amplitudes.size(), reinterpret_cast(amplitudes.data())); } - jobject frequencyProfile = - env->NewObject(sFrequencyProfileClass, sFrequencyProfileCtor, resonantFrequency, - minFrequency, frequencyResolution, maxAmplitudes); - env->CallObjectMethod(vibratorInfoBuilder, sVibratorInfoBuilderClassInfo.setFrequencyProfile, - frequencyProfile); + jobject frequencyProfileLegacy = + env->NewObject(sFrequencyProfileLegacyClass, sFrequencyProfileLegacyCtor, + resonantFrequency, minFrequency, frequencyResolution, maxAmplitudes); + env->CallObjectMethod(vibratorInfoBuilder, + sVibratorInfoBuilderClassInfo.setFrequencyProfileLegacy, + frequencyProfileLegacy); return info.shouldRetry() ? JNI_FALSE : JNI_TRUE; } @@ -566,9 +567,12 @@ int register_android_server_vibrator_VibratorController(JavaVM* jvm, JNIEnv* env sRampClassInfo.endFrequencyHz = GetFieldIDOrDie(env, rampClass, "mEndFrequencyHz", "F"); sRampClassInfo.duration = GetFieldIDOrDie(env, rampClass, "mDuration", "I"); - jclass frequencyProfileClass = FindClassOrDie(env, "android/os/VibratorInfo$FrequencyProfile"); - sFrequencyProfileClass = static_cast(env->NewGlobalRef(frequencyProfileClass)); - sFrequencyProfileCtor = GetMethodIDOrDie(env, sFrequencyProfileClass, "", "(FFF[F)V"); + jclass frequencyProfileLegacyClass = + FindClassOrDie(env, "android/os/VibratorInfo$FrequencyProfileLegacy"); + sFrequencyProfileLegacyClass = + static_cast(env->NewGlobalRef(frequencyProfileLegacyClass)); + sFrequencyProfileLegacyCtor = + GetMethodIDOrDie(env, sFrequencyProfileLegacyClass, "", "(FFF[F)V"); jclass vibratorInfoBuilderClass = FindClassOrDie(env, "android/os/VibratorInfo$Builder"); sVibratorInfoBuilderClassInfo.setCapabilities = @@ -598,9 +602,9 @@ int register_android_server_vibrator_VibratorController(JavaVM* jvm, JNIEnv* env sVibratorInfoBuilderClassInfo.setQFactor = GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setQFactor", "(F)Landroid/os/VibratorInfo$Builder;"); - sVibratorInfoBuilderClassInfo.setFrequencyProfile = - GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setFrequencyProfile", - "(Landroid/os/VibratorInfo$FrequencyProfile;)" + sVibratorInfoBuilderClassInfo.setFrequencyProfileLegacy = + GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setFrequencyProfileLegacy", + "(Landroid/os/VibratorInfo$FrequencyProfileLegacy;)" "Landroid/os/VibratorInfo$Builder;"); sVibratorInfoBuilderClassInfo.setMaxEnvelopeEffectSize = GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setMaxEnvelopeEffectSize", diff --git a/services/tests/vibrator/src/com/android/server/vibrator/RampToStepAdapterTest.java b/services/tests/vibrator/src/com/android/server/vibrator/RampToStepAdapterTest.java index 867c061151b4..81036824f92b 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/RampToStepAdapterTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/RampToStepAdapterTest.java @@ -39,8 +39,8 @@ public class RampToStepAdapterTest { private static final int TEST_STEP_DURATION = 5; private static final float[] TEST_AMPLITUDE_MAP = new float[]{ /* 50Hz= */ 0.1f, 0.2f, 0.4f, 0.8f, /* 150Hz= */ 1f, 0.9f, /* 200Hz= */ 0.8f}; - private static final VibratorInfo.FrequencyProfile TEST_FREQUENCY_PROFILE = - new VibratorInfo.FrequencyProfile( + private static final VibratorInfo.FrequencyProfileLegacy TEST_FREQUENCY_PROFILE = + new VibratorInfo.FrequencyProfileLegacy( /* resonantFrequencyHz= */ 150f, /* minFrequencyHz= */ 50f, /* frequencyResolutionHz= */ 25f, TEST_AMPLITUDE_MAP); private static final VibratorInfo EMPTY_VIBRATOR_INFO = createVibratorInfo(); @@ -121,7 +121,7 @@ public class RampToStepAdapterTest { private static VibratorInfo createVibratorInfo(int... capabilities) { return new VibratorInfo.Builder(0) .setCapabilities(IntStream.of(capabilities).reduce((a, b) -> a | b).orElse(0)) - .setFrequencyProfile(TEST_FREQUENCY_PROFILE) + .setFrequencyProfileLegacy(TEST_FREQUENCY_PROFILE) .build(); } } diff --git a/services/tests/vibrator/src/com/android/server/vibrator/SplitSegmentsAdapterTest.java b/services/tests/vibrator/src/com/android/server/vibrator/SplitSegmentsAdapterTest.java index 6630ccad6189..f2c3726375e6 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/SplitSegmentsAdapterTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/SplitSegmentsAdapterTest.java @@ -41,8 +41,8 @@ public class SplitSegmentsAdapterTest { private static final float[] TEST_AMPLITUDE_MAP = new float[]{ /* 50Hz= */ 0.1f, 0.2f, 0.4f, 0.8f, /* 150Hz= */ 1f, 0.9f, /* 200Hz= */ 0.8f}; - private static final VibratorInfo.FrequencyProfile TEST_FREQUENCY_PROFILE = - new VibratorInfo.FrequencyProfile( + private static final VibratorInfo.FrequencyProfileLegacy TEST_FREQUENCY_PROFILE = + new VibratorInfo.FrequencyProfileLegacy( /* resonantFrequencyHz= */ 150f, /* minFrequencyHz= */ 50f, /* frequencyResolutionHz= */ 25f, TEST_AMPLITUDE_MAP); @@ -125,7 +125,7 @@ public class SplitSegmentsAdapterTest { VibratorInfo vibratorInfo = new VibratorInfo.Builder(0) .setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS) .setPwlePrimitiveDurationMax(10) - .setFrequencyProfile(TEST_FREQUENCY_PROFILE) + .setFrequencyProfileLegacy(TEST_FREQUENCY_PROFILE) .build(); // Update repeat index to skip the ramp splits. @@ -137,7 +137,7 @@ public class SplitSegmentsAdapterTest { private static VibratorInfo createVibratorInfo(int... capabilities) { return new VibratorInfo.Builder(0) .setCapabilities(IntStream.of(capabilities).reduce((a, b) -> a | b).orElse(0)) - .setFrequencyProfile(TEST_FREQUENCY_PROFILE) + .setFrequencyProfileLegacy(TEST_FREQUENCY_PROFILE) .setPwlePrimitiveDurationMax(PWLE_COMPOSITION_PRIMITIVE_DURATION_MAX) .build(); } diff --git a/services/tests/vibrator/src/com/android/server/vibrator/StepToRampAdapterTest.java b/services/tests/vibrator/src/com/android/server/vibrator/StepToRampAdapterTest.java index 82deff011e82..d501dba13ac3 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/StepToRampAdapterTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/StepToRampAdapterTest.java @@ -38,8 +38,8 @@ import java.util.stream.IntStream; public class StepToRampAdapterTest { private static final float[] TEST_AMPLITUDE_MAP = new float[]{ /* 50Hz= */ 0.1f, 0.2f, 0.4f, 0.8f, /* 150Hz= */ 1f, 0.9f, /* 200Hz= */ 0.8f}; - private static final VibratorInfo.FrequencyProfile TEST_FREQUENCY_PROFILE = - new VibratorInfo.FrequencyProfile( + private static final VibratorInfo.FrequencyProfileLegacy TEST_FREQUENCY_PROFILE = + new VibratorInfo.FrequencyProfileLegacy( /* resonantFrequencyHz= */ 150f, /* minFrequencyHz= */ 50f, /* frequencyResolutionHz= */ 25f, TEST_AMPLITUDE_MAP); private static final VibratorInfo EMPTY_VIBRATOR_INFO = createVibratorInfo(); @@ -153,7 +153,7 @@ public class StepToRampAdapterTest { private static VibratorInfo createVibratorInfo(int... capabilities) { return new VibratorInfo.Builder(0) .setCapabilities(IntStream.of(capabilities).reduce((a, b) -> a | b).orElse(0)) - .setFrequencyProfile(TEST_FREQUENCY_PROFILE) + .setFrequencyProfileLegacy(TEST_FREQUENCY_PROFILE) .build(); } } diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorControllerTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorControllerTest.java index e8ca8bf8ec63..81793694a110 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorControllerTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorControllerTest.java @@ -334,13 +334,14 @@ public class VibratorControllerTest { } private void mockVibratorCapabilities(int capabilities) { - VibratorInfo.FrequencyProfile frequencyProfile = new VibratorInfo.FrequencyProfile( + VibratorInfo.FrequencyProfileLegacy + frequencyProfile = new VibratorInfo.FrequencyProfileLegacy( Float.NaN, Float.NaN, Float.NaN, null); when(mNativeWrapperMock.getInfo(any(VibratorInfo.Builder.class))) .then(invocation -> { ((VibratorInfo.Builder) invocation.getArgument(0)) .setCapabilities(capabilities) - .setFrequencyProfile(frequencyProfile); + .setFrequencyProfileLegacy(frequencyProfile); return true; }); } diff --git a/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorControllerProvider.java b/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorControllerProvider.java index 946e1eaa5666..f96177d98052 100644 --- a/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorControllerProvider.java +++ b/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorControllerProvider.java @@ -218,7 +218,7 @@ public final class FakeVibratorControllerProvider { } infoBuilder.setCompositionSizeMax(mCompositionSizeMax); infoBuilder.setQFactor(mQFactor); - infoBuilder.setFrequencyProfile(new VibratorInfo.FrequencyProfile( + infoBuilder.setFrequencyProfileLegacy(new VibratorInfo.FrequencyProfileLegacy( mResonantFrequency, mMinFrequency, mFrequencyResolution, mMaxAmplitudes)); infoBuilder.setMaxEnvelopeEffectSize(mMaxEnvelopeEffectSize); infoBuilder.setMinEnvelopeEffectControlPointDurationMillis( -- GitLab From b417208cecdf01f7ae7b8ca63f2da6a917202ea5 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Sun, 6 Oct 2024 07:18:13 +0000 Subject: [PATCH 089/447] Only set SCHED_RESET_ON_FORK flag if the thread is using the default scheduling policy. Keep nice and policy same as well to reduce the overhead in syscall. Bug: 370988407 Change-Id: I4d9ef914905da6807339cf2c55650b8188787b43 Test: Build Flag: com.android.server.power.hint.reset_on_fork_enabled --- .../server/power/hint/HintManagerService.java | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java index c969eff32f8e..2c0ce252df18 100644 --- a/services/core/java/com/android/server/power/hint/HintManagerService.java +++ b/services/core/java/com/android/server/power/hint/HintManagerService.java @@ -1059,8 +1059,22 @@ public final class HintManagerService extends SystemService { throw new SecurityException(errMsg); } if (resetOnForkEnabled()){ - for (int tid : tids) { - Process.setThreadScheduler(tid, Process.SCHED_RESET_ON_FORK, 0); + try { + for (int tid : tids) { + int policy = Process.getThreadScheduler(tid); + // If the thread is not using the default scheduling policy (SCHED_OTHER), + // we don't change it. + if (policy != Process.SCHED_OTHER) { + continue; + } + // set the SCHED_RESET_ON_FORK flag. + int prio = Process.getThreadPriority(tid); + Process.setThreadScheduler(tid, Process.SCHED_OTHER | Process.SCHED_RESET_ON_FORK, 0); + Process.setThreadPriority(tid, prio); + } + } catch (Exception e) { + Slog.e(TAG, "Failed to set SCHED_RESET_ON_FORK for tids " + + Arrays.toString(tids), e); } } @@ -1454,8 +1468,22 @@ public final class HintManagerService extends SystemService { throw new SecurityException(errMsg); } if (resetOnForkEnabled()){ - for (int tid : tids) { - Process.setThreadScheduler(tid, Process.SCHED_RESET_ON_FORK, 0); + try { + for (int tid : tids) { + int policy = Process.getThreadScheduler(tid); + // If the thread is not using the default scheduling policy (SCHED_OTHER), + // we don't change it. + if (policy != Process.SCHED_OTHER) { + continue; + } + // set the SCHED_RESET_ON_FORK flag. + int prio = Process.getThreadPriority(tid); + Process.setThreadScheduler(tid, Process.SCHED_OTHER | Process.SCHED_RESET_ON_FORK, 0); + Process.setThreadPriority(tid, prio); + } + } catch (Exception e) { + Slog.e(TAG, "Failed to set SCHED_RESET_ON_FORK for tids " + + Arrays.toString(tids), e); } } if (powerhintThreadCleanup()) { -- GitLab From e6aa8aae90400e706bf221bc9566387a82a48bfa Mon Sep 17 00:00:00 2001 From: Vladimir Komsiyski Date: Sun, 6 Oct 2024 16:55:30 +0000 Subject: [PATCH 090/447] Drop VDM permissions from Shell Instead, rely on the relevant role to get these permissions. Replace FakeAssociationRule with VirtualDeviceRule Fix: 370657093 Fix: 318641591 Test: presubmit Test: atest VirtualDeviceManagerServiceTest Test: atest AppOpsActiveWatcherTest AppOpsDeviceAwareServiceTest AppOpsStartedWatcherTest AppOpsNotedWatcherTest Flag: EXEMPT test improvement Change-Id: I65826943040c8650adbfd1ac002094e42bacd1ac --- packages/Shell/AndroidManifest.xml | 6 -- .../tests/servicestests/AndroidManifest.xml | 1 + .../server/appop/AppOpsActiveWatcherTest.java | 1 - .../appop/AppOpsDeviceAwareServiceTest.java | 1 - .../server/appop/AppOpsNotedWatcherTest.java | 25 ++---- .../appop/AppOpsStartedWatcherTest.java | 26 ++---- .../VirtualDeviceManagerServiceTest.java | 81 ++++++++----------- .../MediaProjectionManagerServiceTest.java | 9 ++- 8 files changed, 53 insertions(+), 97 deletions(-) diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 456fedf912ff..408ed1e861c3 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -743,12 +743,6 @@ - - - - - - diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml index 2724149d859f..c645c0852f1b 100644 --- a/services/tests/servicestests/AndroidManifest.xml +++ b/services/tests/servicestests/AndroidManifest.xml @@ -113,6 +113,7 @@ + diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java index c970a3e34d12..840e5c58078b 100644 --- a/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java +++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java @@ -65,7 +65,6 @@ public class AppOpsActiveWatcherTest { VirtualDeviceRule.withAdditionalPermissions( Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, - Manifest.permission.CREATE_VIRTUAL_DEVICE, Manifest.permission.GET_APP_OPS_STATS ); private static final long NOTIFICATION_TIMEOUT_MILLIS = 5000; diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsDeviceAwareServiceTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsDeviceAwareServiceTest.java index 7f2327aa4f24..e3eca6d5fd83 100644 --- a/services/tests/servicestests/src/com/android/server/appop/AppOpsDeviceAwareServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsDeviceAwareServiceTest.java @@ -58,7 +58,6 @@ public class AppOpsDeviceAwareServiceTest { VirtualDeviceRule.withAdditionalPermissions( Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, - Manifest.permission.CREATE_VIRTUAL_DEVICE, Manifest.permission.GET_APP_OPS_STATS); private static final String ATTRIBUTION_TAG_1 = "attributionTag1"; diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java index 1abd4eb6157f..b0846f62628c 100644 --- a/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java +++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java @@ -22,16 +22,14 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; -import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; import android.app.AppOpsManager; import android.app.AppOpsManager.OnOpNotedListener; import android.companion.virtual.VirtualDeviceManager; -import android.companion.virtual.VirtualDeviceParams; import android.content.AttributionSource; import android.content.Context; import android.os.Process; -import android.virtualdevice.cts.common.FakeAssociationRule; +import android.virtualdevice.cts.common.VirtualDeviceRule; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -42,8 +40,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; -import java.util.concurrent.atomic.AtomicInteger; - /** * Tests watching noted ops. */ @@ -51,7 +47,7 @@ import java.util.concurrent.atomic.AtomicInteger; @RunWith(AndroidJUnit4.class) public class AppOpsNotedWatcherTest { @Rule - public FakeAssociationRule mFakeAssociationRule = new FakeAssociationRule(); + public VirtualDeviceRule mVirtualDeviceRule = VirtualDeviceRule.createDefault(); private static final long NOTIFICATION_TIMEOUT_MILLIS = 5000; @Test @@ -119,19 +115,12 @@ public class AppOpsNotedWatcherTest { public void testWatchNotedOpsForExternalDevice() { final AppOpsManager.OnOpNotedListener listener = mock( AppOpsManager.OnOpNotedListener.class); - final VirtualDeviceManager virtualDeviceManager = getContext().getSystemService( - VirtualDeviceManager.class); - AtomicInteger virtualDeviceId = new AtomicInteger(); - runWithShellPermissionIdentity(() -> { - final VirtualDeviceManager.VirtualDevice virtualDevice = - virtualDeviceManager.createVirtualDevice( - mFakeAssociationRule.getAssociationInfo().getId(), - new VirtualDeviceParams.Builder().setName("virtual_device").build()); - virtualDeviceId.set(virtualDevice.getDeviceId()); - }); + final VirtualDeviceManager.VirtualDevice virtualDevice = + mVirtualDeviceRule.createManagedVirtualDevice(); + final int virtualDeviceId = virtualDevice.getDeviceId(); AttributionSource attributionSource = new AttributionSource(Process.myUid(), getContext().getOpPackageName(), getContext().getAttributionTag(), - virtualDeviceId.get()); + virtualDeviceId); final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); appOpsManager.startWatchingNoted(new int[]{AppOpsManager.OP_FINE_LOCATION, @@ -142,7 +131,7 @@ public class AppOpsNotedWatcherTest { verify(listener, timeout(NOTIFICATION_TIMEOUT_MILLIS) .times(1)).onOpNoted(eq(AppOpsManager.OPSTR_FINE_LOCATION), eq(Process.myUid()), eq(getContext().getOpPackageName()), - eq(getContext().getAttributionTag()), eq(virtualDeviceId.get()), + eq(getContext().getAttributionTag()), eq(virtualDeviceId), eq(AppOpsManager.OP_FLAG_SELF), eq(AppOpsManager.MODE_ALLOWED)); appOpsManager.finishOp(getContext().getAttributionSource().getToken(), diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsStartedWatcherTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsStartedWatcherTest.java index 8a6ba4d484f7..d46fb90f40d6 100644 --- a/services/tests/servicestests/src/com/android/server/appop/AppOpsStartedWatcherTest.java +++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsStartedWatcherTest.java @@ -16,8 +16,6 @@ package com.android.server.appop; -import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; - import static org.mockito.Mockito.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; @@ -28,11 +26,10 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import android.app.AppOpsManager; import android.app.AppOpsManager.OnOpStartedListener; import android.companion.virtual.VirtualDeviceManager; -import android.companion.virtual.VirtualDeviceParams; import android.content.AttributionSource; import android.content.Context; import android.os.Process; -import android.virtualdevice.cts.common.FakeAssociationRule; +import android.virtualdevice.cts.common.VirtualDeviceRule; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -43,15 +40,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; -import java.util.concurrent.atomic.AtomicInteger; - /** Tests watching started ops. */ @SmallTest @RunWith(AndroidJUnit4.class) public class AppOpsStartedWatcherTest { @Rule - public FakeAssociationRule mFakeAssociationRule = new FakeAssociationRule(); + public VirtualDeviceRule mVirtualDeviceRule = VirtualDeviceRule.createDefault(); private static final long NOTIFICATION_TIMEOUT_MILLIS = 5000; @Test @@ -124,20 +119,13 @@ public class AppOpsStartedWatcherTest { @Test public void testWatchStartedOpsForExternalDevice() { - final VirtualDeviceManager virtualDeviceManager = getContext().getSystemService( - VirtualDeviceManager.class); - AtomicInteger virtualDeviceId = new AtomicInteger(); - runWithShellPermissionIdentity(() -> { - final VirtualDeviceManager.VirtualDevice virtualDevice = - virtualDeviceManager.createVirtualDevice( - mFakeAssociationRule.getAssociationInfo().getId(), - new VirtualDeviceParams.Builder().setName("virtual_device").build()); - virtualDeviceId.set(virtualDevice.getDeviceId()); - }); + final VirtualDeviceManager.VirtualDevice virtualDevice = + mVirtualDeviceRule.createManagedVirtualDevice(); + final int virtualDeviceId = virtualDevice.getDeviceId(); final OnOpStartedListener listener = mock(OnOpStartedListener.class); AttributionSource attributionSource = new AttributionSource(Process.myUid(), getContext().getOpPackageName(), getContext().getAttributionTag(), - virtualDeviceId.get()); + virtualDeviceId); final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); appOpsManager.startWatchingStarted(new int[]{AppOpsManager.OP_FINE_LOCATION, @@ -150,7 +138,7 @@ public class AppOpsStartedWatcherTest { verify(listener, timeout(NOTIFICATION_TIMEOUT_MILLIS) .times(1)).onOpStarted(eq(AppOpsManager.OP_FINE_LOCATION), eq(Process.myUid()), eq(getContext().getOpPackageName()), - eq(getContext().getAttributionTag()), eq(virtualDeviceId.get()), + eq(getContext().getAttributionTag()), eq(virtualDeviceId), eq(AppOpsManager.OP_FLAG_SELF), eq(AppOpsManager.MODE_ALLOWED), eq(OnOpStartedListener.START_TYPE_STARTED), eq(AppOpsManager.ATTRIBUTION_FLAGS_NONE), diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java index 4d067f6bfc62..e16bc05d24f5 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java @@ -50,7 +50,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.testng.Assert.assertThrows; -import android.Manifest; import android.app.WindowConfiguration; import android.app.admin.DevicePolicyManager; import android.companion.AssociationInfo; @@ -113,10 +112,11 @@ import android.view.Display; import android.view.DisplayInfo; import android.view.KeyEvent; import android.view.WindowManager; +import android.virtualdevice.cts.common.VirtualDeviceRule; import androidx.test.platform.app.InstrumentationRegistry; -import com.android.compatibility.common.util.AdoptShellPermissionsRule; +import com.android.compatibility.common.util.SystemUtil; import com.android.internal.app.BlockedAppStreamingActivity; import com.android.internal.os.BackgroundThread; import com.android.server.LocalServices; @@ -223,9 +223,7 @@ public class VirtualDeviceManagerServiceTest { public SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Rule - public AdoptShellPermissionsRule mAdoptShellPermissionsRule = new AdoptShellPermissionsRule( - InstrumentationRegistry.getInstrumentation().getUiAutomation(), - Manifest.permission.CREATE_VIRTUAL_DEVICE); + public VirtualDeviceRule mVirtualDeviceRule = VirtualDeviceRule.createDefault(); private Context mContext; private InputManagerMockHelper mInputManagerMockHelper; @@ -1069,64 +1067,65 @@ public class VirtualDeviceManagerServiceTest { @Test public void createVirtualDpad_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { - assertThrows(SecurityException.class, - () -> mDeviceImpl.createVirtualDpad(DPAD_CONFIG, BINDER)); - } + // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. + SystemUtil.runWithShellPermissionIdentity(() -> + assertThrows(SecurityException.class, + () -> mDeviceImpl.createVirtualDpad(DPAD_CONFIG, BINDER))); } @Test public void createVirtualKeyboard_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { - assertThrows(SecurityException.class, - () -> mDeviceImpl.createVirtualKeyboard(KEYBOARD_CONFIG, BINDER)); - } + // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. + SystemUtil.runWithShellPermissionIdentity(() -> + assertThrows(SecurityException.class, + () -> mDeviceImpl.createVirtualKeyboard(KEYBOARD_CONFIG, BINDER))); } @Test public void createVirtualMouse_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { - assertThrows(SecurityException.class, - () -> mDeviceImpl.createVirtualMouse(MOUSE_CONFIG, BINDER)); - } + // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. + SystemUtil.runWithShellPermissionIdentity(() -> + assertThrows(SecurityException.class, + () -> mDeviceImpl.createVirtualMouse(MOUSE_CONFIG, BINDER))); } @Test public void createVirtualTouchscreen_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { - assertThrows(SecurityException.class, - () -> mDeviceImpl.createVirtualTouchscreen(TOUCHSCREEN_CONFIG, BINDER)); - } + // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. + SystemUtil.runWithShellPermissionIdentity(() -> + assertThrows(SecurityException.class, + () -> mDeviceImpl.createVirtualTouchscreen(TOUCHSCREEN_CONFIG, BINDER))); } @Test public void createVirtualNavigationTouchpad_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { - assertThrows(SecurityException.class, - () -> mDeviceImpl.createVirtualNavigationTouchpad(NAVIGATION_TOUCHPAD_CONFIG, - BINDER)); - } + // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. + SystemUtil.runWithShellPermissionIdentity(() -> + assertThrows(SecurityException.class, + () -> mDeviceImpl.createVirtualNavigationTouchpad( + NAVIGATION_TOUCHPAD_CONFIG, + BINDER))); } @Test public void onAudioSessionStarting_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { - assertThrows(SecurityException.class, - () -> mDeviceImpl.onAudioSessionStarting( - DISPLAY_ID_1, mRoutingCallback, mConfigChangedCallback)); - } + // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. + SystemUtil.runWithShellPermissionIdentity(() -> + assertThrows(SecurityException.class, + () -> mDeviceImpl.onAudioSessionStarting( + DISPLAY_ID_1, mRoutingCallback, mConfigChangedCallback))); } @Test public void onAudioSessionEnded_noPermission_failsSecurityException() { - try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { - assertThrows(SecurityException.class, () -> mDeviceImpl.onAudioSessionEnded()); - } + // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. + SystemUtil.runWithShellPermissionIdentity(() -> + assertThrows(SecurityException.class, () -> mDeviceImpl.onAudioSessionEnded())); } @Test @@ -2002,18 +2001,4 @@ public class VirtualDeviceManagerServiceTest { /* notifyOnDeviceNearby= */ false, /* revoked= */ false, /* pending= */ false, /* timeApprovedMs= */0, /* lastTimeConnectedMs= */0, /* systemDataSyncFlags= */ -1); } - - /** Helper class to drop permissions temporarily and restore them at the end of a test. */ - static final class DropShellPermissionsTemporarily implements AutoCloseable { - DropShellPermissionsTemporarily() { - InstrumentationRegistry.getInstrumentation().getUiAutomation() - .dropShellPermissionIdentity(); - } - - @Override - public void close() { - InstrumentationRegistry.getInstrumentation().getUiAutomation() - .adoptShellPermissionIdentity(); - } - } } diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java index 425bb158f997..7e22d74c64e1 100644 --- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java @@ -1256,7 +1256,8 @@ public class MediaProjectionManagerServiceTest { Manifest.permission.BYPASS_ROLE_QUALIFICATION); roleManager.setBypassingRoleQualification(true); - roleManager.addRoleHolderAsUser(role, packageName, /* flags = */ 0, user, + roleManager.addRoleHolderAsUser(role, packageName, + /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, mContext.getMainExecutor(), success -> { if (success) { latch.countDown(); @@ -1271,9 +1272,9 @@ public class MediaProjectionManagerServiceTest { } catch (InterruptedException e) { throw new RuntimeException(e); } finally { - roleManager.removeRoleHolderAsUser(role, packageName, 0, user, - mContext.getMainExecutor(), (aBool) -> { - }); + roleManager.removeRoleHolderAsUser(role, packageName, + /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, + mContext.getMainExecutor(), (aBool) -> {}); roleManager.setBypassingRoleQualification(false); instrumentation.getUiAutomation() .dropShellPermissionIdentity(); -- GitLab From f949111353c1762761de735b22885a771e036614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cosmin=20B=C4=83ie=C8=99?= Date: Tue, 1 Oct 2024 16:26:24 +0200 Subject: [PATCH 091/447] Move IME MenuItem list creation in Menu Controller This moves the mapping of ImeSubtypeListItem to MenuItem to Menu Controller, containing the menu item type to this scope. Additionally follows up with some cleaning in the menu controller by extracting updateLanguageSettingsButton as a separate method. Flag: EXEMPT refactor Bug: 369120217 Test: atest testInputMethodPickerShownItems testInputMethodPickerSwitchIme testInputMethodPickerOpenLanguageSettings testInputMethodPickerNoLanguageSettingsWhenDeviceNotProvisioned Change-Id: Icb3fa967ebddbbb02c155f26ccd2f026f97e2cde --- .../layout/input_method_switch_dialog_new.xml | 3 +- .../InputMethodManagerService.java | 83 ++-------- .../InputMethodMenuControllerNew.java | 148 +++++++++++++----- 3 files changed, 124 insertions(+), 110 deletions(-) diff --git a/core/res/res/layout/input_method_switch_dialog_new.xml b/core/res/res/layout/input_method_switch_dialog_new.xml index 058fe3fe3076..cb074f98fec6 100644 --- a/core/res/res/layout/input_method_switch_dialog_new.xml +++ b/core/res/res/layout/input_method_switch_dialog_new.xml @@ -74,8 +74,7 @@ android:text="@string/input_method_switcher_settings_button" android:fontFamily="google-sans-text" android:textAppearance="?attr/textAppearance" - android:contentDescription="@string/input_method_language_settings" - android:visibility="gone"/> + android:contentDescription="@string/input_method_language_settings"/> diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index f0fb33eaaee7..d7b0019da47f 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -185,7 +185,6 @@ import com.android.server.SystemService; import com.android.server.companion.virtual.VirtualDeviceManagerInternal; import com.android.server.input.InputManagerInternal; import com.android.server.inputmethod.InputMethodManagerInternal.InputMethodListListener; -import com.android.server.inputmethod.InputMethodMenuControllerNew.MenuItem; import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem; import com.android.server.pm.UserManagerInternal; import com.android.server.statusbar.StatusBarManagerInternal; @@ -4063,65 +4062,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } } - /** - * Gets the list of Input Method Switcher Menu items and the index of the selected item. - * - * @param items the list of input method and subtype items. - * @param selectedImeId the ID of the selected input method. - * @param selectedSubtypeIndex the index of the selected subtype in the input method's array of - * subtypes, or {@link InputMethodUtils#NOT_A_SUBTYPE_INDEX} if no - * subtype is selected. - * @param userId the ID of the user for which to get the menu items. - * @return the list of menu items, and the index of the selected item, - * or {@code -1} if no item is selected. - */ - @GuardedBy("ImfLock.class") - @NonNull - private Pair, Integer> getInputMethodPickerItems( - @NonNull List items, @Nullable String selectedImeId, - int selectedSubtypeIndex, @UserIdInt int userId) { - final var bindingController = getInputMethodBindingController(userId); - final var settings = InputMethodSettingsRepository.get(userId); - - if (selectedSubtypeIndex == NOT_A_SUBTYPE_INDEX) { - // TODO(b/351124299): Check if this fallback logic is still necessary. - final var curSubtype = bindingController.getCurrentInputMethodSubtype(); - if (curSubtype != null) { - final var curMethodId = bindingController.getSelectedMethodId(); - final var curImi = settings.getMethodMap().get(curMethodId); - selectedSubtypeIndex = SubtypeUtils.getSubtypeIndexFromHashCode( - curImi, curSubtype.hashCode()); - } - } - - // No item is selected by default. When we have a list of explicitly enabled - // subtypes, the implicit subtype is no longer listed. If the implicit one - // is still selected, no items will be shown as selected. - int selectedIndex = -1; - String prevImeId = null; - final var menuItems = new ArrayList(); - for (int i = 0; i < items.size(); i++) { - final var item = items.get(i); - final var imeId = item.mImi.getId(); - if (imeId.equals(selectedImeId)) { - final int subtypeIndex = item.mSubtypeIndex; - // Check if this is the selected IME-subtype pair. - if ((subtypeIndex == 0 && selectedSubtypeIndex == NOT_A_SUBTYPE_INDEX) - || subtypeIndex == NOT_A_SUBTYPE_INDEX - || subtypeIndex == selectedSubtypeIndex) { - selectedIndex = i; - } - } - final boolean hasHeader = !imeId.equals(prevImeId); - final boolean hasDivider = hasHeader && prevImeId != null; - prevImeId = imeId; - menuItems.add(new MenuItem(item.mImeName, item.mSubtypeName, item.mImi, - item.mSubtypeIndex, hasHeader, hasDivider)); - } - - return new Pair<>(menuItems, selectedIndex); - } - @IInputMethodManagerImpl.PermissionVerified(allOf = { Manifest.permission.INTERACT_ACROSS_USERS_FULL, Manifest.permission.WRITE_SECURE_SETTINGS}) @@ -4958,18 +4898,21 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. + " preferredInputMethodSubtypeIndex=" + lastInputMethodSubtypeIndex); } - final var itemsAndIndex = getInputMethodPickerItems(imList, - lastInputMethodId, lastInputMethodSubtypeIndex, userId); - final var menuItems = itemsAndIndex.first; - final int selectedIndex = itemsAndIndex.second; - - if (selectedIndex == -1) { - Slog.w(TAG, "Switching menu shown with no item selected" - + ", IME id: " + lastInputMethodId - + ", subtype index: " + lastInputMethodSubtypeIndex); + int selectedSubtypeIndex = lastInputMethodSubtypeIndex; + if (selectedSubtypeIndex == NOT_A_SUBTYPE_INDEX) { + // TODO(b/351124299): Check if this fallback logic is still necessary. + final var bindingController = getInputMethodBindingController(userId); + final var curSubtype = bindingController.getCurrentInputMethodSubtype(); + if (curSubtype != null) { + final var curMethodId = bindingController.getSelectedMethodId(); + final var curImi = settings.getMethodMap().get(curMethodId); + selectedSubtypeIndex = SubtypeUtils.getSubtypeIndexFromHashCode( + curImi, curSubtype.hashCode()); + } } - mMenuControllerNew.show(menuItems, selectedIndex, displayId, userId); + mMenuControllerNew.show(imList, lastInputMethodId, selectedSubtypeIndex, displayId, + userId); } else { mMenuController.showInputMethodMenuLocked(showAuxSubtypes, displayId, lastInputMethodId, lastInputMethodSubtypeIndex, imList, userId); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java index cf2cdc1500f8..ce3a8579d107 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java @@ -35,6 +35,7 @@ import android.content.Intent; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; +import android.util.Pair; import android.util.Printer; import android.util.Slog; import android.view.Gravity; @@ -49,7 +50,9 @@ import android.widget.ImageView; import android.widget.TextView; import com.android.internal.widget.RecyclerView; +import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem; +import java.util.ArrayList; import java.util.List; /** @@ -80,18 +83,29 @@ final class InputMethodMenuControllerNew { /** * Shows the Input Method Switcher Menu, with a list of IMEs and their subtypes. * - * @param items the list of menu items. - * @param selectedIndex the index of the menu item that is selected. - * If no other IMEs are enabled, this index will be out of reach. - * @param displayId the ID of the display where the menu was requested. - * @param userId the ID of the user that requested the menu. + * @param items the list of input method and subtype items. + * @param selectedImeId the ID of the selected input method. + * @param selectedSubtypeIndex the index of the selected subtype in the input method's array of + * subtypes, or {@link InputMethodUtils#NOT_A_SUBTYPE_INDEX} if no + * subtype is selected. + * @param displayId the ID of the display where the menu was requested. + * @param userId the ID of the user that requested the menu. */ @RequiresPermission(allOf = {INTERACT_ACROSS_USERS, HIDE_OVERLAY_WINDOWS}) - void show(@NonNull List items, int selectedIndex, int displayId, - @UserIdInt int userId) { + void show(@NonNull List items, @Nullable String selectedImeId, + int selectedSubtypeIndex, int displayId, @UserIdInt int userId) { // Hide the menu in case it was already showing. hide(displayId, userId); + final var itemsAndIndex = toMenuItems(items, selectedImeId, selectedSubtypeIndex); + final var menuItems = itemsAndIndex.first; + final int selectedIndex = itemsAndIndex.second; + + if (selectedIndex == -1) { + Slog.w(TAG, "Switching menu shown with no item selected, IME id: " + selectedImeId + + ", subtype index: " + selectedSubtypeIndex); + } + final Context dialogWindowContext = mDialogWindowContext.get(displayId); final var builder = new AlertDialog.Builder(dialogWindowContext, com.android.internal.R.style.Theme_DeviceDefault_InputMethodSwitcherDialog); @@ -106,50 +120,26 @@ final class InputMethodMenuControllerNew { final DialogInterface.OnClickListener onClickListener = (dialog, which) -> { if (which != selectedIndex) { - final var item = items.get(which); + final var item = menuItems.get(which); InputMethodManagerInternal.get() .switchToInputMethod(item.mImi.getId(), item.mSubtypeIndex, userId); } hide(displayId, userId); }; - final var selectedImi = selectedIndex >= 0 ? items.get(selectedIndex).mImi : null; - final var languageSettingsIntent = selectedImi != null - ? selectedImi.createImeLanguageSettingsActivityIntent() : null; - final boolean isDeviceProvisioned = Settings.Global.getInt( - dialogWindowContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, - 0) != 0; - final boolean hasLanguageSettingsButton = languageSettingsIntent != null - && isDeviceProvisioned; - if (hasLanguageSettingsButton) { - final View buttonBar = contentView - .requireViewById(com.android.internal.R.id.button_bar); - buttonBar.setVisibility(View.VISIBLE); - - languageSettingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - final Button languageSettingsButton = contentView - .requireViewById(com.android.internal.R.id.button1); - languageSettingsButton.setVisibility(View.VISIBLE); - languageSettingsButton.setOnClickListener(v -> { - v.getContext().startActivityAsUser(languageSettingsIntent, UserHandle.of(userId)); - hide(displayId, userId); - }); - } - // Create the current IME subtypes list. final RecyclerView recyclerView = contentView .requireViewById(com.android.internal.R.id.list); - recyclerView.setAdapter(new Adapter(items, selectedIndex, inflater, onClickListener)); + recyclerView.setAdapter(new Adapter(menuItems, selectedIndex, inflater, onClickListener)); // Scroll to the currently selected IME. This must run after the recycler view is laid out. recyclerView.post(() -> recyclerView.scrollToPosition(selectedIndex)); - // Indicate that the list can be scrolled. - recyclerView.setScrollIndicators( - hasLanguageSettingsButton ? View.SCROLL_INDICATOR_BOTTOM : 0); // Request focus to enable rotary scrolling on watches. recyclerView.requestFocus(); + updateLanguageSettingsButton(menuItems.get(selectedIndex), contentView, displayId, userId); + builder.setOnCancelListener(dialog -> hide(displayId, userId)); - mMenuItems = items; + mMenuItems = menuItems; mDialog = builder.create(); mDialog.setCanceledOnTouchOutside(true); final Window w = mDialog.getWindow(); @@ -207,11 +197,93 @@ final class InputMethodMenuControllerNew { } } + /** + * Gets the list of Input Method Switcher Menu items and the index of the selected item. + * + * @param items the list of input method and subtype items. + * @param selectedImeId the ID of the selected input method. + * @param selectedSubtypeIndex the index of the selected subtype in the input method's array of + * subtypes, or {@link InputMethodUtils#NOT_A_SUBTYPE_INDEX} if no + * subtype is selected. + * @return the list of menu items, and the index of the selected item, + * or {@code -1} if no item is selected. + */ + @NonNull + private static Pair, Integer> toMenuItems( + @NonNull List items, @Nullable String selectedImeId, + int selectedSubtypeIndex) { + // No item is selected by default. When we have a list of explicitly enabled subtypes, + // the implicit subtype is no longer listed. If the implicit one is still selected, + // no items will be shown as selected. + int selectedIndex = -1; + String prevImeId = null; + final var menuItems = new ArrayList(); + for (int i = 0; i < items.size(); i++) { + final var item = items.get(i); + final var imeId = item.mImi.getId(); + // Check if this is the selected IME-subtype pair. + if (selectedIndex == -1 && imeId.equals(selectedImeId)) { + final int subtypeIndex = item.mSubtypeIndex; + if ((subtypeIndex == 0 && selectedSubtypeIndex == NOT_A_SUBTYPE_INDEX) + || subtypeIndex == NOT_A_SUBTYPE_INDEX + || subtypeIndex == selectedSubtypeIndex) { + selectedIndex = i; + } + } + final boolean hasHeader = !imeId.equals(prevImeId); + final boolean hasDivider = hasHeader && prevImeId != null; + menuItems.add(new MenuItem(item.mImeName, item.mSubtypeName, item.mImi, + item.mSubtypeIndex, hasHeader, hasDivider)); + prevImeId = imeId; + } + + return new Pair<>(menuItems, selectedIndex); + } + + /** + * Updates the visibility of the Language Settings button to visible if the currently selected + * item specifies a (language) settings activity and the device is provisioned. Otherwise, + * the button won't be shown. + * + * @param selectedItem the currently selected item, or {@code null} if no item is selected. + * @param view the menu dialog view. + * @param displayId the ID of the display where the menu was requested. + * @param userId the ID of the user that requested the menu. + */ + @RequiresPermission(allOf = {INTERACT_ACROSS_USERS}) + private void updateLanguageSettingsButton(@Nullable MenuItem selectedItem, @NonNull View view, + int displayId, @UserIdInt int userId) { + final var settingsIntent = selectedItem != null + ? selectedItem.mImi.createImeLanguageSettingsActivityIntent() : null; + final boolean isDeviceProvisioned = Settings.Global.getInt( + view.getContext().getContentResolver(), Settings.Global.DEVICE_PROVISIONED, + 0) != 0; + final boolean hasButton = settingsIntent != null && isDeviceProvisioned; + final View buttonBar = view.requireViewById(com.android.internal.R.id.button_bar); + final Button button = view.requireViewById(com.android.internal.R.id.button1); + final RecyclerView recyclerView = view.requireViewById(com.android.internal.R.id.list); + if (hasButton) { + settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + buttonBar.setVisibility(View.VISIBLE); + button.setOnClickListener(v -> { + v.getContext().startActivityAsUser(settingsIntent, UserHandle.of(userId)); + hide(displayId, userId); + }); + // Indicate that the list can be scrolled. + recyclerView.setScrollIndicators(View.SCROLL_INDICATOR_BOTTOM); + } else { + buttonBar.setVisibility(View.GONE); + button.setOnClickListener(null); + // Remove scroll indicator as there is nothing drawn below the list. + recyclerView.setScrollIndicators(0 /* indicators */); + } + } + /** * Item to be shown in the Input Method Switcher Menu, containing an input method and * optionally an input method subtype. */ - static class MenuItem { + private static class MenuItem { /** The name of the input method. */ @NonNull @@ -268,7 +340,7 @@ final class InputMethodMenuControllerNew { } } - private static class Adapter extends RecyclerView.Adapter { + private static final class Adapter extends RecyclerView.Adapter { /** The list of items to show. */ @NonNull -- GitLab From 9e7e4ab89c39eb0d63b60e9d674375b6219d0a65 Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Fri, 4 Oct 2024 16:55:13 +0900 Subject: [PATCH 092/447] Add OWNERS for ApexManagerTest.java Bug: n/a Test: OWNERS modified Change-Id: I59fc8c0b9d15792d93df1867c46e43c9ae9b38dc --- .../tests/mockingservicestests/src/com/android/server/pm/OWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS b/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS index 5181af14ff65..aa22790022c5 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS +++ b/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS @@ -2,3 +2,4 @@ include /services/core/java/com/android/server/pm/OWNERS per-file BackgroundDexOptServiceUnitTest.java = file:/services/core/java/com/android/server/pm/dex/OWNERS per-file StagingManagerTest.java = dariofreni@google.com, ioffe@google.com, olilan@google.com +per-file ApexManagerTest.java = dariofreni@google.com, ioffe@google.com, olilan@google.com -- GitLab From 56c33e359008b1f4cb6cb6be7636db0b2126a829 Mon Sep 17 00:00:00 2001 From: Ray Chin Date: Mon, 8 Jan 2024 15:39:35 +0800 Subject: [PATCH 093/447] Support reassembling fragmented media events API-Coverage-Bug: 367917024 Flag: android.media.tv.flags.tuner_w_apis Bug: 281787325 Test: atest CtsTvTestCases on cf_x86_tv-staging-userdebug Change-Id: I49aa50bf2d2a8ad0118ef817b5416ad1532db670 --- core/api/system-current.txt | 3 + .../media/tv/tuner/filter/MediaEvent.java | 72 ++++++++++++++++++- media/jni/android_media_tv_Tuner.cpp | 8 ++- 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 3637ca763e0a..643a659cda5e 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -8450,11 +8450,14 @@ package android.media.tv.tuner.filter { method public long getAudioHandle(); method @NonNull public java.util.List getAudioPresentations(); method public long getAvDataId(); + method @FlaggedApi("android.media.tv.flags.tuner_w_apis") public int getDataGroupId(); method public long getDataLength(); method public long getDts(); method @Nullable public android.media.tv.tuner.filter.AudioDescriptor getExtraMetaData(); + method @FlaggedApi("android.media.tv.flags.tuner_w_apis") @IntRange(from=0) public int getIndexInDataGroup(); method @Nullable public android.media.MediaCodec.LinearBlock getLinearBlock(); method @IntRange(from=0) public int getMpuSequenceNumber(); + method @FlaggedApi("android.media.tv.flags.tuner_w_apis") @IntRange(from=0) public int getNumDataPieces(); method public long getOffset(); method public long getPts(); method public int getScIndexMask(); diff --git a/media/java/android/media/tv/tuner/filter/MediaEvent.java b/media/java/android/media/tv/tuner/filter/MediaEvent.java index 4676dffb727f..84a13ab9aba1 100644 --- a/media/java/android/media/tv/tuner/filter/MediaEvent.java +++ b/media/java/android/media/tv/tuner/filter/MediaEvent.java @@ -17,12 +17,14 @@ package android.media.tv.tuner.filter; import android.annotation.BytesLong; +import android.annotation.FlaggedApi; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.media.AudioPresentation; import android.media.MediaCodec.LinearBlock; +import android.media.tv.flags.Flags; import java.util.Collections; import java.util.List; @@ -57,12 +59,16 @@ public class MediaEvent extends FilterEvent { private final int mScIndexMask; private final AudioDescriptor mExtraMetaData; private final List mAudioPresentations; + private final int mNumDataPieces; + private final int mIndexInDataGroup; + private final int mDataGroupId; // This constructor is used by JNI code only private MediaEvent(int streamId, boolean isPtsPresent, long pts, boolean isDtsPresent, long dts, long dataLength, long offset, LinearBlock buffer, boolean isSecureMemory, long dataId, int mpuSequenceNumber, boolean isPrivateData, int scIndexMask, - AudioDescriptor extraMetaData, List audioPresentations) { + AudioDescriptor extraMetaData, List audioPresentations, + int numDataPieces, int indexInDataGroup, int dataGroupId) { mStreamId = streamId; mIsPtsPresent = isPtsPresent; mPts = pts; @@ -78,6 +84,9 @@ public class MediaEvent extends FilterEvent { mScIndexMask = scIndexMask; mExtraMetaData = extraMetaData; mAudioPresentations = audioPresentations; + mNumDataPieces = numDataPieces; + mIndexInDataGroup = indexInDataGroup; + mDataGroupId = dataGroupId; } /** @@ -234,6 +243,67 @@ public class MediaEvent extends FilterEvent { return mAudioPresentations == null ? Collections.emptyList() : mAudioPresentations; } + /** + * Gets the number of data pieces into which the original data was split. + * + *

    The {@link #getNumDataPieces()}, {@link #getIndexInDataGroup()} and + * {@link #getDataGroupId()} methods should be used together to reassemble the original data if + * it was split into pieces. Use {@link #getLinearBlock()} to get the memory where the data + * pieces are stored. + * + * @return 0 or 1 if this MediaEvent object contains the complete data; otherwise the number of + * pieces into which the original data was split. + * @see #getIndexInDataGroup() + * @see #getDataGroupId() + * @see #getLinearBlock() + */ + @FlaggedApi(Flags.FLAG_TUNER_W_APIS) + @IntRange(from = 0) + public int getNumDataPieces() { + return mNumDataPieces; + } + + /** + * Gets the index of the data piece. The index in the data group indicates the order in which + * this {@link MediaEvent}'s data piece should be reassembled. The result should be within the + * range [0, {@link #getNumDataPieces()}). + * + *

    The {@link #getNumDataPieces()}, {@link #getIndexInDataGroup()} and + * {@link #getDataGroupId()} methods should be used together to reassemble the original data if + * it was split into pieces. Use {@link #getLinearBlock()} to get the memory where the data + * pieces are stored. + * + * @return The index in the data group. + * @see #getNumDataPieces() + * @see #getDataGroupId() + * @see #getLinearBlock() + */ + @FlaggedApi(Flags.FLAG_TUNER_W_APIS) + @IntRange(from = 0) + public int getIndexInDataGroup() { + return mIndexInDataGroup; + } + + /** + * Gets the group ID for reassembling the complete data. {@link MediaEvent}s that have the same + * data group ID contain different pieces of the same data. This value should be ignored if + * {@link #getNumDataPieces()} returns 0 or 1. + * + *

    The {@link #getNumDataPieces()}, {@link #getIndexInDataGroup()} and + * {@link #getDataGroupId()} methods should be used together to reassemble the original data if + * it was split into pieces. Use {@link #getLinearBlock()} to get the memory where the data + * pieces are stored. + * + * @return The data group ID. + * @see #getNumDataPieces() + * @see #getIndexInDataGroup() + * @see #getLinearBlock() + */ + @FlaggedApi(Flags.FLAG_TUNER_W_APIS) + public int getDataGroupId() { + return mDataGroupId; + } + /** * Finalize the MediaEvent object. * @hide diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 00b0e57c09ea..49e794116011 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -686,12 +686,16 @@ void FilterClientCallbackImpl::getMediaEvent(const jobjectArray& arr, const int } else if (mediaEvent.scIndexMask.getTag() == DemuxFilterScIndexMask::Tag::scVvc) { sc = mediaEvent.scIndexMask.get(); } + jint numDataPieces = mediaEvent.numDataPieces; + jint indexInDataGroup = mediaEvent.indexInDataGroup; + jint dataGroupId = mediaEvent.dataGroupId; ScopedLocalRef obj(env, env->NewObject(mMediaEventClass, mMediaEventInitID, streamId, isPtsPresent, pts, isDtsPresent, dts, dataLength, offset, nullptr, isSecureMemory, avDataId, mpuSequenceNumber, isPesPrivateData, sc, - audioDescriptor.get(), presentationsJObj.get())); + audioDescriptor.get(), presentationsJObj.get(), + numDataPieces, indexInDataGroup, dataGroupId)); // Protect mFilterClient from being set to null. android::Mutex::Autolock autoLock(mLock); @@ -1048,7 +1052,7 @@ FilterClientCallbackImpl::FilterClientCallbackImpl() { "", "(IZJZJJJLandroid/media/MediaCodec$LinearBlock;" "ZJIZILandroid/media/tv/tuner/filter/AudioDescriptor;" - "Ljava/util/List;)V"); + "Ljava/util/List;III)V"); mAudioDescriptorInitID = env->GetMethodID(mAudioDescriptorClass, "", "(BBCBBB)V"); mPesEventInitID = env->GetMethodID(mPesEventClass, "", "(III)V"); mTsRecordEventInitID = env->GetMethodID(mTsRecordEventClass, "", "(IIIJJI)V"); -- GitLab From 319474c18fe0d66c655862e5194377edd283e9d4 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Sun, 6 Oct 2024 07:08:33 +0000 Subject: [PATCH 094/447] Set reset_on_fork in setRenderThread as well Also check the thread scheduler before setting it to SCHED_OTHER | SCHED_RESET_ON_FORK to avoid overhead. Bug: 370988407 Change-Id: I946f653429978ae2be1c119dd4d99733acd372ff Flag: com.android.server.am.reset_on_fork_enabled Test: Build and check with chrt -p [APP_RT_PID] --- .../com/android/server/am/ActivityManagerService.java | 11 ++++++++++- .../core/java/com/android/server/am/OomAdjuster.java | 11 ++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 9219cc12a697..92215224b6bc 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -8269,7 +8269,16 @@ public class ActivityManagerService extends IActivityManager.Stub setThreadScheduler(proc.getRenderThreadTid(), SCHED_FIFO | SCHED_RESET_ON_FORK, 1); } else { - setThreadPriority(proc.getRenderThreadTid(), THREAD_PRIORITY_TOP_APP_BOOST); + if (Flags.resetOnForkEnabled()) { + if (Process.getThreadScheduler(proc.getRenderThreadTid()) + == Process.SCHED_OTHER) { + Process.setThreadScheduler(proc.getRenderThreadTid(), + Process.SCHED_OTHER | Process.SCHED_RESET_ON_FORK, + 0); + } + } + setThreadPriority(proc.getRenderThreadTid(), + THREAD_PRIORITY_TOP_APP_BOOST); } } } else { diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 796de1982fe5..4073ab848f81 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -459,12 +459,13 @@ public class OomAdjuster { void setThreadPriority(int tid, int priority) { if (Flags.resetOnForkEnabled()) { - Process.setThreadScheduler(tid, - Process.SCHED_OTHER | Process.SCHED_RESET_ON_FORK, - priority); - } else { - Process.setThreadPriority(tid, priority); + if (Process.getThreadScheduler(tid) == Process.SCHED_OTHER) { + Process.setThreadScheduler(tid, + Process.SCHED_OTHER | Process.SCHED_RESET_ON_FORK, + 0); + } } + Process.setThreadPriority(tid, priority); } } -- GitLab From e12c2f0e1d93b36622179f845c625943cde841db Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Mon, 23 Sep 2024 09:54:35 +0800 Subject: [PATCH 095/447] Avoid detached surface from returning to hierarchy Transition#buildFinishTransaction contains the operation that reparent the animation target to original parent. If the target is removed before the transition finishes, when the finish transaction applies, the removed surface may attach to hierarchy again (becomes a handleNotAlive layer). By deferring the WindowToken removal until after the transition is finished, the removal transaction always applies after the finish transaction. Then the the removed window won't attach to its original parent again. Note that the WindowState can still be removed directly, so it (empty children) won't affect animation by showing something. Bug: 366098095 Flag: EXEMPT bugfix Test: atest WindowTokenTests#testTokenRemovalProcess Test: Run the script (The output should be empty): for i in {1..500} do adb shell wm size 200x200 adb shell input keyevent 24 adb shell wm size 1080x2400 adb shell input keyevent 25 done adb shell dumpsys SurfaceFlinger | grep type=2020 Change-Id: Ie9c5857b2c387c4380bbb7718cb366bfe9cd4b7e --- .../com/android/server/wm/ActivityRecord.java | 22 ++------------- .../com/android/server/wm/Transition.java | 1 - .../server/wm/TransitionController.java | 10 +++++++ .../server/wm/WindowManagerService.java | 2 +- .../com/android/server/wm/WindowToken.java | 28 +++++++++++++++++++ .../android/server/wm/WindowTokenTests.java | 10 +++++++ 6 files changed, 51 insertions(+), 22 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 0b36c7eb5fdf..31f4d081d913 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -880,8 +880,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A }) @interface SplashScreenBehavior { } - // TODO: Have a WindowContainer state for tracking exiting/deferred removal. - boolean mIsExiting; // Force an app transition to be ran in the case the visibility of the app did not change. // We use this for the case of moving a Root Task to the back with multiple activities, and the // top activity enters PIP; the bottom activity's visibility stays the same, but we need to @@ -1227,10 +1225,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A pw.print(" lastAllDrawn="); pw.print(mLastAllDrawn); pw.println(")"); } - if (mStartingData != null || firstWindowDrawn || mIsExiting) { + if (mStartingData != null || firstWindowDrawn) { pw.print(prefix); pw.print("startingData="); pw.print(mStartingData); - pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn); - pw.print(" mIsExiting="); pw.println(mIsExiting); + pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn); } if (mStartingWindow != null || mStartingData != null || mStartingSurface != null || startingMoved || mVisibleSetFromTransferredStartingWindow) { @@ -4370,21 +4367,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A super.removeImmediately(); } - @Override - void removeIfPossible() { - mIsExiting = false; - removeAllWindowsIfPossible(); - removeImmediately(); - } - - @Override - boolean handleCompleteDeferredRemoval() { - if (mIsExiting) { - removeIfPossible(); - } - return super.handleCompleteDeferredRemoval(); - } - void onRemovedFromDisplay() { if (mRemovingFromDisplay) { return; diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 188b368c47c5..1659f7bc6eed 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -1753,7 +1753,6 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { } } - @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) static boolean containsChangeFor(WindowContainer wc, ArrayList list) { for (int i = list.size() - 1; i >= 0; --i) { if (list.get(i).mContainer == wc) return true; diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index b7fe32713100..87bdfa4f5d75 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -471,6 +471,16 @@ class TransitionController { return false; } + /** Returns {@code true} if the `wc` is a target of a playing transition. */ + boolean isPlayingTarget(@NonNull WindowContainer wc) { + for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) { + if (Transition.containsChangeFor(wc, mPlayingTransitions.get(i).mTargets)) { + return true; + } + } + return false; + } + /** Returns {@code true} if the finishing transition contains `wc`. */ boolean inFinishingTransition(WindowContainer wc) { return mFinishingTransition != null && mFinishingTransition.isInTransition(wc); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index ebf645d84f95..f4ad0307d24b 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2109,7 +2109,7 @@ public class WindowManagerService extends IWindowManager.Stub ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Removing %s from %s", win, token); // Window will already be removed from token before this post clean-up method is called. if (token.isEmpty() && !token.mPersistOnEmpty) { - token.removeImmediately(); + token.removeIfPossible(); } if (win.mActivityRecord != null) { diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 7e7ca12cd44e..5bde8b5a507c 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -90,6 +90,9 @@ class WindowToken extends WindowContainer { // Is key dispatching paused for this token? boolean paused = false; + /** Whether this container should be removed when it no longer animates. */ + boolean mIsExiting; + /** The owner has {@link android.Manifest.permission#MANAGE_APP_TOKENS} */ final boolean mOwnerCanManageAppTokens; @@ -276,6 +279,28 @@ class WindowToken extends WindowContainer { } } + @Override + void removeIfPossible() { + if (mTransitionController.isPlayingTarget(this)) { + // Defer removing this container until the transition is finished. So the removal can + // execute after the finish transaction (see Transition#buildFinishTransaction) which + // may reparent it to original parent. + mIsExiting = true; + return; + } + mIsExiting = false; + removeAllWindowsIfPossible(); + removeImmediately(); + } + + @Override + boolean handleCompleteDeferredRemoval() { + if (mIsExiting) { + removeIfPossible(); + } + return super.handleCompleteDeferredRemoval(); + } + /** * @return The scale for applications running in compatibility mode. Multiply the size in the * application by this scale will be the size in the screen. @@ -725,6 +750,9 @@ class WindowToken extends WindowContainer { pw.print("fixedRotationConfig="); pw.println(mFixedRotationTransformState.mRotatedOverrideConfiguration); } + if (mIsExiting) { + pw.print(prefix); pw.println("isExiting=true"); + } } @Override diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java index 714eb4b3c093..35328a0e1dc0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java @@ -23,6 +23,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.policy.WindowManagerPolicy.TRANSIT_EXIT; @@ -157,7 +158,16 @@ public class WindowTokenTests extends WindowTestsBase { // Verify that the other token window is still around. assertEquals(1, token.getWindowsCount()); + final TransitionController transitionController = token.mTransitionController; + spyOn(transitionController); + doReturn(true).when(transitionController).isPlayingTarget(token); window2.removeImmediately(); + assertTrue(token.mIsExiting); + assertNotNull("Defer removal for playing transition", token.getParent()); + + doReturn(false).when(transitionController).isPlayingTarget(token); + token.handleCompleteDeferredRemoval(); + assertFalse(token.mIsExiting); // Verify that the token is no-longer attached to its parent assertNull(token.getParent()); // Verify that the token windows are no longer attached to it. -- GitLab From b42a35104d86eb81ef100b6f12b41a3667541b64 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Mon, 7 Oct 2024 15:08:52 +0800 Subject: [PATCH 096/447] Reduce unnecessary invocation of fillTaskInfo The getTaskInfo invokes fillTaskInfo, which is heavy to fill lots of fields. But the specified caller only needs 2 attributes of the task, which is unnecessary to get entire task info that populates many unrelated fields. Bug: 297502610 Flag: EXEMPT remove unnecessary invocation Test: atest DesktopModeLaunchParamsModifierTests Change-Id: I99a9e5306bf16d614ab4f6791f399b3cfe4ff314 --- .../server/wm/DesktopModeBoundsCalculator.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java b/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java index 34b5f6a24d41..1a8f5fc46827 100644 --- a/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java +++ b/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java @@ -30,7 +30,6 @@ import static com.android.server.wm.LaunchParamsUtil.calculateLayoutBounds; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityOptions; -import android.app.TaskInfo; import android.content.pm.ActivityInfo.ScreenOrientation; import android.content.pm.ActivityInfo.WindowLayout; import android.graphics.Rect; @@ -98,7 +97,6 @@ public final class DesktopModeBoundsCalculator { private static Rect calculateInitialBounds(@NonNull Task task, @NonNull ActivityRecord activity, @NonNull Rect stableBounds ) { - final TaskInfo taskInfo = task.getTaskInfo(); // Display bounds not taking into account insets. final TaskDisplayArea displayArea = task.getDisplayArea(); final Rect screenBounds = displayArea.getBounds(); @@ -118,14 +116,15 @@ public final class DesktopModeBoundsCalculator { float appAspectRatio = desktopAppCompatAspectRatioPolicy.calculateAspectRatio(task); final float tdaWidth = stableBounds.width(); final float tdaHeight = stableBounds.height(); + final int taskConfigOrientation = task.getConfiguration().orientation; final int activityOrientation = getActivityOrientation(activity, task); - final Size initialSize = switch (taskInfo.configuration.orientation) { + final Size initialSize = switch (taskConfigOrientation) { case ORIENTATION_LANDSCAPE -> { // Device in landscape orientation. if (appAspectRatio == 0) { appAspectRatio = 1; } - if (canChangeAspectRatio(desktopAppCompatAspectRatioPolicy, taskInfo, task)) { + if (canChangeAspectRatio(desktopAppCompatAspectRatioPolicy, task)) { if (isFixedOrientationPortrait(activityOrientation)) { // For portrait resizeable activities, respect apps fullscreen width but // apply ideal size height. @@ -143,7 +142,7 @@ public final class DesktopModeBoundsCalculator { // Device in portrait orientation. final int customPortraitWidthForLandscapeApp = screenBounds.width() - (DESKTOP_MODE_LANDSCAPE_APP_PADDING * 2); - if (canChangeAspectRatio(desktopAppCompatAspectRatioPolicy, taskInfo, task)) { + if (canChangeAspectRatio(desktopAppCompatAspectRatioPolicy, task)) { if (isFixedOrientationLandscape(activityOrientation)) { if (appAspectRatio == 0) { appAspectRatio = tdaWidth / (tdaWidth - 1); @@ -182,8 +181,8 @@ public final class DesktopModeBoundsCalculator { */ private static boolean canChangeAspectRatio( @NonNull DesktopAppCompatAspectRatioPolicy desktopAppCompatAspectRatioPolicy, - @NonNull TaskInfo taskInfo, @NonNull Task task) { - return taskInfo.isResizeable + @NonNull Task task) { + return task.isResizeable() && !desktopAppCompatAspectRatioPolicy.hasMinAspectRatioOverride(task); } -- GitLab From e38140fcc967b4d6e0efcf2956735c0051f30e54 Mon Sep 17 00:00:00 2001 From: Jorge Gil Date: Thu, 26 Sep 2024 23:51:45 +0000 Subject: [PATCH 097/447] Do not force-show system bars in desktop's full immersive mode Change the force-show policy when in freeform to only apply when the top freeform task isn't taking full-screen bounds, to allow freeform to have an immersive-like mode where the system bars can be hidden. Flag: com.android.window.flags.enable_fully_immersive_in_desktop Bug: 369444183 Bug: 369444147 Bug: 369443876 Test: atest InsetsPolicyTest Test: enter full immersive in desktop, verify system bars are hidden Change-Id: Ic9022dcf31f4b513cea87cba323cf249ee238774 --- .../com/android/server/wm/DisplayPolicy.java | 15 +++++--- .../com/android/server/wm/InsetsPolicy.java | 5 +-- .../android/server/wm/InsetsPolicyTest.java | 36 +++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index c062f5adf755..04a625b4a237 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -79,6 +79,7 @@ import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.L import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import static com.android.window.flags.Flags.enableFullyImmersiveInDesktop; import android.annotation.NonNull; import android.annotation.Nullable; @@ -2515,10 +2516,16 @@ public class DisplayPolicy { defaultTaskDisplayArea.getRootTask(task -> task.isVisible() && task.getTopLeafTask().getAdjacentTask() != null) != null; - final boolean freeformRootTaskVisible = - defaultTaskDisplayArea.isRootTaskVisible(WINDOWING_MODE_FREEFORM); - - getInsetsPolicy().updateSystemBars(win, adjacentTasksVisible, freeformRootTaskVisible); + final Task topFreeformTask = defaultTaskDisplayArea + .getTopRootTaskInWindowingMode(WINDOWING_MODE_FREEFORM); + final boolean freeformRootTaskVisible = topFreeformTask != null + && topFreeformTask.isVisible(); + final boolean inNonFullscreenFreeformMode = freeformRootTaskVisible + && !topFreeformTask.getBounds().equals(mDisplayContent.getBounds()); + + getInsetsPolicy().updateSystemBars(win, adjacentTasksVisible, + enableFullyImmersiveInDesktop() + ? inNonFullscreenFreeformMode : freeformRootTaskVisible); final boolean topAppHidesStatusBar = topAppHidesSystemBar(Type.statusBars()); if (getStatusBar() != null) { diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 61b13a8c97cb..24a6f118ad04 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -628,8 +628,9 @@ class InsetsPolicy { return (mForcedShowingTypes & types) == types; } - void updateSystemBars(WindowState win, boolean inSplitScreenMode, boolean inFreeformMode) { - mForcedShowingTypes = (inSplitScreenMode || inFreeformMode) + void updateSystemBars(WindowState win, boolean inSplitScreenMode, + boolean inNonFullscreenFreeformMode) { + mForcedShowingTypes = (inSplitScreenMode || inNonFullscreenFreeformMode) ? (Type.statusBars() | Type.navigationBars()) : forceShowingNavigationBars(win) ? Type.navigationBars() diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java index b26c267768a7..d2cf03dd4b9a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -41,7 +41,10 @@ import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.verify; import android.app.StatusBarManager; +import android.graphics.Rect; import android.os.Binder; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.view.InsetsFrameProvider; import android.view.InsetsSource; @@ -52,6 +55,7 @@ import android.view.WindowInsets; import androidx.test.filters.SmallTest; import com.android.server.statusbar.StatusBarManagerInternal; +import com.android.window.flags.Flags; import org.junit.Before; import org.junit.Test; @@ -95,6 +99,7 @@ public class InsetsPolicyTest extends WindowTestsBase { } @Test + @DisableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP) public void testControlsForDispatch_freeformTaskVisible() { addStatusBar(); addNavigationBar(); @@ -107,6 +112,37 @@ public class InsetsPolicyTest extends WindowTestsBase { assertNull(controls); } + @Test + @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP) + public void testControlsForDispatch_fullscreenFreeformTaskVisible() { + addStatusBar(); + addNavigationBar(); + + final WindowState win = createWindow(null, WINDOWING_MODE_FREEFORM, + ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app"); + win.setBounds(new Rect()); + final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win); + + // The freeform (w/fullscreen bounds) app window can control both system bars. + assertNotNull(controls); + assertEquals(2, controls.length); + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP) + public void testControlsForDispatch_nonFullscreenFreeformTaskVisible() { + addStatusBar(); + addNavigationBar(); + + final WindowState win = createWindow(null, WINDOWING_MODE_FREEFORM, + ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app"); + win.getTask().setBounds(new Rect(1, 1, 10, 10)); + final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win); + + // The freeform (but not fullscreen bounds) app window must not control any system bars. + assertNull(controls); + } + @Test public void testControlsForDispatch_forceStatusBarVisible() { addStatusBar().mAttrs.forciblyShownTypes |= statusBars(); -- GitLab From 17a295b05caebcd6ed599d78f75d9b27ed0a079d Mon Sep 17 00:00:00 2001 From: Pragya Bajoria Date: Sat, 5 Oct 2024 12:37:05 +0000 Subject: [PATCH 098/447] Handle TRANSIT_TO_BACK in FreeformTaskTransitionObserver This is needed to handle the case where a task is moved to the back of the stack. Bug: 367268953 Flag: EXEMPT (refactor) Change-Id: Ibbc7133b93b3074a792c5eae1586b6441874861e --- .../FreeformTaskTransitionObserver.java | 13 +++++++++++++ .../FreeformTaskTransitionObserverTest.java | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java index d6b920e5b010..056f6b963ebe 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java @@ -119,6 +119,9 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs case WindowManager.TRANSIT_TO_FRONT: onToFrontTransitionReady(change, startT, finishT); break; + case WindowManager.TRANSIT_TO_BACK: + onToBackTransitionReady(change, startT, finishT); + break; case WindowManager.TRANSIT_CLOSE: { taskInfoList.add(change.getTaskInfo()); onCloseTransitionReady(change, startT, finishT); @@ -173,6 +176,16 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs change.getTaskInfo(), change.getLeash(), startT, finishT); } + private void onToBackTransitionReady( + TransitionInfo.Change change, + SurfaceControl.Transaction startT, + SurfaceControl.Transaction finishT) { + mTaskChangeListener.ifPresent( + listener -> listener.onTaskMovingToBack(change.getTaskInfo())); + mWindowDecorViewModel.onTaskChanging( + change.getTaskInfo(), change.getLeash(), startT, finishT); + } + @Override public void onTransitionStarting(@NonNull IBinder transition) {} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java index 86a8502e0d85..da95315c18c1 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java @@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_OPEN; +import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.view.WindowManager.TRANSIT_CHANGE; @@ -160,6 +161,22 @@ public class FreeformTaskTransitionObserverTest { verify(mTaskChangeListener).onTaskMovingToFront(change.getTaskInfo()); } + @Test + public void toBackTransition_notifiesOnTaskMovingToBack() { + final TransitionInfo.Change change = + createChange(TRANSIT_TO_BACK, /* taskId= */ 1, WINDOWING_MODE_FREEFORM); + final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TO_BACK, /* flags= */ 0) + .addChange(change).build(); + + final IBinder transition = mock(IBinder.class); + final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); + final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); + mTransitionObserver.onTransitionReady(transition, info, startT, finishT); + mTransitionObserver.onTransitionStarting(transition); + + verify(mTaskChangeListener).onTaskMovingToBack(change.getTaskInfo()); + } + @Test public void changeTransition_notifiesOnTaskChanging() { final TransitionInfo.Change change = -- GitLab From 835b76cb1fa530843a87ac85737485bc8656b7e3 Mon Sep 17 00:00:00 2001 From: Graciela Wissen Putri Date: Wed, 2 Oct 2024 12:06:27 +0000 Subject: [PATCH 099/447] Respect orientation request from any eligible activity Flag: EXEMPT bug fix Fix: 370878266 Test: atest AppCompatOrientationOverridesTest Manually with fixed orientation activity and freeform Change-Id: I955c2f20678052d4ed2e1e76568a5bea45914a60 --- .../wm/AppCompatOrientationOverrides.java | 11 ++++++ .../com/android/server/wm/DisplayArea.java | 18 ++++----- .../wm/AppCompatOrientationOverridesTest.java | 38 +++++++++++++++++++ 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java b/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java index bd01351251a5..c84711d4be51 100644 --- a/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java +++ b/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION; import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED; import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION; @@ -106,6 +107,16 @@ class AppCompatOrientationOverrides { return isChangeEnabled(mActivityRecord, OVERRIDE_RESPECT_REQUESTED_ORIENTATION); } + boolean shouldRespectRequestedOrientationDueToOverride() { + // Checking TaskFragment rather than ActivityRecord to ensure that transition + // between fullscreen and PiP would work well. Checking TaskFragment rather than + // Task to ensure that Activity Embedding is excluded. + return mActivityRecord.isVisibleRequested() && mActivityRecord.getTaskFragment() != null + && mActivityRecord.getTaskFragment().getWindowingMode() == WINDOWING_MODE_FULLSCREEN + && mActivityRecord.mAppCompatController.getAppCompatOrientationOverrides() + .isOverrideRespectRequestedOrientationEnabled(); + } + /** * Whether an app is calling {@link android.app.Activity#setRequestedOrientation} * in a loop and orientation request should be ignored. diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index 0416f74aa488..29ffda7537ac 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -16,7 +16,6 @@ package com.android.server.wm; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -260,15 +259,14 @@ public class DisplayArea extends WindowContainer { if (mDisplayContent == null) { return false; } - ActivityRecord activity = mDisplayContent.topRunningActivity( - /* considerKeyguardState= */ true); - return activity != null && activity.getTaskFragment() != null - // Checking TaskFragment rather than ActivityRecord to ensure that transition - // between fullscreen and PiP would work well. Checking TaskFragment rather than - // Task to ensure that Activity Embedding is excluded. - && activity.getTaskFragment().getWindowingMode() == WINDOWING_MODE_FULLSCREEN - && activity.mAppCompatController.getAppCompatOrientationOverrides() - .isOverrideRespectRequestedOrientationEnabled(); + + // Top running activity can be freeform and ignore orientation request from bottom activity + // that should be respected, Check all activities in display to make sure any eligible + // activity should be respected. + final ActivityRecord activity = mDisplayContent.getActivity((r) -> + r.mAppCompatController.getAppCompatOrientationOverrides() + .shouldRespectRequestedOrientationDueToOverride()); + return activity != null; } boolean getIgnoreOrientationRequest() { diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java index d9b5f37be86c..8747cfae93f8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java @@ -17,11 +17,13 @@ package com.android.server.wm; import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED; import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE; import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.wm.AppCompatOrientationOverrides.OrientationOverridesState.MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; import static com.android.server.wm.AppCompatOrientationOverrides.OrientationOverridesState.SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS; @@ -31,6 +33,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.compat.testing.PlatformCompatChangeRule; +import android.content.pm.ActivityInfo.ScreenOrientation; import android.platform.test.annotations.Presubmit; import androidx.annotation.NonNull; @@ -228,6 +231,25 @@ public class AppCompatOrientationOverridesTest extends WindowTestsBase { }); } + @Test + public void testOverrideRespectRequestedOrientationIsEnabled_bottomOrientationIsRespected() { + runTestScenario((robot) -> { + robot.applyOnActivity((a) -> { + a.setIgnoreOrientationRequest(true); + a.createActivityWithComponentInNewTask(); + robot.setOverrideRespectRequestedOrientationEnabled(true); + a.configureUnresizableTopActivity(SCREEN_ORIENTATION_LANDSCAPE); + robot.checkDisplayShouldIgnoreOrientationRequest(SCREEN_ORIENTATION_LANDSCAPE, + /* expected */ false); + + a.createActivityWithComponentInNewTask(); + a.setTopActivityInFreeformWindowingMode(true); + }); + robot.checkDisplayShouldIgnoreOrientationRequest(SCREEN_ORIENTATION_LANDSCAPE, + /* expected */ false); + }); + } + /** * Runs a test scenario providing a Robot. */ @@ -291,6 +313,22 @@ public class AppCompatOrientationOverridesTest extends WindowTestsBase { } } + void setOverrideRespectRequestedOrientationEnabled(boolean override) { + spyOn(getTopOrientationOverrides()); + doReturn(override).when(getTopOrientationOverrides()) + .isOverrideRespectRequestedOrientationEnabled(); + } + + void checkDisplayShouldIgnoreOrientationRequest(@ScreenOrientation int candidate, + boolean expected) { + assertEquals(expected, activity().displayContent() + .shouldIgnoreOrientationRequest(candidate)); + } + + void checkExpectedDisplayOrientation(@ScreenOrientation int expected) { + assertEquals(expected, activity().displayContent().getOrientation()); + } + void checkShouldUseDisplayLandscapeNaturalOrientation(boolean expected) { assertEquals(expected, getTopOrientationOverrides().shouldUseDisplayLandscapeNaturalOrientation()); -- GitLab From eb79400202fa3b33655e78f9fe4ada55715f6337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Kurucz?= Date: Mon, 7 Oct 2024 08:34:37 +0000 Subject: [PATCH 100/447] [flexiglass] Remove ScrollViewFields#headsupHeightConsumer This consumer is never set, because we have choosen another delivery method for the height from the NSSL to the PlaceHolder, the NotificationHeadsUpHeight layout modifier. Bug: 296118689 Test: check if HUNs are displayed in flexiglass Flag: com.android.systemui.scene_container Change-Id: I2dc80993b81cfe384b234efd0760eecb289b1e00 --- .../notification/stack/NotificationStackScrollLayout.java | 5 ----- .../statusbar/notification/stack/ScrollViewFields.kt | 3 --- .../notification/stack/ui/view/NotificationScrollView.kt | 3 --- 3 files changed, 11 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index cd3516dadbad..5b2c9c77589b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -1287,11 +1287,6 @@ public class NotificationStackScrollLayout mScrollViewFields.setRemoteInputRowBottomBoundConsumer(consumer); } - @Override - public void setHeadsUpHeightConsumer(@Nullable Consumer consumer) { - mScrollViewFields.setHeadsUpHeightConsumer(consumer); - } - /** * @param listener to be notified after the location of Notification children might have * changed. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt index c08ed6120832..f6e8b8f0166b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt @@ -86,9 +86,6 @@ class ScrollViewFields { fun sendRemoteInputRowBottomBound(bottomY: Float?) = remoteInputRowBottomBoundConsumer?.accept(bottomY) - /** send the [headsUpHeight] to the [headsUpHeightConsumer], if present. */ - fun sendHeadsUpHeight(headsUpHeight: Float) = headsUpHeightConsumer?.accept(headsUpHeight) - fun dump(pw: IndentingPrintWriter) { pw.printSection("StackViewStates") { pw.println("scrimClippingShape", scrimClippingShape) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt index 41c02934efa6..d3a7d0adb8b3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt @@ -77,9 +77,6 @@ interface NotificationScrollView { /** Set a consumer for current remote input notification row bottom bound events */ fun setRemoteInputRowBottomBoundConsumer(consumer: Consumer?) - /** Set a consumer for heads up height changed events */ - fun setHeadsUpHeightConsumer(consumer: Consumer?) - /** sets that scrolling is allowed */ fun setScrollingEnabled(enabled: Boolean) -- GitLab From 8dd13bf37d989b5ef616826ea898e6ff55996bdd Mon Sep 17 00:00:00 2001 From: Ivan Chiang Date: Mon, 19 Aug 2024 07:20:59 +0000 Subject: [PATCH 101/447] [PM] Add more logs to debug the flaky test The CtsPackageInstallerCUJUpdateOwnerShipTestCases is flaky. But, we can't reproduce it (include ABTD). Let's add more logs to debug it. After we find the root cause, revert this patch. Flag: EXEMPT log only update Bug: 360755710 Test: atest CtsPackageInstallerCUJUpdateOwnerShipTestCases Change-Id: I03e00aa031a5f2c18c9aba0c0777404ebea41169 --- .../PackageInstallerActivity.java | 38 +++++++++++++++++- .../server/pm/PackageInstallerSession.java | 40 +++++++++++++++++++ .../server/pm/PackageManagerService.java | 2 +- 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java index 824dd4a5fdaf..d688a1a036d1 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java @@ -44,6 +44,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Process; +import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -100,7 +101,8 @@ public class PackageInstallerActivity extends Activity { private int mActivityResultCode = Activity.RESULT_CANCELED; private int mPendingUserActionReason = -1; - private final boolean mLocalLOGV = false; + private final boolean mLocalLOGV = + TextUtils.equals("userdebug", SystemProperties.get("ro.build.type", "")); PackageManager mPm; AppOpsManager mAppOpsManager; UserManager mUserManager; @@ -143,6 +145,11 @@ public class PackageInstallerActivity extends Activity { private AlertDialog mDialog; private void startInstallConfirm() { + if (mLocalLOGV) { + Log.d(TAG, "startInstallConfirm mAppInfo = " + mAppInfo + + ", existingUpdateOwner = " + getExistingUpdateOwner() + + ", mOriginatingPackage = " + mOriginatingPackage); + } TextView viewToEnable; if (mAppInfo != null) { @@ -183,6 +190,10 @@ public class PackageInstallerActivity extends Activity { try { final String packageName = mPkgInfo.packageName; final InstallSourceInfo sourceInfo = mPm.getInstallSourceInfo(packageName); + if (mLocalLOGV) { + Log.d(TAG, "getExistingUpdateOwner mAppInfo = " + mAppInfo + + ", packageName = " + packageName + ", sourceInfo = " + sourceInfo); + } return sourceInfo.getUpdateOwnerPackageName(); } catch (NameNotFoundException e) { return null; @@ -303,6 +314,12 @@ public class PackageInstallerActivity extends Activity { private void initiateInstall() { final String existingUpdateOwner = getExistingUpdateOwner(); + if (mLocalLOGV) { + Log.d(TAG, "initiateInstall mAppInfo = " + mAppInfo + + ", existingUpdateOwner = " + existingUpdateOwner + + ", mOriginatingPackage = " + mOriginatingPackage + + ", mSessionId = " + mSessionId); + } if (mSessionId == SessionInfo.INVALID_ID && !TextUtils.isEmpty(existingUpdateOwner) && !TextUtils.equals(existingUpdateOwner, mOriginatingPackage)) { @@ -814,15 +831,28 @@ public class PackageInstallerActivity extends Activity { @Override public void onOpChanged(String op, String packageName) { + if (mLocalLOGV) { + Log.d(TAG, "UnknownSourcesListener onOpChanged op = " + op + + ", packageName = " + packageName + + ", mOriginatingPackage = " + mOriginatingPackage); + } if (!mOriginatingPackage.equals(packageName)) { return; } unregister(this); mActiveUnknownSourcesListeners.remove(this); + if (mLocalLOGV) { + Log.d(TAG, "UnknownSourcesListener onOpChanged isDestroyed() = " + + isDestroyed()); + } if (isDestroyed()) { return; } new Handler(Looper.getMainLooper()).postDelayed(() -> { + if (mLocalLOGV) { + Log.d(TAG, "UnknownSourcesListener onOpChanged post isDestroyed()" + + "= " + isDestroyed() + ", getIntent() = " + getIntent()); + } if (!isDestroyed()) { startActivity(getIntent()); // The start flag (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP) doesn't @@ -840,6 +870,9 @@ public class PackageInstallerActivity extends Activity { } private void register(UnknownSourcesListener listener) { + if (mLocalLOGV) { + Log.d(TAG, "UnknownSourcesListener register"); + } mAppOpsManager.startWatchingMode( AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES, mOriginatingPackage, listener); @@ -847,6 +880,9 @@ public class PackageInstallerActivity extends Activity { } private void unregister(UnknownSourcesListener listener) { + if (mLocalLOGV) { + Log.d(TAG, "UnknownSourcesListener unregister"); + } mAppOpsManager.stopWatchingMode(listener); mActiveUnknownSourcesListeners.remove(listener); } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index c581622914fa..897ee4312d22 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -1102,6 +1102,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final boolean isUpdateOwnershipEnforcementEnabled = mPm.isUpdateOwnershipEnforcementAvailable() && existingUpdateOwnerPackageName != null; + + if (Build.IS_USERDEBUG) { + Log.d("updateowner", "PackageInstallerSession computeUserActionRequirement" + + " isUpdateOwnershipEnforcementEnabled= " + isUpdateOwnershipEnforcementEnabled + + ", mPm.isUpdateOwnershipEnforcementAvailable= " + + mPm.isUpdateOwnershipEnforcementAvailable() + + ", existingUpdateOwnerPackageName=" + existingUpdateOwnerPackageName + + ", isUpdateOwner= " + isUpdateOwner + ", getInstallerPackageName()= " + + getInstallerPackageName() + ", isInstallerShell= " + isInstallerShell + + ", mInstallerUid=" + mInstallerUid + ", packageName = " + packageName); + } // For an installation that un-archives an app, if the installer doesn't have the // INSTALL_PACKAGES permission, the user should have already been prompted to confirm the // un-archive request. There's no need for another confirmation during the installation. @@ -1115,6 +1126,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { || isInstallUnarchive; if (noUserActionNecessary) { + if (Build.IS_USERDEBUG) { + Log.d("updateowner", "PackageInstallerSession computeUserActionRequirement" + + " noUserActionNecessary userActionNotTypicallyNeededResponse"); + } return userActionNotTypicallyNeededResponse; } @@ -1124,15 +1139,27 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { && !isInstallerShell // We don't enforce the update ownership for the managed user and profile. && !isFromManagedUserOrProfile) { + if (Build.IS_USERDEBUG) { + Log.d("updateowner", "PackageInstallerSession computeUserActionRequirement" + + "USER_ACTION_REQUIRED_UPDATE_OWNER_REMINDER"); + } return USER_ACTION_REQUIRED_UPDATE_OWNER_REMINDER; } if (isPermissionGranted) { + if (Build.IS_USERDEBUG) { + Log.d("updateowner", "PackageInstallerSession computeUserActionRequirement" + + " permission userActionNotTypicallyNeededResponse"); + } return userActionNotTypicallyNeededResponse; } if (snapshot.isInstallDisabledForPackage(getInstallerPackageName(), mInstallerUid, userId)) { + if (Build.IS_USERDEBUG) { + Log.d("updateowner", "PackageInstallerSession computeUserActionRequirement" + + " disable USER_ACTION_REQUIRED"); + } // show the installer to account for device policy or unknown sources use cases return USER_ACTION_REQUIRED; } @@ -1141,9 +1168,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { && isUpdateWithoutUserActionPermissionGranted && ((isUpdateOwnershipEnforcementEnabled ? isUpdateOwner : isInstallerOfRecord) || isSelfUpdate)) { + if (Build.IS_USERDEBUG) { + Log.d("updateowner", "PackageInstallerSession computeUserActionRequirement" + + " USER_ACTION_PENDING_APK_PARSING"); + } return USER_ACTION_PENDING_APK_PARSING; } + if (Build.IS_USERDEBUG) { + Log.d("updateowner", "PackageInstallerSession computeUserActionRequirement" + + " USER_ACTION_REQUIRED"); + } return USER_ACTION_REQUIRED; } @@ -2714,6 +2749,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @UserActionRequirement int userActionRequirement = USER_ACTION_NOT_NEEDED; // TODO(b/159331446): Move this to makeSessionActiveForInstall and update javadoc userActionRequirement = session.computeUserActionRequirement(); + if (Build.IS_USERDEBUG) { + Log.d("updateowner", "PackageInstallerSession checkUserActionRequirement" + + " userActionRequirement= " + userActionRequirement + + ", session.packageName= " + session.getPackageName()); + } session.updateUserActionRequirement(userActionRequirement); if (userActionRequirement == USER_ACTION_REQUIRED || userActionRequirement == USER_ACTION_REQUIRED_UPDATE_OWNER_REMINDER) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 611e0d86202a..c8cf938099f4 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -340,7 +340,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService static final boolean DEBUG_UPGRADE = false; static final boolean DEBUG_DOMAIN_VERIFICATION = false; static final boolean DEBUG_BACKUP = false; - public static final boolean DEBUG_INSTALL = false; + public static final boolean DEBUG_INSTALL = Build.IS_USERDEBUG; public static final boolean DEBUG_REMOVE = false; static final boolean DEBUG_PACKAGE_INFO = false; static final boolean DEBUG_INTENT_MATCHING = false; -- GitLab From 2883d9c0fc4ff6c0a08f0dfd6ef02b996bae4e70 Mon Sep 17 00:00:00 2001 From: yongnamcha Date: Wed, 11 Sep 2024 02:36:36 +0000 Subject: [PATCH 102/447] Updating the APIs for the Callback Mode This commit updates the APIs for the Callback Mode. This includes System API updates. Bug: 260533540 Bug: 359064059 Test: atest CtsTelephonyTestCases:TelephonyCallbackTest, atest CtsTelephonyTestCases:TelephonyRegistryManagerTest Test: atest TelephonyRegistryTest, atest DefaultPhoneNotifierTest Test: Manual call tests related to emergency and non-emergency calls. Flag: com.android.internal.telephony.flags.emergency_callback_mode_notification Change-Id: I2db870b796b5bef9e9ac7d232ee4b960ed27731e --- core/api/system-current.txt | 16 +++ .../android/telephony/PhoneStateListener.java | 16 ++- .../android/telephony/TelephonyCallback.java | 104 ++++++++++++++---- .../telephony/TelephonyRegistryManager.java | 32 +++++- .../telephony/IPhoneStateListener.aidl | 5 +- .../telephony/ITelephonyRegistry.aidl | 3 +- .../com/android/server/TelephonyRegistry.java | 104 +++++++++++------- .../android/telephony/TelephonyManager.java | 41 +++++-- 8 files changed, 240 insertions(+), 81 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index ede4a8957b6f..199824e377f1 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -15320,6 +15320,7 @@ package android.telephony { field public static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 7; // 0x7 field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_DATA_ENABLED_CHANGED = 34; // 0x22 field public static final int EVENT_DISPLAY_INFO_CHANGED = 21; // 0x15 + field @FlaggedApi("com.android.internal.telephony.flags.emergency_callback_mode_notification") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_EMERGENCY_CALLBACK_MODE_CHANGED = 40; // 0x28 field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25; // 0x19 field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28; // 0x1c field @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public static final int EVENT_LEGACY_CALL_STATE_CHANGED = 36; // 0x24 @@ -15357,6 +15358,12 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onDataEnabledChanged(boolean, int); } + @FlaggedApi("com.android.internal.telephony.flags.emergency_callback_mode_notification") public static interface TelephonyCallback.EmergencyCallbackModeListener { + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onCallbackModeRestarted(int, @NonNull java.time.Duration, int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onCallbackModeStarted(int, @NonNull java.time.Duration, int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onCallbackModeStopped(int, int, int); + } + public static interface TelephonyCallback.LinkCapacityEstimateChangedListener { method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onLinkCapacityEstimateChanged(@NonNull java.util.List); } @@ -15618,6 +15625,8 @@ package android.telephony { field public static final int CELL_BROADCAST_RESULT_SUCCESS = 0; // 0x0 field public static final int CELL_BROADCAST_RESULT_UNKNOWN = -1; // 0xffffffff field public static final int CELL_BROADCAST_RESULT_UNSUPPORTED = 1; // 0x1 + field @FlaggedApi("com.android.internal.telephony.flags.emergency_callback_mode_notification") public static final int EMERGENCY_CALLBACK_MODE_CALL = 1; // 0x1 + field @FlaggedApi("com.android.internal.telephony.flags.emergency_callback_mode_notification") public static final int EMERGENCY_CALLBACK_MODE_SMS = 2; // 0x2 field public static final int ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE = 4; // 0x4 field public static final int ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED = 1; // 0x1 field public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR = 3; // 0x3 @@ -15675,6 +15684,13 @@ package android.telephony { field public static final int SRVCC_STATE_HANDOVER_FAILED = 2; // 0x2 field public static final int SRVCC_STATE_HANDOVER_NONE = -1; // 0xffffffff field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0 + field @FlaggedApi("com.android.internal.telephony.flags.emergency_callback_mode_notification") public static final int STOP_REASON_EMERGENCY_SMS_SENT = 4; // 0x4 + field @FlaggedApi("com.android.internal.telephony.flags.emergency_callback_mode_notification") public static final int STOP_REASON_NORMAL_SMS_SENT = 2; // 0x2 + field @FlaggedApi("com.android.internal.telephony.flags.emergency_callback_mode_notification") public static final int STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED = 3; // 0x3 + field @FlaggedApi("com.android.internal.telephony.flags.emergency_callback_mode_notification") public static final int STOP_REASON_OUTGOING_NORMAL_CALL_INITIATED = 1; // 0x1 + field @FlaggedApi("com.android.internal.telephony.flags.emergency_callback_mode_notification") public static final int STOP_REASON_TIMER_EXPIRED = 5; // 0x5 + field @FlaggedApi("com.android.internal.telephony.flags.emergency_callback_mode_notification") public static final int STOP_REASON_UNKNOWN = 0; // 0x0 + field @FlaggedApi("com.android.internal.telephony.flags.emergency_callback_mode_notification") public static final int STOP_REASON_USER_ACTION = 6; // 0x6 field public static final int THERMAL_MITIGATION_RESULT_INVALID_STATE = 3; // 0x3 field public static final int THERMAL_MITIGATION_RESULT_MODEM_ERROR = 1; // 0x1 field public static final int THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE = 2; // 0x2 diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 5ac0c50a312e..e8ef9d65a2b4 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -1671,14 +1671,22 @@ public class PhoneStateListener { } /** @hide */ - public final void onCallBackModeStarted( - @TelephonyManager.EmergencyCallbackModeType int type) { + public final void onCallbackModeStarted( + @TelephonyManager.EmergencyCallbackModeType int type, long durationMillis, + int subId) { // not support. Can't override. Use TelephonyCallback. } /** @hide */ - public final void onCallBackModeStopped(@EmergencyCallbackModeType int type, - @EmergencyCallbackModeStopReason int reason) { + public final void onCallbackModeRestarted( + @TelephonyManager.EmergencyCallbackModeType int type, long durationMillis, + int subId) { + // not support. Can't override. Use TelephonyCallback. + } + + /** @hide */ + public final void onCallbackModeStopped(@EmergencyCallbackModeType int type, + @EmergencyCallbackModeStopReason int reason, int subId) { // not support. Can't override. Use TelephonyCallback. } diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java index c360e64c8c1a..14d5800e4db7 100644 --- a/core/java/android/telephony/TelephonyCallback.java +++ b/core/java/android/telephony/TelephonyCallback.java @@ -41,6 +41,7 @@ import dalvik.system.VMRuntime; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; +import java.time.Duration; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -619,16 +620,20 @@ public class TelephonyCallback { /** - * Event for changes to the Emergency callback mode + * Event for changes to the emergency callback mode * *

    Requires permission {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} * - * @see EmergencyCallbackModeListener#onCallbackModeStarted(int) - * @see EmergencyCallbackModeListener#onCallbackModeStopped(int, int) + * @see EmergencyCallbackModeListener#onCallbackModeStarted(int, Duration, int) + * @see EmergencyCallbackModeListener#onCallbackModeRestarted(int, Duration, int) + * @see EmergencyCallbackModeListener#onCallbackModeStopped(int, int, int) * * @hide */ + + @FlaggedApi(Flags.FLAG_EMERGENCY_CALLBACK_MODE_NOTIFICATION) @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @SystemApi public static final int EVENT_EMERGENCY_CALLBACK_MODE_CHANGED = 40; /** @@ -1671,39 +1676,64 @@ public class TelephonyCallback { } /** - * Interface for emergency callback mode listener. + * Interface for the emergency callback mode listener. * * @hide */ + @FlaggedApi(Flags.FLAG_EMERGENCY_CALLBACK_MODE_NOTIFICATION) + @SystemApi public interface EmergencyCallbackModeListener { /** - * Indicates that Callback Mode has been started. + * Indicates that emergency callback mode has been started. *

    - * This method will be called when an emergency sms/emergency call is sent - * and the callback mode is supported by the carrier. - * If an emergency SMS is transmitted during callback mode for SMS, this API will be called - * once again with TelephonyManager#EMERGENCY_CALLBACK_MODE_SMS. + * This method will be called when an emergency SMS or emergency call is ended and + * the emergency callback mode is supported by the carrier. + * If the emergency callback mode was started for an emergency call and an emergency SMS is + * transmitted during callback mode for SMS then this API will be called once again with + * TelephonyManager#EMERGENCY_CALLBACK_MODE_SMS. * - * @param type for callback mode entry + * @param type for the emergency callback mode entry * See {@link TelephonyManager.EmergencyCallbackModeType}. * @see TelephonyManager#EMERGENCY_CALLBACK_MODE_CALL * @see TelephonyManager#EMERGENCY_CALLBACK_MODE_SMS + * + * @param timerDuration is the time remaining in the emergency callback mode. + * @param subId The subscription ID used to start the emergency callback mode. */ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - void onCallBackModeStarted(@TelephonyManager.EmergencyCallbackModeType int type); + void onCallbackModeStarted(@TelephonyManager.EmergencyCallbackModeType int type, + @NonNull Duration timerDuration, int subId); /** - * Indicates that Callback Mode has been stopped. + * Indicates that emergency callback mode has been re-started. *

    - * This method will be called when the callback mode timer expires or when - * a normal call/SMS is sent + * This method will be called when an emergency SMS or emergency call is ended + * in the emergency callback mode. + * This is used to restart the emergency callback mode when it is already in progress. * - * @param type for callback mode entry + * @param type for the emergency callback mode entry + * See {@link TelephonyManager.EmergencyCallbackModeType}. * @see TelephonyManager#EMERGENCY_CALLBACK_MODE_CALL * @see TelephonyManager#EMERGENCY_CALLBACK_MODE_SMS * - * @param reason for changing callback mode + * @param timerDuration is the time remaining in the emergency callback mode. + * @param subId The subscription ID used to restart the emergency callback mode. + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + void onCallbackModeRestarted(@TelephonyManager.EmergencyCallbackModeType int type, + @NonNull Duration timerDuration, int subId); + + /** + * Indicates that emergency callback mode has been stopped. + *

    + * This method will be called when the emergency callback mode timer expires or when + * a normal call/SMS is sent + * + * @param type for the emergency callback mode entry + * @see TelephonyManager#EMERGENCY_CALLBACK_MODE_CALL + * @see TelephonyManager#EMERGENCY_CALLBACK_MODE_SMS * + * @param reason for changing emergency callback mode * @see TelephonyManager#STOP_REASON_UNKNOWN * @see TelephonyManager#STOP_REASON_OUTGOING_NORMAL_CALL_INITIATED * @see TelephonyManager#STOP_REASON_NORMAL_SMS_SENT @@ -1711,10 +1741,12 @@ public class TelephonyCallback { * @see TelephonyManager#STOP_REASON_EMERGENCY_SMS_SENT * @see TelephonyManager#STOP_REASON_TIMER_EXPIRED * @see TelephonyManager#STOP_REASON_USER_ACTION + * + * @param subId is the current subscription used the emergency callback mode. */ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - void onCallBackModeStopped(@TelephonyManager.EmergencyCallbackModeType int type, - @TelephonyManager.EmergencyCallbackModeStopReason int reason); + void onCallbackModeStopped(@TelephonyManager.EmergencyCallbackModeType int type, + @TelephonyManager.EmergencyCallbackModeStopReason int reason, int subId); } /** @@ -2132,18 +2164,43 @@ public class TelephonyCallback { mediaQualityStatus))); } - public void onCallBackModeStarted(@TelephonyManager.EmergencyCallbackModeType int type) { + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void onCallbackModeStarted(@TelephonyManager.EmergencyCallbackModeType int type, + long durationMillis, int subId) { + if (!Flags.emergencyCallbackModeNotification()) return; + EmergencyCallbackModeListener listener = (EmergencyCallbackModeListener) mTelephonyCallbackWeakRef.get(); Log.d(LOG_TAG, "onCallBackModeStarted:type=" + type + ", listener=" + listener); if (listener == null) return; + final Duration timerDuration = Duration.ofMillis(durationMillis); Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> listener.onCallBackModeStarted(type))); + () -> mExecutor.execute(() -> listener.onCallbackModeStarted(type, + timerDuration, subId))); } - public void onCallBackModeStopped(@TelephonyManager.EmergencyCallbackModeType int type, - @TelephonyManager.EmergencyCallbackModeStopReason int reason) { + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void onCallbackModeRestarted(@TelephonyManager.EmergencyCallbackModeType int type, + long durationMillis, int subId) { + if (!Flags.emergencyCallbackModeNotification()) return; + + EmergencyCallbackModeListener listener = + (EmergencyCallbackModeListener) mTelephonyCallbackWeakRef.get(); + Log.d(LOG_TAG, "onCallbackModeRestarted:type=" + type + ", listener=" + listener); + if (listener == null) return; + + final Duration timerDuration = Duration.ofMillis(durationMillis); + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onCallbackModeRestarted(type, + timerDuration, subId))); + } + + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void onCallbackModeStopped(@TelephonyManager.EmergencyCallbackModeType int type, + @TelephonyManager.EmergencyCallbackModeStopReason int reason, int subId) { + if (!Flags.emergencyCallbackModeNotification()) return; + EmergencyCallbackModeListener listener = (EmergencyCallbackModeListener) mTelephonyCallbackWeakRef.get(); Log.d(LOG_TAG, "onCallBackModeStopped:type=" + type @@ -2151,7 +2208,8 @@ public class TelephonyCallback { if (listener == null) return; Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> listener.onCallBackModeStopped(type, reason))); + () -> mExecutor.execute(() -> listener.onCallbackModeStopped(type, reason, + subId))); } public void onCarrierRoamingNtnModeChanged(boolean active) { diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 10f03c15310c..3c7e924f07df 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -115,7 +115,6 @@ public class TelephonyRegistryManager { ICarrierConfigChangeListener> mCarrierConfigChangeListenerMap = new ConcurrentHashMap<>(); - /** @hide **/ public TelephonyRegistryManager(@NonNull Context context) { mContext = context; @@ -1721,13 +1720,36 @@ public class TelephonyRegistryManager { * @param subId Sender subscription ID. * @param type for callback mode entry. * See {@link TelephonyManager.EmergencyCallbackModeType}. + * @param durationMillis is the number of milliseconds remaining in the emergency callback + * mode. + * @hide + */ + public void notifyCallbackModeStarted(int phoneId, int subId, + @TelephonyManager.EmergencyCallbackModeType int type, long durationMillis) { + try { + Log.d(TAG, "notifyCallbackModeStarted:type=" + type); + sRegistry.notifyCallbackModeStarted(phoneId, subId, type, durationMillis); + } catch (RemoteException ex) { + // system process is dead + throw ex.rethrowFromSystemServer(); + } + } + + /** + * Notify Callback Mode has been restarted. + * @param phoneId Sender phone ID. + * @param subId Sender subscription ID. + * @param type for callback mode entry. + * See {@link TelephonyManager.EmergencyCallbackModeType}. + * @param durationMillis is the number of milliseconds remaining in the emergency callback + * mode. * @hide */ - public void notifyCallBackModeStarted(int phoneId, int subId, - @TelephonyManager.EmergencyCallbackModeType int type) { + public void notifyCallbackModeRestarted(int phoneId, int subId, + @TelephonyManager.EmergencyCallbackModeType int type, long durationMillis) { try { - Log.d(TAG, "notifyCallBackModeStarted:type=" + type); - sRegistry.notifyCallbackModeStarted(phoneId, subId, type); + Log.d(TAG, "notifyCallbackModeRestarted:type=" + type); + sRegistry.notifyCallbackModeRestarted(phoneId, subId, type, durationMillis); } catch (RemoteException ex) { // system process is dead throw ex.rethrowFromSystemServer(); diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl index f177e1473b6a..81b885aa626b 100644 --- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -78,8 +78,9 @@ oneway interface IPhoneStateListener { void onAllowedNetworkTypesChanged(in int reason, in long allowedNetworkType); void onLinkCapacityEstimateChanged(in List linkCapacityEstimateList); void onMediaQualityStatusChanged(in MediaQualityStatus mediaQualityStatus); - void onCallBackModeStarted(int type); - void onCallBackModeStopped(int type, int reason); + void onCallbackModeStarted(int type, long durationMillis, int subId); + void onCallbackModeRestarted(int type, long durationMillis, int subId); + void onCallbackModeStopped(int type, int reason, int subId); void onSimultaneousCallingStateChanged(in int[] subIds); void onCarrierRoamingNtnModeChanged(in boolean active); void onCarrierRoamingNtnEligibleStateChanged(in boolean eligible); diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index e500a37abb53..f836cf2b9d87 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -118,7 +118,8 @@ interface ITelephonyRegistry { void removeCarrierConfigChangeListener(ICarrierConfigChangeListener listener, String pkg); void notifyCarrierConfigChanged(int phoneId, int subId, int carrierId, int specificCarrierId); - void notifyCallbackModeStarted(int phoneId, int subId, int type); + void notifyCallbackModeStarted(int phoneId, int subId, int type, long durationMillis); + void notifyCallbackModeRestarted(int phoneId, int subId, int type, long durationMillis); void notifyCallbackModeStopped(int phoneId, int subId, int type, int reason); void notifyCarrierRoamingNtnModeChanged(int subId, in boolean active); void notifyCarrierRoamingNtnEligibleStateChanged(int subId, in boolean eligible); diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 744227760d95..39ac5150c7f1 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -422,9 +422,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private int[] mSimultaneousCellularCallingSubIds = {}; private int[] mECBMReason; - private boolean[] mECBMStarted; + private long[] mECBMDuration; private int[] mSCBMReason; - private boolean[] mSCBMStarted; + private long[] mSCBMDuration; private boolean[] mCarrierRoamingNtnMode = null; private boolean[] mCarrierRoamingNtnEligible = null; @@ -724,9 +724,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mAllowedNetworkTypeReason = copyOf(mAllowedNetworkTypeReason, mNumPhones); mAllowedNetworkTypeValue = copyOf(mAllowedNetworkTypeValue, mNumPhones); mECBMReason = copyOf(mECBMReason, mNumPhones); - mECBMStarted = copyOf(mECBMStarted, mNumPhones); + mECBMDuration = copyOf(mECBMDuration, mNumPhones); mSCBMReason = copyOf(mSCBMReason, mNumPhones); - mSCBMStarted = copyOf(mSCBMStarted, mNumPhones); + mSCBMDuration = copyOf(mSCBMDuration, mNumPhones); mCarrierRoamingNtnMode = copyOf(mCarrierRoamingNtnMode, mNumPhones); mCarrierRoamingNtnEligible = copyOf(mCarrierRoamingNtnEligible, mNumPhones); // ds -> ss switch. @@ -784,9 +784,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0])); mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID)); mECBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN; - mECBMStarted[i] = false; + mECBMDuration[i] = 0; mSCBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN; - mSCBMStarted[i] = false; + mSCBMDuration[i] = 0; mCarrierRoamingNtnMode[i] = false; mCarrierRoamingNtnEligible[i] = false; } @@ -859,9 +859,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCarrierPrivilegeStates = new ArrayList<>(); mCarrierServiceStates = new ArrayList<>(); mECBMReason = new int[numPhones]; - mECBMStarted = new boolean[numPhones]; + mECBMDuration = new long[numPhones]; mSCBMReason = new int[numPhones]; - mSCBMStarted = new boolean[numPhones]; + mSCBMDuration = new long[numPhones]; mCarrierRoamingNtnMode = new boolean[numPhones]; mCarrierRoamingNtnEligible = new boolean[numPhones]; @@ -904,9 +904,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0])); mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID)); mECBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN; - mECBMStarted[i] = false; + mECBMDuration[i] = 0; mSCBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN; - mSCBMStarted[i] = false; + mSCBMDuration[i] = 0; mCarrierRoamingNtnMode[i] = false; mCarrierRoamingNtnEligible[i] = false; } @@ -1493,24 +1493,24 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } if (events.contains(TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)) { try { - boolean ecbmStarted = mECBMStarted[r.phoneId]; - if (ecbmStarted) { - r.callback.onCallBackModeStarted( - TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL); + if (mECBMDuration[r.phoneId] != 0) { + r.callback.onCallbackModeStarted( + TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL, + mECBMDuration[r.phoneId], r.subId); } else { - r.callback.onCallBackModeStopped( + r.callback.onCallbackModeStopped( TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL, - mECBMReason[r.phoneId]); + mECBMReason[r.phoneId], r.subId); } - boolean scbmStarted = mSCBMStarted[r.phoneId]; - if (scbmStarted) { - r.callback.onCallBackModeStarted( - TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS); + if (mSCBMReason[r.phoneId] != 0) { + r.callback.onCallbackModeStarted( + TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS, + mSCBMDuration[r.phoneId], r.subId); } else { - r.callback.onCallBackModeStopped( + r.callback.onCallbackModeStopped( TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS, - mSCBMReason[r.phoneId]); + mSCBMReason[r.phoneId], r.subId); } } catch (RemoteException ex) { remove(r.binder); @@ -3457,10 +3457,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void notifyCallbackModeStarted(int phoneId, int subId, int type) { - if (!checkNotifyPermission("notifyCallbackModeStarted()")) { - return; - } + public void notifyCallbackModeStarted(int phoneId, int subId, int type, long durationMillis) { + if (!checkNotifyPermission("notifyCallbackModeStarted()")) return; + if (VDBG) { log("notifyCallbackModeStarted: phoneId=" + phoneId + ", subId=" + subId + ", type=" + type); @@ -3468,9 +3467,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { if (validatePhoneId(phoneId)) { if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL) { - mECBMStarted[phoneId] = true; + mECBMDuration[phoneId] = durationMillis; } else if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS) { - mSCBMStarted[phoneId] = true; + mSCBMDuration[phoneId] = durationMillis; } } for (Record r : mRecords) { @@ -3478,7 +3477,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (r.matchTelephonyCallbackEvent( TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)) { try { - r.callback.onCallBackModeStarted(type); + r.callback.onCallbackModeStarted(type, durationMillis, subId); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -3489,10 +3488,41 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void notifyCallbackModeStopped(int phoneId, int subId, int type, int reason) { - if (!checkNotifyPermission("notifyCallbackModeStopped()")) { - return; + public void notifyCallbackModeRestarted(int phoneId, int subId, int type, + long durationMillis) { + if (!checkNotifyPermission("notifyCallbackModeRestarted()")) return; + + if (VDBG) { + log("notifyCallbackModeRestarted: phoneId=" + phoneId + ", subId=" + subId + + ", type=" + type); } + synchronized (mRecords) { + if (validatePhoneId(phoneId)) { + if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL) { + mECBMDuration[phoneId] = durationMillis; + } else if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS) { + mSCBMDuration[phoneId] = durationMillis; + } + } + for (Record r : mRecords) { + // Send to all listeners regardless of subscription + if (r.matchTelephonyCallbackEvent( + TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)) { + try { + r.callback.onCallbackModeRestarted(type, durationMillis, subId); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + } + } + handleRemoveListLocked(); + } + + @Override + public void notifyCallbackModeStopped(int phoneId, int subId, int type, int reason) { + if (!checkNotifyPermission("notifyCallbackModeStopped()")) return; + if (VDBG) { log("notifyCallbackModeStopped: phoneId=" + phoneId + ", subId=" + subId + ", type=" + type + ", reason=" + reason); @@ -3500,11 +3530,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { if (validatePhoneId(phoneId)) { if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL) { - mECBMStarted[phoneId] = false; mECBMReason[phoneId] = reason; + mECBMDuration[phoneId] = 0; } else if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS) { - mSCBMStarted[phoneId] = false; mSCBMReason[phoneId] = reason; + mSCBMDuration[phoneId] = 0; } } for (Record r : mRecords) { @@ -3512,7 +3542,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (r.matchTelephonyCallbackEvent( TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)) { try { - r.callback.onCallBackModeStopped(type, reason); + r.callback.onCallbackModeStopped(type, reason, subId); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -3662,9 +3692,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mPhysicalChannelConfigs=" + mPhysicalChannelConfigs.get(i)); pw.println("mLinkCapacityEstimateList=" + mLinkCapacityEstimateLists.get(i)); pw.println("mECBMReason=" + mECBMReason[i]); - pw.println("mECBMStarted=" + mECBMStarted[i]); + pw.println("mECBMDuration=" + mECBMDuration[i]); pw.println("mSCBMReason=" + mSCBMReason[i]); - pw.println("mSCBMStarted=" + mSCBMStarted[i]); + pw.println("mSCBMDuration=" + mSCBMDuration[i]); pw.println("mCarrierRoamingNtnMode=" + mCarrierRoamingNtnMode[i]); pw.println("mCarrierRoamingNtnEligible=" + mCarrierRoamingNtnEligible[i]); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 3e226ccf2737..6fe9be12af2d 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -19185,15 +19185,19 @@ public class TelephonyManager { public @interface EmergencyCallbackModeType {} /** - * The callback mode is due to emergency call. + * The emergency callback mode is due to emergency call. * @hide */ + @FlaggedApi(Flags.FLAG_EMERGENCY_CALLBACK_MODE_NOTIFICATION) + @SystemApi public static final int EMERGENCY_CALLBACK_MODE_CALL = 1; /** - * The callback mode is due to emergency SMS. + * The emergency callback mode is due to emergency SMS. * @hide */ + @FlaggedApi(Flags.FLAG_EMERGENCY_CALLBACK_MODE_NOTIFICATION) + @SystemApi public static final int EMERGENCY_CALLBACK_MODE_SMS = 2; /** @@ -19214,45 +19218,64 @@ public class TelephonyManager { public @interface EmergencyCallbackModeStopReason {} /** - * unknown reason. + * Indicates that emergency callback mode has been stopped for an unknown reason. * @hide */ + @FlaggedApi(Flags.FLAG_EMERGENCY_CALLBACK_MODE_NOTIFICATION) + @SystemApi public static final int STOP_REASON_UNKNOWN = 0; /** - * The call back mode is exited due to a new normal call is originated. + * Indicates that emergency callback mode has been stopped because a new non-emergency call was + * initiated. * @hide */ + @FlaggedApi(Flags.FLAG_EMERGENCY_CALLBACK_MODE_NOTIFICATION) + @SystemApi public static final int STOP_REASON_OUTGOING_NORMAL_CALL_INITIATED = 1; /** - * The call back mode is exited due to a new normal SMS is originated. + * Indicates that emergency callback mode has been stopped because a new non-emergency SMS was + * sent. * @hide */ + @FlaggedApi(Flags.FLAG_EMERGENCY_CALLBACK_MODE_NOTIFICATION) + @SystemApi public static final int STOP_REASON_NORMAL_SMS_SENT = 2; /** - * The call back mode is exited due to a new emergency call is originated. + * Indicates that emergency callback mode has been stopped because a new outgoing emergency + * call was initiated. * @hide */ + @FlaggedApi(Flags.FLAG_EMERGENCY_CALLBACK_MODE_NOTIFICATION) + @SystemApi public static final int STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED = 3; /** - * The call back mode is exited due to a new emergency SMS is originated. + * Indicates that emergency callback mode has been stopped because a new emergency SMS was sent. * @hide */ + @FlaggedApi(Flags.FLAG_EMERGENCY_CALLBACK_MODE_NOTIFICATION) + @SystemApi public static final int STOP_REASON_EMERGENCY_SMS_SENT = 4; /** - * The call back mode is exited due to timer expiry. + * Indicates that emergency callback mode has been stopped due to the emergency callback mode + * timer expiry. * @hide */ + @FlaggedApi(Flags.FLAG_EMERGENCY_CALLBACK_MODE_NOTIFICATION) + @SystemApi public static final int STOP_REASON_TIMER_EXPIRED = 5; /** - * The call back mode is exited due to user action. + * Indicates that emergency callback mode has been stopped due to user ending the emergency + * mode by clicking the notification. * @hide */ + @FlaggedApi(Flags.FLAG_EMERGENCY_CALLBACK_MODE_NOTIFICATION) + @SystemApi public static final int STOP_REASON_USER_ACTION = 6; /** -- GitLab From 34bb4166d47c694e563aa226e95e58e76f77cb42 Mon Sep 17 00:00:00 2001 From: Edgar Wang Date: Mon, 7 Oct 2024 08:20:56 +0000 Subject: [PATCH 103/447] Update SettingsLib resource and fix lint warning Bug: 366336385 Test: manual Flag: EXEMPT resource only update Change-Id: I8478007c2e81a3c72a47c8d24c5b18c0a37723c8 --- .../res/drawable/half_rounded_left_bk.xml | 26 +++++----- .../res/drawable/left_rounded_ripple.xml | 26 +++++----- .../res/drawable/right_rounded_ripple.xml | 26 +++++----- .../res/drawable/rounded_ripple.xml | 26 +++++----- .../res/drawable/square_bk.xml | 26 +++++----- .../res/drawable/square_ripple.xml | 26 +++++----- .../res/values/arrays.xml | 26 +++++----- ...ettingslib_expressive_preference_intro.xml | 1 - .../res/values/attrs.xml | 29 +++++------ .../drawable-v31/settingslib_list_divider.xml | 22 +++++++++ .../settingslib_expressive_icon_chevron.xml | 26 +++++----- .../drawable-v35/settingslib_list_divider.xml | 22 +++++++++ .../settingslib_preference_frame.xml | 2 - .../res/layout-v33/settingslib_preference.xml | 48 ------------------- .../settingslib_preference_frame.xml | 2 - ...ngslib_expressive_collapsable_textview.xml | 1 + .../settingslib_expressive_preference.xml | 3 +- ...gslib_expressive_preference_icon_frame.xml | 3 +- ...ttingslib_expressive_preference_switch.xml | 1 + ...gslib_expressive_preference_text_frame.xml | 13 +++-- ...tingslib_expressive_two_target_divider.xml | 29 +++++------ ...ttingslib_preference_category_no_title.xml | 3 +- .../res/values-night-v31/colors.xml | 2 + .../SettingsTheme/res/values-v31/colors.xml | 2 + .../SettingsTheme/res/values-v31/themes.xml | 1 + .../res/{values-v35 => values}/strings.xml | 2 +- .../settingslib/widget/CollapsableTextView.kt | 4 +- .../settingslib/widget/SettingsThemeHelper.kt | 4 +- 28 files changed, 203 insertions(+), 199 deletions(-) create mode 100644 packages/SettingsLib/SettingsTheme/res/drawable-v31/settingslib_list_divider.xml create mode 100644 packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_list_divider.xml delete mode 100644 packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference.xml rename packages/SettingsLib/SettingsTheme/res/{values-v35 => values}/strings.xml (94%) diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml index 0d4ef3c52e4c..8d6f0da4262f 100644 --- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml +++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml @@ -1,18 +1,18 @@ diff --git a/packages/SettingsLib/IntroPreference/res/layout/settingslib_expressive_preference_intro.xml b/packages/SettingsLib/IntroPreference/res/layout/settingslib_expressive_preference_intro.xml index 203a395c3e98..2edc001ccc3f 100644 --- a/packages/SettingsLib/IntroPreference/res/layout/settingslib_expressive_preference_intro.xml +++ b/packages/SettingsLib/IntroPreference/res/layout/settingslib_expressive_preference_intro.xml @@ -31,7 +31,6 @@ diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v31/settingslib_list_divider.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v31/settingslib_list_divider.xml new file mode 100644 index 000000000000..eb588d9fd585 --- /dev/null +++ b/packages/SettingsLib/SettingsTheme/res/drawable-v31/settingslib_list_divider.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_expressive_icon_chevron.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_expressive_icon_chevron.xml index 16ca18ae2200..94476538a6a5 100644 --- a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_expressive_icon_chevron.xml +++ b/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_expressive_icon_chevron.xml @@ -1,18 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v31/settingslib_preference_frame.xml b/packages/SettingsLib/SettingsTheme/res/layout-v31/settingslib_preference_frame.xml index 433d26445c4d..128f7a1bbb09 100644 --- a/packages/SettingsLib/SettingsTheme/res/layout-v31/settingslib_preference_frame.xml +++ b/packages/SettingsLib/SettingsTheme/res/layout-v31/settingslib_preference_frame.xml @@ -29,7 +29,6 @@ android:layout_height="wrap_content" android:layout_gravity="start" android:textAlignment="viewStart" - android:text="Title" android:maxLines="2" android:textAppearance="?android:attr/textAppearanceListItem" android:ellipsize="marquee"/> @@ -41,7 +40,6 @@ android:layout_below="@android:id/title" android:layout_alignLeft="@android:id/title" android:layout_alignStart="@android:id/title" - android:text="Summary summary summary" android:layout_gravity="start" android:textAlignment="viewStart" android:textColor="?android:attr/textColorSecondary" diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference.xml b/packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference.xml deleted file mode 100644 index 4e23b6562e3e..000000000000 --- a/packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference_frame.xml b/packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference_frame.xml index f93e1b975eb2..599e8170d538 100644 --- a/packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference_frame.xml +++ b/packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference_frame.xml @@ -29,7 +29,6 @@ android:layout_height="wrap_content" android:layout_gravity="start" android:textAlignment="viewStart" - android:text="Title" android:maxLines="2" android:hyphenationFrequency="normalFast" android:lineBreakWordStyle="phrase" @@ -47,7 +46,6 @@ android:textAlignment="viewStart" android:textColor="?android:attr/textColorSecondary" android:maxLines="10" - android:text="Summary summary summary" android:hyphenationFrequency="normalFast" android:lineBreakWordStyle="phrase" style="@style/PreferenceSummaryTextStyle"/> diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml index 4cc3c89dadb5..ea7baa42a2c7 100644 --- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml +++ b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml @@ -25,6 +25,7 @@ android:orientation="vertical" android:animateLayoutChanges="true" android:background="?android:attr/selectableItemBackground" + android:filterTouchesWhenObscured="false" android:clipToPadding="false"> + android:baselineAligned="false" + android:filterTouchesWhenObscured="false"> diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_icon_frame.xml b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_icon_frame.xml index f5017a5ae368..ccdf37d452b0 100644 --- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_icon_frame.xml +++ b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_icon_frame.xml @@ -22,7 +22,8 @@ android:minWidth="@dimen/settingslib_expressive_space_medium3" android:minHeight="@dimen/settingslib_expressive_space_medium3" android:gravity="center" - android:layout_marginEnd="-8dp"> + android:layout_marginEnd="-8dp" + android:filterTouchesWhenObscured="false"> \ No newline at end of file diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_text_frame.xml b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_text_frame.xml index e3e689b4838c..cc42dab6737e 100644 --- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_text_frame.xml +++ b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_preference_text_frame.xml @@ -20,7 +20,8 @@ android:layout_width="@dimen/settingslib_expressive_space_none" android:layout_height="wrap_content" android:layout_weight="1" - android:padding="@dimen/settingslib_expressive_space_small1"> + android:paddingVertical="@dimen/settingslib_expressive_space_small1" + android:filterTouchesWhenObscured="false"> - + android:maxLines="10" + android:hyphenationFrequency="normalFast" + android:lineBreakWordStyle="phrase"/> + \ No newline at end of file diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_two_target_divider.xml b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_two_target_divider.xml index 3f751812ee40..9be9ec331984 100644 --- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_two_target_divider.xml +++ b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_two_target_divider.xml @@ -1,18 +1,18 @@ + android:paddingVertical="@dimen/settingslib_expressive_space_extrasmall7" + android:filterTouchesWhenObscured="false"> + android:baselineAligned="false" + android:filterTouchesWhenObscured="false"> diff --git a/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml index 0a36a4fa035f..313748d8f091 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml @@ -56,4 +56,6 @@ @color/settingslib_surface_dark + + @android:color/system_neutral1_700 \ No newline at end of file diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml index 7706e0e8a296..b99ee5123491 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml @@ -90,4 +90,6 @@ @android:color/system_neutral1_900 @android:color/system_neutral2_700 + + @android:color/system_neutral1_200 diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml index 698f21d8d8a6..3ccbbc063064 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml @@ -27,6 +27,7 @@ @style/Switch.SettingsLib @style/SwitchCompat.SettingsLib @style/HorizontalProgressBar.SettingsLib + @drawable/settingslib_list_divider - - diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 629c94f9a044..1727a5fec0a2 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -2048,5 +2048,6 @@ 64dp 64dp - 70dp + 80dp + 2dp diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 1c09f84b6fd0..a02c35461031 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -1720,10 +1720,4 @@ - - diff --git a/packages/SystemUI/src/com/android/systemui/education/ui/view/ContextualEduDialog.kt b/packages/SystemUI/src/com/android/systemui/education/ui/view/ContextualEduDialog.kt index 287e85ca4358..ca92953dca4a 100644 --- a/packages/SystemUI/src/com/android/systemui/education/ui/view/ContextualEduDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/education/ui/view/ContextualEduDialog.kt @@ -16,32 +16,40 @@ package com.android.systemui.education.ui.view -import android.app.AlertDialog +import android.app.Dialog import android.content.Context import android.os.Bundle import android.view.Gravity +import android.view.Window import android.view.WindowManager -import android.widget.ToastPresenter +import android.widget.ImageView +import android.widget.TextView import com.android.systemui.education.ui.viewmodel.ContextualEduToastViewModel import com.android.systemui.res.R class ContextualEduDialog(context: Context, private val model: ContextualEduToastViewModel) : - AlertDialog(context, R.style.ContextualEduDialog) { + Dialog(context) { override fun onCreate(savedInstanceState: Bundle?) { setUpWindowProperties() setWindowPosition() // title is used for a11y announcement window?.setTitle(context.getString(R.string.contextual_education_dialog_title)) - // TODO: b/369791926 - replace the below toast view with a custom dialog view - val toastView = ToastPresenter.getTextToastView(context, model.message) - setView(toastView) + setContentView(R.layout.contextual_edu_dialog) + setContent() super.onCreate(savedInstanceState) } + private fun setContent() { + findViewById(R.id.edu_message)?.let { it.text = model.message } + findViewById(R.id.edu_icon)?.let { it.setImageResource(model.icon) } + } + private fun setUpWindowProperties() { window?.apply { + requestFeature(Window.FEATURE_NO_TITLE) setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG) clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) + setBackgroundDrawableResource(android.R.color.transparent) } setCanceledOnTouchOutside(false) } diff --git a/packages/SystemUI/src/com/android/systemui/education/ui/viewmodel/ContextualEduContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/education/ui/viewmodel/ContextualEduContentViewModel.kt index 632b250512cb..5a02cda8c3f5 100644 --- a/packages/SystemUI/src/com/android/systemui/education/ui/viewmodel/ContextualEduContentViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/education/ui/viewmodel/ContextualEduContentViewModel.kt @@ -21,8 +21,11 @@ sealed class ContextualEduContentViewModel(open val userId: Int) data class ContextualEduNotificationViewModel( val title: String, val message: String, - override val userId: Int + override val userId: Int, ) : ContextualEduContentViewModel(userId) -data class ContextualEduToastViewModel(val message: String, override val userId: Int) : - ContextualEduContentViewModel(userId) +data class ContextualEduToastViewModel( + val message: String, + val icon: Int, + override val userId: Int, +) : ContextualEduContentViewModel(userId) diff --git a/packages/SystemUI/src/com/android/systemui/education/ui/viewmodel/ContextualEduViewModel.kt b/packages/SystemUI/src/com/android/systemui/education/ui/viewmodel/ContextualEduViewModel.kt index 32e7f41f36b8..9eb88f8590f4 100644 --- a/packages/SystemUI/src/com/android/systemui/education/ui/viewmodel/ContextualEduViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/education/ui/viewmodel/ContextualEduViewModel.kt @@ -71,7 +71,7 @@ constructor( it.userId, ) } else { - ContextualEduToastViewModel(getEduContent(it), it.userId) + ContextualEduToastViewModel(getEduContent(it), getEduIcon(it), it.userId) } } .timeout(timeoutMillis, emitAfterTimeout = null) @@ -118,4 +118,13 @@ constructor( return resources.getString(resourceId) } + + private fun getEduIcon(educationInfo: EducationInfo): Int { + return when (educationInfo.gestureType) { + BACK -> R.drawable.contextual_edu_swipe_back + HOME, + OVERVIEW -> R.drawable.contextual_edu_swipe_up + ALL_APPS -> R.drawable.contextual_edu_all_apps + } + } } -- GitLab From 9fe1ba455ad3d8c86be12d4469f4073387673807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Hern=C3=A1ndez?= Date: Mon, 7 Oct 2024 16:25:38 +0200 Subject: [PATCH 120/447] Allow access to the SelectorWithWidgetPreference's widget, for testing Bug: 371513451 Test: N/A, tested in ZenModePrioritySendersPreferenceControllerTest Flag: EXEMPT trivial Change-Id: I74cae2ec2d32c1528d901e4493cdc7d2f1ef8e79 --- .../settingslib/widget/SelectorWithWidgetPreference.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java b/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java index e6726dcbb17a..03a2101544be 100644 --- a/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java +++ b/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java @@ -255,4 +255,9 @@ public class SelectorWithWidgetPreference extends CheckBoxPreference { a.recycle(); } } + + @VisibleForTesting(otherwise = VisibleForTesting.NONE) + public View getExtraWidget() { + return mExtraWidget; + } } -- GitLab From 0120f3ed69121b25615320d62af6e98f4e3aac87 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Mon, 23 Sep 2024 17:23:15 -0700 Subject: [PATCH 121/447] Don't discriminate getPhoneType against data-only devices Bug: 364345595 Test: atest android.carrierapi.cts.CarrierApiTest Flag: EXEMPT bugfix Change-Id: Iaaf3360bce1ac949746d794e8aa38acd84250cce --- telephony/java/android/telephony/TelephonyManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 92effe05882a..4217814f726b 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -2757,7 +2757,7 @@ public class TelephonyManager { /** * Returns a constant indicating the device phone type. This - * indicates the type of radio used to transmit voice calls. + * indicates the type of radio used to transmit voice/data calls. * * @see #PHONE_TYPE_NONE * @see #PHONE_TYPE_GSM @@ -2769,7 +2769,7 @@ public class TelephonyManager { */ @RequiresFeature(PackageManager.FEATURE_TELEPHONY) public int getPhoneType() { - if (!isVoiceCapable()) { + if (!isVoiceCapable() && !isDataCapable()) { return PHONE_TYPE_NONE; } return getCurrentPhoneType(); -- GitLab From 8aa05f5e6aed3014c9e69df2e438d9bce850c950 Mon Sep 17 00:00:00 2001 From: Jordan Demeulenaere Date: Mon, 7 Oct 2024 14:29:10 +0200 Subject: [PATCH 122/447] Enable interruptions in compose Lockscreen This CL enables the enableInterruptions flag in the STLState used by the compose Lockscreen. This flag is already enabled by default in STLState and is going to be removed soon. Bug: 371951148 Test: Performed the AOD <=> Lockscreen transition with flexiglass on Flag: com.android.systemui.compose_lockscreen Change-Id: I6a3de04f59013202573e81490281943067365635 --- .../ui/composable/section/TopAreaSection.kt | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt index 97d89a2631bf..afa92f2533ce 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt @@ -83,11 +83,7 @@ constructor( } val state = remember { - MutableSceneTransitionLayoutState( - currentScene, - ClockTransition.defaultClockTransitions, - enableInterruptions = false, - ) + MutableSceneTransitionLayoutState(currentScene, ClockTransition.defaultClockTransitions) } // Update state whenever currentSceneKey has changed. @@ -102,7 +98,7 @@ constructor( scene(splitShadeLargeClockScene) { LargeClockWithSmartSpace( smartSpacePaddingTop = smartSpacePaddingTop, - shouldOffSetClockToOneHalf = !hasCustomPositionUpdatedAnimation + shouldOffSetClockToOneHalf = !hasCustomPositionUpdatedAnimation, ) } @@ -114,21 +110,15 @@ constructor( } scene(smallClockScene) { - SmallClockWithSmartSpace( - smartSpacePaddingTop = smartSpacePaddingTop, - ) + SmallClockWithSmartSpace(smartSpacePaddingTop = smartSpacePaddingTop) } scene(largeClockScene) { - LargeClockWithSmartSpace( - smartSpacePaddingTop = smartSpacePaddingTop, - ) + LargeClockWithSmartSpace(smartSpacePaddingTop = smartSpacePaddingTop) } scene(WeatherClockScenes.largeClockScene) { - WeatherLargeClockWithSmartSpace( - smartSpacePaddingTop = smartSpacePaddingTop, - ) + WeatherLargeClockWithSmartSpace(smartSpacePaddingTop = smartSpacePaddingTop) } scene(WeatherClockScenes.splitShadeLargeClockScene) { @@ -154,7 +144,7 @@ constructor( SmallClock( burnInParams = burnIn.parameters, onTopChanged = burnIn.onSmallClockTopChanged, - modifier = Modifier.wrapContentSize() + modifier = Modifier.wrapContentSize(), ) } with(smartSpaceSection) { @@ -202,7 +192,7 @@ constructor( y = 0, ) } - } + }, ) } } @@ -226,10 +216,7 @@ constructor( Column(modifier = modifier) { val currentClock = currentClockState.value ?: return@Column with(weatherClockSection) { - Time( - clock = currentClock, - burnInParams = burnIn.parameters, - ) + Time(clock = currentClock, burnInParams = burnIn.parameters) } val density = LocalDensity.current val context = LocalContext.current @@ -242,7 +229,7 @@ constructor( modifier = Modifier.heightIn( min = getDimen(context, "enhanced_smartspace_height", density) - ) + ), ) } with(weatherClockSection) { -- GitLab From 234c5e843ca427b1dd47e91e3969f3309dd787bf Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Mon, 7 Oct 2024 11:10:31 -0400 Subject: [PATCH 123/447] Always show all approved apps Regardless of what the current criteria is in order to be approved, show everything that's currently approved, since the criteria might have been more lax when it was approved Test: manual Test: ServiceListingTest Flag: EXEMPT bug fix Bug: 365738306 Change-Id: I6c19d3dbff6ecabc74729a7f021f293e26601944 --- .../applications/ServiceListing.java | 32 ++++++--- .../applications/ServiceListingTest.java | 66 ++++++++++++++++++- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java b/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java index c8bcabff1094..261c722e517c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java @@ -138,23 +138,37 @@ public class ServiceListing { } final PackageManager pmWrapper = mContext.getPackageManager(); + // Add requesting apps, with full validation List installedServices = pmWrapper.queryIntentServicesAsUser( new Intent(mIntentAction), flags, user); for (ResolveInfo resolveInfo : installedServices) { ServiceInfo info = resolveInfo.serviceInfo; - if (!mPermission.equals(info.permission)) { - Slog.w(mTag, "Skipping " + mNoun + " service " - + info.packageName + "/" + info.name - + ": it does not require the permission " - + mPermission); - continue; + if (!mEnabledServices.contains(info.getComponentName())) { + if (!mPermission.equals(info.permission)) { + Slog.w(mTag, "Skipping " + mNoun + " service " + + info.packageName + "/" + info.name + + ": it does not require the permission " + + mPermission); + continue; + } + if (mValidator != null && !mValidator.test(info)) { + continue; + } + mServices.add(info); } - if (mValidator != null && !mValidator.test(info)) { - continue; + } + + // Add all apps with access, in case prior approval was granted without full validation + for (ComponentName cn : mEnabledServices) { + List enabledServices = pmWrapper.queryIntentServicesAsUser( + new Intent().setComponent(cn), flags, user); + for (ResolveInfo resolveInfo : enabledServices) { + ServiceInfo info = resolveInfo.serviceInfo; + mServices.add(info); } - mServices.add(info); } + for (Callback callback : mCallbacks) { callback.onServicesReloaded(mServices); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java index 7ff0988c494d..feef559dfe26 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java @@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -29,6 +30,7 @@ import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; @@ -42,6 +44,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @@ -72,19 +75,26 @@ public class ServiceListingTest { .build(); } + private ArgumentMatcher filterEquals(Intent intent) { + return (test) -> { + return intent.filterEquals(test); + }; + } + @Test public void testValidator() { ServiceInfo s1 = new ServiceInfo(); s1.permission = "testPermission"; s1.packageName = "pkg"; + s1.name = "Service1"; ServiceInfo s2 = new ServiceInfo(); s2.permission = "testPermission"; s2.packageName = "pkg2"; + s2.name = "service2"; ResolveInfo r1 = new ResolveInfo(); r1.serviceInfo = s1; ResolveInfo r2 = new ResolveInfo(); r2.serviceInfo = s2; - when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn( ImmutableList.of(r1, r2)); @@ -118,9 +128,11 @@ public class ServiceListingTest { ServiceInfo s1 = new ServiceInfo(); s1.permission = "testPermission"; s1.packageName = "pkg"; + s1.name = "Service1"; ServiceInfo s2 = new ServiceInfo(); s2.permission = "testPermission"; s2.packageName = "pkg2"; + s2.name = "service2"; ResolveInfo r1 = new ResolveInfo(); r1.serviceInfo = s1; ResolveInfo r2 = new ResolveInfo(); @@ -193,4 +205,56 @@ public class ServiceListingTest { assertThat(Settings.Secure.getString(RuntimeEnvironment.application.getContentResolver(), TEST_SETTING)).contains(testComponent2.flattenToString()); } + + @Test + public void testHasPermissionWithoutMeetingCurrentRegs() { + ServiceInfo s1 = new ServiceInfo(); + s1.permission = "testPermission"; + s1.packageName = "pkg"; + s1.name = "Service1"; + ServiceInfo s2 = new ServiceInfo(); + s2.permission = "testPermission"; + s2.packageName = "pkg2"; + s2.name = "service2"; + ResolveInfo r1 = new ResolveInfo(); + r1.serviceInfo = s1; + ResolveInfo r2 = new ResolveInfo(); + r2.serviceInfo = s2; + + ComponentName approvedComponent = new ComponentName(s2.packageName, s2.name); + + Settings.Secure.putString( + mContext.getContentResolver(), TEST_SETTING, approvedComponent.flattenToString()); + + when(mPm.queryIntentServicesAsUser(argThat( + filterEquals(new Intent(TEST_INTENT))), anyInt(), anyInt())) + .thenReturn(ImmutableList.of(r1)); + when(mPm.queryIntentServicesAsUser(argThat( + filterEquals(new Intent().setComponent(approvedComponent))), + anyInt(), anyInt())) + .thenReturn(ImmutableList.of(r2)); + + mServiceListing = new ServiceListing.Builder(mContext) + .setTag("testTag") + .setSetting(TEST_SETTING) + .setNoun("testNoun") + .setIntentAction(TEST_INTENT) + .setValidator(info -> { + if (info.packageName.equals("pkg")) { + return true; + } + return false; + }) + .setPermission("testPermission") + .build(); + ServiceListing.Callback callback = mock(ServiceListing.Callback.class); + mServiceListing.addCallback(callback); + mServiceListing.reload(); + + verify(mPm, times(2)).queryIntentServicesAsUser(any(), anyInt(), anyInt()); + ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class); + verify(callback, times(1)).onServicesReloaded(captor.capture()); + + assertThat(captor.getValue()).containsExactlyElementsIn(ImmutableList.of(s2, s1)); + } } -- GitLab From ee335b206abeb31e27972230b5761bc8eb853191 Mon Sep 17 00:00:00 2001 From: Jordan Demeulenaere Date: Tue, 2 Jul 2024 13:12:25 +0200 Subject: [PATCH 124/447] Enable and configure interruptions in Flexiglass This CL enables interruptions in Flexiglass and configures the most common interruptions that happen when face authentication kicks in while we were transition from one scene to Bouncer. Enabling this flag will also to have multiple transitions to happen in parallel, which is going to be more and more important with overlays and once we have scenes with horizontal swipes like Communal. See b/290184746#comment13 for details and before/after videos. Bug: 290184746 Test: Manual, see b/290184746#comment13. Unfortunately motion tests are not configured for a full Flexiglass set up yet so I can't unit test it. Flag: com.android.systemui.scene_container Change-Id: Ia4fd64162d8930dcd091c6616ff219a58eeae4e3 --- .../scene/ui/composable/SceneContainer.kt | 1 - .../SceneContainerInterruptionHandler.kt | 72 +++++++++++++++++++ .../composable/SceneContainerTransitions.kt | 1 + 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerInterruptionHandler.kt diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt index 56de096effce..417f2b8922e4 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt @@ -81,7 +81,6 @@ fun SceneContainer( initialScene = initialSceneKey, canChangeScene = { toScene -> viewModel.canChangeScene(toScene) }, transitions = SceneContainerTransitions, - enableInterruptions = false, ) } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerInterruptionHandler.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerInterruptionHandler.kt new file mode 100644 index 000000000000..7e99847a7200 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerInterruptionHandler.kt @@ -0,0 +1,72 @@ +/* + * 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.scene.ui.composable + +import com.android.compose.animation.scene.InterruptionHandler +import com.android.compose.animation.scene.InterruptionResult +import com.android.compose.animation.scene.SceneKey +import com.android.compose.animation.scene.content.state.TransitionState +import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.scene.ui.composable.transitions.TO_BOUNCER_FADE_FRACTION + +object SceneContainerInterruptionHandler : InterruptionHandler { + override fun onInterruption( + interrupted: TransitionState.Transition.ChangeScene, + newTargetScene: SceneKey, + ): InterruptionResult? { + return handleTransitionToGoneDuringTransitionToBouncer(interrupted, newTargetScene) + } + + /** + * Handle the case where we start transitioning to Bouncer but then we are interrupted to + * transition to Gone, for instance because face auth kicked in. + */ + private fun handleTransitionToGoneDuringTransitionToBouncer( + transition: TransitionState.Transition.ChangeScene, + targetScene: SceneKey, + ): InterruptionResult? { + if (targetScene != Scenes.Gone || !transition.isTransitioningFromOrTo(Scenes.Bouncer)) { + return null + } + + // Animate Bouncer => Gone only when the bouncer is fully opaque, otherwise animate + // OtherScene => Gone and reverse the OtherScene => Bouncer transition (note: OtherScene is + // usually the Lockscreen scene). + val otherScene: SceneKey + val animatesFromBouncer = + if (transition.isTransitioning(to = Scenes.Bouncer)) { + otherScene = transition.fromScene + transition.progress >= TO_BOUNCER_FADE_FRACTION + } else { + otherScene = transition.toScene + transition.progress <= 1f - TO_BOUNCER_FADE_FRACTION + } + + return if (animatesFromBouncer) { + InterruptionResult( + animateFrom = Scenes.Bouncer, + + // We don't want the content of the lockscreen to be shown during the Bouncer => + // Launcher transition. We disable chaining of the transitions so that only the + // Bouncer and Launcher scenes are composed. + chain = false, + ) + } else { + InterruptionResult(animateFrom = otherScene) + } + } +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt index 8728521348de..dc545b8bf7c2 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt @@ -46,6 +46,7 @@ import com.android.systemui.shade.ui.composable.Shade * Please keep the list sorted alphabetically. */ val SceneContainerTransitions = transitions { + interruptionHandler = SceneContainerInterruptionHandler // Overscroll progress starts linearly with some resistance (3f) and slowly approaches 0.2f defaultOverscrollProgressConverter = ProgressConverter.tanh(maxProgress = 0.2f, tilt = 3f) -- GitLab From 381813c412594d242a934bdaaa292d6f1b0befb9 Mon Sep 17 00:00:00 2001 From: Mark White Date: Mon, 7 Oct 2024 16:19:11 +0000 Subject: [PATCH 125/447] Update Compat Framework so all system uid apps are treated as targeting current sdk Previously if there were some system uid apps targeting an older sdk, then all sytem uid-based compat framework checks would return behaviour of the older sdk. Flag: com.android.server.compat.system_uid_target_system_sdk Bug: 282922910 Change-Id: Ia92f3ac378c18edc45015a80103da87097bb5233 --- AconfigFlags.bp | 16 ++++ .../android/server/compat/PlatformCompat.java | 15 +++- .../compat/platform_compat_flags.aconfig | 10 +++ .../server/compat/PlatformCompatTest.java | 84 +++++++++++++++++++ 4 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 services/core/java/com/android/server/compat/platform_compat_flags.aconfig diff --git a/AconfigFlags.bp b/AconfigFlags.bp index a0f38d9a7bd9..5189910f7ed5 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -63,6 +63,7 @@ aconfig_declarations_group { "android.server.app.flags-aconfig-java", "android.service.autofill.flags-aconfig-java", "android.service.chooser.flags-aconfig-java", + "android.service.compat.flags-aconfig-java", "android.service.controls.flags-aconfig-java", "android.service.dreams.flags-aconfig-java", "android.service.notification.flags-aconfig-java", @@ -861,6 +862,21 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } +aconfig_declarations { + name: "android.service.compat.flags-aconfig", + package: "com.android.server.compat", + container: "system", + srcs: [ + "services/core/java/com/android/server/compat/*.aconfig", + ], +} + +java_aconfig_library { + name: "android.service.compat.flags-aconfig-java", + aconfig_declarations: "android.service.compat.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + // Multi user aconfig_declarations { name: "android.multiuser.flags-aconfig", diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index a9fe8cb01b3a..8d64383b32b9 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -242,7 +242,8 @@ public class PlatformCompat extends IPlatformCompat.Stub { boolean enabled = true; final int userId = UserHandle.getUserId(uid); for (String packageName : packages) { - final var appInfo = getApplicationInfo(packageName, userId); + final var appInfo = + fixTargetSdk(getApplicationInfo(packageName, userId), uid); enabled &= isChangeEnabledInternal(changeId, appInfo); } return enabled; @@ -261,7 +262,8 @@ public class PlatformCompat extends IPlatformCompat.Stub { boolean enabled = true; final int userId = UserHandle.getUserId(uid); for (String packageName : packages) { - final var appInfo = getApplicationInfo(packageName, userId); + final var appInfo = + fixTargetSdk(getApplicationInfo(packageName, userId), uid); enabled &= isChangeEnabledInternalNoLogging(changeId, appInfo); } return enabled; @@ -504,6 +506,15 @@ public class PlatformCompat extends IPlatformCompat.Stub { packageName, 0, Process.myUid(), userId); } + private ApplicationInfo fixTargetSdk(ApplicationInfo appInfo, int uid) { + // b/282922910 - we don't want apps sharing system uid and targeting + // older target sdk to impact all system uid apps + if (Flags.systemUidTargetSystemSdk() && uid == Process.SYSTEM_UID) { + appInfo.targetSdkVersion = Build.VERSION.SDK_INT; + } + return appInfo; + } + private void killPackage(String packageName) { int uid = LocalServices.getService(PackageManagerInternal.class).getPackageUid(packageName, 0, UserHandle.myUserId()); diff --git a/services/core/java/com/android/server/compat/platform_compat_flags.aconfig b/services/core/java/com/android/server/compat/platform_compat_flags.aconfig new file mode 100644 index 000000000000..fb323238c38e --- /dev/null +++ b/services/core/java/com/android/server/compat/platform_compat_flags.aconfig @@ -0,0 +1,10 @@ +package: "com.android.server.compat" +container: "system" + +flag { + name: "system_uid_target_system_sdk" + namespace: "app_compat" + description: "Compat framework feature flag for forcing all system uid apps to target system sdk" + bug: "29702703" + is_fixed_read_only: true +} diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java index 9df7a3612a92..1d075401832d 100644 --- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java +++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; @@ -33,6 +34,11 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.os.Build; +import android.os.Process; + +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.runner.AndroidJUnit4; @@ -43,6 +49,7 @@ import com.android.internal.compat.CompatibilityChangeInfo; import com.android.server.LocalServices; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -55,6 +62,8 @@ import java.util.Set; public class PlatformCompatTest { private static final String PACKAGE_NAME = "my.package"; + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Mock private Context mContext; @Mock @@ -441,4 +450,79 @@ public class PlatformCompatTest { assertThat(mPlatformCompat.isChangeEnabled(3L, systemAppInfo)).isTrue(); verify(mChangeReporter).reportChange(123, 3L, ChangeReporter.STATE_ENABLED, true, false); } + + @DisableFlags(Flags.FLAG_SYSTEM_UID_TARGET_SYSTEM_SDK) + @Test + public void testSharedSystemUidFlagOff() throws Exception { + testSharedSystemUid(false); + } + + @EnableFlags(Flags.FLAG_SYSTEM_UID_TARGET_SYSTEM_SDK) + @Test + public void testSharedSystemUidFlagOn() throws Exception { + testSharedSystemUid(true); + } + + private void testSharedSystemUid(Boolean expectSystemUidTargetSystemSdk) throws Exception { + final String systemUidPackageNameTargetsR = "systemuid.package1"; + final String systemUidPackageNameTargetsQ = "systemuid.package2"; + final String nonSystemUidPackageNameTargetsR = "nonsystemuid.package1"; + final String nonSystemUidPackageNameTargetsQ = "nonsystemuid.package2"; + final int nonSystemUid = 123; + + mCompatConfig = + CompatConfigBuilder.create(mBuildClassifier, mContext) + .addEnableSinceSdkChangeWithId(Build.VERSION_CODES.R, 1L) + .build(); + mCompatConfig.forceNonDebuggableFinalForTest(true); + mPlatformCompat = + new PlatformCompat(mContext, mCompatConfig, mBuildClassifier, mChangeReporter); + + ApplicationInfo systemUidAppInfo1 = ApplicationInfoBuilder.create() + .withPackageName(systemUidPackageNameTargetsR) + .withUid(Process.SYSTEM_UID) + .withTargetSdk(Build.VERSION_CODES.R) + .build(); + when(mPackageManagerInternal.getApplicationInfo( + eq(systemUidPackageNameTargetsR), anyLong(), anyInt(), anyInt())) + .thenReturn(systemUidAppInfo1); + + ApplicationInfo systemUidAppInfo2 = ApplicationInfoBuilder.create() + .withPackageName(systemUidPackageNameTargetsQ) + .withUid(Process.SYSTEM_UID) + .withTargetSdk(Build.VERSION_CODES.Q) + .build(); + when(mPackageManagerInternal.getApplicationInfo( + eq(systemUidPackageNameTargetsQ), anyLong(), anyInt(), anyInt())) + .thenReturn(systemUidAppInfo2); + + ApplicationInfo nonSystemUidAppInfo1 = ApplicationInfoBuilder.create() + .withPackageName(nonSystemUidPackageNameTargetsR) + .withUid(nonSystemUid) + .withTargetSdk(Build.VERSION_CODES.R) + .build(); + when(mPackageManagerInternal.getApplicationInfo( + eq(nonSystemUidPackageNameTargetsR), anyLong(), anyInt(), anyInt())) + .thenReturn(nonSystemUidAppInfo1); + + ApplicationInfo nonSystemUidAppInfo2 = ApplicationInfoBuilder.create() + .withPackageName(nonSystemUidPackageNameTargetsQ) + .withUid(nonSystemUid) + .withTargetSdk(Build.VERSION_CODES.Q) + .build(); + when(mPackageManagerInternal.getApplicationInfo( + eq(nonSystemUidPackageNameTargetsQ), anyLong(), anyInt(), anyInt())) + .thenReturn(nonSystemUidAppInfo2); + + when(mPackageManager.getPackagesForUid(eq(Process.SYSTEM_UID))) + .thenReturn(new String[] {systemUidPackageNameTargetsR, systemUidPackageNameTargetsQ}); + when(mPackageManager.getPackagesForUid(eq(nonSystemUid))) + .thenReturn(new String[] { + nonSystemUidPackageNameTargetsR, nonSystemUidPackageNameTargetsQ + }); + + assertThat(mPlatformCompat.isChangeEnabledByUid(1L, Process.SYSTEM_UID)) + .isEqualTo(expectSystemUidTargetSystemSdk); + assertThat(mPlatformCompat.isChangeEnabledByUid(1L, nonSystemUid)).isFalse(); + } } -- GitLab From 94f559201889f76cfdb620e4f8838564933167eb Mon Sep 17 00:00:00 2001 From: Orhan Uysal Date: Wed, 2 Oct 2024 14:17:01 +0000 Subject: [PATCH 126/447] Make TaskStackTransitionObserver... - Update tasks moved to front on all tasks rather than just freeform - Do the updates onTransitionReady so that the launcher is updated before the animation plays. Fix: 369975365 Fix: 356619247 Test: atest TaskStackTransitionObserverTest Flag: com.android.window.flags.enable_task_stack_observer_in_shell Change-Id: I08404b2dfbd42169f0be33c4f7c7b7d53ee6aa11 --- .../recents/TaskStackTransitionObserver.kt | 72 +++---------------- .../TaskStackTransitionObserverTest.kt | 6 +- 2 files changed, 11 insertions(+), 67 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt index e5bfccf0682e..f2c08dc3d1e5 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt @@ -17,14 +17,12 @@ package com.android.wm.shell.recents import android.app.ActivityManager.RunningTaskInfo -import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.os.IBinder import android.util.ArrayMap import android.view.SurfaceControl -import android.view.WindowManager import android.window.TransitionInfo -import com.android.wm.shell.shared.TransitionUtil import android.window.flags.DesktopModeFlags +import com.android.wm.shell.shared.TransitionUtil import com.android.wm.shell.sysui.ShellInit import com.android.wm.shell.transition.Transitions import dagger.Lazy @@ -40,9 +38,6 @@ class TaskStackTransitionObserver( private val transitions: Lazy, shellInit: ShellInit ) : Transitions.TransitionObserver { - - private val transitionToTransitionChanges: MutableMap = - mutableMapOf() private val taskStackTransitionObserverListeners = ArrayMap() @@ -63,9 +58,6 @@ class TaskStackTransitionObserver( finishTransaction: SurfaceControl.Transaction ) { if (DesktopModeFlags.ENABLE_TASK_STACK_OBSERVER_IN_SHELL.isTrue) { - val taskInfoList = mutableListOf() - val transitionTypeList = mutableListOf() - for (change in info.changes) { if (change.flags and TransitionInfo.FLAG_IS_WALLPAPER != 0) { continue @@ -76,59 +68,21 @@ class TaskStackTransitionObserver( continue } - // Filter out changes that we care about - if (change.mode == WindowManager.TRANSIT_OPEN) { - change.taskInfo?.let { taskInfoList.add(it) } - transitionTypeList.add(change.mode) + // Find the first task that is opening, this should be the one at the front after + // the transition + if (TransitionUtil.isOpeningType(change.mode)) { + notifyTaskStackTransitionObserverListeners(taskInfo) + break } } - // Only add the transition to map if it has a change we care about - if (taskInfoList.isNotEmpty()) { - transitionToTransitionChanges.put( - transition, - TransitionChanges(taskInfoList, transitionTypeList) - ) - } } } override fun onTransitionStarting(transition: IBinder) {} - override fun onTransitionMerged(merged: IBinder, playing: IBinder) { - val mergedTransitionChanges = - transitionToTransitionChanges.get(merged) - ?: - // We are adding changes of the merged transition to changes of the playing - // transition so if there is no changes nothing to do. - return - - transitionToTransitionChanges.remove(merged) - val playingTransitionChanges = transitionToTransitionChanges.get(playing) - if (playingTransitionChanges != null) { - playingTransitionChanges.merge(mergedTransitionChanges) - } else { - transitionToTransitionChanges.put(playing, mergedTransitionChanges) - } - } - - override fun onTransitionFinished(transition: IBinder, aborted: Boolean) { - val taskInfoList = - transitionToTransitionChanges.getOrDefault(transition, TransitionChanges()).taskInfoList - val typeList = - transitionToTransitionChanges - .getOrDefault(transition, TransitionChanges()) - .transitionTypeList - transitionToTransitionChanges.remove(transition) + override fun onTransitionMerged(merged: IBinder, playing: IBinder) {} - for ((index, taskInfo) in taskInfoList.withIndex()) { - if ( - TransitionUtil.isOpeningType(typeList[index]) && - taskInfo.windowingMode == WINDOWING_MODE_FREEFORM - ) { - notifyTaskStackTransitionObserverListeners(taskInfo) - } - } - } + override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {} fun addTaskStackTransitionObserverListener( taskStackTransitionObserverListener: TaskStackTransitionObserverListener, @@ -154,14 +108,4 @@ class TaskStackTransitionObserver( /** Called when a task is moved to front. */ fun onTaskMovedToFrontThroughTransition(taskInfo: RunningTaskInfo) {} } - - private data class TransitionChanges( - val taskInfoList: MutableList = ArrayList(), - val transitionTypeList: MutableList = ArrayList(), - ) { - fun merge(transitionChanges: TransitionChanges) { - taskInfoList.addAll(transitionChanges.taskInfoList) - transitionTypeList.addAll(transitionChanges.transitionTypeList) - } - } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt index 0e5efa650cc4..afdb68776d04 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt @@ -114,7 +114,7 @@ class TaskStackTransitionObserverTest { @Test @EnableFlags(Flags.FLAG_ENABLE_TASK_STACK_OBSERVER_IN_SHELL) - fun taskCreated_fullscreenWindow_listenerNotNotified() { + fun taskCreated_fullscreenWindow_listenerNotified() { val listener = TestListener() val executor = TestShellExecutor() transitionObserver.addTaskStackTransitionObserverListener(listener, executor) @@ -130,9 +130,9 @@ class TaskStackTransitionObserverTest { callOnTransitionFinished() executor.flushAll() - assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(0) + assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(1) assertThat(listener.taskInfoToBeNotified.windowingMode) - .isEqualTo(WindowConfiguration.WINDOWING_MODE_UNDEFINED) + .isEqualTo(WindowConfiguration.WINDOWING_MODE_FULLSCREEN) } @Test -- GitLab From 632b25f909f6450ff021c5c8543efc267741be3a Mon Sep 17 00:00:00 2001 From: Ben Murdoch Date: Mon, 7 Oct 2024 16:09:08 +0000 Subject: [PATCH 127/447] Initialise desktop_mode_visible_tasks system property. Bug: 370478775 Flag: EXEMPT bugfix Test: Manual + atest DesktopModeLoggerTransitionObserverTest Change-Id: I2064c4f391205fcf58b1f3d0374f375ef8a7d91b --- .../desktopmode/DesktopModeLoggerTransitionObserver.kt | 4 ++++ .../DesktopModeLoggerTransitionObserverTest.kt | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt index 063747494a82..2b38cdae3c47 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt @@ -101,6 +101,9 @@ class DesktopModeLoggerTransitionObserver( fun onInit() { transitions.registerObserver(this) + SystemProperties.set( + VISIBLE_TASKS_COUNTER_SYSTEM_PROPERTY, + VISIBLE_TASKS_COUNTER_SYSTEM_PROPERTY_DEFAULT_VALUE) } override fun onTransitionReady( @@ -441,5 +444,6 @@ class DesktopModeLoggerTransitionObserver( @VisibleForTesting const val VISIBLE_TASKS_COUNTER_SYSTEM_PROPERTY = "debug.tracing." + VISIBLE_TASKS_COUNTER_NAME + const val VISIBLE_TASKS_COUNTER_SYSTEM_PROPERTY_DEFAULT_VALUE = "0" } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt index d399b20abb2a..db65ae11fc7e 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt @@ -122,6 +122,16 @@ class DesktopModeLoggerTransitionObserverTest : ShellTestCase() { } } + @Test + fun testInitialiseVisibleTasksSystemProperty() { + ExtendedMockito.verify { + SystemProperties.set( + eq(DesktopModeLoggerTransitionObserver.VISIBLE_TASKS_COUNTER_SYSTEM_PROPERTY), + eq(DesktopModeLoggerTransitionObserver + .VISIBLE_TASKS_COUNTER_SYSTEM_PROPERTY_DEFAULT_VALUE)) + } + } + @Test fun testRegistersObserverAtInit() { verify(transitions).registerObserver(same(transitionObserver)) -- GitLab From 096190a93b1672b582ccdf648754676ab7a5ef7e Mon Sep 17 00:00:00 2001 From: Sally Date: Thu, 23 May 2024 15:46:08 +0000 Subject: [PATCH 128/447] Add a Duration type and ARG_SECONDS to TtsSpan This will enable more understandable speech output of durations for screen readers, since by default numbers like "4:33" will typically be announced as times, but depending on the context the ideal speech may instead be "4 minutes 33 seconds". This will also move developers away from content descriptions, which reduce app resources used and avoids conflicts between accessibility events (Example: simultaneous content description and text changes in stopwatches/timers). Flag: com.android.text.flags.tts_span_duration Bug: 337103893 Test: atest TtsSpanTest, manual Change-Id: I7e08eeaa67b0d1dbcf31dacf1465cb427dfa80c6 --- core/api/current.txt | 10 +++ core/java/android/text/flags/flags.aconfig | 7 ++ core/java/android/text/style/TtsSpan.java | 85 +++++++++++++++++++++- 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/core/api/current.txt b/core/api/current.txt index 53da33835d31..1ff211d7faf4 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -49238,6 +49238,7 @@ package android.text.style { field public static final String ARG_PROTOCOL = "android.arg.protocol"; field public static final String ARG_QUANTITY = "android.arg.quantity"; field public static final String ARG_QUERY_STRING = "android.arg.query_string"; + field @FlaggedApi("com.android.text.flags.tts_span_duration") public static final String ARG_SECONDS = "android.arg.seconds"; field public static final String ARG_TEXT = "android.arg.text"; field public static final String ARG_UNIT = "android.arg.unit"; field public static final String ARG_USERNAME = "android.arg.username"; @@ -49274,6 +49275,7 @@ package android.text.style { field public static final String TYPE_DATE = "android.type.date"; field public static final String TYPE_DECIMAL = "android.type.decimal"; field public static final String TYPE_DIGITS = "android.type.digits"; + field @FlaggedApi("com.android.text.flags.tts_span_duration") public static final String TYPE_DURATION = "android.type.duration"; field public static final String TYPE_ELECTRONIC = "android.type.electronic"; field public static final String TYPE_FRACTION = "android.type.fraction"; field public static final String TYPE_MEASURE = "android.type.measure"; @@ -49333,6 +49335,13 @@ package android.text.style { method public android.text.style.TtsSpan.DigitsBuilder setDigits(String); } + @FlaggedApi("com.android.text.flags.tts_span_duration") public static class TtsSpan.DurationBuilder extends android.text.style.TtsSpan.SemioticClassBuilder { + ctor @FlaggedApi("com.android.text.flags.tts_span_duration") public TtsSpan.DurationBuilder(); + method @FlaggedApi("com.android.text.flags.tts_span_duration") @NonNull public android.text.style.TtsSpan.DurationBuilder setHours(int); + method @FlaggedApi("com.android.text.flags.tts_span_duration") @NonNull public android.text.style.TtsSpan.DurationBuilder setMinutes(int); + method @FlaggedApi("com.android.text.flags.tts_span_duration") @NonNull public android.text.style.TtsSpan.DurationBuilder setSeconds(int); + } + public static class TtsSpan.ElectronicBuilder extends android.text.style.TtsSpan.SemioticClassBuilder { ctor public TtsSpan.ElectronicBuilder(); method public android.text.style.TtsSpan.ElectronicBuilder setDomain(String); @@ -49415,6 +49424,7 @@ package android.text.style { ctor public TtsSpan.TimeBuilder(int, int); method public android.text.style.TtsSpan.TimeBuilder setHours(int); method public android.text.style.TtsSpan.TimeBuilder setMinutes(int); + method @FlaggedApi("com.android.text.flags.tts_span_duration") @NonNull public android.text.style.TtsSpan.TimeBuilder setSeconds(int); } public static class TtsSpan.VerbatimBuilder extends android.text.style.TtsSpan.SemioticClassBuilder { diff --git a/core/java/android/text/flags/flags.aconfig b/core/java/android/text/flags/flags.aconfig index ec5b488ccbbd..09b2201efb4e 100644 --- a/core/java/android/text/flags/flags.aconfig +++ b/core/java/android/text/flags/flags.aconfig @@ -188,3 +188,10 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "tts_span_duration" + namespace: "text" + description: "Feature flag for adding a TYPE_DURATION to TtsSpan" + bug: "337103893" +} diff --git a/core/java/android/text/style/TtsSpan.java b/core/java/android/text/style/TtsSpan.java index f9a1a0d36d30..b7b8f0b1b5d8 100644 --- a/core/java/android/text/style/TtsSpan.java +++ b/core/java/android/text/style/TtsSpan.java @@ -16,6 +16,10 @@ package android.text.style; +import static com.android.text.flags.Flags.FLAG_TTS_SPAN_DURATION; + +import android.annotation.FlaggedApi; +import android.annotation.NonNull; import android.os.Parcel; import android.os.PersistableBundle; import android.text.ParcelableSpan; @@ -111,6 +115,16 @@ public class TtsSpan implements ParcelableSpan { */ public static final String TYPE_TIME = "android.type.time"; + /** + * The text associated with this span is a duration, consisting of a number of + * hours, minutes, and seconds specified with {@link #ARG_HOURS}, + * {@link #ARG_MINUTES}, and {@link #ARG_SECONDS}. This is different from {@link #TYPE_TIME}. + * This should be used to convey an interval of time, while {@link #TYPE_TIME} should be used to + * convey a particular moment in time, such as a clock time. + */ + @FlaggedApi(FLAG_TTS_SPAN_DURATION) + public static final String TYPE_DURATION = "android.type.duration"; + /** * The text associated with this span is a date. At least one of the * arguments {@link #ARG_MONTH} and {@link #ARG_YEAR} has to be provided. @@ -302,12 +316,20 @@ public class TtsSpan implements ParcelableSpan { public static final String ARG_HOURS = "android.arg.hours"; /** - * Argument used to specify the minutes of a time. The hours should be + * Argument used to specify the minutes of a time. The minutes should be * provided as an integer in the range from 0 up to and including 59. * Can be used with {@link #TYPE_TIME}. */ public static final String ARG_MINUTES = "android.arg.minutes"; + /** + * Argument used to specify the seconds of a time or duration. The seconds should be + * provided as an integer in the range from 0 up to and including 59. + * Can be used with {@link #TYPE_TIME} or {@link #TYPE_DURATION}. + */ + @FlaggedApi(FLAG_TTS_SPAN_DURATION) + public static final String ARG_SECONDS = "android.arg.seconds"; + /** * Argument used to specify the weekday of a date. The value should be * provided as an integer and can be any of {@link #WEEKDAY_SUNDAY}, @@ -1132,8 +1154,69 @@ public class TtsSpan implements ParcelableSpan { public TimeBuilder setMinutes(int minutes) { return setIntArgument(TtsSpan.ARG_MINUTES, minutes); } + + /** + * Sets the {@link #ARG_SECONDS} argument. + * @param seconds The value to be set for seconds. + * @return This instance. + */ + @FlaggedApi(FLAG_TTS_SPAN_DURATION) + @NonNull + public TimeBuilder setSeconds(int seconds) { + return setIntArgument(TtsSpan.ARG_SECONDS, seconds); + } } + /** + * A builder for TtsSpans of type {@link #TYPE_DURATION}. + */ + @FlaggedApi(FLAG_TTS_SPAN_DURATION) + public static class DurationBuilder + extends SemioticClassBuilder { + + /** + * Creates a builder for a TtsSpan of type {@link #TYPE_DURATION}. + */ + @FlaggedApi(FLAG_TTS_SPAN_DURATION) + public DurationBuilder() { + super(TtsSpan.TYPE_DURATION); + } + + /** + * Sets the {@link #ARG_HOURS} argument. + * @param hours The value to be set for hours. + * @return This instance. + */ + @FlaggedApi(FLAG_TTS_SPAN_DURATION) + @NonNull + public DurationBuilder setHours(int hours) { + return setIntArgument(TtsSpan.ARG_HOURS, hours); + } + + /** + * Sets the {@link #ARG_MINUTES} argument. + * @param minutes The value to be set for minutes. + * @return This instance. + */ + @FlaggedApi(FLAG_TTS_SPAN_DURATION) + @NonNull + public DurationBuilder setMinutes(int minutes) { + return setIntArgument(TtsSpan.ARG_MINUTES, minutes); + } + + /** + * Sets the {@link #ARG_SECONDS} argument. + * @param seconds The value to be set for seconds. + * @return This instance. + */ + @FlaggedApi(FLAG_TTS_SPAN_DURATION) + @NonNull + public DurationBuilder setSeconds(int seconds) { + return setIntArgument(TtsSpan.ARG_SECONDS, seconds); + } + } + + /** * A builder for TtsSpans of type {@link #TYPE_DATE}. */ -- GitLab From bf742c7f9ec86ce109eac1fdf3460f3a44840a80 Mon Sep 17 00:00:00 2001 From: Ibrahim Yilmaz Date: Mon, 7 Oct 2024 11:53:30 +0000 Subject: [PATCH 129/447] [ENR] Improve Group Notif dump Bug: 369608449 Test: dumpsysui NotificationStackScrollLayout Flag: EXEMPT changing dumps only Change-Id: If03e0a9ff16904e9e3649da940a5212042cd87bf --- .../notification/row/ExpandableNotificationRow.java | 6 ++++++ .../notification/stack/NotificationChildrenContainer.java | 1 + 2 files changed, 7 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 5003a6af5c4c..11e88daa1ddf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -3873,7 +3873,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView pw.print(", mShowingPublicInitialized: " + mShowingPublicInitialized); NotificationContentView showingLayout = getShowingLayout(); pw.print(", privateShowing: " + (showingLayout == mPrivateLayout)); + pw.print(", childrenContainerShowing: " + + (!shouldShowPublic() && mIsSummaryWithChildren)); pw.print(", mShowNoBackground: " + mShowNoBackground); + pw.print(", clipBounds: " + getClipBounds()); + pw.println(); if (NotificationContentView.INCLUDE_HEIGHTS_TO_DUMP) { dumpHeights(pw); @@ -3896,6 +3900,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView ? 0 : mChildrenContainer.getTransientViewCount(); if (mIsSummaryWithChildren || transientViewCount > 0) { pw.println(mChildrenContainer.debugString()); + pw.println("Children Container Intrinsic Height: " + + mChildrenContainer.getIntrinsicHeight()); pw.println(); List notificationChildren = getAttachedChildren(); pw.print("Children: " + notificationChildren.size() + " {"); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java index b1083888ca7f..cfca8307e703 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java @@ -1704,6 +1704,7 @@ public class NotificationChildrenContainer extends ViewGroup + "visibility: " + getVisibility() + ", alpha: " + getAlpha() + ", translationY: " + getTranslationY() + + ", clipBounds: " + getClipBounds() + ", roundableState: " + getRoundableState().debugString() + "}"; } } -- GitLab From 2d8b1249f7e997dfd37cb2754d0ae9c90af186b9 Mon Sep 17 00:00:00 2001 From: Anna Bauza Date: Mon, 7 Oct 2024 17:01:27 +0000 Subject: [PATCH 130/447] Add flags for caching Profiles data Flags for adding caching methods: - getProfileIds - getProfiles - getProfileType Flag: android.multiuser.cache_profile_ids Flag: android.multiuser.cache_profile_type Flag: android.multiuser.cache_profiles Test: N/A Bug: 350421409 Bug: 350417403 Bug: 350419395 Change-Id: I8204cae0821ff94fb33bc0972acd0f4012c6e5ce --- .../java/android/content/pm/multiuser.aconfig | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig index cf65539946a9..fa26837a0429 100644 --- a/core/java/android/content/pm/multiuser.aconfig +++ b/core/java/android/content/pm/multiuser.aconfig @@ -207,6 +207,36 @@ flag { } } +flag { + name: "cache_profile_ids" + namespace: "multiuser" + description: "Cache getProfileIds to avoid unnecessary binder calls" + bug: "350421409" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "cache_profile_type" + namespace: "multiuser" + description: "Cache getProfileType to avoid unnecessary binder calls" + bug: "350417403" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "cache_profiles" + namespace: "multiuser" + description: "Cache getProfiles to avoid unnecessary binder calls" + bug: "350419395" + metadata { + purpose: PURPOSE_BUGFIX + } +} + flag { name: "fix_disabling_of_mu_toggle_when_restriction_applied" namespace: "multiuser" -- GitLab From 78b3fd928bab63eb37411da2819dcbafd6b9991a Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Mon, 7 Oct 2024 16:46:37 +0100 Subject: [PATCH 131/447] Fully qualify @attr reference to android.R field Currently, Metalava has some special handling of '@attr ref R.` references to make sure that they are fully qualified, i.e. `@attr ref android.R.`. That special handling complicates Metalava and is blocking some flagged API work so will be removed. Before that can be done, the existing incorrect documentation needs to be cleaned up. This change cleans up those cases in this repo. Bug: 371997321 Test: Run `m offline-sdk-docs` before and after to make sure that there are no differences. Flag: DOCS_ONLY Change-Id: Ie4386107205f97a90b970ceb98a0fe4889812ebf --- core/java/android/view/inputmethod/InputMethodInfo.java | 6 +++--- core/java/android/widget/ListView.java | 4 ++-- .../com/android/systemui/util/AlphaTintDrawableWrapper.java | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java index 806a59334689..0a83bdc35b1f 100644 --- a/core/java/android/view/inputmethod/InputMethodInfo.java +++ b/core/java/android/view/inputmethod/InputMethodInfo.java @@ -860,7 +860,7 @@ public final class InputMethodInfo implements Parcelable { *

    e.g.

    startActivity(createStylusHandwritingSettingsActivityIntent());
          * 

    * - * @attr ref R.styleable#InputMethod_stylusHandwritingSettingsActivity + * @attr ref android.R.styleable#InputMethod_stylusHandwritingSettingsActivity * @see #getSettingsActivity() * @see #supportsStylusHandwriting() */ @@ -888,8 +888,8 @@ public final class InputMethodInfo implements Parcelable { * the IME language settings activity.

    *

    e.g.

    startActivity(createImeLanguageSettingsActivityIntent());

    * - * @attr ref R.styleable#InputMethod_languageSettingsActivity - * @attr ref R.styleable#InputMethod_settingsActivity + * @attr ref android.R.styleable#InputMethod_languageSettingsActivity + * @attr ref android.R.styleable#InputMethod_settingsActivity */ @FlaggedApi(android.view.inputmethod.Flags.FLAG_IME_SWITCHER_REVAMP_API) @Nullable diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 510a92d1b2ca..3f611c7efbdd 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -3636,7 +3636,7 @@ public class ListView extends AbsListView { * Returns the drawable that will be drawn between each item in the list. * * @return the current drawable drawn between list elements - * @attr ref R.styleable#ListView_divider + * @attr ref android.R.styleable#ListView_divider */ @InspectableProperty @Nullable @@ -3651,7 +3651,7 @@ public class ListView extends AbsListView { * height, you should also call {@link #setDividerHeight(int)}. * * @param divider the drawable to use - * @attr ref R.styleable#ListView_divider + * @attr ref android.R.styleable#ListView_divider */ public void setDivider(@Nullable Drawable divider) { if (divider != null) { diff --git a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java index 947746c94198..4b2fe49c41b4 100644 --- a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java @@ -45,8 +45,8 @@ import java.io.IOException; * This class should only be used in XML. * * @attr ref android.R.styleable#DrawableWrapper_drawable - * @attr ref R.styleable#AlphaTintDrawableWrapper_tint - * @attr ref R.styleable#AlphaTintDrawableWrapper_alpha + * @attr ref android.R.styleable#AlphaTintDrawableWrapper_tint + * @attr ref android.R.styleable#AlphaTintDrawableWrapper_alpha */ public class AlphaTintDrawableWrapper extends InsetDrawable { private ColorStateList mTint; -- GitLab From a7d538f9606336f10b35fdd37e641316519f5a3d Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Mon, 7 Oct 2024 16:46:37 +0100 Subject: [PATCH 132/447] Fully qualify @attr reference to android.R field Currently, Metalava has some special handling of '@attr ref R.` references to make sure that they are fully qualified, i.e. `@attr ref android.R.`. That special handling complicates Metalava and is blocking some flagged API work so will be removed. Before that can be done, the existing incorrect documentation needs to be cleaned up. This change cleans up those cases in this repo. Bug: 371997321 Test: Run `m offline-sdk-docs` before and after to make sure that there are no differences. Flag: DOCS_ONLY Merged-In: Ie4386107205f97a90b970ceb98a0fe4889812ebf Change-Id: Ie4386107205f97a90b970ceb98a0fe4889812ebf --- core/java/android/view/inputmethod/InputMethodInfo.java | 4 ++-- core/java/android/widget/ListView.java | 4 ++-- .../com/android/systemui/util/AlphaTintDrawableWrapper.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java index 11ee286652a1..0a39389556d5 100644 --- a/core/java/android/view/inputmethod/InputMethodInfo.java +++ b/core/java/android/view/inputmethod/InputMethodInfo.java @@ -860,7 +860,7 @@ public final class InputMethodInfo implements Parcelable { *

    e.g.

    startActivity(createStylusHandwritingSettingsActivityIntent());
          * 

    * - * @attr ref R.styleable#InputMethod_stylusHandwritingSettingsActivity + * @attr ref android.R.styleable#InputMethod_stylusHandwritingSettingsActivity * @see #getSettingsActivity() * @see #supportsStylusHandwriting() */ @@ -886,7 +886,7 @@ public final class InputMethodInfo implements Parcelable { * the IME language settings activity.

    *

    e.g.

    startActivity(createImeLanguageSettingsActivityIntent());

    * - * @attr ref R.styleable#InputMethod_languageSettingsActivity + * @attr ref android.R.styleable#InputMethod_languageSettingsActivity */ @FlaggedApi(android.view.inputmethod.Flags.FLAG_IME_SWITCHER_REVAMP) @Nullable diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 510a92d1b2ca..3f611c7efbdd 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -3636,7 +3636,7 @@ public class ListView extends AbsListView { * Returns the drawable that will be drawn between each item in the list. * * @return the current drawable drawn between list elements - * @attr ref R.styleable#ListView_divider + * @attr ref android.R.styleable#ListView_divider */ @InspectableProperty @Nullable @@ -3651,7 +3651,7 @@ public class ListView extends AbsListView { * height, you should also call {@link #setDividerHeight(int)}. * * @param divider the drawable to use - * @attr ref R.styleable#ListView_divider + * @attr ref android.R.styleable#ListView_divider */ public void setDivider(@Nullable Drawable divider) { if (divider != null) { diff --git a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java index 947746c94198..4b2fe49c41b4 100644 --- a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java @@ -45,8 +45,8 @@ import java.io.IOException; * This class should only be used in XML. * * @attr ref android.R.styleable#DrawableWrapper_drawable - * @attr ref R.styleable#AlphaTintDrawableWrapper_tint - * @attr ref R.styleable#AlphaTintDrawableWrapper_alpha + * @attr ref android.R.styleable#AlphaTintDrawableWrapper_tint + * @attr ref android.R.styleable#AlphaTintDrawableWrapper_alpha */ public class AlphaTintDrawableWrapper extends InsetDrawable { private ColorStateList mTint; -- GitLab From d9e92f1fb63a0b1414be6c65c2f9978aa532f181 Mon Sep 17 00:00:00 2001 From: Xiaowen Lei Date: Wed, 18 Sep 2024 01:55:30 +0000 Subject: [PATCH 133/447] Add NotificationProgressDrawable to support segments and points in progress bar. Flag: android.app.api_rich_ongoing Bug: 367804171 Test: Android Studio resource preview. Change-Id: I6ee191e6af9e85dfcb583a0c25affb49dc092f4f --- .../widget/NotificationProgressDrawable.java | 722 ++++++++++++++++++ core/res/res/values/attrs.xml | 38 + 2 files changed, 760 insertions(+) create mode 100644 core/java/com/android/internal/widget/NotificationProgressDrawable.java diff --git a/core/java/com/android/internal/widget/NotificationProgressDrawable.java b/core/java/com/android/internal/widget/NotificationProgressDrawable.java new file mode 100644 index 000000000000..4d88546a1bd8 --- /dev/null +++ b/core/java/com/android/internal/widget/NotificationProgressDrawable.java @@ -0,0 +1,722 @@ +/* + * 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.internal.widget; + +import android.content.pm.ActivityInfo.Config; +import android.content.res.Resources; +import android.content.res.Resources.Theme; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.DashPathEffect; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.Log; + +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.internal.R; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; + +/** + * This is used by NotificationProgressBar for displaying a custom background. It composes of + * segments, which have non-zero length, and points, which have zero length. + * + * @see Segment + * @see Point + */ +public final class NotificationProgressDrawable extends Drawable { + private static final String TAG = "NotifProgressDrawable"; + + private State mState; + private boolean mMutated; + + private final ArrayList mParts = new ArrayList<>(); + + private final Rect mPointRect = new Rect(); + private final RectF mPointRectF = new RectF(); + + private final Paint mStrokePaint = new Paint(); + private final Paint mDashedStrokePaint = new Paint(); + private final Paint mFillPaint = new Paint(); + + { + mStrokePaint.setStyle(Paint.Style.STROKE); + mStrokePaint.setStrokeCap(Paint.Cap.ROUND); + + mDashedStrokePaint.setStyle(Paint.Style.STROKE); + + mFillPaint.setStyle(Paint.Style.FILL); + } + + private int mAlpha; + + public NotificationProgressDrawable() { + this(new State(), null); + } + + /** + *

    Set the stroke width and default color for the drawable.

    + *

    Note: changing this property will affect all instances of a drawable loaded from a + * resource. It is recommended to invoke + * {@link #mutate()} before changing this property.

    + * + * @param width The width in pixels of the stroke + * @param color The color of the stroke + * @see #mutate() + * @see #setStroke(int, int, float, float) + */ + public void setStroke(int width, @ColorInt int color) { + setStroke(width, color, 0, 0); + } + + /** + *

    Set the stroke width and default color for the drawable. This method can also be used + * to dash the stroke for the dashed segments.

    + *

    Note: changing this property will affect all instances of a drawable loaded from a + * resource. It is recommended to invoke {@link #mutate()} before changing this property.

    + * + * @param width The width in pixels of the stroke + * @param color The color of the stroke + * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes + * @param dashGap The gap in pixels between dashes + * @see #mutate() + * @see #setStroke(int, int) + */ + public void setStroke(int width, @ColorInt int color, float dashWidth, float dashGap) { + mState.setStroke(width, color, dashWidth, dashGap); + setStrokeInternal(width, dashWidth, dashGap); + } + + /** + *

    Set the stroke default color for the drawable.

    + *

    Note: changing this property will affect all instances of a drawable loaded from a + * resource. It is recommended to invoke {@link #mutate()} before changing this property.

    + * + * @param color The color of the stroke + * @see #mutate() + * @see #setStroke(int, int, float, float) + */ + public void setStrokeDefaultColor(@ColorInt int color) { + mState.mStrokeColor = color; + } + + /** + *

    Set the point rect default color for the drawable.

    + *

    Note: changing this property will affect all instances of a drawable loaded from a + * resource. It is recommended to invoke {@link #mutate()} before changing this property.

    + * + * @param color The color of the point rect + * @see #mutate() + */ + public void setPointRectDefaultColor(@ColorInt int color) { + mState.mPointRectColor = color; + } + + private void setStrokeInternal(int width, float dashWidth, float dashGap) { + mStrokePaint.setStrokeWidth(width); + + mDashedStrokePaint.setStrokeWidth(width); + DashPathEffect e = null; + if (dashWidth > 0) { + e = new DashPathEffect(new float[] { dashWidth, dashGap }, 0); + } + mDashedStrokePaint.setPathEffect(e); + + invalidateSelf(); + } + + /** + * + */ + public void setParts(@NonNull Part... parts) { + mParts.clear(); + mParts.addAll(Arrays.asList(parts)); + } + + @Override + public void draw(@NonNull Canvas canvas) { + final float pointRadius = + mState.mPointRadius; // how big the point icon will be, halved + + // generally, we will start drawing at (x, y) and end at (x+w, y) + float x = (float) getBounds().left; + final float centerY = (float) getBounds().centerY(); + final float totalWidth = (float) getBounds().width(); + + final int numParts = mParts.size(); + for (int iPart = 0; iPart < numParts; iPart++) { + final Part part = mParts.get(iPart); + final Part prevPart = iPart == 0 ? null : mParts.get(iPart - 1); + final Part nextPart = iPart + 1 == numParts ? null : mParts.get(iPart + 1); + if (part instanceof Segment segment) { + final float segWidth = segment.mFraction * totalWidth; + // Advance the start position to account for a point immediately prior. + final float startOffset = getSegStartOffset(prevPart, pointRadius, + mState.mSegPointGap); + final float start = x + startOffset; + // Retract the end position to account for the padding and a point immediately + // after. + final float endOffset = getSegEndOffset(nextPart, pointRadius, mState.mSegPointGap, + mState.mSegSegGap); + final float end = x + segWidth - endOffset; + + // Transparent is not allowed (and also is the default in the data), so use that + // as a sentinel to be replaced by default + mStrokePaint.setColor(segment.mColor != Color.TRANSPARENT ? segment.mColor + : mState.mStrokeColor); + mDashedStrokePaint.setColor(segment.mColor != Color.TRANSPARENT ? segment.mColor + : mState.mStrokeColor); + + // Leave space for the rounded line cap which extends beyond start/end. + final float capWidth = mStrokePaint.getStrokeWidth() / 2F; + + canvas.drawLine(start + capWidth, centerY, end - capWidth, centerY, + segment.mDashed ? mDashedStrokePaint : mStrokePaint); + + // Advance the current position to account for the segment's fraction of the total + // width (ignoring offset and padding) + x += segWidth; + } else if (part instanceof Point point) { + mPointRect.set((int) (x - pointRadius), (int) (centerY - pointRadius), + (int) (x + pointRadius), (int) (centerY + pointRadius)); + if (point.mIcon != null) { + point.mIcon.setBounds(mPointRect); + point.mIcon.draw(canvas); + } else { + // TODO: b/367804171 - actually use a vector asset for the default point + // rather than drawing it as a box? + mPointRectF.set(mPointRect); + final float inset = mState.mPointRectInset; + final float cornerRadius = mState.mPointRectCornerRadius; + mPointRectF.inset(inset, inset); + + mFillPaint.setColor(point.mColor != Color.TRANSPARENT ? point.mColor + : mState.mPointRectColor); + + canvas.drawRoundRect(mPointRectF, cornerRadius, cornerRadius, mFillPaint); + } + } + } + } + + private static float getSegStartOffset(Part prevPart, float pointRadius, float segPointGap) { + return (prevPart instanceof Point) ? pointRadius + segPointGap : 0F; + } + + private static float getSegEndOffset(Part nextPart, float pointRadius, float segPointGap, + float segSegGap) { + if (nextPart == null) return 0F; + return (nextPart instanceof Point) ? segPointGap + pointRadius : segSegGap; + } + + @Override + public @Config int getChangingConfigurations() { + return super.getChangingConfigurations() | mState.getChangingConfigurations(); + } + + @Override + public void setAlpha(int alpha) { + if (mAlpha != alpha) { + mAlpha = alpha; + invalidateSelf(); + } + } + + @Override + public int getAlpha() { + return mAlpha; + } + + @Override + public void setColorFilter(@Nullable ColorFilter colorFilter) { + // NO-OP + } + + @Override + public int getOpacity() { + // This method is deprecated. Hence we return UNKNOWN. + return PixelFormat.UNKNOWN; + } + + @Override + public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser, + @NonNull AttributeSet attrs, @Nullable Resources.Theme theme) + throws XmlPullParserException, IOException { + super.inflate(r, parser, attrs, theme); + + mState.setDensity(resolveDensity(r, 0)); + + final TypedArray a = obtainAttributes(r, theme, attrs, + R.styleable.NotificationProgressDrawable); + updateStateFromTypedArray(a); + a.recycle(); + + inflateChildElements(r, parser, attrs, theme); + + updateLocalState(); + } + + @Override + public void applyTheme(@NonNull Theme t) { + super.applyTheme(t); + + final State state = mState; + if (state == null) { + return; + } + + state.setDensity(resolveDensity(t.getResources(), 0)); + + if (state.mThemeAttrs != null) { + final TypedArray a = t.resolveAttributes( + state.mThemeAttrs, R.styleable.NotificationProgressDrawable); + updateStateFromTypedArray(a); + a.recycle(); + } + + applyThemeChildElements(t); + + updateLocalState(); + } + + @Override + public boolean canApplyTheme() { + return (mState.canApplyTheme()) || super.canApplyTheme(); + } + + private void updateStateFromTypedArray(TypedArray a) { + final State state = mState; + + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); + + // Extract the theme attributes, if any. + state.mThemeAttrs = a.extractThemeAttrs(); + + state.mSegSegGap = a.getDimension(R.styleable.NotificationProgressDrawable_segSegGap, + state.mSegSegGap); + state.mSegPointGap = a.getDimension(R.styleable.NotificationProgressDrawable_segPointGap, + state.mSegPointGap); + } + + private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs, + Theme theme) throws XmlPullParserException, IOException { + TypedArray a; + int type; + + final int innerDepth = parser.getDepth() + 1; + int depth; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlPullParser.END_TAG)) { + if (type != XmlPullParser.START_TAG) { + continue; + } + + if (depth > innerDepth) { + continue; + } + + String name = parser.getName(); + + if (name.equals("segments")) { + a = obtainAttributes(r, theme, attrs, + R.styleable.NotificationProgressDrawableSegments); + updateSegmentsFromTypedArray(a); + a.recycle(); + } else if (name.equals("points")) { + a = obtainAttributes(r, theme, attrs, + R.styleable.NotificationProgressDrawablePoints); + updatePointsFromTypedArray(a); + a.recycle(); + } else { + Log.w(TAG, "Bad element under NotificationProgressDrawable: " + name); + } + } + } + + private void applyThemeChildElements(Theme t) { + final State state = mState; + + if (state.mThemeAttrsSegments != null) { + final TypedArray a = t.resolveAttributes( + state.mThemeAttrsSegments, R.styleable.NotificationProgressDrawableSegments); + updateSegmentsFromTypedArray(a); + a.recycle(); + } + + if (state.mThemeAttrsPoints != null) { + final TypedArray a = t.resolveAttributes( + state.mThemeAttrsPoints, R.styleable.NotificationProgressDrawablePoints); + updateSegmentsFromTypedArray(a); + a.recycle(); + } + } + + private void updateSegmentsFromTypedArray(TypedArray a) { + final State state = mState; + + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); + + // Extract the theme attributes, if any. + state.mThemeAttrsSegments = a.extractThemeAttrs(); + + final int width = a.getDimensionPixelSize( + R.styleable.NotificationProgressDrawableSegments_width, state.mStrokeWidth); + final float dashWidth = a.getDimension( + R.styleable.NotificationProgressDrawableSegments_dashWidth, state.mStrokeDashWidth); + + final int color = a.getColor(R.styleable.NotificationProgressDrawableSegments_color, + state.mStrokeColor); + + if (dashWidth != 0.0f) { + final float dashGap = a.getDimension( + R.styleable.NotificationProgressDrawableSegments_dashGap, state.mStrokeDashGap); + setStroke(width, color, dashWidth, dashGap); + } else { + setStroke(width, color); + } + } + + private void updatePointsFromTypedArray(TypedArray a) { + final State state = mState; + + // Account for any configuration changes. + state.mChangingConfigurations |= a.getChangingConfigurations(); + + // Extract the theme attributes, if any. + state.mThemeAttrsPoints = a.extractThemeAttrs(); + + state.mPointRadius = a.getDimension(R.styleable.NotificationProgressDrawablePoints_radius, + state.mPointRadius); + state.mPointRectInset = a.getDimension(R.styleable.NotificationProgressDrawablePoints_inset, + state.mPointRectInset); + state.mPointRectCornerRadius = a.getDimension( + R.styleable.NotificationProgressDrawablePoints_cornerRadius, + state.mPointRectCornerRadius); + state.mPointRectColor = a.getColor(R.styleable.NotificationProgressDrawablePoints_color, + state.mPointRectColor); + } + + static int resolveDensity(@Nullable Resources r, int parentDensity) { + final int densityDpi = r == null ? parentDensity : r.getDisplayMetrics().densityDpi; + return densityDpi == 0 ? DisplayMetrics.DENSITY_DEFAULT : densityDpi; + } + + /** + * Scales a floating-point pixel value from the source density to the + * target density. + */ + private static float scaleFromDensity(float pixels, int sourceDensity, int targetDensity) { + return pixels * targetDensity / sourceDensity; + } + + /** + * Scales a pixel value from the source density to the target density. + *

    + * Optionally, when {@code isSize} is true, handles the resulting pixel value as a size, + * which is rounded to the closest positive integer. + *

    + * Note: Iteratively applying density changes could result in drift of the pixel values due + * to rounding, especially for paddings which are truncated. Therefore it should be avoided. + * This isn't an issue for the notifications because the inflation pipeline reinflates + * notification views on density change. + */ + private static int scaleFromDensity( + int pixels, int sourceDensity, int targetDensity, boolean isSize) { + if (pixels == 0 || sourceDensity == targetDensity) { + return pixels; + } + + final float result = pixels * targetDensity / (float) sourceDensity; + if (!isSize) { + return (int) result; + } + + final int rounded = Math.round(result); + if (rounded != 0) { + return rounded; + } else if (pixels > 0) { + return 1; + } else { + return -1; + } + } + + /** + * A part of the progress bar, which is either a S{@link Segment} with non-zero length, or a + * {@link Point} with zero length. + */ + public interface Part { + + } + + /** + * A segment is a part of the progress bar with non-zero length. For example, it can + * represent a portion in a navigation journey with certain traffic condition. + */ + public static final class Segment implements Part { + private final float mFraction; + @ColorInt private final int mColor; + private final boolean mDashed; + + public Segment(float fraction) { + this(fraction, Color.TRANSPARENT); + } + + public Segment(float fraction, @ColorInt int color) { + this(fraction, color, false); + } + + public Segment(float fraction, @ColorInt int color, boolean dashed) { + mFraction = fraction; + mColor = color; + mDashed = dashed; + } + + public float getFraction() { + return this.mFraction; + } + + public int getColor() { + return this.mColor; + } + + public boolean getDashed() { + return this.mDashed; + } + + @Override + public String toString() { + return "Segment(fraction=" + this.mFraction + ", color=" + this.mColor + ", dashed=" + + this.mDashed + ')'; + } + } + + /** + * A point is a part of the progress bar with zero length. Points are designated points within a + * progressbar to visualize distinct stages or milestones. For example, a stop in a multi-stop + * ride-share journey. + */ + public static final class Point implements Part { + @Nullable + private final Drawable mIcon; + @ColorInt private final int mColor; + + public Point(@Nullable Drawable icon) { + this(icon, Color.TRANSPARENT); + } + + public Point(@Nullable Drawable icon, @ColorInt int color) { + mIcon = icon; + mColor = color; + } + + @Nullable + public Drawable getIcon() { + return this.mIcon; + } + + @Override + public String toString() { + return "Point(icon=" + this.mIcon + ", color=" + this.mColor + ')'; + } + } + + @Override + public Drawable mutate() { + if (!mMutated && super.mutate() == this) { + mState = new State(mState, null); + updateLocalState(); + mMutated = true; + } + return this; + } + + @Override + public void clearMutated() { + super.clearMutated(); + mMutated = false; + } + + static final class State extends ConstantState { + @Config + int mChangingConfigurations; + float mSegSegGap = 0.0f; + float mSegPointGap = 0.0f; + int mStrokeWidth = 0; + int mStrokeColor; + float mStrokeDashWidth = 0.0f; + float mStrokeDashGap = 0.0f; + float mPointRadius; + float mPointRectInset; + float mPointRectCornerRadius; + int mPointRectColor; + + int[] mThemeAttrs; + int[] mThemeAttrsSegments; + int[] mThemeAttrsPoints; + + int mDensity = DisplayMetrics.DENSITY_DEFAULT; + + State() { + } + + State(@NonNull State orig, @Nullable Resources res) { + mChangingConfigurations = orig.mChangingConfigurations; + mStrokeColor = orig.mStrokeColor; + mStrokeWidth = orig.mStrokeWidth; + mStrokeDashWidth = orig.mStrokeDashWidth; + mStrokeDashGap = orig.mStrokeDashGap; + mPointRadius = orig.mPointRadius; + mPointRectInset = orig.mPointRectInset; + mPointRectCornerRadius = orig.mPointRectCornerRadius; + mPointRectColor = orig.mPointRectColor; + + mThemeAttrs = orig.mThemeAttrs; + mThemeAttrsSegments = orig.mThemeAttrsSegments; + mThemeAttrsPoints = orig.mThemeAttrsPoints; + + mDensity = resolveDensity(res, orig.mDensity); + if (orig.mDensity != mDensity) { + applyDensityScaling(orig.mDensity, mDensity); + } + } + + private void applyDensityScaling(int sourceDensity, int targetDensity) { + if (mStrokeWidth > 0) { + mStrokeWidth = scaleFromDensity( + mStrokeWidth, sourceDensity, targetDensity, true); + } + if (mStrokeDashWidth > 0) { + mStrokeDashWidth = scaleFromDensity( + mStrokeDashWidth, sourceDensity, targetDensity); + } + if (mStrokeDashGap > 0) { + mStrokeDashGap = scaleFromDensity( + mStrokeDashGap, sourceDensity, targetDensity); + } + if (mPointRadius > 0) { + mPointRadius = scaleFromDensity( + mPointRadius, sourceDensity, targetDensity); + } + if (mPointRectInset > 0) { + mPointRectInset = scaleFromDensity( + mPointRectInset, sourceDensity, targetDensity); + } + if (mPointRectCornerRadius > 0) { + mPointRectCornerRadius = scaleFromDensity( + mPointRectCornerRadius, sourceDensity, targetDensity); + } + } + + @NonNull + @Override + public Drawable newDrawable() { + return new NotificationProgressDrawable(this, null); + } + + @Override + public Drawable newDrawable(@Nullable Resources res) { + // If this drawable is being created for a different density, + // just create a new constant state and call it a day. + final State state; + final int density = resolveDensity(res, mDensity); + if (density != mDensity) { + state = new State(this, res); + } else { + state = this; + } + + return new NotificationProgressDrawable(state, res); + } + + @Override + public int getChangingConfigurations() { + return mChangingConfigurations; + } + + @Override + public boolean canApplyTheme() { + return mThemeAttrs != null || mThemeAttrsSegments != null || mThemeAttrsPoints != null + || super.canApplyTheme(); + } + + public void setDensity(int targetDensity) { + if (mDensity != targetDensity) { + final int sourceDensity = mDensity; + mDensity = targetDensity; + + applyDensityScaling(sourceDensity, targetDensity); + } + } + + public void setStroke(int width, int color, float dashWidth, float dashGap) { + mStrokeWidth = width; + mStrokeColor = color; + mStrokeDashWidth = dashWidth; + mStrokeDashGap = dashGap; + } + } + + @Override + public ConstantState getConstantState() { + mState.mChangingConfigurations = getChangingConfigurations(); + return mState; + } + + /** + * Creates a new themed NotificationProgressDrawable based on the specified constant state. + *

    + * The resulting drawable is guaranteed to have a new constant state. + * + * @param state Constant state from which the drawable inherits + */ + private NotificationProgressDrawable(@NonNull State state, @Nullable Resources res) { + mState = state; + + updateLocalState(); + } + + private void updateLocalState() { + final State state = mState; + + mStrokePaint.setStrokeWidth(state.mStrokeWidth); + + if (state.mStrokeDashWidth != 0.0f) { + final DashPathEffect e = new DashPathEffect( + new float[] { state.mStrokeDashWidth, state.mStrokeDashGap }, 0); + mDashedStrokePaint.setPathEffect(e); + } + } +} diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 440219de9561..02f9f3c5f0db 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -7720,6 +7720,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- GitLab From 50ac74570f4372eb229dd44f26cfc048325d4106 Mon Sep 17 00:00:00 2001 From: "Priyanka Advani (xWF)" Date: Mon, 7 Oct 2024 17:25:52 +0000 Subject: [PATCH 134/447] Revert "Make mUserAspectRatio final" This reverts commit 173a38237569a20a12ebead102c30d50fcf1ad59. Reason for revert: Droidmonitor created revert due to b/371943256. Will be verifying through ABTD before submission. Change-Id: I310469a591460f5f4bf235c5bb59063315efeebd --- .../wm/AppCompatAspectRatioOverrides.java | 58 +++++++++++++------ .../server/wm/AppCompatOrientationPolicy.java | 24 +++++++- .../wm/DesktopAppCompatAspectRatioPolicy.java | 2 +- .../server/wm/AppCompatActivityRobot.java | 9 +-- .../wm/AppCompatAspectRatioOverridesTest.java | 20 +++---- .../wm/AppCompatOrientationPolicyTest.java | 6 +- .../DesktopModeLaunchParamsModifierTests.java | 2 +- .../android/server/wm/SizeCompatTests.java | 40 +++++++------ 8 files changed, 99 insertions(+), 62 deletions(-) diff --git a/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java index 1c232124e775..d59046f44129 100644 --- a/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java +++ b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java @@ -62,8 +62,8 @@ class AppCompatAspectRatioOverrides { private final ActivityRecord mActivityRecord; @NonNull private final AppCompatConfiguration mAppCompatConfiguration; - @PackageManager.UserMinAspectRatio - final int mUserAspectRatioType; + @NonNull + private final UserAspectRatioState mUserAspectRatioState; @NonNull private final OptPropFactory.OptProp mAllowMinAspectRatioOverrideOptProp; @@ -86,7 +86,7 @@ class AppCompatAspectRatioOverrides { mActivityRecord = activityRecord; mAppCompatConfiguration = appCompatConfiguration; mAppCompatDeviceStateQuery = appCompatDeviceStateQuery; - mUserAspectRatioType = getUserMinAspectRatioOverrideType(); + mUserAspectRatioState = new UserAspectRatioState(); mAppCompatReachabilityOverrides = appCompatReachabilityOverrides; mAllowMinAspectRatioOverrideOptProp = optPropBuilder.create( PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE); @@ -122,28 +122,41 @@ class AppCompatAspectRatioOverrides { * current app. */ boolean shouldApplyUserMinAspectRatioOverride() { - return shouldEnableUserAspectRatioSettings() - && mUserAspectRatioType != USER_MIN_ASPECT_RATIO_UNSET - && mUserAspectRatioType != USER_MIN_ASPECT_RATIO_APP_DEFAULT - && mUserAspectRatioType != USER_MIN_ASPECT_RATIO_FULLSCREEN; + if (!shouldEnableUserAspectRatioSettings()) { + return false; + } + + mUserAspectRatioState.mUserAspectRatio = getUserMinAspectRatioOverrideCode(); + + return mUserAspectRatioState.mUserAspectRatio != USER_MIN_ASPECT_RATIO_UNSET + && mUserAspectRatioState.mUserAspectRatio != USER_MIN_ASPECT_RATIO_APP_DEFAULT + && mUserAspectRatioState.mUserAspectRatio != USER_MIN_ASPECT_RATIO_FULLSCREEN; } boolean shouldApplyUserFullscreenOverride() { - return isUserFullscreenOverrideEnabled() - && mUserAspectRatioType == USER_MIN_ASPECT_RATIO_FULLSCREEN; + if (isUserFullscreenOverrideEnabled()) { + mUserAspectRatioState.mUserAspectRatio = getUserMinAspectRatioOverrideCode(); + + return mUserAspectRatioState.mUserAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN; + } + + return false; } boolean isUserFullscreenOverrideEnabled() { - return !mAllowUserAspectRatioOverrideOptProp.isFalse() - && !mAllowUserAspectRatioFullscreenOverrideOptProp.isFalse() - && mAppCompatConfiguration.isUserAppAspectRatioFullscreenEnabled(); + if (mAllowUserAspectRatioOverrideOptProp.isFalse() + || mAllowUserAspectRatioFullscreenOverrideOptProp.isFalse() + || !mAppCompatConfiguration.isUserAppAspectRatioFullscreenEnabled()) { + return false; + } + return true; } boolean isSystemOverrideToFullscreenEnabled() { return isChangeEnabled(mActivityRecord, OVERRIDE_ANY_ORIENTATION_TO_USER) && !mAllowOrientationOverrideOptProp.isFalse() - && (mUserAspectRatioType == USER_MIN_ASPECT_RATIO_UNSET - || mUserAspectRatioType == USER_MIN_ASPECT_RATIO_FULLSCREEN); + && (mUserAspectRatioState.mUserAspectRatio == USER_MIN_ASPECT_RATIO_UNSET + || mUserAspectRatioState.mUserAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN); } /** @@ -160,11 +173,12 @@ class AppCompatAspectRatioOverrides { } boolean hasFullscreenOverride() { + // `mUserAspectRatio` is always initialized first in `shouldApplyUserFullscreenOverride()`. return shouldApplyUserFullscreenOverride() || isSystemOverrideToFullscreenEnabled(); } float getUserMinAspectRatio() { - switch (mUserAspectRatioType) { + switch (mUserAspectRatioState.mUserAspectRatio) { case USER_MIN_ASPECT_RATIO_DISPLAY_SIZE: return getDisplaySizeMinAspectRatio(); case USER_MIN_ASPECT_RATIO_SPLIT_SCREEN: @@ -177,7 +191,7 @@ class AppCompatAspectRatioOverrides { return 3 / 2f; default: throw new AssertionError("Unexpected user min aspect ratio override: " - + mUserAspectRatioType); + + mUserAspectRatioState.mUserAspectRatio); } } @@ -254,15 +268,14 @@ class AppCompatAspectRatioOverrides { return !mAllowUserAspectRatioOverrideOptProp.isFalse(); } - // TODO(b/359217664): make this private. - int getUserMinAspectRatioOverrideType() { + int getUserMinAspectRatioOverrideCode() { try { return mActivityRecord.mAtmService.getPackageManager() .getUserMinAspectRatio(mActivityRecord.packageName, mActivityRecord.mUserId); } catch (RemoteException e) { Slog.w(TAG, "Exception thrown retrieving aspect ratio user override " + this, e); } - return USER_MIN_ASPECT_RATIO_UNSET; + return mUserAspectRatioState.mUserAspectRatio; } private float getDefaultMinAspectRatioForUnresizableApps() { @@ -286,6 +299,13 @@ class AppCompatAspectRatioOverrides { return getDisplaySizeMinAspectRatio(); } + private static class UserAspectRatioState { + // TODO(b/315140179): Make mUserAspectRatio final + // The min aspect ratio override set by user + @PackageManager.UserMinAspectRatio + private int mUserAspectRatio = USER_MIN_ASPECT_RATIO_UNSET; + } + private Resources getResources() { return mActivityRecord.mWmService.mContext.getResources(); } diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java index af9e1fdc64ff..f5d58eac1113 100644 --- a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java +++ b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java @@ -56,11 +56,11 @@ class AppCompatOrientationPolicy { final DisplayContent displayContent = mActivityRecord.mDisplayContent; final boolean isIgnoreOrientationRequestEnabled = displayContent != null && displayContent.getIgnoreOrientationRequest(); - final boolean hasFullscreenOverride = mAppCompatOverrides - .getAppCompatAspectRatioOverrides().hasFullscreenOverride(); + final boolean shouldApplyUserFullscreenOverride = mAppCompatOverrides + .getAppCompatAspectRatioOverrides().shouldApplyUserFullscreenOverride(); final boolean shouldCameraCompatControlOrientation = AppCompatCameraPolicy.shouldCameraCompatControlOrientation(mActivityRecord); - if (hasFullscreenOverride && isIgnoreOrientationRequestEnabled + if (shouldApplyUserFullscreenOverride && isIgnoreOrientationRequestEnabled // Do not override orientation to fullscreen for camera activities. // Fixed-orientation activities are rarely tested in other orientations, and it // often results in sideways or stretched previews. As the camera compat treatment @@ -101,6 +101,24 @@ class AppCompatOrientationPolicy { return candidate; } + // mUserAspectRatio is always initialized first in shouldApplyUserFullscreenOverride(), + // which will always come first before this check as user override > device + // manufacturer override. + final boolean isSystemOverrideToFullscreenEnabled = mAppCompatOverrides + .getAppCompatAspectRatioOverrides().isSystemOverrideToFullscreenEnabled(); + if (isSystemOverrideToFullscreenEnabled && isIgnoreOrientationRequestEnabled + // Do not override orientation to fullscreen for camera activities. + // Fixed-orientation activities are rarely tested in other orientations, and it + // often results in sideways or stretched previews. As the camera compat treatment + // targets fixed-orientation activities, overriding the orientation disables the + // treatment. + && !shouldCameraCompatControlOrientation) { + Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate) + + " for " + mActivityRecord + " is overridden to " + + screenOrientationToString(SCREEN_ORIENTATION_USER)); + return SCREEN_ORIENTATION_USER; + } + final AppCompatOrientationOverrides.OrientationOverridesState capabilityState = mAppCompatOverrides.getAppCompatOrientationOverrides() .mOrientationOverridesState; diff --git a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java index b9db5d39a302..c8cb62132b4c 100644 --- a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java +++ b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java @@ -265,7 +265,7 @@ public class DesktopAppCompatAspectRatioPolicy { } final int userAspectRatioCode = mAppCompatOverrides.getAppCompatAspectRatioOverrides() - .getUserMinAspectRatioOverrideType(); + .getUserMinAspectRatioOverrideCode(); return userAspectRatioCode != USER_MIN_ASPECT_RATIO_UNSET && userAspectRatioCode != USER_MIN_ASPECT_RATIO_APP_DEFAULT diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java index 049e5cfba0e6..c8a35598479f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java @@ -25,7 +25,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; -import static com.android.server.wm.BackgroundActivityStartControllerTests.setViaReflection; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -228,13 +227,7 @@ class AppCompatActivityRobot { void setGetUserMinAspectRatioOverrideCode(@UserMinAspectRatio int overrideCode) { doReturn(overrideCode).when(mActivityStack.top().mAppCompatController - .getAppCompatAspectRatioOverrides()).getUserMinAspectRatioOverrideType(); - } - - void setUserAspectRatioType(@UserMinAspectRatio int aspectRatio) { - final AppCompatAspectRatioOverrides aspectRatioOverrides = mActivityStack.top() - .mAppCompatController.getAppCompatAspectRatioOverrides(); - setViaReflection(aspectRatioOverrides, "mUserAspectRatioType", aspectRatio); + .getAppCompatAspectRatioOverrides()).getUserMinAspectRatioOverrideCode(); } void setGetUserMinAspectRatioOverrideValue(float overrideValue) { diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java index b051aaf8a1f5..b83911337c5c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java @@ -75,7 +75,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().disable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_FULLSCREEN); + robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN); robot.checkShouldApplyUserFullscreenOverride(/* expected */ false); }); @@ -88,7 +88,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().disable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_FULLSCREEN); + robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN); robot.checkShouldApplyUserFullscreenOverride(/* expected */ false); }); } @@ -100,7 +100,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.conf().enableUserAppAspectRatioFullscreen(/* enabled */ true); robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.activity().createActivityWithComponent(); - robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_FULLSCREEN); + robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN); robot.checkShouldApplyUserFullscreenOverride(/* expected */ true); }); @@ -113,7 +113,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().disable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldEnableUserAspectRatioSettings(/* expected */ false); }); @@ -126,7 +126,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().enable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldEnableUserAspectRatioSettings(/* expected */ true); }); @@ -139,7 +139,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().enable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldEnableUserAspectRatioSettings(/* expected */ false); }); @@ -152,7 +152,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.prop().disable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE); robot.activity().createActivityWithComponent(); - robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldEnableUserAspectRatioSettings(/* expected */ false); }); @@ -175,7 +175,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.conf().enableUserAppAspectRatioSettings(/* enabled */ true); robot.activity().setIgnoreOrientationRequest(/* enabled */ false); robot.activity().createActivityWithComponent(); - robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldApplyUserMinAspectRatioOverride(/* expected */ false); }); @@ -187,7 +187,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.conf().enableUserAppAspectRatioSettings(/* enabled */ true); robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.activity().createActivityWithComponent(); - robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldApplyUserMinAspectRatioOverride(/* expected */ true); }); @@ -199,7 +199,7 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase { robot.conf().enableUserAppAspectRatioSettings(/* enabled */ false); robot.activity().setIgnoreOrientationRequest(/* enabled */ true); robot.activity().createActivityWithComponent(); - robot.activity().setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); + robot.activity().setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); robot.checkShouldApplyUserMinAspectRatioOverride(/* expected */ false); }); diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java index fa2eca57ea22..76101d51f931 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java @@ -118,7 +118,7 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase { robot.applyOnActivity((a) -> { a.createActivityWithComponent(); a.setIgnoreOrientationRequest(true); - a.setUserAspectRatioType(USER_MIN_ASPECT_RATIO_FULLSCREEN); + a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN); }); robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT, @@ -135,7 +135,7 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase { robot.applyOnActivity((a) -> { a.createActivityWithComponent(); a.setIgnoreOrientationRequest(true); - a.setUserAspectRatioType(USER_MIN_ASPECT_RATIO_FULLSCREEN); + a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN); }); robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT, @@ -164,7 +164,7 @@ public class AppCompatOrientationPolicyTest extends WindowTestsBase { robot.applyOnActivity((a) -> { a.createActivityWithComponent(); a.setIgnoreOrientationRequest(true); - a.setUserAspectRatioType(USER_MIN_ASPECT_RATIO_3_2); + a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2); }); robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT, diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java index 3c0d83b75e08..6d508eabcd52 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java @@ -1322,7 +1322,7 @@ public class DesktopModeLaunchParamsModifierTests extends spyOn(appCompatAspectRatioOverrides); doReturn(overrideValue).when(appCompatAspectRatioOverrides).getUserMinAspectRatio(); doReturn(overrideCode).when(appCompatAspectRatioOverrides) - .getUserMinAspectRatioOverrideType(); + .getUserMinAspectRatioOverrideCode(); } private TestDisplayContent createDisplayContent(int orientation, Rect displayBounds) { diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index c2ef6eaa1728..72f4fa9158fb 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -63,10 +63,9 @@ import static com.android.server.wm.ActivityRecord.State.PAUSED; import static com.android.server.wm.ActivityRecord.State.RESTARTING_PROCESS; import static com.android.server.wm.ActivityRecord.State.RESUMED; import static com.android.server.wm.ActivityRecord.State.STOPPED; -import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_POSITION_MULTIPLIER_CENTER; import static com.android.server.wm.AppCompatUtils.computeAspectRatio; -import static com.android.server.wm.BackgroundActivityStartControllerTests.setViaReflection; import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; +import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_POSITION_MULTIPLIER_CENTER; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.google.common.truth.Truth.assertThat; @@ -96,11 +95,13 @@ import android.compat.testing.PlatformCompatChangeRule; import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.ScreenOrientation; +import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Insets; import android.graphics.Rect; import android.os.Binder; +import android.os.RemoteException; import android.os.UserHandle; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; @@ -1086,7 +1087,9 @@ public class SizeCompatTests extends WindowTestsBase { spyOn(activity.mAppCompatController.getAppCompatAspectRatioOverrides()); doReturn(true).when(activity.mWmService.mAppCompatConfiguration) .isUserAppAspectRatioFullscreenEnabled(); - setUserAspectRatioType(activity, USER_MIN_ASPECT_RATIO_FULLSCREEN); + doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN) + .when(activity.mAppCompatController.getAppCompatAspectRatioOverrides()) + .getUserMinAspectRatioOverrideCode(); assertFalse(activity.shouldCreateAppCompatDisplayInsets()); } @@ -2207,9 +2210,11 @@ public class SizeCompatTests extends WindowTestsBase { doReturn(true).when(mActivity.mWmService.mAppCompatConfiguration) .isUserAppAspectRatioFullscreenEnabled(); - // Set user aspect ratio override. + // Set user aspect ratio override spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()); - setUserAspectRatioType(mActivity, USER_MIN_ASPECT_RATIO_FULLSCREEN); + doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN) + .when(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()) + .getUserMinAspectRatioOverrideCode(); prepareMinAspectRatio(mActivity, 16 / 9f, SCREEN_ORIENTATION_PORTRAIT); @@ -2232,7 +2237,10 @@ public class SizeCompatTests extends WindowTestsBase { // Set user aspect ratio override spyOn(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()); - setUserAspectRatioType(mActivity, USER_MIN_ASPECT_RATIO_FULLSCREEN); + doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN) + .when(mActivity.mAppCompatController.getAppCompatAspectRatioOverrides()) + .getUserMinAspectRatioOverrideCode(); + prepareMinAspectRatio(mActivity, 16 / 9f, SCREEN_ORIENTATION_LANDSCAPE); final Rect bounds = mActivity.getBounds(); @@ -2415,7 +2423,7 @@ public class SizeCompatTests extends WindowTestsBase { true); } - private void testUserOverrideAspectRatio(boolean isUnresizeable, int screenOrientation, + private void testUserOverrideAspectRatio(boolean isUnresizable, int screenOrientation, float expectedAspectRatio, @PackageManager.UserMinAspectRatio int aspectRatio, boolean enabled) { final ActivityRecord activity = getActivityBuilderWithoutTask().build(); @@ -2429,10 +2437,15 @@ public class SizeCompatTests extends WindowTestsBase { spyOn(activity.mWmService.mAppCompatConfiguration); doReturn(enabled).when(activity.mWmService.mAppCompatConfiguration) .isUserAppAspectRatioSettingsEnabled(); - // Set user aspect ratio override. - setUserAspectRatioType(activity, aspectRatio); + // Set user aspect ratio override + final IPackageManager pm = mAtm.getPackageManager(); + try { + doReturn(aspectRatio).when(pm) + .getUserMinAspectRatio(activity.packageName, activity.mUserId); + } catch (RemoteException ignored) { + } - prepareLimitedBounds(activity, screenOrientation, isUnresizeable); + prepareLimitedBounds(activity, screenOrientation, isUnresizable); final Rect afterBounds = activity.getBounds(); final int width = afterBounds.width(); @@ -5189,11 +5202,4 @@ public class SizeCompatTests extends WindowTestsBase { DeviceConfig.setProperty(NAMESPACE_CONSTRAIN_DISPLAY_APIS, CONFIG_ALWAYS_CONSTRAIN_DISPLAY_APIS, value, makeDefault); } - - private void setUserAspectRatioType(ActivityRecord activity, - @PackageManager.UserMinAspectRatio int aspectRatio) { - final AppCompatAspectRatioOverrides aspectRatioOverrides = activity.mAppCompatController - .getAppCompatAspectRatioOverrides(); - setViaReflection(aspectRatioOverrides, "mUserAspectRatioType", aspectRatio); - } } -- GitLab From d5808587e600da858da31150908c26951d9e76c7 Mon Sep 17 00:00:00 2001 From: Ibrahim Yilmaz Date: Fri, 4 Oct 2024 19:44:38 +0000 Subject: [PATCH 135/447] [RONs] Create ProgressStyle Expanded Template This CL creates ProgressStyle template and binds start and end icons. Bug: 370497239 Test: Presubmit && check the attacted ProgressStyle expanded view screenshot Flag: android.app.api_rich_ongoing Change-Id: I2ea492b471074125a5ce21a2a7e77764aabcc393 --- core/java/android/app/Notification.java | 40 ++++++ .../notification_progress_icon_background.xml | 20 +++ ...otification_template_material_progress.xml | 121 ++++++++++++++++++ core/res/res/values/dimens.xml | 3 + core/res/res/values/symbols.xml | 5 + 5 files changed, 189 insertions(+) create mode 100644 core/res/res/drawable/notification_progress_icon_background.xml create mode 100644 core/res/res/layout/notification_template_material_progress.xml diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 38632bdeeff5..bc7ebce5c5c2 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -810,6 +810,11 @@ public class Notification implements Parcelable } private static boolean isStandardLayout(int layoutId) { + if (Flags.apiRichOngoing()) { + if (layoutId == R.layout.notification_template_material_progress) { + return true; + } + } return STANDARD_LAYOUTS.contains(layoutId); } @@ -7683,6 +7688,10 @@ public class Notification implements Parcelable return R.layout.notification_template_material_conversation; } + private int getProgressLayoutResource() { + return R.layout.notification_template_material_progress; + } + private int getActionLayoutResource() { return R.layout.notification_material_action; } @@ -11640,6 +11649,37 @@ public class Notification implements Parcelable return getStandardView(mBuilder.getHeadsUpBaseLayoutResource(), p, null /* result */); } + /** + * @hide + */ + @Override + public RemoteViews makeBigContentView() { + StandardTemplateParams p = mBuilder.mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_BIG) + .allowTextWithProgress(true) + .fillTextsFrom(mBuilder); + + // Replace the text with the big text, but only if the big text is not empty. + RemoteViews contentView = getStandardView(mBuilder.getProgressLayoutResource(), p, + null /* result */); + + // Bind progress start and end icons. + if (mStartIcon != null) { + contentView.setViewVisibility(R.id.notification_progress_start_icon, View.VISIBLE); + contentView.setImageViewIcon(R.id.notification_progress_start_icon, mStartIcon); + } else { + contentView.setViewVisibility(R.id.notification_progress_start_icon, View.GONE); + } + + if (mEndIcon != null) { + contentView.setViewVisibility(R.id.notification_progress_end_icon, View.VISIBLE); + contentView.setImageViewIcon(R.id.notification_progress_end_icon, mEndIcon); + } else { + contentView.setViewVisibility(R.id.notification_progress_end_icon, View.GONE); + } + + return contentView; + } private static @NonNull ArrayList getProgressSegmentsAsBundleList( @Nullable List progressSegments) { diff --git a/core/res/res/drawable/notification_progress_icon_background.xml b/core/res/res/drawable/notification_progress_icon_background.xml new file mode 100644 index 000000000000..8e843bea3d6a --- /dev/null +++ b/core/res/res/drawable/notification_progress_icon_background.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/core/res/res/layout/notification_template_material_progress.xml b/core/res/res/layout/notification_template_material_progress.xml new file mode 100644 index 000000000000..b413c701d6c5 --- /dev/null +++ b/core/res/res/layout/notification_template_material_progress.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 6683dc044c9a..b92aa2f355ed 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -304,6 +304,9 @@ 8dp + + 2dp + 56dp diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index c50c336f8fd8..b7c876545f05 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -224,6 +224,8 @@ + + @@ -2390,6 +2392,7 @@ + @@ -3205,6 +3208,7 @@ + @@ -4076,6 +4080,7 @@ + -- GitLab From 20c095b3faee1a57e7a523e9e092a689075bd69e Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 7 Oct 2024 10:55:15 -0700 Subject: [PATCH 136/447] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I695a5c9e1a2554ad94a0b38b9f37cbe0f0c9968d --- core/res/res/values-af/strings.xml | 5 ----- core/res/res/values-am/strings.xml | 5 ----- core/res/res/values-ar/strings.xml | 5 ----- core/res/res/values-as/strings.xml | 5 ----- core/res/res/values-az/strings.xml | 5 ----- core/res/res/values-b+sr+Latn/strings.xml | 5 ----- core/res/res/values-be/strings.xml | 5 ----- core/res/res/values-bg/strings.xml | 5 ----- core/res/res/values-bn/strings.xml | 5 ----- core/res/res/values-bs/strings.xml | 5 ----- core/res/res/values-ca/strings.xml | 13 ++++--------- core/res/res/values-cs/strings.xml | 5 ----- core/res/res/values-da/strings.xml | 5 ----- core/res/res/values-de/strings.xml | 5 ----- core/res/res/values-el/strings.xml | 9 ++------- core/res/res/values-en-rAU/strings.xml | 5 ----- core/res/res/values-en-rCA/strings.xml | 5 ----- core/res/res/values-en-rGB/strings.xml | 5 ----- core/res/res/values-en-rIN/strings.xml | 5 ----- core/res/res/values-en-rXC/strings.xml | 5 ----- core/res/res/values-es-rUS/strings.xml | 5 ----- core/res/res/values-es/strings.xml | 7 +------ core/res/res/values-et/strings.xml | 5 ----- core/res/res/values-eu/strings.xml | 7 +------ core/res/res/values-fa/strings.xml | 7 +------ core/res/res/values-fi/strings.xml | 5 ----- core/res/res/values-fr-rCA/strings.xml | 5 ----- core/res/res/values-fr/strings.xml | 7 +------ core/res/res/values-gl/strings.xml | 5 ----- core/res/res/values-gu/strings.xml | 5 ----- core/res/res/values-hi/strings.xml | 5 ----- core/res/res/values-hr/strings.xml | 5 ----- core/res/res/values-hu/strings.xml | 5 ----- core/res/res/values-hy/strings.xml | 5 ----- core/res/res/values-in/strings.xml | 5 ----- core/res/res/values-is/strings.xml | 5 ----- core/res/res/values-it/strings.xml | 5 ----- core/res/res/values-iw/strings.xml | 5 ----- core/res/res/values-ja/strings.xml | 5 ----- core/res/res/values-ka/strings.xml | 5 ----- core/res/res/values-kk/strings.xml | 5 ----- core/res/res/values-km/strings.xml | 5 ----- core/res/res/values-kn/strings.xml | 5 ----- core/res/res/values-ko/strings.xml | 5 ----- core/res/res/values-ky/strings.xml | 5 ----- core/res/res/values-lo/strings.xml | 5 ----- core/res/res/values-lt/strings.xml | 5 ----- core/res/res/values-lv/strings.xml | 5 ----- core/res/res/values-mk/strings.xml | 5 ----- core/res/res/values-ml/strings.xml | 5 ----- core/res/res/values-mn/strings.xml | 5 ----- core/res/res/values-mr/strings.xml | 5 ----- core/res/res/values-ms/strings.xml | 5 ----- core/res/res/values-my/strings.xml | 7 +------ core/res/res/values-nb/strings.xml | 5 ----- core/res/res/values-ne/strings.xml | 5 ----- core/res/res/values-nl/strings.xml | 5 ----- core/res/res/values-or/strings.xml | 5 ----- core/res/res/values-pa/strings.xml | 5 ----- core/res/res/values-pl/strings.xml | 5 ----- core/res/res/values-pt-rBR/strings.xml | 5 ----- core/res/res/values-pt-rPT/strings.xml | 5 ----- core/res/res/values-pt/strings.xml | 5 ----- core/res/res/values-ro/strings.xml | 5 ----- core/res/res/values-ru/strings.xml | 5 ----- core/res/res/values-si/strings.xml | 5 ----- core/res/res/values-sk/strings.xml | 5 ----- core/res/res/values-sl/strings.xml | 5 ----- core/res/res/values-sq/strings.xml | 5 ----- core/res/res/values-sr/strings.xml | 5 ----- core/res/res/values-sv/strings.xml | 11 +++-------- core/res/res/values-sw/strings.xml | 5 ----- core/res/res/values-ta/strings.xml | 5 ----- core/res/res/values-te/strings.xml | 5 ----- core/res/res/values-th/strings.xml | 5 ----- core/res/res/values-tl/strings.xml | 5 ----- core/res/res/values-tr/strings.xml | 5 ----- core/res/res/values-uk/strings.xml | 5 ----- core/res/res/values-ur/strings.xml | 5 ----- core/res/res/values-uz/strings.xml | 5 ----- core/res/res/values-vi/strings.xml | 5 ----- core/res/res/values-zh-rCN/strings.xml | 5 ----- core/res/res/values-zh-rHK/strings.xml | 5 ----- core/res/res/values-zh-rTW/strings.xml | 5 ----- core/res/res/values-zu/strings.xml | 5 ----- 85 files changed, 14 insertions(+), 439 deletions(-) diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 1cd21504193c..cdae26541737 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -2129,11 +2129,6 @@ "Oproepe en kennisgewings sal vibreer" "Oproepe en kennisgewings sal gedemp wees" "Stelselveranderinge" - "Moenie Steur Nie" - "Nuut: Moenie Steur Nie versteek tans kennisgewings" - "Tik om meer te wete te kom en te verander." - "Moenie Steur Nie het verander" - "Tik om te kyk wat geblokkeer word." "Gaan kennisgewinginstellings na" "Vanaf Android 13 het programme wat jy installeer jou toestemming nodig om kennisgewings te stuur. Tik om hierdie toestemming vir bestaande programme te verander." "Herinner my later" diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 484afc3c344e..cc8ab3e03f6e 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -2129,11 +2129,6 @@ "ጥሪዎች እና ማሳወቂያዎች ይነዝራሉ" "ጥሪዎች እና ማሳወቂያዎች ድምፀ-ከል ይሆናሉ" "የሥርዓት ለውጦች" - "አትረብሽ" - "አዲስ፦ አትረብሽ ማሳወቂያዎችን እየደበቀ ነው" - "የበለጠ ለመረዳት እና ለመለወጥ መታ ያድርጉ።" - "አትረብሽ ተቀይሯል" - "ምን እንደታገደ ለመፈተሽ መታ ያድርጉ።" "የማሳወቂያ ቅንብሮችን ይገምግሙ" "ከAndroid 13 ጀምረው የሚጭኗቸው መተግበሪያዎች ማሳወቂያዎችን ለመላክ የእርስዎ ፈቃድ ያስፈልጋቸዋል። ይህን ፈቃድ ለነባር መተግበሪያዎች ለመቀየር መታ ያድርጉ።" "በኋላ አስታውሰኝ" diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 75e93d1aa315..e81ec89ebe51 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -2133,11 +2133,6 @@ "سيهتز الهاتف عند تلقّي المكالمات والإشعارات." "سيتم كتم صوت الهاتف عند تلقي المكالمات والإشعارات." "تغييرات النظام" - "عدم الإزعاج" - "جديد: يؤدي تفعيل ميزة \"عدم الإزعاج\" إلى إخفاء الإشعارات." - "انقر لمعرفة مزيد من المعلومات وإجراء التغيير." - "تم تغيير ميزة \"عدم الإزعاج\"" - "انقر للاطّلاع على ما تم حظره." "مراجعة إعدادات الإشعارات" "‏بدءً من نظام التشغيل Android 13، يجب أن تحصل التطبيقات التي تُثبِّتها على إذن لإرسال الإشعارات. انقر لتغيير هذا الإذن للتطبيقات الحالية." "تذكيري لاحقًا" diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index e64c85e058d5..f36a659dd84d 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -2129,11 +2129,6 @@ "কল আৰু জাননীসমূহে কম্পন কৰিব" "কল আৰু জাননীসমূহ মিউট কৰা হ\'ব" "ছিষ্টেমৰ সালসলনি" - "অসুবিধা নিদিব" - "নতুন: অসুবিধা নিদিব ম\'ডে জাননীসমূহ লুকাই ৰাখিছে" - "অধিক জানিবলৈ আৰু সলনি কৰিবলৈ টিপক।" - "অসুবিধা নিদিব সলনি হৈছে" - "কি কি অৱৰোধ কৰা হৈছে জানিবলৈ টিপক।" "জাননীৰ ছেটিং পৰ্যালোচনা কৰক" "Android 13ৰ পৰা, আপুনি ইনষ্টল কৰা এপক জাননী পঠিয়াবলৈ আপোনাৰ অনুমতিৰ প্ৰয়োজন। আগৰে পৰা থকা এপৰ বাবে এই অনুমতিটো সলনি কৰিবলৈ টিপক।" "পাছত মনত পেলাই দিব" diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 25dc42904995..2a77df23934c 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -2129,11 +2129,6 @@ "Zəng və bildirişlər vibrasiya verəcək" "Zəng və bildirişlər səssiz ediləcək" "Sistem dəyişiklikləri" - "Narahat Etməyin" - "Yenilik: \"Narahat etməyin\" rejimi bildirişləri gizlədir" - "Ətraflı məıumat əldə edərək dəyişmək üçün klikləyin." - "\"Narahat Etməyin\" rejimi dəyişdirildi" - "Nəyin blok edildiyini yoxlamaq üçün klikləyin." "Bildiriş ayarlarını nəzərdən keçirin" "Android 13-dən başlayaraq quraşdırdığınız tətbiqlər bildiriş göndərmək üçün icazənizi tələb edir. Mövcud tətbiqlər üçün bu icazəni dəyişmək üçün toxunun." "Sonra xatırladın" diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 7413703e2ada..a51aad24b06f 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -2130,11 +2130,6 @@ "Vibracija za pozive i obaveštenja je uključena" "Melodija zvona za pozive i obaveštenje je isključena" "Sistemske promene" - "Ne uznemiravaj" - "Novo: Režim Ne uznemiravaj krije obaveštenja" - "Dodirnite da biste saznali više i promenili podešavanje." - "Režim Ne uznemiravaj je promenjen" - "Dodirnite da biste proverili šta je blokirano." "Pregledajte podešavanja obaveštenja" "Od Android-a 13 aplikacije koje instalirate moraju da imaju dozvolu za slanje obaveštenja. Dodirnite da biste promenili ovu dozvolu za postojeće aplikacije." "Podseti me kasnije" diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index a5af4b9fbdfe..26f11df6259c 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -2131,11 +2131,6 @@ "Для выклікаў і апавяшчэнняў уключаны вібрасігнал" "Для выклікаў і апавяшчэнняў гук выключаны" "Сістэмныя змены" - "Не турбаваць" - "Новае: у рэжыме \"Не турбаваць\" апавяшчэнні не паказваюцца" - "Дакраніцеся, каб даведацца больш і змяніць." - "Зменены налады рэжыму \"Не турбаваць\"" - "Націсніце, каб паглядзець заблакіраванае." "Праверце налады апавяшчэнняў" "Пачынаючы з версіі Android 13 усталяваным вамі праграмам неабходна даваць дазвол на адпраўку апавяшчэнняў. Націсніце, каб змяніць дазвол для існуючых праграм." "Нагадаць пазней" diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 9b5a825b9e38..38c9d0b7cd94 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -2129,11 +2129,6 @@ "При обаждания и известия устройството ще вибрира" "Обажданията и известията ще бъдат заглушени" "Промени в системата" - "Не безпокойте" - "Ново: Режимът „Не безпокойте“ скрива известията" - "Докоснете, за да научите повече и да извършите промени." - "Настройките за „Не безпокойте“ са променени" - "Докоснете, за да проверите какво е блокирано." "Преглед на настройките за известия" "От Android 13 инсталираните от вас приложения трябва да получат разрешението ви, за да изпращат известия. Докоснете, за да промените това разрешение за съществуващите приложения." "Напомняне по-късно" diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 0871bfd244fe..8a833c88e44a 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -2129,11 +2129,6 @@ "কল এবং বিজ্ঞপ্তি আসলে ভাইব্রেট হবে" "কল এবং বিজ্ঞপ্তিগুলি মিউট করা হবে" "সিস্টেমে হয়ে থাকা পরিবর্তন" - "বিরক্ত করবে না" - "নতুন: \'বিরক্ত করবে না\' মোড চালু আছে, তাই বিজ্ঞপ্তি লুকিয়ে ফেলা হচ্ছে" - "আরও জানতে এবং পরিবর্তন করতে ট্যাপ করুন।" - "\'বিরক্ত করবে না\' মোডের সেটিং বদলে গেছে" - "কী কী ব্লক করা আছে তা দেখতে ট্যাপ করুন।" "বিজ্ঞপ্তির সেটিংস পর্যালোচনা করুন" "Android 13 থেকে শুরু করে, বিজ্ঞপ্তি পাঠানোর জন্য আপনার ইনস্টল করা অ্যাপকে অনুমতি নিতে হবে। বর্তমান অ্যাপের জন্য এই অনুমতি পরিবর্তন করতে ট্যাপ করুন।" "পরে মনে করিয়ে দিও" diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 9d5ecdcc1933..9e29b7f7795f 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -2130,11 +2130,6 @@ "Pozivi i obavještenja će vibrirati" "Pozivi i obavještenja će se isključiti" "Sistemske promjene" - "Ne ometaj" - "Novo: Način rada Ne ometaj sakriva obavještenja" - "Dodirnite da saznate više i izvršite promjene." - "Način rada Ne ometaj je promijenjen" - "Dodirnite da provjerite šta je blokirano." "Pregledajte postavke obavještenja" "Počevši od Androida 13, aplikacije koje instalirate trebaju odobrenje da šalju obavještenja. Dodirnite da promijenite ovo odobrenje za postojeće aplikacije." "Podsjeti me kasnije" diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 5728aed8551a..0dd1bca868ad 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -2130,11 +2130,6 @@ "Les trucades i les notificacions vibraran" "Les trucades i les notificacions se silenciaran" "Canvis del sistema" - "No molestis" - "Novetat: el mode No molestis està amagant notificacions" - "Toca per obtenir més informació i canviar la configuració." - "S\'ha canviat el mode No molestis" - "Toca per consultar què s\'ha bloquejat." "Consulta la configuració de notificacions" "A partir de la versió Android 13, les aplicacions que instal·les necessiten el teu permís per enviar notificacions. Toca per canviar aquest permís per a les aplicacions existents." "Recorda-m\'ho més tard" @@ -2394,12 +2389,12 @@ "Utilitza un altre cable i torna-ho a provar" "El dispositiu està massa calent i no pot duplicar a la pantalla fins que es refredi" "Pantalla dual" - "La pantalla dual està activada" + "Pantalla dual està activada" "%1$s està utilitzant les dues pantalles per mostrar contingut" "El dispositiu està massa calent" - "La pantalla dual no està disponible perquè el telèfon està massa calent" - "Dual Screen no està disponible" - "Dual Screen no està disponible perquè la funció Estalvi de bateria està activada. Pots desactivar aquesta opció a Configuració." + "Pantalla dual no està disponible perquè el telèfon està massa calent" + "Pantalla dual no està disponible" + "Pantalla dual no està disponible perquè la funció Estalvi de bateria està activada. Pots desactivar aquesta opció a Configuració." "Ves a Configuració" "Desactiva" "%s configurat" diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 2fea7fba45dc..35f269ab48e0 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -2131,11 +2131,6 @@ "Volání a oznámení budou vibrovat" "Volání a oznámení budou ztlumena" "Změny nastavení systému" - "Nerušit" - "Novinka: Režim Nerušit skrývá oznámení" - "Klepnutím zobrazíte další informace a provedete změny." - "Nastavení režimu Nerušit se změnilo" - "Klepnutím zkontrolujete, co je blokováno." "Zkontrolujte nastavení oznámení" "Počínaje systémem Android 13 od vás nainstalované aplikace potřebují oprávnění k odesílání oznámení. Klepnutím toto oprávnění změníte pro stávající aplikace." "Připomenout později" diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index a9626a650cf9..833b0c5f29b1 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -2129,11 +2129,6 @@ "Telefonen vibrerer ved opkald og notifikationer" "Der afspilles ikke lyd ved opkald og notifikationer" "Systemændringer" - "Forstyr ikke" - "Nyhed! Forstyr ikke skjuler notifikationer" - "Tryk for at få flere oplysninger og foretage ændringer." - "Tilstanden Forstyr ikke blev ændret" - "Tryk for at se, hvad der er blokeret." "Gennemgå indstillinger for notifikationer" "Fra og med Android 13 skal de apps, som du installerer, have din tilladelse til at sende notifikationer. Tryk for at ændre denne indstilling for eksisterende apps." "Påmind mig senere" diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index da0e9bd2c835..1318f64178f8 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -2129,11 +2129,6 @@ "Gerät vibriert bei Anrufen und Benachrichtigungen" "Anrufe und Benachrichtigungen stummgeschaltet" "Systemänderungen" - "Bitte nicht stören" - "Neu: Durch „Bitte nicht stören“ werden Benachrichtigungen nicht mehr angezeigt" - "Für weitere Informationen und zum Ändern tippen." - "„Bitte nicht stören“ wurde geändert" - "Tippe, um zu überprüfen, welche Inhalte blockiert werden." "Benachrichtigungseinstellungen überprüfen" "Ab Android 13 benötigen Apps, die du installierst, die Berechtigung zum Senden von Benachrichtigungen. Wenn du diese Berechtigung für bereits installierte Apps ändern möchtest, tippe hier." "Später erinnern" diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 0556a0820dea..bccea8f8bc0b 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -507,7 +507,7 @@ "Επιτρέπει στην εφαρμογή την τροποποίηση καθολικών ρυθμίσεων ήχου, όπως η ένταση και ποιο ηχείο χρησιμοποιείται για έξοδο." "εγγράφει ήχο" "Αυτή η εφαρμογή μπορεί να εγγράφει ήχο μέσω του μικροφώνου, όταν τη χρησιμοποιείτε." - "εγγραφή ήχου στο παρασκήνιο" + "ηχογράφηση στο παρασκήνιο" "Αυτή η εφαρμογή μπορεί να εγγράφει ήχο μέσω του μικροφώνου, ανά πάσα στιγμή." "ανίχνευση καταγραφών οθόνης που περιέχουν τα παράθυρα της εφαρμογής" "Η εφαρμογή θα λάβει ειδοποίηση όταν ληφθεί ένα στιγμιότυπο οθόνης ενώ βρίσκεται σε χρήση." @@ -541,7 +541,7 @@ "προβολή και έλεγχος κλήσεων μέσω του συστήματος." "Επιτρέπει στην εφαρμογή να βλέπει και να ελέγχει τις εισερχόμενες κλήσεις στη συσκευή. Αυτό περιλαμβάνει πληροφορίες όπως τους αριθμούς κλήσεων για τις κλήσεις και την κατάσταση των κλήσεων." "εξαίρεση από περιορισμούς εγγραφής ήχου" - "Εξαιρέστε την εφαρμογή από περιορισμούς για την εγγραφή ήχου." + "Εξαιρέστε την εφαρμογή από περιορισμούς για την ηχογράφηση." "συνέχιση κλήσης από άλλη συσκευή" "Επιτρέπει στην εφαρμογή να συνεχίσει μια κλήση η οποία ξεκίνησε σε άλλη εφαρμογή." "ανάγνωση αριθμών τηλεφώνου" @@ -2129,11 +2129,6 @@ "Θα υπάρχει δόνηση για κλήσεις και ειδοποιήσεις" "Οι κλήσεις και οι ειδοποιήσεις θα τεθούν σε παύση" "Αλλαγές στο σύστημα" - "Μην ενοχλείτε" - "Νέο: Η λειτουργία \"Μην ενοχλείτε\" αποκρύπτει ειδοποιήσεις" - "Πατήστε για να μάθετε περισσότερα και να κάνετε αλλαγές." - "Η λειτουργία \"Μην ενοχλείτε\" άλλαξε" - "Πατήστε για να ελέγξετε το περιεχόμενο που έχει αποκλειστεί." "Έλεγχος ρυθμίσεων ειδοποιήσεων" "Από το Android 13 και έπειτα, οι εφαρμογές που εγκαθιστάτε θα χρειάζονται την άδειά σας για την αποστολή ειδοποιήσεων. Πατήστε για να αλλάξετε αυτή την άδεια για υπάρχουσες εφαρμογές." "Υπενθύμιση αργότερα" diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 086835c1cd5a..e9239e233092 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -2129,11 +2129,6 @@ "Calls and notifications will vibrate" "Calls and notifications will be muted" "System changes" - "Do not disturb" - "New: Do Not Disturb is hiding notifications" - "Tap to find out more and change." - "Do Not Disturb has changed" - "Tap to check what\'s blocked." "Review notification settings" "Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps." "Remind me later" diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 88a83b595520..c624e2a724a5 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -2129,11 +2129,6 @@ "Calls and notifications will vibrate" "Calls and notifications will be muted" "System changes" - "Do Not Disturb" - "New: Do Not Disturb is hiding notifications" - "Tap to learn more and change." - "Do Not Disturb has changed" - "Tap to check what\'s blocked." "Review notification settings" "Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps." "Remind me later" diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index ef399b715631..9ffaa5d31e95 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -2129,11 +2129,6 @@ "Calls and notifications will vibrate" "Calls and notifications will be muted" "System changes" - "Do not disturb" - "New: Do Not Disturb is hiding notifications" - "Tap to find out more and change." - "Do Not Disturb has changed" - "Tap to check what\'s blocked." "Review notification settings" "Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps." "Remind me later" diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 94ddc434926f..23441bbb0e4d 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -2129,11 +2129,6 @@ "Calls and notifications will vibrate" "Calls and notifications will be muted" "System changes" - "Do not disturb" - "New: Do Not Disturb is hiding notifications" - "Tap to find out more and change." - "Do Not Disturb has changed" - "Tap to check what\'s blocked." "Review notification settings" "Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps." "Remind me later" diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index a0a891eefac2..b1ba09c406c9 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -2129,11 +2129,6 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎Calls and notifications will vibrate‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎Calls and notifications will be muted‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎System changes‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‎Do Not Disturb‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‎New: Do Not Disturb is hiding notifications‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎Tap to learn more and change.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎Do Not Disturb has changed‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎Tap to check what\'s blocked.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‎‏‎‎‎Review notification settings‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‏‏‏‏‏‎Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‏‎Remind me later‎‏‎‎‏‎" diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index cbb30fd70768..89b22b975ef2 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -2130,11 +2130,6 @@ "Vibrarán las llamadas y notificaciones" "Se silenciarán las llamadas y notificaciones" "Cambios del sistema" - "No interrumpir" - "Nuevo: No interrumpir oculta las notificaciones" - "Presiona para obtener más información y realizar cambios." - "Se modificó la opción No interrumpir" - "Presiona para consultar lo que está bloqueado." "Revisa la configuración de notificaciones" "A partir de Android 13, las apps que instales necesitarán tu permiso a fin de enviar notificaciones. Presiona para cambiar este permiso para las apps existentes." "Recordarme más tarde" diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 23024f097dec..0082adecddce 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1407,7 +1407,7 @@ "Se ha detectado un accesorio de audio analógico" "El dispositivo adjunto no es compatible con este teléfono. Toca para obtener más información." "Depuración por USB activa" - "Toca para desactivar la depuración por USB" + "Toca para desactivar depuración USB" "Seleccionar para inhabilitar la depuración por USB" "Depuración inalámbrica conectada" "Toca para desactivar la depuración inalámbrica" @@ -2130,11 +2130,6 @@ "Las llamadas y las notificaciones vibrarán" "Las llamadas y las notificaciones se silenciarán" "Cambios del sistema" - "No molestar" - "Novedad: El modo No molestar oculta las notificaciones" - "Toca para obtener más información y hacer cambios." - "Ha cambiado el modo No molestar" - "Toca para consultar lo que se está bloqueando." "Consulta los ajustes de notificaciones" "A partir de Android 13, las aplicaciones que instalas necesitan tu permiso para enviar notificaciones. Toca para cambiar este permiso en las aplicaciones que ya tengas." "Recordar más tarde" diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 326b3db247c8..44f105544454 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -2129,11 +2129,6 @@ "Kõnede ja märguannete puhul seade vibreerib" "Kõned ja märguanded on vaigistatud" "Süsteemi muudatused" - "Mitte segada" - "Uus: režiim Mitte segada peidab märguandeid" - "Puudutage lisateabe vaatamiseks ja muutmiseks." - "Režiimi Mitte segada muudeti" - "Puudutage, et kontrollida, mis on blokeeritud." "Vaadake üle märguandeseaded" "Alates operatsioonisüsteemist Android 13 vajavad installitavad rakendused märguannete saatmiseks teie luba. Puudutage, et muuta seda luba olemasolevate rakenduste jaoks." "Tuleta hiljem meelde" diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index d092f46ab6c2..d017a05a57c7 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -745,7 +745,7 @@ "Saiakera gehiegi egin dira. Horren ordez, erabili pantailaren blokeoa." "Ezin da egiaztatu aurpegia. Saiatu berriro." "Ez duzu konfiguratu aurpegi bidez desblokeatzeko eginbidea" - "Aurpegi bidez desblokeatzeko eginbidea ez da bateragarria gailu honekin" + "Aurpegi bidez desblokeatzeko eginbidea ez da onartzen gailu honetan" "Sentsorea aldi baterako desgaitu da." "%d aurpegia" "Erabili aurpegi bidez desblokeatzeko eginbidea" @@ -2129,11 +2129,6 @@ "Dar-dar egingo du deiak eta jakinarazpenak jasotzean" "Ez da joko tonurik deiak eta jakinarazpenak jasotzean" "Sistema-aldaketak" - "Ez molestatzeko modua" - "Berria: Ez molestatzeko modua jakinarazpenak ezkutatzen ari da" - "Sakatu informazio gehiago lortzeko eta portaera aldatzeko." - "Ez molestatzeko modua aldatu da" - "Sakatu zer dagoen blokeatuta ikusteko." "Berrikusi jakinarazpen-ezarpenak" "Android 13 ezkero, jakinarazpenak bidaltzeko baimena eman behar diezu instalatzen dituzun aplikazioei. Sakatu hau lehendik dauden aplikazioen baimenak aldatzeko." "Gogorarazi geroago" diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 6933a16dd97e..ad8f056a8609 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -458,7 +458,7 @@ "اجرای سرویس پیش‌نما از نوع «استفاده ویژه»" "به برنامه اجازه می‌دهد از سرویس‌های پیش‌نما از نوع «استفاده ویژه» استفاده کند" "اندازه‌گیری اندازه فضای ذخیره‌سازی برنامه" - "‏به برنامه اجازه می‎دهد تا کدها، داده‎ها و اندازه‎های حافظهٔ پنهان خود را بازیابی کند" + "‏به برنامه اجازه می‎دهد تا کدها، داده‎ها و اندازه‎های حافظه نهان خود را بازیابی کند" "تغییر تنظیمات سیستم" "‏به برنامه اجازه می‎دهد تا داده‎های تنظیم سیستم را تغییر دهد. برنامه‌های مخرب می‎توانند پیکربندی سیستم شما را خراب کنند." "اجرا شدن در هنگام راه‌اندازی" @@ -2129,11 +2129,6 @@ "دستگاهتان برای تماس‌ها و اعلان‌ها می‌لرزد" "دستگاهتان برای تماس‌ها و اعلان‌ها بی‌صدا خواهد شد" "تغییرات سیستم" - "مزاحم نشوید" - "جدید: «مزاحم نشوید» اعلان‌ها را پنهان می‌کند" - "برای اطلاعات بیشتر و تغییر دادن، تک‌ضرب بزنید." - "«مزاحم نشوید» تغییر کرده است" - "برای بررسی موارد مسدودشده تک‌ضرب بزنید." "مرور تنظیمات اعلان" "‏از Android نسخه ۱۳ به بعد، برنامه‌هایی که نصب می‌کنید برای ارسال اعلان به اجازه شما نیاز دارند. برای تغییر دادن این اجازه در برنامه‌های موجود، تک‌ضرب بزنید." "بعداً یادآوری شود" diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 18c7902511a0..196db127fb0e 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -2129,11 +2129,6 @@ "Puhelut ja ilmoitukset värisevät" "Puhelut ja ilmoitukset mykistetään" "Järjestelmän muutokset" - "Älä häiritse" - "Uutta: Älä häiritse ‑tila piilottaa ilmoitukset" - "Napauta, jos haluat lukea lisää ja tehdä muutoksia." - "Älä häiritse ‑tila muuttui" - "Napauta niin näet, mitä on estetty." "Tarkista ilmoitusasetukset" "Asentamasi sovellukset tarvitsevat sinulta luvan ilmoitusten lähettämiseen Android 13 ‑käyttöjärjestelmästä alkaen. Napauta muuttaaksesi nykyisten sovellusten lupia." "Muistuta myöhemmin" diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index bc11e547bb82..ac87d3bac69d 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -2130,11 +2130,6 @@ "Les appels et les notifications vibreront" "Les appels et les notifications seront silencieux" "Changements système" - "Ne pas déranger" - "Nouveau : Le mode Ne pas déranger masque les notifications" - "Touchez ici pour en savoir plus et changer les paramètres" - "Les paramètres du mode Ne pas déranger ont changé" - "Touchez l\'écran pour vérifier ce qui est bloqué." "Examiner les paramètres de notification" "À partir d\'Android 13, les applis que vous installez ont besoin de votre autorisation pour envoyer des notifications. Touchez pour modifier cette autorisation pour les applis existantes." "Me rappeler plus tard" diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 03cf4634bad2..2368c885ccf9 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1407,7 +1407,7 @@ "Accessoire audio analogique détecté" "L\'appareil connecté n\'est pas compatible avec ce téléphone. Appuyez ici pour en savoir plus." "Débogage USB activé" - "Appuyez pour désactiver le débogage USB" + "Appuyez pour le désactiver" "Sélectionnez cette option pour désactiver le débogage USB." "Débogage sans fil connecté" "Appuyez pour désactiver le débogage sans fil" @@ -2130,11 +2130,6 @@ "Les appels et les notifications vibreront" "Les appels et les notifications seront silencieux" "Modifications du système" - "Ne pas déranger" - "Nouveau : Le mode Ne pas déranger masque les notifications" - "Appuyez pour en savoir plus et pour modifier les paramètres." - "Le mode Ne pas déranger a été modifié" - "Appuyez pour vérifier les contenus bloqués." "Vérifiez les paramètres de notification" "À partir d\'Android 13, les applications que vous installez ont besoin de votre autorisation pour envoyer des notifications. Appuyez pour modifier cette autorisation pour les applications déjà installées." "Plus tard" diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 430d64918470..2aba79031b69 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -2129,11 +2129,6 @@ "As chamadas e as notificacións vibrarán" "As chamadas e as notificacións estarán silenciadas" "Cambios no sistema" - "Non molestar" - "Novidade! O modo Non molestar oculta as notificacións" - "Toca para obter máis información e facer cambios." - "O modo Non molestar cambiou" - "Toca para comprobar o contido bloqueado." "Consulta a configuración de notificacións" "Desde Android 13, as aplicacións que instales necesitan o teu permiso para enviar notificacións. Toca para cambiar este permiso nas aplicacións que xa teñas." "Lembrarmo máis tarde" diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index f40fb93ca6a9..8d90e3b82c92 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -2129,11 +2129,6 @@ "કૉલ અને નોટિફિકેશન માટે ઉપકરણ વાઇબ્રેટ થશે" "કૉલ અને નોટિફિકેશન મ્યૂટ કરવામાં આવશે" "સિસ્ટમના ફેરફારો" - "ખલેલ પાડશો નહીં" - "નવું: ખલેલ પાડશો નહીં હવે નોટિફિકેશન છુપાવી શકે છે" - "વધુ જાણવા અને બદલવા માટે ટૅપ કરો." - "ખલેલ પાડશો નહીંમાં ફેરફાર થયો છે" - "શું બ્લૉક કરેલ છે તે તપાસવા માટે ટૅપ કરો." "નોટિફિકેશનના સેટિંગ રિવ્યૂ કરો" "Android 13થી શરૂઆત કરીને, તમે જે પણ ઍપ ઇન્સ્ટૉલ કરશો, તેને નોટિફિકેશન મોકલવા માટે તમારી પરવાનગીની જરૂર રહેશે. હાલની બધી ઍપ માટે આ પરવાનગીમાં ફેરફાર કરવા માટે ટૅપ કરો." "મને પછી યાદ અપાવજો" diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 0386387fc134..12ffe8774fe8 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -2129,11 +2129,6 @@ "कॉल और सूचनाओं आने पर डिवाइस वाइब्रेट हाेगा" "कॉल और सूचनाओं के लिए डिवाइस म्यूट रहेगा" "सिस्टम में हुए बदलाव" - "परेशान न करें" - "नई सुविधा: परेशान न करें सुविधा चालू होने की वजह से सूचनाएं नहीं दिखाई जा रही हैं" - "ज़्यादा जानने और बदलाव करने के लिए टैप करें." - "परेशान न करें की सुविधा बदल गई है" - "टैप करके देखें कि किन चीज़ों पर रोक लगाई गई है." "सूचना सेटिंग देखें" "Android 13 में जो ऐप्लिकेशन इंस्टॉल किए जाएंगे, उन्हें आपको सूचनाएं भेजने के लिए अनुमति लेनी होगी. पहले से इंस्टॉल किए गए ऐप्लिकेशन को दी गई अनुमति बदलने के लिए टैप करें." "बाद में याद दिलाएं" diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 54dc55de7991..895c3fa420ec 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -2130,11 +2130,6 @@ "Uređaj će vibrirati za pozive i obavijesti" "Zvučni signal poziva i obavijesti bit će isključen" "Promjene sustava" - "Ne uznemiravaj" - "Novo: način Ne uznemiravaj sakriva obavijesti" - "Dodirnite da biste saznali više i promijenili postavke." - "Promijenjena je postavka Ne uznemiravaj" - "Dodirnite da biste provjerili što je blokirano." "Pregledajte postavke obavijesti" "Od Androida 13 aplikacije koje instalirate trebaju vaše dopuštenje za slanje obavijesti. Dodirnite da biste promijenili to dopuštenje za postojeće aplikacije." "Podsjeti me kasnije" diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 179de2009dc5..3bbaef2b18ac 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -2129,11 +2129,6 @@ "A hívások és az értesítések rezegnek" "A hívások és az értesítések némák" "Rendszermódosítások" - "Ne zavarjanak" - "Újdonság: A Ne zavarjanak mód elrejti az értesítéseket" - "Koppintással további információhoz juthat, és elvégezheti a módosítást." - "Módosultak a Ne zavarjanak mód beállításai" - "Koppintson a letiltott elemek megtekintéséhez." "Értesítési beállítások áttekintése" "Az Android 13-as rendszertől kezdődően a telepített alkalmazásoknak engedélyre van szükségük értesítések küldéséhez. Koppintással módosíthatja ezt az engedélyt a meglévő alkalmazások esetében." "Emlékeztessen később" diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 312a105285e1..d341adafd871 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -2129,11 +2129,6 @@ "Զանգերի և ծանուցումների համար թրթռոցը միացված է" "Զանգերի և ծանուցումների համար ձայնն անջատված է" "Համակարգի փոփոխություններ" - "Չանհանգստացնել" - "Այժմ «Չանհանգստացնել» ռեժիմում ծանուցումները թաքցվում են" - "Հպեք՝ ավելին իմանալու և կարգավորումները փոխելու համար:" - "«Չանհանգստացնել» ռեժիմի կարգավորումները փոխվել են" - "Հպեք՝ տեսնելու, թե ինչ է արգելափակվել:" "Ստուգեք ծանուցումների կարգավորումները" "Հավելվածներին, որոնք տեղադրում եք Android 13 և ավելի նոր տարբերակներով սարքերում, անհրաժեշտ է տրամադրել ծանուցումներ ուղարկելու թույլտվություն։ Հպեք և փոխեք այս թույլտվությունն արդեն տեղադրված հավելվածների համար։" "Հիշեցնել ավելի ուշ" diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index e830d6d10e0e..1d205264af99 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -2129,11 +2129,6 @@ "Panggilan dan notifikasi akan bergetar" "Suara panggilan dan notifikasi akan dinonaktifkan" "Perubahan sistem" - "Jangan Ganggu" - "Baru: Mode Jangan Ganggu menyembunyikan notifikasi" - "Ketuk untuk mempelajari lebih lanjut dan mengubah." - "Jangan Ganggu telah berubah" - "Ketuk untuk memeriksa item yang diblokir." "Tinjau setelan notifikasi" "Mulai Android 13, aplikasi yang Anda instal memerlukan izin untuk mengirim notifikasi. Ketuk guna mengubah izin ini untuk aplikasi yang sudah ada." "Ingatkan saya nanti" diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 307fb529b903..b6d1c12549df 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -2129,11 +2129,6 @@ "Titringur er virkur fyrir símtöl og tilkynningar" "Slökkt verður á hljóði símtala og tilkynninga" "Breytingar á kerfi" - "Ónáðið ekki" - "Nýtt: „Ónáðið ekki“ er að fela tilkynningar" - "Ýttu til að fá frekari upplýsingar og breyta." - "„Ónáðið ekki“ var breytt" - "Ýttu til að skoða hvað lokað hefur verið á." "Yfirfara tilkynningastillingar" "Frá og með Android 13 þurfa forrit sem þú setur upp heimild frá þér til að senda tilkynningar. Ýttu til að breyta þessari heimild fyrir forrit sem fyrir eru." "Minna mig á seinna" diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 08ea1f1adee4..66e5f72fcabb 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -2130,11 +2130,6 @@ "La vibrazione sarà attiva per chiamate e notifiche" "L\'audio di chiamate e notifiche sarà disattivato" "Modifiche al sistema" - "Non disturbare" - "Novità: la modalità Non disturbare nasconde le notifiche" - "Tocca per avere ulteriori informazioni e modificare." - "L\'impostazione Non disturbare è cambiata" - "Tocca per controllare le notifiche bloccate." "Controlla le impostazioni di notifica" "A partire da Android 13, le app che installi devono avere la tua autorizzazione per poter inviare notifiche. Tocca per cambiare questa autorizzazione per le app esistenti." "Ricordamelo dopo" diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 1c1918cac58b..8f4fbcd76939 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -2130,11 +2130,6 @@ "שיחות והודעות ירטטו" "שיחות והתראות יושתקו" "שינויים במערכת" - "נא לא להפריע" - "חדש: מצב \'נא לא להפריע\' מסתיר התראות" - "אפשר להקיש כדי לקבל מידע נוסף ולבצע שינויים." - "ההגדרה \'נא לא להפריע\' השתנתה" - "יש להקיש כדי לבדוק מה חסום." "בדיקת הגדרת ההתראות" "‏החל מגרסת Android 13, אפליקציות שיותקנו יוכלו לשלוח התראות רק אם יקבלו ממך הרשאה. אפשר להקיש כדי לשנות את ההרשאה הזו באפליקציות קיימות." "תזכירו לי מאוחר יותר" diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 36d956c3bdd0..cd5527c80cba 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -2129,11 +2129,6 @@ "着信や通知をバイブレーションで知らせます" "着信音と通知音が鳴りません" "システムの変更" - "サイレント モード" - "新機能: サイレント モードでは通知が非表示になります" - "タップすると、詳細を確認して設定を変更できます。" - "サイレント モードが変わりました" - "タップしてブロック対象をご確認ください。" "通知設定の確認" "Android 13 以降では、インストールするアプリに、通知を送信する権限を付与する必要があります。既存のアプリのこの権限を変更するには、タップしてください。" "後で" diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 9a88e545b0c6..9b1c07fb2af6 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -2129,11 +2129,6 @@ "ზარების და შეტყობინებების მიღებისას ვიბრაცია ჩაირთვება" "ზარები და შეტყობინებები დადუმებული იქნება" "სისტემის ცვლილებები" - "არ შემაწუხოთ" - "ახალი: „არ შემაწუხოთ“ რეჟიმი მალავს შეტყობინებებს" - "შეეხეთ მეტის გასაგებად და შესაცვლელად." - "„არ შემაწუხოთ“ რეჟიმი შეცვლილია" - "შეეხეთ იმის სანახავად, თუ რა არის დაბლოკილი." "შეტყობინების პარამეტრების შემოწმება" "Android 13-ზე შეტყობინებების გასაგზავნად საჭიროა თქვენ მიერ დაინსტალირებული აპებისთვის ნებართვის მინიჭება. არსებული აპებისთვის ამ ნებართვის შესაცვლელად შეეხეთ." "შემახსენე მოგვიან." diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 595b9baaa254..ebf627f763ba 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -2129,11 +2129,6 @@ "Қоңыраулар мен хабарландырулардың дірілі болады." "Қоңыраулар мен хабарландырулардың дыбыстық сигналы өшіріледі" "Жүйе өзгерістері" - "Мазаламау режимі" - "Жаңа: Мазаламау режимі хабарландыруларды жасыруда" - "Толығырақ ақпарат алу және өзгерту үшін түртіңіз." - "Мазаламау режимі өзгерді" - "Түймені түртіп, неге тыйым салынатынын көріңіз." "Хабарландыру параметрлерін қарау" "Android 13 нұсқасынан бастап орнатылатын қолданбалар үшін хабарландыру жіберу рұқсаты керек. Бұрынғы қолданбаларда осы рұқсатты өзгерту үшін түртіңіз." "Кейінірек еске салу" diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 696bd79509ac..df7006ace657 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -2129,11 +2129,6 @@ "ការហៅ​ទូរសព្ទ និងការជូន​ដំណឹងនឹងញ័រ" "ការហៅ​ទូរសព្ទ និងការជូន​ដំណឹងនឹង​បិទសំឡេង" "ការផ្លាស់ប្ដូរ​ប្រព័ន្ធ" - "កុំ​រំខាន" - "ថ្មី៖ មុខងារ​កុំរំខាន​កំពុងលាក់​ការជូនដំណឹង" - "ចុចដើម្បីស្វែងយល់បន្ថែម និងផ្លាស់ប្ដូរ។" - "មុខងារ​កុំ​រំខាន​ត្រូវ​បាន​ប្ដូរ" - "សូមចុច​ដើម្បី​មើល​ថា​​បានទប់ស្កាត់អ្វីខ្លះ។" "ពិនិត្យមើលការកំណត់ការជូនដំណឹង" "ចាប់ពី Android 13 ឡើងទៅ កម្មវិធីដែលអ្នកដំឡើងត្រូវការ​ការអនុញ្ញាតរបស់អ្នក ដើម្បីផ្ញើការជូនដំណឹង។ សូមចុចដើម្បីផ្លាស់ប្ដូរការអនុញ្ញាតនេះសម្រាប់កម្មវិធីដែលមានស្រាប់។" "រំលឹក​ខ្ញុំ​ពេលក្រោយ" diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 419dd17d233c..5ddb586b541e 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -2129,11 +2129,6 @@ "ಕರೆಗಳು ಮತ್ತು ಅಧಿಸೂಚನೆಗಳು ವೈಬ್ರೇಟ್‌ ಆಗುತ್ತವೆ" "ಕರೆಗಳು ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಲಾಗುತ್ತದೆ" "ಸಿಸ್ಟಂ ಬದಲಾವಣೆಗಳು" - "ಅಡಚಣೆ ಮಾಡಬೇಡಿ" - "ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಮೋಡ್ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮರೆಮಾಡುತ್ತಿದೆ" - "ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಮತ್ತು ಬದಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ." - "ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಬದಲಾಗಿದೆ" - "ಏನನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ ಎಂಬುದನ್ನು ಪರೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ." "ನೋಟಿಫಿಕೇಶನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ" "Android 13 ನಿಂದ ಪ್ರಾರಂಭಿಸಿ, ನೀವು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡುವ ಆ್ಯಪ್‌ಗಳಿಗೆ, ಅಧಿಸೂಚನೆಗಳನ್ನು ಕಳುಹಿಸಲು ನಿಮ್ಮ ಅನುಮತಿಯ ಅಗತ್ಯವಿದೆ. ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗಳಿಗಾಗಿ ಈ ಅನುಮತಿಯನ್ನು ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ." "ನಂತರ ರಿಮೈಂಡ್ ಮಾಡಿ" diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 5f0e1f9760e0..92ca1d529563 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -2129,11 +2129,6 @@ "전화 및 알림이 오면 진동이 사용됩니다." "전화 및 알림 소리가 음소거됩니다." "시스템 변경사항" - "방해 금지 모드" - "새로운 기능: 방해 금지 모드로 알림 숨기기" - "자세히 알아보고 변경하려면 탭하세요." - "방해 금지 모드 변경" - "차단된 항목을 확인하려면 탭하세요." "알림 설정 검토" "Android 13부터 설치된 앱에는 알림을 전송하기 위한 권한이 필요합니다. 기존 앱의 알림 전송 권한을 변경하려면 탭하세요." "나중에 알림" diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 14e1064a9aec..a4380253cd73 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -2129,11 +2129,6 @@ "Чалуулар менен билдирмелер дирилдөө режиминде иштейт" "Чалуулар менен эскертмелердин үнү өчүрүлөт" "Система өзгөрүүлөрү" - "Тынчымды алба" - "Жаңы: \"Тынчымды алба\" режими билдирмелерди жашырууда" - "Көбүрөөк маалымат алып, өзгөртүү үчүн таптаңыз." - "\"Тынчымды алба\" режими өзгөрдү" - "Бөгөттөлгөн нерселерди көрүү үчүн таптаңыз." "Билдирмелердин параметрлерин карап чыгуу" "Android 13 версиясынан баштап билдирмелерди жөнөтүү үчүн орноткон колдонмолоруңузга уруксат берүү керек. Учурдагы колдонмолор үчүн бул уруксатты өзгөртүү үчүн таптап коюңуз." "Кийинчерээк эскертүү" diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index fb677cf1e44f..be09c1081f28 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -2129,11 +2129,6 @@ "ການໂທ ແລະ ການແຈ້ງເຕືອນຈະສັ່ນ" "ການໂທ ແລະ ການແຈ້ງເຕືອນຈະບໍ່ມີສຽງ" "ການປ່ຽນແປງລະບົບ" - "ຫ້າມລົບກວນ" - "ໃໝ່: ໂໝດຫ້າມລົບກວນຈະເຊື່ອງການແຈ້ງເຕືອນໄວ້" - "ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ ແລະ ປ່ຽນແປງ." - "ປ່ຽນໂໝດຫ້າມລົບກວນແລ້ວ" - "ແຕະເພື່ອກວດສອບວ່າມີຫຍັງຖືກບລັອກໄວ້ແດ່." "ກວດສອບ​ການ​ຕັ້ງ​ຄ່າ​ການ​ແຈ້ງ​ເຕືອນ" "ເລີ່ມຕົ້ນໃນ Android 13, ແອັບຕ່າງໆທີ່ທ່ານຕິດຕັ້ງຈະຕ້ອງໃຊ້ການອະນຸຍາດຂອງທ່ານເພື່ອສົ່ງການແຈ້ງເຕືອນ. ແຕະເພື່ອປ່ຽນການອະນຸຍາດນີ້ສຳລັບແອັບທີ່ມີຢູ່ກ່ອນແລ້ວ." "ແຈ້ງເຕືອນຂ້ອຍພາຍຫຼັງ" diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index e617a4cfbfc6..45998ee38787 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -2131,11 +2131,6 @@ "Skambučiai ir pranešimai vibruos" "Skambučiai ir pranešimai bus nutildyti" "Sistemos pakeitimai" - "Netrukdymo režimas" - "Naujiena: naudojant netrukdymo režimą pranešimai slepiami" - "Palieskite, kad sužinotumėte daugiau ir pakeistumėte." - "Netrukdymo režimas pakeistas" - "Palieskite, kad patikrintumėte, kas blokuojama." "Peržiūrėkite pranešimų nustatymus" "Tryliktos ir naujesnių versijų „Android” jūsų įdiegtoms programoms reikia suteikti leidimą siųsti pranešimus. Palieskite, kad pakeistumėte šį leidimą esamoms programoms." "Priminti vėliau" diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index b04dd4521a31..973d8e2c0568 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -2130,11 +2130,6 @@ "Zvaniem un paziņojumiem tiks aktivizēta vibrācija." "Zvanu un paziņojumu signāla skaņa būs izslēgta." "Sistēmas izmaiņas" - "Netraucēt" - "Jaunums: režīmā “Netraucēt” paziņojumi tiek paslēpti" - "Pieskarieties, lai uzzinātu vairāk un veiktu izmaiņas." - "Režīms “Netraucēt” ir mainīts" - "Pieskarieties, lai uzzinātu, kas tiek bloķēts." "Pārskatīt paziņojumu iestatījumus" "Operētājsistēmā Android 13 un jaunākās versijās jūsu instalētajām lietotnēm ir nepieciešama atļauja sūtīt paziņojumus. Pieskarieties, lai mainītu šo atļauju esošajām lietotnēm." "Atgādināt vēlāk" diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index b0d6351f5667..3943dc359bd9 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -2129,11 +2129,6 @@ "Повиците и известувањата ќе вибрираат" "Повиците и известувањата нема да имаат звук" "Системски промени" - "Не вознемирувај" - "Ново: режимот „Не вознемирувај“ ги крие известувањата" - "Допрете за да дознаете повеќе и да ги промените поставките." - "Поставките за „Не вознемирувај“ се изменија" - "Допрете за да проверите што е блокирано." "Прегледајте ги поставките за известувања" "Почнувајќи од Android 13, на апликациите што ги инсталирате им е потребна ваша дозвола за испраќање известувања. Допрете за да ја промените оваа дозвола за постојни апликации." "Потсети ме подоцна" diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index cc545e29ac4f..242e9679baf6 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -2129,11 +2129,6 @@ "കോളുകളും അറിയിപ്പുകളും വൈബ്രേറ്റ് ചെയ്യും" "കോളുകളും അറിയിപ്പുകളും മ്യൂട്ട് ചെയ്യപ്പെടും" "സിസ്‌റ്റത്തിലെ മാറ്റങ്ങൾ" - "ശല്യപ്പെടുത്തരുത്" - "പുതിയത്: അറിയിപ്പുകളെ \'ശല്യപ്പെടുത്തരുത്\' അദൃശ്യമാക്കുന്നു" - "കൂടുതലറിയാനും മാറ്റാനും ടാപ്പ് ചെയ്യുക." - "\'ശല്യപ്പെടുത്തരുത്\' മാറ്റി" - "എന്തിനെയാണ് ബ്ലോക്ക് ചെയ്‌തതെന്ന് പരിശോധിക്കാൻ ടാപ്പ് ചെയ്യുക." "അറിയിപ്പ് ക്രമീകരണം അവലോകനം ചെയ്യുക" "Android 13 മുതൽ, നിങ്ങൾ ഇൻസ്‌റ്റാൾ ചെയ്യുന്ന ആപ്പുകൾക്ക് അറിയിപ്പുകൾ അയയ്‌ക്കാൻ നിങ്ങളുടെ അനുമതി വേണം. നിലവിലുള്ള ആപ്പുകൾക്ക് ഈ അനുമതി മാറ്റാൻ ടാപ്പ് ചെയ്യുക." "പിന്നീട് ഓർമ്മിപ്പിക്കൂ" diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 87ce94ba6939..c8f2eaaf0b5c 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -2129,11 +2129,6 @@ "Дуудлага болон мэдэгдэл чичирнэ" "Дуудлага болон мэдэгдлийн дууг хаана" "Системийн өөрчлөлт" - "Бүү саад бол" - "Шинэ: Бүү саад бол горим мэдэгдлийг нууж байна" - "Илүү ихийг мэдэж, өөрчлөхийн тулд товшино уу." - "Бүү саад бол горимыг өөрчилсөн" - "Блоклосон зүйлийг шалгахын тулд товшино уу." "Мэдэгдлийн тохиргоог шалгах" "Android 13-аас эхлэн таны суулгасан аппууд мэдэгдэл илгээхийн тулд танаас зөвшөөрөл авах шаардлагатай. Одоо байгаа аппуудын уг зөвшөөрлийг өөрчлөхийн тулд товшино уу." "Надад дараа сануул" diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 03cabc31f573..9980d9f5e4c8 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -2129,11 +2129,6 @@ "कॉल आणि सूचनांवर व्हायब्रेट होईल" "कॉल आणि सूचना म्यूट केल्या जातील" "सिस्टम बदल" - "व्यत्यय आणू नका" - "व्यत्यय आणू नका सूचना लपवत आहे" - "अधिक जाणून घेण्‍यासाठी आणि बदलण्‍यासाठी टॅप करा." - "व्यत्यय आणू नका बदलले आहे" - "काय ब्लॉक केले आहे हे तपासण्यासाठी टॅप करा." "सूचना सेटिंग्जचे पुनरावलोकन करा" "Android 13 पासून, तुम्ही त्यामध्ये इंस्टॉल केलेल्या अ‍ॅप्सना सूचना पाठवण्यासाठी तुमच्या परवानगीची आवश्यकता आहे. सध्याच्या अ‍ॅप्ससाठी ही परवानगी बदलण्याकरिता टॅप करा." "मला आठवण करून द्या" diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 57f1472b6f34..e8116355477e 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -2129,11 +2129,6 @@ "Panggilan dan pemberitahuan akan bergetar" "Panggilan dan pemberitahuan akan diredamkan" "Perubahan sistem" - "Jangan Ganggu" - "Baharu: Jangan Ganggu menyembunyikan pemberitahuan" - "Ketik untuk mengetahui lebih lanjut dan menukar tetapan." - "Jangan Ganggu telah berubah" - "Ketik untuk menyemak item yang disekat." "Semak tetapan pemberitahuan" "Bermula dengan Android 13, apl yang anda pasang memerlukan kebenaran anda untuk menghantar pemberitahuan. Ketik untuk menukar kebenaran ini bagi apl sedia ada." "Ingatkan saya nanti" diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index f568d7112cc0..7088a15797f3 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -322,7 +322,7 @@ "တည်နေရာ" "ဤစက်ပစ္စည်း၏ တည်နေရာကို ရယူရန်" "ပြက္ခဒိန်" - "သင့်ပြက္ခဒိန်အား ဝင်ရောက်သုံးရန်" + "သင့်ပြက္ခဒိန်အား ဝင်သုံးရန်" "SMS စာတိုစနစ်" "SMS စာများကို ပို့ကာ ကြည့်မည်" "ဖိုင်များ" @@ -2129,11 +2129,6 @@ "ခေါ်ဆိုမှုများနှင့် အကြောင်းကြားချက်များ တုန်ခါပါမည်" "ခေါ်ဆိုမှုများနှင့် အကြောင်းကြားချက်များကို အသံပိတ်ထားပါမည်" "စနစ် အပြောင်းအလဲများ" - "မနှောင့်ယှက်ရ" - "အသစ်− \'မနှောင့်ယှက်ရ\' က အကြောင်းကြားချက်များကို ဖျောက်ထားသည်" - "ပိုမိုလေ့လာရန်နှင့် ပြောင်းလဲရန် တို့ပါ။" - "\'မနှောင့်ယှက်ရ\' ပြောင်းလဲသွားပါပြီ" - "ပိတ်ထားသည့်အရာများကို ကြည့်ရန် တို့ပါ။" "အကြောင်းကြားချက် ဆက်တင်များ စိစစ်ရန်" "Android 13 မှစ၍ ထည့်သွင်းသော အက်ပ်များသည် အကြောင်းကြားချက်များပို့ရန် သင်၏ခွင့်ပြုချက် လိုအပ်ပါမည်။ ရှိပြီးသားအက်ပ်များအတွက် ဤခွင့်ပြုချက်ကိုပြောင်းရန် တို့ပါ။" "နောက်မှ သတိပေးပါ" diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 6d24bdfc39b3..f39a4f8a1a8e 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -2129,11 +2129,6 @@ "Anrop og varsler vibrerer" "Anrop og varsler er lydløse" "Systemendringer" - "Ikke forstyrr" - "Nytt: «Ikke forstyrr» skjuler varsler" - "Trykk for å finne ut mer og endre." - "Ikke forstyrr er endret" - "Trykk for å sjekke hva som er blokkert." "Gjennomgå varslingsinnstillingene" "Fra og med Android 13 må apper du installerer, få tillatelse til å sende varsler. Trykk for å endre denne tillatelsen for eksisterende apper." "Påminn meg senere" diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 914c04c65495..82052b5b2806 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -2129,11 +2129,6 @@ "कल तथा सूचनाहरू आउँदा कम्पन हुने छ" "कल तथा सूचनाहरूलाई म्युट गरिने छ" "प्रणालीसम्बन्धी परिवर्तनहरू" - "बाधा नपुऱ्याउनुहोस्" - "नयाँ: बाधा नपुर्‍याउनुहोस् नामक मोडले सूचनाहरू लुकाइरहेको छ" - "थप जान्न र परिवर्तन गर्न ट्याप गर्नुहोस्।" - "बाधा नपुर्‍याउनुहोस् मोड परिवर्तन भएको छ" - "रोक लगाइएका कुराहरू जाँच गर्न ट्याप गर्नुहोस्‌।" "सूचनाका सेटिङको समीक्षा गर्नुहोस्" "Android १३ मा तपाईंले अनुमति दिनुभएका खण्डमा मात्र तपाईंले इन्स्टल गर्नुभएका एपले सूचना पठाउन सक्छन्। यसअघि इन्स्टल गरिसकिएका एपका हकमा यो अनुमति परिवर्तन गर्न ट्याप गर्नुहोस्।" "मलाई पछि स्मरण गराइयोस्" diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index d2ec4ba725a3..f591754aafb6 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -2129,11 +2129,6 @@ "Trillen bij gesprekken en meldingen" "Telefoon- en meldingsgeluid wordt uitgezet" "Systeemwijzigingen" - "Niet storen" - "Nieuw: \'Niet storen\' verbergt meldingen" - "Tik voor meer informatie en om te wijzigen." - "\'Niet storen\' is gewijzigd" - "Tik om te controleren wat er is geblokkeerd." "Instellingen voor meldingen bekijken" "Vanaf Android 13 hebben de apps die je installeert je toestemming nodig om meldingen te sturen. Tik om deze toestemming voor bestaande apps te wijzigen." "Later herinneren" diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 85a6aecda0bd..1a952a3a8e14 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -2129,11 +2129,6 @@ "କଲ୍ ଓ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଭାଇବ୍ରେଟ୍ ହେବ" "କଲ୍ ଓ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ନିଃଶବ୍ଦ କରିଦିଆଯିବ" "ସିଷ୍ଟମ୍‌ରେ ପରିବର୍ତ୍ତନ" - "ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ" - "ନୂଆ: \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ମୋଡ୍‌ ଅନ୍‌ ଥିବା ଯୋଗୁଁ ବିଜ୍ଞପ୍ତି ଲୁଚାଇ ଦିଆଯାଉଛି" - "ଅଧିକ ଜାଣିବାକୁ ଟ୍ୟାପ୍‌ କରନ୍ତୁ ଏବଂ ବଦଳାନ୍ତୁ।" - "’ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ’ ବଦଳିଯାଇଛି" - "କ’ଣ ଅବରୋଧ ହୋଇଛି ଯାଞ୍ଚ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।" "ବିଜ୍ଞପ୍ତି ସେଟିଂସକୁ ସମୀକ୍ଷା କରନ୍ତୁ" "Android 13ଠାରୁ, ଆପଣ ଇନଷ୍ଟଲ କରୁଥିବା ଆପ୍ସ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପଠାଇବା ପାଇଁ ଆପଣଙ୍କ ଅନୁମତି ଆବଶ୍ୟକ କରେ। ପୂର୍ବରୁ ଥିବା ଆପ୍ସ ପାଇଁ ଏହି ଅନୁମତିକୁ ପରିବର୍ତ୍ତନ କରିବାକୁ ଟାପ କରନ୍ତୁ।" "ମୋତେ ପରେ ରିମାଇଣ୍ଡ କର" diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 51d71ff28260..69535091213a 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -2129,11 +2129,6 @@ "ਕਾਲਾਂ ਅਤੇ ਸੂਚਨਾਵਾਂ ਦੀ ਥਰਥਰਾਹਟ ਹੋਵੇਗੀ" "ਕਾਲਾਂ ਅਤੇ ਸੂਚਨਾਵਾਂ ਨੂੰ ਮਿਊਟ ਕੀਤਾ ਜਾਵੇਗਾ" "ਸਿਸਟਮ ਬਦਲਾਅ" - "ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ" - "ਨਵਾਂ: \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਮੋਡ ਸੂਚਨਾਵਾਂ ਨੂੰ ਲੁਕਾ ਰਿਹਾ ਹੈ" - "ਹੋਰ ਜਾਣਨ ਲਈ ਅਤੇ ਬਦਲਾਅ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।" - "\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵਿਕਲਪ ਬਦਲ ਗਿਆ ਹੈ" - "ਟੈਪ ਕਰਕੇ ਦੋਖੋ ਕਿ ਕਿਹੜੀਆਂ ਚੀਜ਼ਾਂ ਬਲਾਕ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ।" "ਸੂਚਨਾ ਸੈਟਿੰਗਾਂ ਦੀ ਸਮੀਖਿਆ ਕਰੋ" "Android 13 ਜਾਂ ਇਸ ਤੋਂ ਬਾਅਦ ਵਾਲੇ ਵਰਜਨਾਂ ਵਿੱਚ, ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਜਾਣ ਵਾਲੀਆਂ ਐਪਾਂ ਨੂੰ ਸੂਚਨਾਵਾਂ ਭੇਜਣ ਲਈ ਤੁਹਾਡੀ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ। ਮੌਜੂਦਾ ਐਪਾਂ ਲਈ ਇਸ ਇਜਾਜ਼ਤ ਨੂੰ ਬਦਲਣ ਵਾਸਤੇ ਟੈਪ ਕਰੋ।" "ਬਾਅਦ ਵਿੱਚ ਯਾਦ ਕਰਵਾਓ" diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 49c30c771044..065e9bae5334 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -2131,11 +2131,6 @@ "Wibracje przy połączeniach i powiadomieniach" "Wyciszenie połączeń i powiadomień" "Zmiany w systemie" - "Nie przeszkadzać" - "Nowość: w trybie Nie przeszkadzać powiadomienia są ukrywane" - "Kliknij, by dowiedzieć się więcej i zmienić ustawienia." - "Zmiany w trybie Nie przeszkadzać" - "Kliknij, by sprawdzić, co jest zablokowane." "Sprawdź ustawienia powiadomień" "W Androidzie 13 i nowszych zainstalowane aplikacje będą potrzebowały zezwolenia na wysyłanie powiadomień. Kliknij, aby zmienić uprawnienia dla istniejących aplikacji." "Przypomnij później" diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 99ef60484276..c972e7afa3b1 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -2130,11 +2130,6 @@ "Chamadas e notificações farão o dispositivo vibrar" "Chamadas e notificações ficarão silenciadas" "Alterações do sistema" - "Não perturbe" - "Novo: o modo Não perturbe está ocultando as notificações" - "Toque para saber mais e fazer alterações." - "O modo \"Não perturbe\" foi alterado" - "Toque para verificar o que está bloqueado." "Revise as configurações de notificação" "No Android 13 ou em versões mais recentes, os apps que você instala precisam de permissão para enviar notificações. Toque para mudar essa permissão para os apps já instalados." "Lembrar mais tarde" diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 12245b9a65e3..8dddd95b87cc 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -2130,11 +2130,6 @@ "As chamadas e as notificações vibram." "É desativado o som das chamadas e das notificações." "Alterações ao sistema" - "Não incomodar" - "Novo: o modo Não incomodar está a ocultar as notificações" - "Toque para saber mais e alterar." - "O modo Não incomodar foi alterado" - "Toque para verificar o que está bloqueado." "Analise as definições de notificação" "A partir do Android 13, as apps que instalar precisam da sua autorização para enviar notificações. Toque para alterar esta autorização para as apps existentes." "Lembrar mais tarde" diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 99ef60484276..c972e7afa3b1 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -2130,11 +2130,6 @@ "Chamadas e notificações farão o dispositivo vibrar" "Chamadas e notificações ficarão silenciadas" "Alterações do sistema" - "Não perturbe" - "Novo: o modo Não perturbe está ocultando as notificações" - "Toque para saber mais e fazer alterações." - "O modo \"Não perturbe\" foi alterado" - "Toque para verificar o que está bloqueado." "Revise as configurações de notificação" "No Android 13 ou em versões mais recentes, os apps que você instala precisam de permissão para enviar notificações. Toque para mudar essa permissão para os apps já instalados." "Lembrar mais tarde" diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 85f859240b7f..014a11543ea2 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -2130,11 +2130,6 @@ "Apelurile și notificările vor vibra" "Apelurile și notificările vor avea sunetul dezactivat" "Modificări de sistem" - "Nu deranja" - "Funcția nouă Nu deranja ascunde notificările" - "Atinge ca să afli mai multe și să modifici" - "Funcția Nu deranja s-a schimbat" - "Atinge pentru a verifica ce este blocat." "Verifică setările pentru notificări" "Începând cu Android 13, aplicațiile pe care le instalezi necesită permisiunea de a trimite notificări. Atinge ca să modifici permisiunea pentru aplicațiile existente." "Mai târziu" diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 65597649917c..1e819d607858 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -2131,11 +2131,6 @@ "Для звонков и уведомлений включен вибросигнал." "Для звонков и уведомлений отключен звук." "Системные изменения" - "Не беспокоить" - "Теперь в режиме \"Не беспокоить\" уведомления не приходят" - "Нажмите, чтобы узнать больше и изменить настройки." - "Настройки режима \"Не беспокоить\" изменены" - "Нажмите, чтобы проверить настройки." "Проверьте настройки уведомлений" "В Android 13 и более поздних версий приложения могут отправлять вам уведомления только в том случае, если вы предоставили им такое разрешение. Нажмите, чтобы настроить разрешения для установленных приложений." "Напомнить позже" diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index be4151280e3a..8c808038f898 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -2129,11 +2129,6 @@ "ඇමතුම් සහ දැනුම්දීම් කම්පනය වනු ඇත" "ඇමතුම් සහ දැනුම්දීම් නිහඬ වනු ඇත" "පද්ධති වෙනස් කිරීම්" - "බාධා නොකරන්න" - "නව: බාධා නොකරන්න දැනුම්දීම් සඟවමින්" - "තව දැන ගැනීමට සහ වෙනස් කිරීමට තට්ටු කරන්න." - "බාධා නොකරන්න වෙනස් කර ඇත" - "අවහිර කර ඇති දේ පරීක්ෂා කිරීමට තට්ටු කරන්න." "දැනුම්දීම් සැකසීම් සමාලෝචනය කරන්න" "Android 13 හි සිට ආරම්භ වෙමින්, ඔබ ස්ථාපනය කරන යෙදුම්වලට දැනුම්දීම් යැවීමට ඔබගේ අවසරය අවශ්‍ය වේ. තිබෙන යෙදුම් සඳහා මෙම අවසරය වෙනස් කිරීමට තට්ටු කරන්න." "මට පසුව මතක් කරන්න" diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 61d322951879..cb3cd610c678 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -2131,11 +2131,6 @@ "Hovory a upozornenia budú vibrovať" "Hovory a upozornenia budú stlmené" "Zmeny systému" - "Režim bez vyrušení" - "Novinka: režim bez vyrušení skrýva upozornenia" - "Klepnutím získate ďalšie informácie a budete môcť vykonať zmeny." - "Režim bez vyrušení sa zmenil" - "Klepnutím skontrolujete, čo je blokované." "Kontrola nastavení upozornení" "V Androide verzie 13 a novších vyžadujú nainštalované aplikácie povolenie, aby mohli odosielať upozornenia. Klepnutím môžete zmeniť toto povolenie pre existujúce aplikácie." "Pripomenúť neskôr" diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index ed8cf505d7eb..5378875ed2f2 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -2131,11 +2131,6 @@ "Vibriranje bo vklopljeno za klice in obvestila" "Zvonjenje bo izklopljeno za klice in obvestila" "Sistemske spremembe" - "Ne moti" - "Novi način »ne moti« skriva obvestila" - "Dotaknite se, če želite izvedeti več in spremeniti." - "Način »ne moti« je spremenjen" - "Dotaknite se, da preverite, kaj je blokirano." "Preglejte nastavitve obvestil" "V Androidu 13 in novejših različicah bodo aplikacije, ki jih namestite, za pošiljanje obvestil potrebovale vaše dovoljenje. Dotaknite se, če želite spremeniti to dovoljenje za obstoječe aplikacije." "Opomni me pozneje" diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index e24e310e5772..4c8dfbcf6f1e 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -2129,11 +2129,6 @@ "Do të lëshojë dridhje për telefonatat dhe njoftimet" "Do të hiqet zëri për telefonatat dhe njoftimet" "Ndryshimet e sistemit" - "Mos shqetëso" - "E re: Modaliteti \"Mos shqetëso\" po fsheh njoftimet" - "Trokit për të mësuar më shumë dhe për të ndryshuar." - "\"Mos shqetëso\" ka ndryshuar" - "Trokit për të shënuar atë që është bllokuar" "Rishiko cilësimet e njoftimeve" "Nga Android 13, aplikacionet që instalon kanë nevojë për lejen tënde për të dërguar njoftime. Trokit për ta ndryshuar këtë leje për aplikacionet ekzistuese." "Më kujto më vonë" diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 915486e990e9..c9f44dbbfc43 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -2130,11 +2130,6 @@ "Вибрација за позиве и обавештења је укључена" "Мелодија звона за позиве и обавештење је искључена" "Системске промене" - "Не узнемиравај" - "Ново: Режим Не узнемиравај крије обавештења" - "Додирните да бисте сазнали више и променили подешавање." - "Режим Не узнемиравај је промењен" - "Додирните да бисте проверили шта је блокирано." "Прегледајте подешавања обавештења" "Од Android-а 13 апликације које инсталирате морају да имају дозволу за слање обавештења. Додирните да бисте променили ову дозволу за постојеће апликације." "Подсети ме касније" diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 0c5b6acec0fd..574b4e8ce925 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -202,7 +202,7 @@ "För många försök med lösenord" "Administratören tillåter inte längre privat bruk av enheten" "Privat område har tagits bort" - "Din organisation tillåter inte privata områden på den här hanterade enheten." + "Din organisation tillåter inte privata utrymmen på den här hanterade enheten." "Enheten hanteras" "Organisationen hanterar den här enheten och kan övervaka nätverkstrafiken. Tryck om du vill veta mer." "Appar har åtkomst till din plats" @@ -2009,8 +2009,8 @@ "Nödsituation" "Ställ in ett skärmlås" "Ställ in skärmlås" - "Ställ in ett skärmlås för enheten om du vill använda ditt privata område." - "Ange ett skärmlås för enheten om du vill radera privat område" + "Ställ in ett skärmlås för enheten om du vill använda ditt privata utrymme." + "Ange ett skärmlås för enheten om du vill radera privat utrymme" "Appen är inte tillgänglig" "%1$s är inte tillgängligt just nu." "%1$s är inte tillgänglig" @@ -2129,11 +2129,6 @@ "Vibrerar vid samtal och aviseringar" "Ljudet stängs av för samtal och aviseringar" "Systemändringar" - "Stör ej" - "Nytt: Aviseringar döljs av Stör ej" - "Tryck här om du vill läsa mer och ändra inställningarna." - "Stör ej har ändrats" - "Tryck om du vill se vad som blockeras." "Granska aviseringsinställningarna" "I Android 13 behöver appar som du installerar behörighet att skicka aviseringar. Tryck om du vill ändra denna behörighet för befintliga appar." "Påminn mig senare" diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index c002866aa6ad..676e7abef414 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -2129,11 +2129,6 @@ "Itatetema arifa ikitumwa au simu ikipigwa" "Haitatoa mlio arifa ikitumwa au simu ikipigwa" "Mabadiliko kwenye mfumo" - "Usinisumbue" - "Mpya: Kipengele cha Usinisumbue kinaficha arifa" - "Gusa ili upate maelezo zaidi na ubadilishe." - "Kipengele cha Usinisumbue kimebadilishwa" - "Gusa ili uangalie kipengee ambacho kimezuiwa." "Kagua mipangilio ya arifa" "Kuanzia Android toleo la 13, programu unazosakinisha zitahitaji ruhusa yako ili zitume arifa. Gusa ili ubadilishe ruhusa hii kwa programu zilizopo." "Nikumbushe baadaye" diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index dfc6a791e876..35cad789af8a 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -2129,11 +2129,6 @@ "அழைப்புகள் மற்றும் அறிவிப்புகளுக்கு அதிரும்" "அழைப்புகள் மற்றும் அறிவிப்புகளுக்கு ஒலியை முடக்கும்" "சிஸ்டம் மாற்றங்கள்" - "தொந்தரவு செய்ய வேண்டாம்" - "புதியது: \'தொந்தரவு செய்ய வேண்டாம்\' பயன்முறையானது அறிவிப்புகளைக் காட்டாமல் மறைக்கிறது" - "மேலும் அறிந்து மாற்ற, தட்டவும்." - "தொந்தரவு செய்ய வேண்டாம் அமைப்புகள் மாற்றப்பட்டன" - "எவற்றையெல்லாம் தடுக்கிறது என்பதைப் பார்க்க, தட்டவும்." "அறிவிப்பு அமைப்புகளை மதிப்பாய்வு செய்யுங்கள்" "Android 13 பதிப்பு முதல், நீங்கள் நிறுவுகின்ற ஆப்ஸ் உங்களுக்கு அறிவிப்புகளை அனுப்ப அனுமதி தேவை. ஏற்கெனவே உள்ள ஆப்ஸுக்கு இந்த அனுமதியை மாற்ற தட்டவும்." "பின்னர் நினைவூட்டு" diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 70732664c973..fd78f1d13304 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -2129,11 +2129,6 @@ "కాల్స్‌ మరియు నోటిఫికేషన్‌లు వైబ్రేట్ అవుతాయి" "కాల్స్‌ మరియు నోటిఫికేషన్‌లు మ్యూట్ చేయబడతాయి" "సిస్టమ్ మార్పులు" - "అంతరాయం కలిగించవద్దు" - "కొత్తది: అంతరాయం కలిగించవద్దు నోటిఫికేషన్‌లను దాస్తోంది" - "మరింత తెలుసుకోవడానికి మరియు మార్చడానికి నొక్కండి." - "అంతరాయం కలిగించవద్దు మార్చబడింది" - "బ్లాక్ చేయబడిన దాన్ని చెక్ చేయడానికి నొక్కండి." "నోటిఫికేషన్ సెట్టింగ్‌లను రివ్యూ చేయండి" "Android 13తో మొదలుకుని, మీరు ఇన్‌స్టాల్ చేసే యాప్‌లకు నోటిఫికేషన్‌లను పంపడానికి మీ అనుమతి అవసరం. ఇప్పటికే ఉన్న యాప్‌ల కోసం ఈ అనుమతిని మార్చడానికి ట్యాప్ చేయండి." "తర్వాత గుర్తు చేయి" diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 5ee187fa8a41..cbac93d4d681 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -2129,11 +2129,6 @@ "สายเรียกเข้าและการแจ้งเตือนจะสั่น" "สายเรียกเข้าและการแจ้งเตือนจะไม่ส่งเสียง" "การเปลี่ยนแปลงระบบ" - "ห้ามรบกวน" - "ใหม่: โหมดห้ามรบกวนซ่อนการแจ้งเตือนไว้" - "แตะเพื่อดูข้อมูลเพิ่มเติมและเปลี่ยนแปลง" - "เปลี่ยน \"ห้ามรบกวน\" แล้ว" - "แตะเพื่อดูรายการที่ถูกบล็อก" "ตรวจสอบการตั้งค่าการแจ้งเตือน" "ตั้งแต่ Android 13 เป็นต้นไป แอปที่คุณติดตั้งจะต้องได้รับสิทธิ์จากคุณเพื่อส่งการแจ้งเตือน แตะเพื่อเปลี่ยนแปลงสิทธิ์นี้สำหรับแอปที่มีอยู่" "เตือนภายหลัง" diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index e76dacdf0191..f9edcdca9a4a 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -2129,11 +2129,6 @@ "Magva-vibrate ang mga tawag at notification" "Mamu-mute ang mga tawag at notification" "Mga pagbabago sa system" - "Huwag Istorbohin" - "Bago: Itinatago ng Huwag Istorbohin ang mga notification" - "I-tap para matuto pa at baguhin." - "Binago ang Huwag Istorbohin" - "I-tap para tingnan kung ano ang naka-block." "Suriin ang mga setting ng notification" "Simula sa Android 13, kakailanganin na ng mga app na ii-install mo ang iyong pahintulot para makapagpadala ng mga notification. I-tap para baguhin ang pahintulot na ito para sa mga kasalukuyang app." "Ipaalala mamaya" diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index ad6fc0de5cd5..fea095101da9 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -2129,11 +2129,6 @@ "Aramalar ve bildirimler titreşim yapacak" "Aramalar ve bildirimlerin sesi kapalı olacak" "Sistem değişiklikleri" - "Rahatsız Etmeyin" - "Yeni: Rahatsız Etmeyin ayarı bildirimleri gizliyor" - "Daha fazla bilgi edinmek ve değiştirmek için dokunun." - "Rahatsız Etmeyin modu değişti" - "Nelerin engellendiğini kontrol etmek için dokunun." "Bildirim ayarlarını inceleyin" "Android 13\'te başlayarak yüklediğiniz uygulamaların bildirim gönderebilmesi için izniniz gereklidir. Mevcut uygulamalarda bu izni değiştirmek için dokunun." "Sonra hatırlat" diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index a63f3fbf4e92..68f85b8b5342 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -2131,11 +2131,6 @@ "Вібросигнал для викликів і сповіщень увімкнено" "Звуковий сигнал для викликів і сповіщень вимкнено" "Системні зміни" - "Не турбувати" - "Нове: у режимі \"Не турбувати\" сповіщення ховаються" - "Торкніться, щоб дізнатися більше та змінити." - "Налаштування режиму \"Не турбувати\" змінено" - "Торкніться, щоб перевірити, що заблоковано." "Перегляньте налаштування сповіщень" "Починаючи з ОС Android 13, установленим додаткам потрібно надати дозвіл, щоб вони могли надсилати сповіщення. Натисніть, щоб змінити цей дозвіл для наявних додатків." "Нагадати пізніше" diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 52d9e3bbc5cc..4f0971765bcc 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -2129,11 +2129,6 @@ "کالز اور اطلاعات پر وائبریٹ کرے گا" "کالز اور اطلاعات کی آواز خاموش کر دی جائے گی" "سسٹم کی تبدیلیاں" - "ڈسٹرب نہ کریں" - "نئی: \'ڈسٹرب نہ کریں\' اطلاعات کو چھپا رہی ہے" - "مزید جاننے اور تبدیل کرنے کیلئے تھپتھپائیں۔" - "\'ڈسٹرب نہ کریں\' تبدیل ہو گيا ہے" - "مسدود کی گئی چیزوں کو چیک کرنے کے لیے تھپتھپائیں۔" "اطلاع کی ترتیبات کا جائزہ لیں" "‏Android 13 کے ساتھ اب آپ جو بھی ایپس انسٹال کریں گے انہیں اطلاعات بھیجنے کے لیے آپ کی اجازت درکار ہوگی۔ موجودہ ایپس کے لیے اس اجازت کو تبدیل کرنے کی خاطر تھپتھپائیں۔" "بعد میں یاد دلائیں" diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index f62074e060d7..1bb3bcdc9759 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -2129,11 +2129,6 @@ "Chaqiruvlar va bildirishnomalar tebranadi" "Chaqiruvlar va bildirishnomalar ovozsiz qilinadi" "Tizimga oid o‘zgarishlar" - "Bezovta qilinmasin" - "Yangi: Bezovta qilinmasin rejimi bildirishnomalarni berkitmoqda" - "Batafsil axborot olish va o‘zgartirish uchun bosing." - "Bezovta qilinmasin rejimi sozlamalari o‘zgartirildi" - "Nimalar bloklanganini tekshirish uchun bosing" "Bildirishnoma sozlamalarini tekshiring" "Android 13 versiyasidan boshlab, oʻrnatiladigan ilovalar bildirishnoma yuborish uchun sizdan ruxsat oladi. Mavjud ilovalarda ushbu ruxsatni oʻzgartirish uchun bosing." "Keyinroq eslatilsin" diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 3b08a22ea956..3b1b21d7c3c6 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -2129,11 +2129,6 @@ "Cuộc gọi và thông báo sẽ rung" "Cuộc gọi và thông báo sẽ tắt tiếng" "Thay đổi hệ thống" - "Không làm phiền" - "Mới: Chế độ Không làm phiền sẽ ẩn thông báo" - "Nhấn để tìm hiểu thêm và thay đổi." - "Cài đặt Không làm phiền đã thay đổi" - "Nhấn để xem những thông báo bị chặn." "Xem lại chế độ cài đặt thông báo" "Bắt đầu trên Android 13, các ứng dụng bạn cài đặt sẽ cần bạn cấp quyền để gửi thông báo. Hãy nhấn để thay đổi quyền này cho các ứng dụng hiện có." "Nhắc tôi sau" diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 95753ebb093b..e7ebb6cff1c5 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -2129,11 +2129,6 @@ "有来电和通知时会振动" "有来电和通知时会静音" "系统变更" - "勿扰" - "新功能:勿扰模式目前可隐藏通知" - "点按即可了解详情以及进行更改。" - "“勿扰”设置有变更" - "点按即可查看屏蔽内容。" "查看通知设置" "从 Android 13 开始,您安装的应用需要您授予相应权限才能发送通知。点按即可为现有应用更改此权限。" "稍后提醒我" diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index df04ec8e8387..8f7e17c749fa 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -2129,11 +2129,6 @@ "有來電和通知時會震動" "有來電和通知時會靜音" "系統變更" - "請勿騷擾" - "新通知:「請勿騷擾」模式目前隱藏通知" - "輕按即可瞭解詳情和作出變更。" - "請勿騷擾已變更" - "輕按即可查看封鎖內容。" "查看通知設定" "由 Android 13 開始,你安裝的應用程式須獲得授權才能傳送通知。輕按即可變更現有應用程式的這項權限。" "稍後提醒我" diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index f0351ceb5591..76c581c8f73d 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -2129,11 +2129,6 @@ "有來電和通知時會震動" "有來電和通知時會靜音" "系統變更" - "零打擾" - "新功能:「零打擾」模式現在可以隱藏通知" - "輕觸即可瞭解詳情及進行變更。" - "「零打擾」設定已變更" - "輕觸即可查看遭封鎖的項目。" "查看通知設定" "從 Android 13 開始,你安裝的應用程式必須獲得授權,才能傳送通知。輕觸即可為現有應用程式變更這項權限。" "稍後提醒我" diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index f051a456a9bb..5aab13b2f087 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -2129,11 +2129,6 @@ "Amakholi nezaziso zizodlidliza" "Amakholi nezaziso zizothuliswa" "Ushintsho lwesistimu" - "Ungaphazamisi" - "Ukungaphazamisi kufihle izaziso" - "Thepha ukuze ufunde kabanzi futhi ushintshe." - "Ukungaphazamisi kushintshile" - "Thepha ukuze uhlole ukuthi yini evinjelwe." "Buyekeza amasethingi wesaziso" "Kusukela ku-Android 13, ama-app owafakayo adinga imvume yakho yokuthumela izaziso. Thepha ukuze ushintshe le mvume yama-app akhona kakade." "Ngikhumbuze ngesinye isikhathi" -- GitLab From d4f86834d5b494a1083c219bab9f63d6150e4e53 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 7 Oct 2024 11:22:23 -0700 Subject: [PATCH 137/447] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I50aeacad72fdcf4d29f532f41efc6a4c82d700d0 --- .../Shell/res/values-af/strings.xml | 21 +++++++++++++----- .../Shell/res/values-am/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ar/strings.xml | 21 +++++++++++++----- .../Shell/res/values-as/strings.xml | 21 +++++++++++++----- .../Shell/res/values-az/strings.xml | 21 +++++++++++++----- .../Shell/res/values-b+sr+Latn/strings.xml | 21 +++++++++++++----- .../Shell/res/values-be/strings.xml | 21 +++++++++++++----- .../Shell/res/values-bg/strings.xml | 15 ++++++++++++- .../Shell/res/values-bn/strings.xml | 15 ++++++++++++- .../Shell/res/values-bs/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ca/strings.xml | 21 +++++++++++++----- .../Shell/res/values-cs/strings.xml | 15 ++++++++++++- .../Shell/res/values-da/strings.xml | 21 +++++++++++++----- .../Shell/res/values-de/strings.xml | 21 +++++++++++++----- .../Shell/res/values-el/strings.xml | 21 +++++++++++++----- .../Shell/res/values-en-rAU/strings.xml | 15 ++++++++++++- .../Shell/res/values-en-rCA/strings.xml | 15 ++++++++++++- .../Shell/res/values-en-rGB/strings.xml | 22 ++++++++++++------- .../Shell/res/values-en-rIN/strings.xml | 15 ++++++++++++- .../Shell/res/values-en-rXC/strings.xml | 15 ++++++++++++- .../Shell/res/values-es-rUS/strings.xml | 21 +++++++++++++----- .../Shell/res/values-es/strings.xml | 21 +++++++++++++----- .../Shell/res/values-et/strings.xml | 21 +++++++++++++----- .../Shell/res/values-eu/strings.xml | 21 +++++++++++++----- .../Shell/res/values-fa/strings.xml | 21 +++++++++++++----- .../Shell/res/values-fi/strings.xml | 21 +++++++++++++----- .../Shell/res/values-fr-rCA/strings.xml | 21 +++++++++++++----- .../Shell/res/values-fr/strings.xml | 21 +++++++++++++----- .../Shell/res/values-gl/strings.xml | 21 +++++++++++++----- .../Shell/res/values-gu/strings.xml | 21 +++++++++++++----- .../Shell/res/values-hi/strings.xml | 15 ++++++++++++- .../Shell/res/values-hr/strings.xml | 21 +++++++++++++----- .../Shell/res/values-hu/strings.xml | 15 ++++++++++++- .../Shell/res/values-hy/strings.xml | 21 +++++++++++++----- .../Shell/res/values-in/strings.xml | 21 +++++++++++++----- .../Shell/res/values-is/strings.xml | 21 +++++++++++++----- .../Shell/res/values-it/strings.xml | 21 +++++++++++++----- .../Shell/res/values-iw/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ja/strings.xml | 15 ++++++++++++- .../Shell/res/values-ka/strings.xml | 15 ++++++++++++- .../Shell/res/values-kk/strings.xml | 21 +++++++++++++----- .../Shell/res/values-km/strings.xml | 21 +++++++++++++----- .../Shell/res/values-kn/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ko/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ky/strings.xml | 21 +++++++++++++----- .../Shell/res/values-lo/strings.xml | 15 ++++++++++++- .../Shell/res/values-lt/strings.xml | 15 ++++++++++++- .../Shell/res/values-lv/strings.xml | 21 +++++++++++++----- .../Shell/res/values-mk/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ml/strings.xml | 15 ++++++++++++- .../Shell/res/values-mn/strings.xml | 21 +++++++++++++----- .../Shell/res/values-mr/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ms/strings.xml | 15 ++++++++++++- .../Shell/res/values-my/strings.xml | 21 +++++++++++++----- .../Shell/res/values-nb/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ne/strings.xml | 21 +++++++++++++----- .../Shell/res/values-nl/strings.xml | 21 +++++++++++++----- .../Shell/res/values-or/strings.xml | 21 +++++++++++++----- .../Shell/res/values-pa/strings.xml | 15 ++++++++++++- .../Shell/res/values-pl/strings.xml | 15 ++++++++++++- .../Shell/res/values-pt-rBR/strings.xml | 22 ++++++++++++------- .../Shell/res/values-pt-rPT/strings.xml | 15 ++++++++++++- .../Shell/res/values-pt/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ro/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ru/strings.xml | 15 ++++++++++++- .../Shell/res/values-si/strings.xml | 21 +++++++++++++----- .../Shell/res/values-sk/strings.xml | 21 +++++++++++++----- .../Shell/res/values-sl/strings.xml | 15 ++++++++++++- .../Shell/res/values-sq/strings.xml | 21 +++++++++++++----- .../Shell/res/values-sr/strings.xml | 21 +++++++++++++----- .../Shell/res/values-sv/strings.xml | 15 ++++++++++++- .../Shell/res/values-sw/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ta/strings.xml | 21 +++++++++++++----- .../Shell/res/values-te/strings.xml | 21 +++++++++++++----- .../Shell/res/values-th/strings.xml | 21 +++++++++++++----- .../Shell/res/values-tl/strings.xml | 21 +++++++++++++----- .../Shell/res/values-tr/strings.xml | 21 +++++++++++++----- .../Shell/res/values-uk/strings.xml | 21 +++++++++++++----- .../Shell/res/values-ur/strings.xml | 21 +++++++++++++----- .../Shell/res/values-uz/strings.xml | 15 ++++++++++++- .../Shell/res/values-vi/strings.xml | 21 +++++++++++++----- .../Shell/res/values-zh-rCN/strings.xml | 21 +++++++++++++----- .../Shell/res/values-zh-rHK/strings.xml | 21 +++++++++++++----- .../Shell/res/values-zh-rTW/strings.xml | 21 +++++++++++++----- .../Shell/res/values-zu/strings.xml | 21 +++++++++++++----- 85 files changed, 1251 insertions(+), 404 deletions(-) diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index 50aa4ca1a1f1..582c1a22a203 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -97,6 +97,9 @@ "Kamerakwessies?\nTik om aan te pas" "Nie opgelos nie?\nTik om terug te stel" "Geen kamerakwessies nie? Tik om toe te maak." + "Tik om die appkieslys oop te maak" + "Tik om verskeie apps saam te wys" + "Keer terug na volskerm van die appkieslys af" "Sien en doen meer" "Sleep ’n ander app in vir verdeelde skerm" "Dubbeltik buite ’n program om dit te herposisioneer" @@ -126,15 +129,21 @@ "Bestuur vensters" "Maak toe" "Maak kieslys toe" - - + "Maak kieslys oop" "Maksimeer skerm" "Gryp skerm vas" - "Hierdie app se grootte kan nie verander word nie" - + "App kan nie hierheen geskuif word nie" + "Maksimeer" + "Spring na links" + "Spring na regs" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index 281e313d328f..0798c9a8fbe0 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -97,6 +97,9 @@ "የካሜራ ችግሮች አሉ?\nዳግም ለማበጀት መታ ያድርጉ" "አልተስተካከለም?\nለማህደር መታ ያድርጉ" "ምንም የካሜራ ችግሮች የሉም? ለማሰናበት መታ ያድርጉ።" + "የመተግበሪያ ምናሌውን ለመክፈት መታ ያድርጉ" + "በርካታ መተግበሪያዎችን በአንድ ላይ ለማየት መታ ያድርጉ" + "ከመተግበሪያ ምናሌው ወደ ሙሉ ማያ ገፅ ይመለሱ" "ተጨማሪ ይመልከቱ እና ያድርጉ" "ለተከፈለ ማያ ገፅ ሌላ መተግበሪያ ይጎትቱ" "ቦታውን ለመቀየር ከመተግበሪያው ውጭ ሁለቴ መታ ያድርጉ" @@ -126,15 +129,21 @@ "መስኮቶችን አስተዳድር" "ዝጋ" "ምናሌ ዝጋ" - - + "ምናሌን ክፈት" "የማያ ገጹ መጠን አሳድግ" "ማያ ገጹን አሳድግ" - "ይህ መተግበሪያ መጠኑ ሊቀየር አይችልም" - + "መተግበሪያ ወደዚህ መንቀሳቀስ አይችልም" + "አሳድግ" + "ወደ ግራ አሳድግ" + "ወደ ቀኝ አሳድግ" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index 2c0b34a604a9..9dcb5ec26273 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -97,6 +97,9 @@ "هل هناك مشاكل في الكاميرا؟\nانقر لإعادة الضبط." "ألم يتم حل المشكلة؟\nانقر للعودة" "أليس هناك مشاكل في الكاميرا؟ انقر للإغلاق." + "انقر لفتح قائمة التطبيق" + "انقر لعرض عدة تطبيقات معًا" + "الرجوع إلى وضع ملء الشاشة من قائمة التطبيق" "استخدام تطبيقات متعدّدة في وقت واحد" "اسحب تطبيقًا آخر لاستخدام وضع تقسيم الشاشة." "انقر مرّتين خارج تطبيق لتغيير موضعه." @@ -126,15 +129,21 @@ "إدارة النوافذ" "إغلاق" "إغلاق القائمة" - - + "فتح القائمة" "تكبير الشاشة إلى أقصى حدّ" "التقاط صورة للشاشة" - "لا يمكن تغيير حجم نافذة هذا التطبيق" - + "لا يمكن نقل التطبيق إلى هنا" + "تكبير" + "المحاذاة إلى اليسار" + "المحاذاة إلى اليمين" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index c5e37162e2d9..484eef53e087 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -97,6 +97,9 @@ "কেমেৰাৰ কোনো সমস্যা হৈছে নেকি?\nপুনৰ খাপ খোৱাবলৈ টিপক" "এইটো সমাধান কৰা নাই নেকি?\nপূৰ্বাৱস্থালৈ নিবলৈ টিপক" "কেমেৰাৰ কোনো সমস্যা নাই নেকি? অগ্ৰাহ্য কৰিবলৈ টিপক।" + "এপৰ মেনুখন খুলিবলৈ টিপক" + "একাধিক এপ্ একেলগে দেখুৱাবলৈ টিপক" + "এপৰ মেনুখনৰ পৰা পূৰ্ণ স্ক্ৰীনলৈ উভতি যাওক" "চাওক আৰু অধিক কৰক" "বিভাজিত স্ক্ৰীনৰ বাবে অন্য এটা এপ্‌ টানি আনি এৰক" "এপ্‌টোৰ স্থান সলনি কৰিবলৈ ইয়াৰ বাহিৰত দুবাৰ টিপক" @@ -126,15 +129,21 @@ "ৱিণ্ড’ পৰিচালনা কৰক" "বন্ধ কৰক" "মেনু বন্ধ কৰক" - - + "মেনু খোলক" "স্ক্ৰীন মেক্সিমাইজ কৰক" "স্ক্ৰীন স্নেপ কৰক" - "এই এপ্‌টোৰ আকাৰ সলনি কৰিব নোৱাৰি" - + "ইয়ালৈ এপ্‌টো আনিব নোৱাৰি" + "মেক্সিমাইজ কৰক" + "বাওঁফাললৈ স্নেপ কৰক" + "সোঁফাললৈ স্নেপ কৰক" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index e23e8d049a8f..ded6da80464d 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -97,6 +97,9 @@ "Kamera problemi var?\nBərpa etmək üçün toxunun" "Düzəltməmisiniz?\nGeri qaytarmaq üçün toxunun" "Kamera problemi yoxdur? Qapatmaq üçün toxunun." + "Tətbiq menyusunu açmaq üçün toxunun" + "Bir neçə tətbiqi birlikdə göstərmək üçün toxunun" + "Tətbiq menyusundan tam ekrana qayıdın" "Ardını görün və edin" "Bölünmüş ekran üçün başqa tətbiq sürüşdürün" "Tətbiqin yerini dəyişmək üçün kənarına iki dəfə toxunun" @@ -126,15 +129,21 @@ "Pəncərələri idarə edin" "Bağlayın" "Menyunu bağlayın" - - + "Menyunu açın" "Ekranı maksimum böyüdün" "Ekranı çəkin" - "Bu tətbiqin ölçüsünü dəyişmək olmur" - + "Tətbiqi bura köçürmək mümkün deyil" + "Böyüdün" + "Sola tərəf çəkin" + "Sağa tərəf çəkin" + + + + + - + - + 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 283d1f5578cf..415547c790f4 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -97,6 +97,9 @@ "Imate problema sa kamerom?\nDodirnite da biste ponovo uklopili" "Problem nije rešen?\nDodirnite da biste vratili" "Nemate problema sa kamerom? Dodirnite da biste odbacili." + "Dodirnite da biste otvorili meni aplikacije" + "Dodirnite da biste prikazali više aplikacija zajedno" + "Vratite se iz menija aplikacije na prikaz preko celog ekrana" "Vidite i uradite više" "Prevucite drugu aplikaciju da biste koristili podeljeni ekran" "Dvaput dodirnite izvan aplikacije da biste promenili njenu poziciju" @@ -126,15 +129,21 @@ "Upravljajte prozorima" "Zatvorite" "Zatvorite meni" - - + "Otvorite meni" "Povećaj ekran" "Uklopi ekran" - "Veličina ove aplikacije ne može da se promeni" - + "Aplikacija ne može da se premesti ovde" + "Uvećajte" + "Prikačite levo" + "Prikačite desno" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index 48914f1eb27c..aded647d43a1 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -97,6 +97,9 @@ "Праблемы з камерай?\nНацісніце, каб пераабсталяваць" "Не ўдалося выправіць?\nНацісніце, каб аднавіць" "Ніякіх праблем з камерай? Націсніце, каб адхіліць." + "Адкрыць меню праграмы" + "Паказаць некалькі праграм разам" + "Вярнуцца ў поўнаэкранны рэжым з меню праграмы" "Адначасова выконвайце розныя задачы" "Перацягніце іншую праграму, каб выкарыстоўваць падзелены экран" "Двойчы націсніце экран па-за праграмай, каб перамясціць яе" @@ -126,15 +129,21 @@ "Кіраваць вокнамі" "Закрыць" "Закрыць меню" - - + "Адкрыць меню" "Разгарнуць на ўвесь экран" "Размясціць на палавіне экрана" - "Немагчыма змяніць памер праграмы" - + "Нельга перамясціць сюды праграму" + "Разгарнуць" + "Размясціць злева" + "Размясціць справа" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index f5e94da56055..8a69176f2b6f 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -97,6 +97,9 @@ "Имате проблеми с камерата?\nДокоснете за ремонтиране" "Проблемът не се отстрани?\nДокоснете за връщане в предишното състояние" "Нямате проблеми с камерата? Докоснете, за да отхвърлите." + "Докоснете, за да отворите менюто на приложението" + "Докоснете, за да видите няколко приложения заедно" + "Връщане към цял екран от менюто на приложението" "Преглеждайте и правете повече неща" "Преместете друго приложение с плъзгане, за да преминете в режим за разделен екран" "Докоснете два пъти извън дадено приложение, за да промените позицията му" @@ -129,8 +132,18 @@ "Отваряне на менюто" "Увеличаване на екрана" "Прилепване на екрана" - "Това приложение не може да бъде преоразмерено" + "Приложението не може да бъде преместено тук" "Увеличаване" "Прилепване наляво" "Прилепване надясно" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index 5d6374403662..3799c9fd1dca 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -97,6 +97,9 @@ "ক্যামেরা সংক্রান্ত সমস্যা?\nরিফিট করতে ট্যাপ করুন" "এখনও সমাধান হয়নি?\nরিভার্ট করার জন্য ট্যাপ করুন" "ক্যামেরা সংক্রান্ত সমস্যা নেই? বাতিল করতে ট্যাপ করুন।" + "অ্যাপ মেনু খুলতে ট্যাপ করুন" + "একাধিক অ্যাপ একসাথে দেখতে ট্যাপ করুন" + "অ্যাপ মেনু থেকে ফুল-স্ক্রিন মোডে ফিরে যান" "দেখুন ও আরও অনেক কিছু করুন" "স্প্লিট স্ক্রিনের ক্ষেত্রে অন্য কোনও অ্যাপ টেনে আনুন" "কোনও অ্যাপের স্থান পরিবর্তন করতে তার বাইরে ডবল ট্যাপ করুন" @@ -129,8 +132,18 @@ "মেনু খুলুন" "স্ক্রিন বড় করুন" "স্ক্রিনে অ্যাপ মানানসই হিসেবে ছোট বড় করুন" - "এই অ্যাপ ছোট বড় করা যাবে না" + "অ্যাপটি এখানে সরানো যাবে না" "বড় করুন" "বাঁদিকে স্ন্যাপ করুন" "ডানদিকে স্ন্যাপ করুন" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index 95362bbfeab5..f0d172ad20d0 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -97,6 +97,9 @@ "Problemi s kamerom?\nDodirnite da ponovo namjestite" "Nije popravljeno?\nDodirnite da vratite" "Nema problema s kamerom? Dodirnite da odbacite." + "Otvaranje menija aplikacije dodirom" + "Istovremeni prikaz više aplikacija dodirom" + "Povratak na prikaz preko cijelog ekrana putem menija aplikacije" "Pogledajte i učinite više" "Prevucite još jednu aplikaciju za podijeljeni ekran" "Dvaput dodirnite izvan aplikacije da promijenite njen položaj" @@ -126,15 +129,21 @@ "Upravljanje prozorima" "Zatvaranje" "Zatvaranje menija" - - + "Otvaranje menija" "Maksimiziraj ekran" "Snimi ekran" - "Nije moguće promijeniti veličinu aplikacije" - + "Ne možete premjestiti aplikaciju ovdje" + "Maksimiziranje" + "Pomicanje ulijevo" + "Pomicanje udesno" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index e0b25389e6f1..bf35c90f89ab 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -97,6 +97,9 @@ "Tens problemes amb la càmera?\nToca per resoldre\'ls" "El problema no s\'ha resolt?\nToca per desfer els canvis" "No tens cap problema amb la càmera? Toca per ignorar." + "Toca per obrir el menú de l\'aplicació" + "Toca per mostrar diverses aplicacions alhora" + "Torna a la pantalla completa des del menú de l\'aplicació" "Consulta i fes més coses" "Arrossega una altra aplicació per utilitzar la pantalla dividida" "Fes doble toc fora d\'una aplicació per canviar-ne la posició" @@ -126,15 +129,21 @@ "Gestiona les finestres" "Tanca" "Tanca el menú" - - + "Obre el menú" "Maximitza la pantalla" "Ajusta la pantalla" - "No es pot canviar la mida d\'aquesta aplicació" - + "L\'aplicació no es pot moure aquí" + "Maximitza" + "Ajusta a l\'esquerra" + "Ajusta a la dreta" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index 716491020c65..7fc1033b71be 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -97,6 +97,9 @@ "Problémy s fotoaparátem?\nKlepnutím vyřešíte" "Nepomohlo to?\nKlepnutím se vrátíte" "Žádné problémy s fotoaparátem? Klepnutím zavřete." + "Klepnutím otevřete nabídku aplikace" + "Klepnutím zobrazíte několik aplikací najednou" + "Návrat na celou obrazovku z nabídky aplikace" "Lepší zobrazení a více možností" "Přetáhnutím druhé aplikace použijete rozdělenou obrazovku" "Dvojitým klepnutím mimo aplikaci změníte její umístění" @@ -129,8 +132,18 @@ "Otevřít nabídku" "Maximalizovat obrazovku" "Rozpůlit obrazovku" - "Velikost aplikace nelze změnit" + "Aplikaci sem nelze přesunout" "Maximalizovat" "Přichytit vlevo" "Přichytit vpravo" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index fdc59137dd5e..717e6c42dd51 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -97,6 +97,9 @@ "Har du problemer med dit kamera?\nTryk for at gendanne det oprindelige format" "Løste det ikke problemet?\nTryk for at fortryde" "Har du ingen problemer med dit kamera? Tryk for at afvise." + "Tryk for at åbne appmenuen" + "Tryk for at se flere apps på én gang" + "Gå tilbage til fuld skærm via appmenuen" "Se og gør mere" "Træk en anden app hertil for at bruge opdelt skærm" "Tryk to gange uden for en app for at justere dens placering" @@ -126,15 +129,21 @@ "Administrer vinduer" "Luk" "Luk menu" - - + "Åbn menu" "Maksimér skærm" "Tilpas skærm" - "Størrelsen på denne app kan ikke justeres" - + "Apps kan ikke flyttes hertil" + "Maksimér" + "Fastgør til venstre" + "Fastgør til højre" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index 913e3d0abf0f..bccd4ae1d6df 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -97,6 +97,9 @@ "Probleme mit der Kamera?\nZum Anpassen tippen." "Das Problem ist nicht behoben?\nZum Rückgängigmachen tippen." "Keine Probleme mit der Kamera? Zum Schließen tippen." + "Zum Öffnen des App-Menüs tippen" + "Tippen, um mehrere Apps gleichzeitig anzuzeigen" + "Über das App-Menü zum Vollbildmodus zurückkehren" "Mehr sehen und erledigen" "Für Splitscreen-Modus weitere App hineinziehen" "Außerhalb einer App doppeltippen, um die Position zu ändern" @@ -126,15 +129,21 @@ "Fenster verwalten" "Schließen" "Menü schließen" - - + "Menü öffnen" "Bildschirm maximieren" "Bildschirm teilen" - "Die Größe dieser App kann nicht geändert werden" - + "Die App kann nicht hierher verschoben werden" + "Maximieren" + "Links andocken" + "Rechts andocken" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index 564fa910fdcd..1039273978e1 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -97,6 +97,9 @@ "Προβλήματα με την κάμερα;\nΠατήστε για επιδιόρθωση." "Δεν διορθώθηκε;\nΠατήστε για επαναφορά." "Δεν αντιμετωπίζετε προβλήματα με την κάμερα; Πατήστε για παράβλεψη." + "Πατήστε για άνοιγμα του μενού της εφαρμογής" + "Πατήστε για εμφάνιση πολλών εφαρμογών μαζί" + "Επιστρέψτε στην πλήρη οθόνη από το μενού της εφαρμογής" "Δείτε και κάντε περισσότερα" "Σύρετε σε μια άλλη εφαρμογή για διαχωρισμό οθόνης." "Πατήστε δύο φορές έξω από μια εφαρμογή για να αλλάξετε τη θέση της" @@ -126,15 +129,21 @@ "Διαχείριση παραθύρων" "Κλείσιμο" "Κλείσιμο μενού" - - + "Άνοιγμα μενού" "Μεγιστοποίηση οθόνης" "Προβολή στο μισό της οθόνης" - "Δεν είναι δυνατή η αλλαγή μεγέθους αυτής της εφαρμογής" - + "Δεν είναι δυνατή η μετακίνηση της εφαρμογής εδώ" + "Μεγιστοποίηση" + "Κούμπωμα αριστερά" + "Κούμπωμα δεξιά" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index 766852d4b1f0..98da627a4434 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -97,6 +97,9 @@ "Camera issues?\nTap to refit" "Didn’t fix it?\nTap to revert" "No camera issues? Tap to dismiss." + "Tap to open the app menu" + "Tap to show multiple apps together" + "Return to fullscreen from the app menu" "See and do more" "Drag in another app for split screen" "Double-tap outside an app to reposition it" @@ -129,8 +132,18 @@ "Open menu" "Maximise screen" "Snap screen" - "This app can\'t be resized" + "App can\'t be moved here" "Maximise" "Snap left" "Snap right" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index aa3a484079f8..e928fe02fbcf 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -97,6 +97,9 @@ "Camera issues?\nTap to refit" "Didn’t fix it?\nTap to revert" "No camera issues? Tap to dismiss." + "Tap to open the app menu" + "Tap to show multiple apps together" + "Return to fullscreen from the app menu" "See and do more" "Drag in another app for split screen" "Double-tap outside an app to reposition it" @@ -129,8 +132,18 @@ "Open Menu" "Maximize Screen" "Snap Screen" - "This app can\'t be resized" + "App can\'t be moved here" "Maximize" "Snap left" "Snap right" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml index d5b97037496a..98da627a4434 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -97,12 +97,9 @@ "Camera issues?\nTap to refit" "Didn’t fix it?\nTap to revert" "No camera issues? Tap to dismiss." - - - - - - + "Tap to open the app menu" + "Tap to show multiple apps together" + "Return to fullscreen from the app menu" "See and do more" "Drag in another app for split screen" "Double-tap outside an app to reposition it" @@ -135,9 +132,18 @@ "Open menu" "Maximise screen" "Snap screen" - - + "App can\'t be moved here" "Maximise" "Snap left" "Snap right" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml index 766852d4b1f0..98da627a4434 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -97,6 +97,9 @@ "Camera issues?\nTap to refit" "Didn’t fix it?\nTap to revert" "No camera issues? Tap to dismiss." + "Tap to open the app menu" + "Tap to show multiple apps together" + "Return to fullscreen from the app menu" "See and do more" "Drag in another app for split screen" "Double-tap outside an app to reposition it" @@ -129,8 +132,18 @@ "Open menu" "Maximise screen" "Snap screen" - "This app can\'t be resized" + "App can\'t be moved here" "Maximise" "Snap left" "Snap right" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml index bda5132156cd..e48a9dbc2ebb 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -97,6 +97,9 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎Camera issues?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap to refit‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎Didn’t fix it?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap to revert‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‎No camera issues? Tap to dismiss.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎Tap to open the app menu‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎Tap to show multiple apps together‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎Return to fullscreen from the app menu‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎See and do more‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‎Drag in another app for split screen‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‏‎Double-tap outside an app to reposition it‎‏‎‎‏‎" @@ -129,8 +132,18 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎Open Menu‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‏‎Maximize Screen‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎Snap Screen‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎This app can\'t be resized‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‎App can\'t be moved here‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‎‏‎Maximize‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‏‏‎‎‎‎‎Snap left‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎Snap right‎‏‎‎‏‎" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index a4c03632cbe4..f349cbb1aeed 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -97,6 +97,9 @@ "¿Tienes problemas con la cámara?\nPresiona para reajustarla" "¿No se resolvió?\nPresiona para revertir los cambios" "¿No tienes problemas con la cámara? Presionar para descartar." + "Presiona para abrir el menú de la app" + "Presiona para mostrar varias apps juntas" + "Regresa a pantalla completa desde el menú de la app" "Aprovecha más" "Arrastra otra app para el modo de pantalla dividida" "Presiona dos veces fuera de una app para cambiar su ubicación" @@ -126,15 +129,21 @@ "Administrar ventanas" "Cerrar" "Cerrar menú" - - + "Abrir el menú" "Maximizar pantalla" "Ajustar pantalla" - "No se puede cambiar el tamaño de esta app" - + "No se puede mover la app aquí" + "Maximizar" + "Ajustar a la izquierda" + "Ajustar a la derecha" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index 69f7d7b020d6..9f6b2e65c27c 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -97,6 +97,9 @@ "¿Problemas con la cámara?\nToca para reajustar" "¿No se ha solucionado?\nToca para revertir" "¿No hay problemas con la cámara? Toca para cerrar." + "Toca para abrir el menú de aplicaciones" + "Toca para mostrar varias aplicaciones a la vez" + "Vuelve a pantalla completa desde el menú de aplicaciones" "Consulta más información y haz más" "Arrastra otra aplicación para activar la pantalla dividida" "Toca dos veces fuera de una aplicación para cambiarla de posición" @@ -126,15 +129,21 @@ "Gestionar ventanas" "Cerrar" "Cerrar menú" - - + "Abrir menú" "Maximizar pantalla" "Ajustar pantalla" - "No se puede cambiar el tamaño de esta aplicación" - + "La aplicación no se puede mover aquí" + "Maximizar" + "Acoplar a la izquierda" + "Acoplar a la derecha" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index 3d929f6cd8d3..b2b06d6db5d2 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -97,6 +97,9 @@ "Kas teil on kaameraprobleeme?\nPuudutage ümberpaigutamiseks." "Kas probleemi ei lahendatud?\nPuudutage ennistamiseks." "Kas kaameraprobleeme pole? Puudutage loobumiseks." + "Puudutage rakenduse menüü avamiseks" + "Puudutage mitme rakenduse koos kuvamiseks" + "Minge rakenduse menüüst tagasi täisekraanile" "Vaadake ja tehke rohkem" "Lohistage muusse rakendusse, et jagatud ekraanikuva kasutada" "Topeltpuudutage rakendusest väljaspool, et selle asendit muuta" @@ -126,15 +129,21 @@ "Akende haldamine" "Sule" "Sule menüü" - - + "Ava menüü" "Kuva täisekraanil" "Kuva poolel ekraanil" - "Selle rakenduse aknasuurust ei saa muuta" - + "Rakendust ei saa siia teisaldada" + "Maksimeeri" + "Tõmmake vasakule" + "Tõmmake paremale" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index 39bcf080fcf3..4a71c49b8d8a 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -97,6 +97,9 @@ "Arazoak dauzkazu kamerarekin?\nBerriro doitzeko, sakatu hau." "Ez al da konpondu?\nLeheneratzeko, sakatu hau." "Ez daukazu arazorik kamerarekin? Baztertzeko, sakatu hau." + "Sakatu hau aplikazioen menua irekitzeko" + "Sakatu hau aplikazio bat baino gehiago aldi berean erakusteko" + "Itzuli pantaila osora aplikazioen menutik" "Ikusi eta egin gauza gehiago" "Pantaila zatitua ikusteko, arrastatu beste aplikazio bat" "Aplikazioaren posizioa aldatzeko, sakatu birritan haren kanpoaldea" @@ -126,15 +129,21 @@ "Kudeatu leihoak" "Itxi" "Itxi menua" - - + "Ireki menua" "Handitu pantaila" "Zatitu pantaila" - "Ezin zaio aldatu tamaina aplikazio honi" - + "Aplikazioa ezin da hona ekarri" + "Maximizatu" + "Ezarri ezkerrean" + "Ezarri eskuinean" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index 9f607bf89656..941ff84b7799 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -97,6 +97,9 @@ "دوربین مشکل دارد؟\nبرای تنظیم مجدد اندازه تک‌ضرب بزنید" "مشکل برطرف نشد؟\nبرای برگرداندن تک‌ضرب بزنید" "دوربین مشکلی ندارد؟ برای بستن تک‌ضرب بزنید." + "برای باز کردن منو برنامه، تک‌ضرب بزنید" + "برای نمایش چند برنامه با هم، تک‌ضرب بزنید" + "از منو برنامه به تمام‌صفحه برگردید" "از چندین برنامه به‌طور هم‌زمان استفاده کنید" "برای حالت صفحهٔ دونیمه، در برنامه‌ای دیگر بکشید" "برای جابه‌جا کردن برنامه، بیرون از آن دو تک‌ضرب بزنید" @@ -126,15 +129,21 @@ "مدیریت کردن پنجره‌ها" "بستن" "بستن منو" - - + "باز کردن منو" "بزرگ کردن صفحه" "بزرگ کردن صفحه" - "اندازه این برنامه را نمی‌توان تغییر داد" - + "برنامه را نمی‌توان به اینجا منتقل کرد" + "بزرگ کردن" + "کشیدن به‌چپ" + "کشیدن به‌راست" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index 04b6241ca90b..a45e9afeabfc 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -97,6 +97,9 @@ "Onko kameran kanssa ongelmia?\nKorjaa napauttamalla" "Eikö ongelma ratkennut?\nKumoa napauttamalla" "Ei ongelmia kameran kanssa? Hylkää napauttamalla." + "Avaa sovellusvalikko napauttamalla" + "Näytä useita sovelluksia yhdessä napauttamalla" + "Palaa koko näytön tilaan sovellusvalikosta" "Näe ja tee enemmän" "Käytä jaettua näyttöä vetämällä tähän toinen sovellus" "Kaksoisnapauta sovelluksen ulkopuolella, jos haluat siirtää sitä" @@ -126,15 +129,21 @@ "Hallinnoi ikkunoita" "Sulje" "Sulje valikko" - - + "Avaa valikko" "Suurenna näyttö" "Jaa näyttö" - "Tämän sovellusikkunan kokoa ei voi muuttaa" - + "Sovellusta ei voi siirtää tänne" + "Suurenna" + "Siirrä vasemmalle" + "Siirrä oikealle" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index 73129525ebdd..c163165a8296 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -97,6 +97,9 @@ "Problèmes d\'appareil photo?\nTouchez pour réajuster" "Problème non résolu?\nTouchez pour rétablir" "Aucun problème d\'appareil photo? Touchez pour ignorer." + "Toucher ici pour ouvrir le menu de l\'appli" + "Toucher ici pour afficher plusieurs applis ensemble" + "Revenir au mode Plein écran à partir du menu de l\'appli" "Voir et en faire plus" "Faites glisser une autre appli pour utiliser l\'écran partagé" "Touchez deux fois à côté d\'une appli pour la repositionner" @@ -126,15 +129,21 @@ "Gérer les fenêtres" "Fermer" "Fermer le menu" - - + "Ouvrir le menu" "Agrandir l\'écran" "Aligner l\'écran" - "Impossible de redimensionner cette appli" - + "Impossible de déplacer l\'appli ici" + "Agrandir" + "Épingler à gauche" + "Épingler à droite" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index 8f4e58f99a13..b2a6f16733b3 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -97,6 +97,9 @@ "Problèmes d\'appareil photo ?\nAppuyez pour réajuster" "Problème non résolu ?\nAppuyez pour rétablir" "Aucun problème d\'appareil photo ? Appuyez pour ignorer." + "Appuyer pour ouvrir le menu de l\'appli" + "Appuyer pour afficher plusieurs applis simultanément" + "Revenir en plein écran depuis le menu de l\'appli" "Voir et interagir plus" "Faites glisser une autre appli pour utiliser l\'écran partagé" "Appuyez deux fois en dehors d\'une appli pour la repositionner" @@ -126,15 +129,21 @@ "Gérer les fenêtres" "Fermer" "Fermer le menu" - - + "Ouvrir le menu" "Mettre en plein écran" "Fractionner l\'écran" - "Impossible de redimensionner cette appli" - + "Impossible de déplacer l\'appli ici" + "Agrandir" + "Ancrer à gauche" + "Ancrer à droite" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index 5c0aa074b329..ab972f94af22 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -97,6 +97,9 @@ "Tes problemas coa cámara?\nToca para reaxustala" "Non se solucionaron os problemas?\nToca para reverter o seu tratamento" "Non hai problemas coa cámara? Tocar para ignorar." + "Toca para abrir o menú da aplicación" + "Toca para mostrar varias aplicacións xuntas" + "Volve á pantalla completa desde o menú da aplicación" "Ver e facer máis" "Arrastra outra aplicación para usar a pantalla dividida" "Toca dúas veces fóra da aplicación para cambiala de posición" @@ -126,15 +129,21 @@ "Xestionar as ventás" "Pechar" "Pechar o menú" - - + "Abrir o menú" "Maximizar pantalla" "Encaixar pantalla" - "Non se pode cambiar o tamaño desta aplicación" - + "Non se pode mover aquí a aplicación" + "Maximizar" + "Axustar á esquerda" + "Axustar á dereita" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index a382d0b41652..0dc2f73f1134 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -97,6 +97,9 @@ "કૅમેરામાં સમસ્યાઓ છે?\nફરીથી ફિટ કરવા માટે ટૅપ કરો" "સુધારો નથી થયો?\nપહેલાંના પર પાછું ફેરવવા માટે ટૅપ કરો" "કૅમેરામાં કોઈ સમસ્યા નથી? છોડી દેવા માટે ટૅપ કરો." + "ઍપ મેનૂ ખોલવા માટે ટૅપ કરો" + "એકથી વધુ ઍપ એકસાથે બતાવવા માટે ટૅપ કરો" + "ઍપ મેનૂમાંથી પૂર્ણસ્ક્રીન પર પાછા ફરો" "જુઓ અને બીજું ઘણું કરો" "વિભાજિત સ્ક્રીન માટે કોઈ અન્ય ઍપમાં ખેંચો" "કોઈ ઍપની જગ્યા બદલવા માટે, તેની બહાર બે વાર ટૅપ કરો" @@ -126,15 +129,21 @@ "વિન્ડો મેનેજ કરો" "બંધ કરો" "મેનૂ બંધ કરો" - - + "મેનૂ ખોલો" "સ્ક્રીન કરો મોટી કરો" "સ્ક્રીન સ્નૅપ કરો" - "આ ઍપના કદમાં વધઘટ કરી શકાતો નથી" - + "ઍપ અહીં ખસેડી શકાતી નથી" + "મોટું કરો" + "ડાબે સ્નૅપ કરો" + "જમણે સ્નૅપ કરો" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index 37608207b721..679d800a4dd2 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -97,6 +97,9 @@ "क्या कैमरे से जुड़ी कोई समस्या है?\nफिर से फ़िट करने के लिए टैप करें" "क्या समस्या ठीक नहीं हुई?\nपहले जैसा करने के लिए टैप करें" "क्या कैमरे से जुड़ी कोई समस्या नहीं है? खारिज करने के लिए टैप करें." + "ऐप्लिकेशन मेन्यू खोलने के लिए टैप करें" + "कई ऐप्लिकेशन एक साथ दिखाने के लिए टैप करें" + "ऐप्लिकेशन मेन्यू से फ़ुलस्क्रीन मोड पर वापस जाएं" "पूरी जानकारी लेकर, बेहतर तरीके से काम करें" "स्प्लिट स्क्रीन का इस्तेमाल करने के लिए, किसी अन्य ऐप्लिकेशन को खींचें और छोड़ें" "किसी ऐप्लिकेशन की जगह बदलने के लिए, उसके बाहर दो बार टैप करें" @@ -129,8 +132,18 @@ "मेन्यू खोलें" "स्क्रीन को बड़ा करें" "स्नैप स्क्रीन" - "इस ऐप्लिकेशन का साइज़ नहीं बदला जा सकता" + "ऐप्लिकेशन को यहां मूव नहीं किया जा सकता" "बड़ा करें" "बाईं ओर स्नैप करें" "दाईं ओर स्नैप करें" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index f233c029c752..1e5ffc858b86 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -97,6 +97,9 @@ "Problemi s fotoaparatom?\nDodirnite za popravak" "Problem nije riješen?\nDodirnite za vraćanje" "Nemate problema s fotoaparatom? Dodirnite za odbacivanje." + "Dodirnite za otvaranje izbornika aplikacije" + "Dodirnite za prikaz više aplikacija zajedno" + "Vratite se na cijeli zaslon iz izbornika aplikacije" "Gledajte i učinite više" "Povucite drugu aplikaciju unutra da biste podijelili zaslon" "Dvaput dodirnite izvan aplikacije da biste je premjestili" @@ -126,15 +129,21 @@ "Upravljanje prozorima" "Zatvorite" "Zatvorite izbornik" - - + "Otvaranje izbornika" "Maksimalno povećaj zaslon" "Izradi snimku zaslona" - "Nije moguće promijeniti veličinu aplikacije" - + "Aplikacija se ne može premjestiti ovdje" + "Maksimiziraj" + "Poravnaj lijevo" + "Poravnaj desno" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index fb44cd855a7b..7c90a1924214 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -97,6 +97,9 @@ "Kamerával kapcsolatos problémába ütközött?\nKoppintson a megoldáshoz." "Nem sikerült a hiba kijavítása?\nKoppintson a visszaállításhoz." "Nincsenek problémái kamerával? Koppintson az elvetéshez." + "Koppintson az alkalmazásmenü megnyitásához" + "Koppintson több alkalmazás együttes megjelenítéséhez" + "A teljes képernyőre az alkalmazásmenüben térhet vissza" "Több mindent láthat és tehet" "Húzzon ide egy másik alkalmazást az osztott képernyő használatához" "Koppintson duplán az alkalmazáson kívül az áthelyezéséhez" @@ -129,8 +132,18 @@ "Menü megnyitása" "Képernyő méretének maximalizálása" "Igazodás a képernyő adott részéhez" - "Ezt az alkalmazást nem lehet átméretezni" + "Az alkalmazás nem helyezhető át ide" "Teljes méret" "Balra igazítás" "Jobbra igazítás" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index cd21faab45c2..e8ed4ac9c9a4 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -97,6 +97,9 @@ "Տեսախցիկի հետ կապված խնդիրնե՞ր կան։\nՀպեք՝ վերակարգավորելու համար։" "Չհաջողվե՞ց շտկել։\nՀպեք՝ փոփոխությունները չեղարկելու համար։" "Տեսախցիկի հետ կապված խնդիրներ չկա՞ն։ Փակելու համար հպեք։" + "Հպեք՝ հավելվածի ընտրացանկը բացելու համար" + "Հպեք՝ էկրանին մի քանի հավելված միասին դիտելու համար" + "Հավելվածի ընտրացանկից վերադառնալ լիաէկրան ռեժիմ" "Միաժամանակ կատարեք մի քանի առաջադրանք" "Քաշեք մյուս հավելվածի մեջ՝ էկրանի տրոհումն օգտագործելու համար" "Կրկնակի հպեք հավելվածի կողքին՝ այն տեղափոխելու համար" @@ -126,15 +129,21 @@ "Կառավարել պատուհանները" "Փակել" "Փակել ընտրացանկը" - - + "Բացել ընտրացանկը" "Ծավալել էկրանը" "Ծալել էկրանը" - "Այս հավելվածի չափը հնարավոր չէ փոխել" - + "Հավելվածը հնարավոր չէ տեղափոխել այստեղ" + "Ծավալել" + "Ամրացնել ձախ կողմում" + "Ամրացնել աջ կողմում" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index ba0683deecd8..06b1634917e9 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -97,6 +97,9 @@ "Masalah kamera?\nKetuk untuk memperbaiki" "Tidak dapat diperbaiki?\nKetuk untuk mengembalikan" "Tidak ada masalah kamera? Ketuk untuk menutup." + "Ketuk untuk membuka menu aplikasi" + "Ketuk untuk menampilkan beberapa aplikasi secara bersamaan" + "Kembali ke layar penuh dari menu aplikasi" "Lihat dan lakukan lebih banyak hal" "Tarik aplikasi lain untuk menggunakan layar terpisah" "Ketuk dua kali di luar aplikasi untuk mengubah posisinya" @@ -126,15 +129,21 @@ "Kelola Jendela" "Tutup" "Tutup Menu" - - + "Buka Menu" "Perbesar Layar" "Gabungkan Layar" - "Ukuran aplikasi ini tidak dapat diubah" - + "Aplikasi tidak dapat dipindahkan ke sini" + "Maksimalkan" + "Maksimalkan ke kiri" + "Maksimalkan ke kanan" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index b427eaf23290..2d447771de25 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -97,6 +97,9 @@ "Myndavélavesen?\nÝttu til að breyta stærð" "Ennþá vesen?\nÝttu til að afturkalla" "Ekkert myndavélavesen? Ýttu til að hunsa." + "Ýttu til að opna forritavalmyndina" + "Ýttu til að sjá mörg forrit saman" + "Opnaðu allan skjáinn aftur á forritavalmyndinni" "Sjáðu og gerðu meira" "Dragðu annað forrit inn til að nota skjáskiptingu" "Ýttu tvisvar utan við forrit til að færa það" @@ -126,15 +129,21 @@ "Stjórna gluggum" "Loka" "Loka valmynd" - - + "Opna valmynd" "Stækka skjá" "Smelluskjár" - "Ekki er hægt að breyta stærð þessa forrits" - + "Ekki er hægt að færa forritið hingað" + "Stækka" + "Smella til vinstri" + "Smella til hægri" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index 9eb9d4e3a403..b56424594f29 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -97,6 +97,9 @@ "Problemi con la fotocamera?\nTocca per risolverli" "Il problema non si è risolto?\nTocca per ripristinare" "Nessun problema con la fotocamera? Tocca per ignorare." + "Tocca per aprire il menu dell\'app" + "Tocca per mostrare più app insieme" + "Torna allo schermo intero dal menu dell\'app" "Visualizza più contenuti e fai di più" "Trascina in un\'altra app per usare lo schermo diviso" "Tocca due volte fuori da un\'app per riposizionarla" @@ -126,15 +129,21 @@ "Gestisci finestre" "Chiudi" "Chiudi il menu" - - + "Apri il menu" "Massimizza schermo" "Aggancia schermo" - "Non è possibile ridimensionare questa app" - + "Impossibile spostare l\'app qui" + "Ingrandisci" + "Aggancia a sinistra" + "Aggancia a destra" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index 3e82198201b9..fa072639f089 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -97,6 +97,9 @@ "בעיות במצלמה?\nאפשר להקיש כדי לבצע התאמה מחדש" "הבעיה לא נפתרה?\nאפשר להקיש כדי לחזור לגרסה הקודמת" "אין בעיות במצלמה? אפשר להקיש כדי לסגור." + "צריך להקיש כדי לפתוח את תפריט האפליקציה" + "אפשר להקיש כדי להציג כמה אפליקציות יחד" + "חזרה למסך מלא מתפריט האפליקציה" "רוצה לראות ולעשות יותר?" "צריך לגרור אפליקציה אחרת כדי להשתמש במסך המפוצל" "צריך להקיש הקשה כפולה מחוץ לאפליקציה כדי למקם אותה מחדש" @@ -126,15 +129,21 @@ "ניהול החלונות" "סגירה" "סגירת התפריט" - - + "פתיחת התפריט" "הגדלת המסך" "כיווץ המסך" - "לא ניתן לשנות את גודל החלון של האפליקציה הזו" - + "לא ניתן להעביר את האפליקציה לכאן" + "הגדלה" + "הצמדה לשמאל" + "הצמדה לימין" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index 1225b62c96d9..91667c00ce12 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -97,6 +97,9 @@ "カメラに関する問題の場合は、\nタップすると修正できます" "修正されなかった場合は、\nタップすると元に戻ります" "カメラに関する問題でない場合は、タップすると閉じます。" + "タップするとアプリメニューが開きます" + "タップすると複数のアプリが同時に表示されます" + "アプリメニューから全画面表示に戻ります" "表示を拡大して機能を強化" "分割画面にするにはもう 1 つのアプリをドラッグしてください" "位置を変えるにはアプリの外側をダブルタップしてください" @@ -129,8 +132,18 @@ "メニューを開く" "画面の最大化" "画面のスナップ" - "このアプリはサイズ変更できません" + "アプリはここに移動できません" "最大化" "左にスナップ" "右にスナップ" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index 3e1f726ca0ef..2208348485af 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -97,6 +97,9 @@ "კამერად პრობლემები აქვს?\nშეეხეთ გამოსასწორებლად" "არ გამოსწორდა?\nშეეხეთ წინა ვერსიის დასაბრუნებლად" "კამერას პრობლემები არ აქვს? შეეხეთ უარყოფისთვის." + "შეეხეთ აპის მენიუს გასახსნელად" + "შეეხეთ რამდენიმე აპის ერთად საჩვენებლად" + "სრულეკრანიან რეჟიმზე დაბრუნდით აპის მენიუდან" "მეტის ნახვა და გაკეთება" "ეკრანის გასაყოფად ჩავლებით გადაიტანეთ სხვა აპში" "ორმაგად შეეხეთ აპის გარშემო სივრცეს, რათა ის სხვაგან გადაიტანოთ" @@ -129,8 +132,18 @@ "მენიუს გახსნა" "აპლიკაციის გაშლა სრულ ეკრანზე" "აპლიკაციის დაპატარავება ეკრანზე" - "აპის ზომის შეცვლა შეუძლებელია" + "აპის აქ გადატანა შეუძლებელია" "მაქსიმალურად გაშლა" "მარცხნივ გადატანა" "მარჯვნივ გადატანა" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index dd4e5c94fc27..416a84c86281 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -97,6 +97,9 @@ "Камерада қателер шықты ма?\nЖөндеу үшін түртіңіз." "Жөнделмеді ме?\nҚайтару үшін түртіңіз." "Камерада қателер шықпады ма? Жабу үшін түртіңіз." + "Қолданба мәзірін ашу үшін түртіңіз" + "Бірнеше қолданбаны қатар көрсету үшін түртіңіз" + "Қолданба мәзірінен толық экран режиміне қайту" "Қосымша ақпаратты қарап, әрекеттер жасау" "Экранды бөлу үшін басқа қолданбаға өтіңіз." "Қолданбаның орнын өзгерту үшін одан тыс жерді екі рет түртіңіз." @@ -126,15 +129,21 @@ "Терезелерді басқару" "Жабу" "Мәзірді жабу" - - + "Мәзірді ашу" "Экранды ұлғайту" "Экранды бөлу" - "Бұл қолданбаның өлшемі өзгертілмейді." - + "Қолданба бұл жерге қойылмайды." + "Жаю" + "Солға тіркеу" + "Оңға тіркеу" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index 96fe62e4f034..b074d65700f4 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -97,6 +97,9 @@ "មានបញ្ហា​ពាក់ព័ន្ធនឹង​កាមេរ៉ាឬ?\nចុចដើម្បី​ដោះស្រាយ" "មិនបាន​ដោះស្រាយ​បញ្ហានេះទេឬ?\nចុចដើម្បី​ត្រឡប់" "មិនមាន​បញ្ហាពាក់ព័ន្ធនឹង​កាមេរ៉ាទេឬ? ចុចដើម្បី​ច្រានចោល។" + "ចុច​ដើម្បីបើក​ម៉ឺនុយ​កម្មវិធី" + "ចុច​ដើម្បីបង្ហាញ​កម្មវិធី​ច្រើនរួមគ្នា" + "ត្រឡប់ទៅ​អេក្រង់​ពេញវិញ​ពីម៉ឺនុយ​កម្មវិធី" "មើលឃើញ និងធ្វើបានកាន់តែច្រើន" "អូស​កម្មវិធី​មួយ​ទៀត​ចូល ដើម្បី​ប្រើ​មុខងារ​បំបែកអេក្រង់" "ចុចពីរដង​នៅ​ក្រៅ​កម្មវិធី ដើម្បី​ប្ដូរ​ទីតាំង​កម្មវិធី​នោះ" @@ -126,15 +129,21 @@ "គ្រប់គ្រង​វិនដូ" "បិទ" "បិទ​ម៉ឺនុយ" - - + "បើកម៉ឺនុយ" "ពង្រីកអេក្រង់" "ថតអេក្រង់" - "មិនអាចប្ដូរទំហំ​កម្មវិធីនេះ​បានទេ" - + "មិនអាចផ្លាស់ទីកម្មវិធីមកទីនេះបានទេ" + "ពង្រីក" + "ផ្លាស់ទីទៅឆ្វេង" + "ផ្លាស់ទីទៅស្ដាំ" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index b38f74411db2..9c22241f5037 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -97,6 +97,9 @@ "ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿವೆಯೇ?\nಮರುಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ" "ಅದನ್ನು ಸರಿಪಡಿಸಲಿಲ್ಲವೇ?\nಹಿಂತಿರುಗಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ" "ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿಲ್ಲವೇ? ವಜಾಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ." + "ಆ್ಯಪ್‌ ಮೆನುವನ್ನು ತೆರೆಯಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ" + "ಅನೇಕ ಆ್ಯಪ್‌ಗಳನ್ನು ಒಟ್ಟಿಗೆ ತೋರಿಸಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ" + "ಆ್ಯಪ್‌ ಮೆನುವಿನಿಂದ ಫುಲ್‌ಸ್ಕ್ರೀನ್‌ಗೆ ಹಿಂತಿರುಗಿ" "ನೋಡಿ ಮತ್ತು ಹೆಚ್ಚಿನದನ್ನು ಮಾಡಿ" "ಸ್ಪ್ಲಿಟ್‌ ಸ್ಕ್ರೀನ್‌ಗಾಗಿ ಮತ್ತೊಂದು ಆ್ಯಪ್‌ನಲ್ಲಿ ಡ್ರ್ಯಾಗ್ ಮಾಡಿ" "ಆ್ಯಪ್ ಒಂದರ ಸ್ಥಾನವನ್ನು ಬದಲಾಯಿಸಲು ಅದರ ಹೊರಗೆ ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ" @@ -126,15 +129,21 @@ "ವಿಂಡೋಗಳನ್ನು ನಿರ್ವಹಿಸಿ" "ಮುಚ್ಚಿ" "ಮೆನು ಮುಚ್ಚಿ" - - + "ಮೆನು ತೆರೆಯಿರಿ" "ಸ್ಕ್ರೀನ್ ಅನ್ನು ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ" "ಸ್ನ್ಯಾಪ್ ಸ್ಕ್ರೀನ್" - "ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಗಾತ್ರಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" - + "ಆ್ಯಪ್ ಅನ್ನು ಇಲ್ಲಿಗೆ ಸರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" + "ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ" + "ಎಡಕ್ಕೆ ಸ್ನ್ಯಾಪ್ ಮಾಡಿ" + "ಬಲಕ್ಕೆ ಸ್ನ್ಯಾಪ್ ಮಾಡಿ" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index 421d4666911e..58dd6f8e7e99 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -97,6 +97,9 @@ "카메라 문제가 있나요?\n해결하려면 탭하세요." "해결되지 않았나요?\n되돌리려면 탭하세요." "카메라에 문제가 없나요? 닫으려면 탭하세요." + "탭하여 앱 메뉴 열기" + "탭하여 여러 앱을 함께 표시하기" + "앱 메뉴에서 전체 화면으로 돌아가기" "더 많은 정보를 보고 더 많은 작업을 처리하세요" "화면 분할을 사용하려면 다른 앱을 드래그해 가져옵니다." "앱 위치를 조정하려면 앱 외부를 두 번 탭합니다." @@ -126,15 +129,21 @@ "창 관리" "닫기" "메뉴 닫기" - - + "메뉴 열기" "화면 최대화" "화면 분할" - "이 앱은 크기를 조절할 수 없습니다." - + "앱을 여기로 이동할 수 없음" + "최대화하기" + "왼쪽으로 맞추기" + "오른쪽으로 맞추기" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index abafd7ac0330..75feedea1b89 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -97,6 +97,9 @@ "Камерада маселелер келип чыктыбы?\nОңдоо үчүн таптаңыз" "Оңдолгон жокпу?\nАртка кайтаруу үчүн таптаңыз" "Камерада маселе жокпу? Этибарга албоо үчүн таптаңыз." + "Колдонмонун менюсун ачуу үчүн таптап коюңуз" + "Бир нече колдонмону чогуу көрүү үчүн таптап коюңуз" + "Колдонмонун менюсунан толук экранга кайтыңыз" "Көрүп, көбүрөөк нерселерди жасаңыз" "Экранды бөлүү үчүн башка колдонмону сүйрөңүз" "Колдонмону жылдыруу үчүн сырт жагын эки жолу таптаңыз" @@ -126,15 +129,21 @@ "Терезелерди тескөө" "Жабуу" "Менюну жабуу" - - + "Менюну ачуу" "Экранды чоңойтуу" "Экранды сүрөткө тартып алуу" - "Бул колдонмонун өлчөмүн өзгөртүүгө болбойт" - + "Колдонмону бул жерге жылдырууга болбойт" + "Чоңойтуу" + "Солго жылдыруу" + "Оңго жылдыруу" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index 4e10621c719b..8f28504b41b4 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -97,6 +97,9 @@ "ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ?\nແຕະເພື່ອປັບໃໝ່" "ບໍ່ໄດ້ແກ້ໄຂມັນບໍ?\nແຕະເພື່ອແປງກັບຄືນ" "ບໍ່ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ? ແຕະເພື່ອ​ປິດ​ໄວ້." + "ແຕະເພື່ອເປີດເມນູແອັບ" + "ແຕະເພື່ອສະແດງແອັບຫຼາຍລາຍການພ້ອມກັນ" + "ກັບຄືນໄປຫາໂໝດເຕັມຈໍຈາກເມນູແອັບ" "ເບິ່ງ ແລະ ເຮັດຫຼາຍຂຶ້ນ" "ລາກໄປໄວ້ໃນແອັບອື່ນເພື່ອແບ່ງໜ້າຈໍ" "ແຕະສອງເທື່ອໃສ່ນອກແອັບໃດໜຶ່ງເພື່ອຈັດຕຳແໜ່ງຂອງມັນຄືນໃໝ່" @@ -129,8 +132,18 @@ "ເປີດເມນູ" "ປັບຈໍໃຫຍ່ສຸດ" "ສະແນັບໜ້າຈໍ" - "ບໍ່ສາມາດປັບຂະໜາດແອັບນີ້ໄດ້" + "ບໍ່ສາມາດຍ້າຍແອັບມາບ່ອນນີ້ໄດ້" "ຂະຫຍາຍໃຫຍ່ສຸດ" "ແນບຊ້າຍ" "ແນບຂວາ" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index 6d3c58cf01bb..b97b8787ed10 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -97,6 +97,9 @@ "Iškilo problemų dėl kameros?\nPalieskite, kad pritaikytumėte iš naujo" "Nepavyko pataisyti?\nPalieskite, kad grąžintumėte" "Nėra jokių problemų dėl kameros? Palieskite, kad atsisakytumėte." + "Palieskite, kad atidarytumėte programos meniu" + "Palieskite, kad būtų rodomos kelios programos kartu" + "Grįžkite į viso ekrano režimą iš programos meniu" "Daugiau turinio ir funkcijų" "Vilkite kitoje programoje, kad galėtumėte naudoti išskaidyto ekrano režimą" "Dukart palieskite už programos ribų, kad pakeistumėte jos poziciją" @@ -129,8 +132,18 @@ "Atidaryti meniu" "Išskleisti ekraną" "Sutraukti ekraną" - "Negalima keisti šios programos dydžio" + "Programos negalima perkelti čia" "Padidinti" "Pritraukti kairėje" "Pritraukti dešinėje" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index 2f235babd721..de200d816e7a 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -97,6 +97,9 @@ "Vai ir problēmas ar kameru?\nPieskarieties, lai tās novērstu." "Vai problēma netika novērsta?\nPieskarieties, lai atjaunotu." "Vai nav problēmu ar kameru? Pieskarieties, lai nerādītu." + "Lai atvērtu lietotnes izvēlni, pieskarieties." + "Lai parādītu vairākas lietotnes kopā, pieskarieties." + "Varat atgriezties pilnekrāna režīmā no lietotnes izvēlnes." "Uzziniet un paveiciet vairāk" "Lai izmantotu sadalītu ekrānu, ievelciet vēl vienu lietotni" "Lai pārvietotu lietotni, veiciet dubultskārienu ārpus lietotnes" @@ -126,15 +129,21 @@ "Pārvaldīt logus" "Aizvērt" "Aizvērt izvēlni" - - + "Atvērt izvēlni" "Maksimizēt ekrānu" "Fiksēt ekrānu" - "Šīs lietotnes loga lielumu nevar mainīt." - + "Lietotni nevar pārvietot šeit." + "Maksimizēt" + "Piestiprināt pa kreisi" + "Piestiprināt pa labi" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index e58d8fc945f4..4922d042c6ac 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -97,6 +97,9 @@ "Проблеми со камерата?\nДопрете за да се совпадне повторно" "Не се поправи?\nДопрете за враќање" "Нема проблеми со камерата? Допрете за отфрлање." + "Допрете за да го отворите менито со апликации" + "Допрете за да се прикажат повеќе апликации заедно" + "Вратете се на цел екран од менито со апликации" "Погледнете и направете повеќе" "Повлечете друга апликација за поделен екран" "Допрете двапати надвор од некоја апликација за да ја преместите" @@ -126,15 +129,21 @@ "Управувајте со прозорци" "Затворете" "Затворете го менито" - - + "Отвори го менито" "Максимизирај го екранот" "Подели го екранот на половина" - "Не може да се промени големината на апликацијава" - + "Апликацијата не може да се премести овде" + "Максимизирај" + "Фотографирај лево" + "Фотографирај десно" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index a48df0b71b1b..61277d6765fd 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -97,6 +97,9 @@ "ക്യാമറ പ്രശ്നങ്ങളുണ്ടോ?\nശരിയാക്കാൻ ടാപ്പ് ചെയ്യുക" "അത് പരിഹരിച്ചില്ലേ?\nപുനഃസ്ഥാപിക്കാൻ ടാപ്പ് ചെയ്യുക" "ക്യാമറാ പ്രശ്നങ്ങളൊന്നുമില്ലേ? നിരസിക്കാൻ ടാപ്പ് ചെയ്യുക." + "ആപ്പ് മെനു തുറക്കാൻ ടാപ്പ് ചെയ്യുക" + "ഒന്നിലധികം ആപ്പുകൾ ഒരുമിച്ച് കാണിക്കാൻ ടാപ്പ് ചെയ്യുക" + "ആപ്പ് മെനുവിൽ നിന്ന് പൂർണ്ണസ്‌ക്രീനിലേക്ക് മടങ്ങുക" "കൂടുതൽ കാണുക, ചെയ്യുക" "സ്‌ക്രീൻ വിഭജന മോഡിന്, മറ്റൊരു ആപ്പ് വലിച്ചിടുക" "ആപ്പിന്റെ സ്ഥാനം മാറ്റാൻ അതിന് പുറത്ത് ഡബിൾ ടാപ്പ് ചെയ്യുക" @@ -129,8 +132,18 @@ "മെനു തുറക്കുക" "സ്‌ക്രീൻ വലുതാക്കുക" "സ്‌ക്രീൻ സ്‌നാപ്പ് ചെയ്യുക" - "ഈ ആപ്പിന്റെ വലുപ്പം മാറ്റാനാകില്ല" + "ആപ്പ് ഇവിടേക്ക് നീക്കാനാകില്ല" "വലുതാക്കുക" "ഇടതുവശത്തേക്ക് സ്‌നാപ്പ് ചെയ്യുക" "വലതുവശത്തേക്ക് സ്‌നാപ്പ് ചെയ്യുക" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index f7e6a6c87890..2b313a2be17c 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -97,6 +97,9 @@ "Камерын асуудал гарсан уу?\nДахин тааруулахын тулд товшино уу" "Үүнийг засаагүй юу?\nБуцаахын тулд товшино уу" "Камерын асуудал байхгүй юу? Хаахын тулд товшино уу." + "Аппын цэсийг нээхийн тулд товшино уу" + "Олон аппыг хамтад нь харуулахын товшино уу" + "Аппын цэсээс бүтэн дэлгэц рүү буцна уу" "Харж илүү ихийг хий" "Дэлгэц хуваах горимд ашиглахын тулд өөр аппыг чирнэ үү" "Аппыг дахин байрлуулахын тулд гадна талд нь хоёр товшино" @@ -126,15 +129,21 @@ "Windows-г удирдах" "Хаах" "Цэсийг хаах" - - + "Цэсийг нээх" "Дэлгэцийг томруулах" "Дэлгэцийг таллах" - "Энэ аппын хэмжээг өөрчлөх боломжгүй" - + "Аппыг ийш зөөх боломжгүй" + "Томруулах" + "Зүүн тийш зэрэгцүүлэх" + "Баруун тийш зэрэгцүүлэх" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index 483228424d44..9778dcd0a166 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -97,6 +97,9 @@ "कॅमेराशी संबंधित काही समस्या आहेत का?\nपुन्हा फिट करण्यासाठी टॅप करा" "निराकरण झाले नाही?\nरिव्हर्ट करण्यासाठी कृपया टॅप करा" "कॅमेराशी संबंधित कोणत्याही समस्या नाहीत का? डिसमिस करण्‍यासाठी टॅप करा." + "अ‍ॅप मेनू उघडण्यासाठी टॅप करा" + "एकाहून अधिक ॲप्स एकत्र दाखवण्यासाठी टॅप करा" + "ॲप मेनूमधून फुलस्क्रीनवर परत या" "पहा आणि आणखी बरेच काही करा" "स्प्लिट स्क्रीन वापरण्यासाठी दुसरे ॲप ड्रॅग करा" "ॲपची स्थिती पुन्हा बदलण्यासाठी, त्याच्या बाहेर दोनदा टॅप करा" @@ -126,15 +129,21 @@ "विंडो व्यवस्थापित करा" "बंद करा" "मेनू बंद करा" - - + "मेनू उघडा" "स्क्रीन मोठी करा" "स्क्रीन स्नॅप करा" - "या अ‍ॅपचा आकार बदलला जाऊ शकत नाही" - + "अ‍ॅप इथे हलवू शकत नाही" + "मोठे करा" + "डावीकडे स्नॅप करा" + "उजवीकडे स्नॅप करा" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index 15ccfbbad39f..0ee439657e2a 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -97,6 +97,9 @@ "Isu kamera?\nKetik untuk memuatkan semula" "Isu tidak dibetulkan?\nKetik untuk kembali" "Tiada isu kamera? Ketik untuk mengetepikan." + "Ketik untuk membuka menu apl" + "Ketik untuk memaparkan berbilang apl serentak" + "Kembali kepada skrin penuh daripada menu apl" "Lihat dan lakukan lebih" "Seret masuk apl lain untuk menggunakan skrin pisah" "Ketik dua kali di luar apl untuk menempatkan semula apl itu" @@ -129,8 +132,18 @@ "Buka Menu" "Maksimumkan Skrin" "Tangkap Skrin" - "Apl ini tidak boleh diubah saiz" + "Apl tidak boleh dialihkan ke sini" "Maksimumkan" "Autojajar ke kiri" "Autojajar ke kanan" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index aac6f8420d7a..57d09500b3bf 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -97,6 +97,9 @@ "ကင်မရာပြဿနာလား။\nပြင်ဆင်ရန် တို့ပါ" "ကောင်းမသွားဘူးလား။\nပြန်ပြောင်းရန် တို့ပါ" "ကင်မရာပြဿနာ မရှိဘူးလား။ ပယ်ရန် တို့ပါ။" + "အက်ပ်မီနူးကိုဖွင့်ရန် တို့ပါ" + "အက်ပ်များစွာကို အတူတကွပြရန် တို့ပါ" + "အက်ပ်မီနူးမှ ဖန်သားပြင်အပြည့်သို့ ပြန်သွားပါ" "ကြည့်ပြီး ပိုမိုလုပ်ဆောင်ပါ" "မျက်နှာပြင် ခွဲ၍ပြသခြင်းအတွက် အက်ပ်နောက်တစ်ခုကို ဖိဆွဲပါ" "နေရာပြန်ချရန် အက်ပ်အပြင်ဘက်ကို နှစ်ချက်တို့ပါ" @@ -126,15 +129,21 @@ "ဝင်းဒိုးများ စီမံရန်" "ပိတ်ရန်" "မီနူး ပိတ်ရန်" - - + "မီနူး ဖွင့်ရန်" "စခရင်ကို ချဲ့မည်" "စခရင်ကို ချုံ့မည်" - "ဤအက်ပ်ကို အရွယ်ပြင်၍ မရပါ" - + "အက်ပ်ကို ဤနေရာသို့ ရွှေ့၍မရပါ" + "ချဲ့ရန်" + "ဘယ်တွင် ချဲ့ရန်" + "ညာတွင် ချဲ့ရန်" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index 175133d1744a..eb505ec43a65 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -97,6 +97,9 @@ "Har du kameraproblemer?\nTrykk for å tilpasse" "Ble ikke problemet løst?\nTrykk for å gå tilbake" "Har du ingen kameraproblemer? Trykk for å lukke." + "Trykk for å åpne appmenyen" + "Trykk for å vise flere apper sammen" + "Gå tilbake til fullskjerm fra appmenyen" "Se og gjør mer" "Dra inn en annen app for å bruke delt skjerm" "Dobbelttrykk utenfor en app for å flytte den" @@ -126,15 +129,21 @@ "Administrer vinduene" "Lukk" "Lukk menyen" - - + "Åpne menyen" "Maksimer skjermen" "Fest skjermen" - "Du kan ikke endre størrelse på denne appen" - + "Appen kan ikke flyttes hit" + "Maksimer" + "Fest til venstre" + "Fest til høyre" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index d3a7e12c0df4..47d66d5deec8 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -97,6 +97,9 @@ "क्यामेरासम्बन्धी समस्या देखियो?\nसमस्या हल गर्न ट्याप गर्नुहोस्" "समस्या हल भएन?\nपहिलेको जस्तै बनाउन ट्याप गर्नुहोस्" "क्यामेरासम्बन्धी कुनै पनि समस्या छैन? खारेज गर्न ट्याप गर्नुहोस्।" + "एपको मेनु खोल्न ट्याप गर्नुहोस्" + "एकभन्दा बढी एपहरू सँगै देखाउन ट्याप गर्नुहोस्" + "एपको मेनुबाट फुल स्क्रिनमा फर्कनुहोस्" "थप कुरा हेर्नुहोस् र गर्नुहोस्" "स्प्लिट स्क्रिन मोड प्रयोग गर्न अर्को एप ड्रयाग एन्ड ड्रप गर्नुहोस्" "तपाईं जुन एपको स्थिति मिलाउन चाहनुहुन्छ सोही एपको बाहिर डबल ट्याप गर्नुहोस्" @@ -126,15 +129,21 @@ "विन्डोहरू व्यवस्थापन गर्नुहोस्" "बन्द गर्नुहोस्" "मेनु बन्द गर्नुहोस्" - - + "मेनु खोल्नुहोस्" "स्क्रिन ठुलो बनाउनुहोस्" "स्क्रिन स्न्याप गर्नुहोस्" - "यो एपको आकार बदल्न मिल्दैन" - + "एप सारेर यहाँ ल्याउन सकिएन" + "ठुलो बनाउनुहोस्" + "बायाँतिर स्न्याप गर्नुहोस्" + "दायाँतिर स्न्याप गर्नुहोस्" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index 747afe3eb034..e3e344124e0b 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -97,6 +97,9 @@ "Cameraproblemen?\nTik om opnieuw passend te maken." "Is dit geen oplossing?\nTik om terug te zetten." "Geen cameraproblemen? Tik om te sluiten." + "Tik om het app-menu te openen" + "Tik om meerdere apps tegelijk te tonen" + "Terug naar volledig scherm vanuit het app-menu" "Zie en doe meer" "Sleep een andere app hier naartoe om het scherm te splitsen" "Dubbeltik naast een app om deze opnieuw te positioneren" @@ -126,15 +129,21 @@ "Vensters beheren" "Sluiten" "Menu sluiten" - - + "Menu openen" "Scherm maximaliseren" "Scherm halveren" - "Het formaat van deze app kan niet worden aangepast" - + "Kan de app niet hierheen verplaatsen" + "Maximaliseren" + "Links uitlijnen" + "Rechts uitlijnen" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index a5adcbe36db1..baf009e8f28c 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -97,6 +97,9 @@ "କ୍ୟାମେରାରେ ସମସ୍ୟା ଅଛି?\nପୁଣି ଫିଟ କରିବାକୁ ଟାପ କରନ୍ତୁ" "ଏହାର ସମାଧାନ ହୋଇନାହିଁ?\nଫେରିଯିବା ପାଇଁ ଟାପ କରନ୍ତୁ" "କ୍ୟାମେରାରେ କିଛି ସମସ୍ୟା ନାହିଁ? ଖାରଜ କରିବାକୁ ଟାପ କରନ୍ତୁ।" + "ଆପ ମେନୁ ଖୋଲିବାକୁ ଟାପ କରନ୍ତୁ" + "ଏକାଠି ଏକାଧିକ ଆପ୍ସ ଦେଖାଇବା ପାଇଁ ଟାପ କରନ୍ତୁ" + "ଆପ ମେନୁରୁ ପୂର୍ଣ୍ଣସ୍କ୍ରିନକୁ ଫେରନ୍ତୁ" "ଦେଖନ୍ତୁ ଏବଂ ଆହୁରି ଅନେକ କିଛି କରନ୍ତୁ" "ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ପାଇଁ ଅନ୍ୟ ଏକ ଆପକୁ ଡ୍ରାଗ କରନ୍ତୁ" "ଏକ ଆପକୁ ରିପୋଜିସନ କରିବା ପାଇଁ ଏହାର ବାହାରେ ଦୁଇଥର-ଟାପ କରନ୍ତୁ" @@ -126,15 +129,21 @@ "ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ପରିଚାଳନା କରନ୍ତୁ" "ବନ୍ଦ କରନ୍ତୁ" "ମେନୁ ବନ୍ଦ କରନ୍ତୁ" - - + "ମେନୁ ଖୋଲନ୍ତୁ" "ସ୍କ୍ରିନକୁ ବଡ଼ କରନ୍ତୁ" "ସ୍କ୍ରିନକୁ ସ୍ନାପ କରନ୍ତୁ" - "ଏହି ଆପକୁ ରିସାଇଜ କରାଯାଇପାରିବ ନାହିଁ" - + "ଆପକୁ ଏଠାକୁ ମୁଭ କରାଯାଇପାରିବ ନାହିଁ" + "ବଡ଼ କରନ୍ତୁ" + "ବାମରେ ସ୍ନାପ କରନ୍ତୁ" + "ଡାହାଣରେ ସ୍ନାପ କରନ୍ତୁ" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index e11cc1c1f76d..2c29c7f80411 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -97,6 +97,9 @@ "ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ?\nਮੁੜ-ਫਿੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ" "ਕੀ ਇਹ ਠੀਕ ਨਹੀਂ ਹੋਈ?\nਵਾਪਸ ਉਹੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ" "ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਕੋਈ ਸਮੱਸਿਆ ਨਹੀਂ ਹੈ? ਖਾਰਜ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।" + "ਐਪ ਮੀਨੂ ਨੂੰ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ" + "ਕਈ ਐਪਾਂ ਇਕੱਠੀਆਂ ਦਿਖਾਉਣ ਲਈ ਟੈਪ ਕਰੋ" + "ਐਪ ਮੀਨੂ ਤੋਂ ਪੂਰੀ-ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਵਾਪਸ ਜਾਓ" "ਦੇਖੋ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ ਕਰੋ" "ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੇ ਲਈ ਕਿਸੇ ਹੋਰ ਐਪ ਵਿੱਚ ਘਸੀਟੋ" "ਕਿਸੇ ਐਪ ਦੀ ਜਗ੍ਹਾ ਬਦਲਣ ਲਈ ਉਸ ਦੇ ਬਾਹਰ ਡਬਲ ਟੈਪ ਕਰੋ" @@ -129,8 +132,18 @@ "ਮੀਨੂ ਖੋਲ੍ਹੋ" "ਸਕ੍ਰੀਨ ਦਾ ਆਕਾਰ ਵਧਾਓ" "ਸਕ੍ਰੀਨ ਨੂੰ ਸਨੈਪ ਕਰੋ" - "ਇਸ ਐਪ ਦਾ ਆਕਾਰ ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ" + "ਐਪ ਨੂੰ ਇੱਥੇ ਨਹੀਂ ਲਿਜਾਇਆ ਜਾ ਸਕਦਾ" "ਵੱਡਾ ਕਰੋ" "ਖੱਬੇ ਪਾਸੇ ਸਨੈਪ ਕਰੋ" "ਸੱਜੇ ਪਾਸੇ ਸਨੈਪ ਕਰੋ" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index 2640c0f368a8..1e7b18117812 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -97,6 +97,9 @@ "Problemy z aparatem?\nKliknij, aby dopasować" "Naprawa się nie udała?\nKliknij, aby cofnąć" "Brak problemów z aparatem? Kliknij, aby zamknąć" + "Kliknij, aby otworzyć menu aplikacji" + "Kliknij, aby wyświetlić jednocześnie kilka aplikacji" + "Wróć do trybu pełnoekranowego z menu aplikacji" "Zobacz i zrób więcej" "Aby podzielić ekran, przeciągnij drugą aplikację" "Kliknij dwukrotnie poza aplikacją, aby ją przenieść" @@ -129,8 +132,18 @@ "Otwórz menu" "Maksymalizuj ekran" "Przyciągnij ekran" - "Nie można zmienić rozmiaru tej aplikacji" + "Nie można przenieść aplikacji tutaj" "Maksymalizuj" "Przyciągnij do lewej" "Przyciągnij do prawej" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index 18048ff045b5..7d728a03b4ec 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -97,12 +97,9 @@ "Problemas com a câmera?\nToque para ajustar o enquadramento" "O problema não foi corrigido?\nToque para reverter" "Não tem problemas com a câmera? Toque para dispensar." - - - - - - + "Toque para abrir o menu do app" + "Toque para mostrar vários apps juntos" + "Volte para a tela cheia no menu do app" "Veja e faça mais" "Arraste outro app para dividir a tela" "Toque duas vezes fora de um app para reposicionar" @@ -135,9 +132,18 @@ "Abrir o menu" "Ampliar tela" "Ajustar tela" - - + "Não é possível mover o app para cá" "Maximizar" "Ajustar à esquerda" "Ajustar à direita" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index 46f8b38dd621..752fd6fb8970 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -97,6 +97,9 @@ "Problemas com a câmara?\nToque aqui para reajustar" "Não foi corrigido?\nToque para reverter" "Nenhum problema com a câmara? Toque para ignorar." + "Toque para abrir o menu de apps" + "Toque para mostrar várias apps em conjunto" + "Regresse ao ecrã inteiro a partir do menu de apps" "Veja e faça mais" "Arraste outra app para usar o ecrã dividido" "Toque duas vezes fora de uma app para a reposicionar" @@ -129,8 +132,18 @@ "Abrir menu" "Maximizar ecrã" "Encaixar ecrã" - "Não é possível redimensionar esta app" + "Não é possível mover a app para aqui" "Maximizar" "Encaixar à esquerda" "Encaixar à direita" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index 75c445c6f35c..7d728a03b4ec 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -97,6 +97,9 @@ "Problemas com a câmera?\nToque para ajustar o enquadramento" "O problema não foi corrigido?\nToque para reverter" "Não tem problemas com a câmera? Toque para dispensar." + "Toque para abrir o menu do app" + "Toque para mostrar vários apps juntos" + "Volte para a tela cheia no menu do app" "Veja e faça mais" "Arraste outro app para dividir a tela" "Toque duas vezes fora de um app para reposicionar" @@ -126,15 +129,21 @@ "Gerenciar janelas" "Fechar" "Fechar menu" - - + "Abrir o menu" "Ampliar tela" "Ajustar tela" - "Não é possível redimensionar o app" - + "Não é possível mover o app para cá" + "Maximizar" + "Ajustar à esquerda" + "Ajustar à direita" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index 3c763ea8a6a4..3985d9bc792a 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -97,6 +97,9 @@ "Ai probleme cu camera foto?\nAtinge pentru a reîncadra" "Nu ai remediat problema?\nAtinge pentru a reveni" "Nu ai probleme cu camera foto? Atinge pentru a închide." + "Atinge pentru a deschide meniul aplicației" + "Atinge pentru a afișa mai multe aplicații împreună" + "Revino la ecranul complet din meniul aplicației" "Vezi și fă mai multe" "Trage în altă aplicație pentru a folosi ecranul împărțit" "Atinge de două ori lângă o aplicație pentru a o repoziționa" @@ -126,15 +129,21 @@ "Gestionează ferestrele" "Închide" "Închide meniul" - - + "Deschide meniul" "Maximizează fereastra" "Micșorează fereastra și fixeaz-o" - "Aplicația nu poate fi redimensionată" - + "Aplicația nu poate fi mutată aici" + "Maximizează" + "Trage la stânga" + "Trage la dreapta" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index affd0cb0853a..58a196b4eecb 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -97,6 +97,9 @@ "Проблемы с камерой?\nНажмите, чтобы исправить." "Не помогло?\nНажмите, чтобы отменить изменения." "Нет проблем с камерой? Нажмите, чтобы закрыть." + "Нажмите, чтобы открыть меню приложения" + "Нажмите, чтобы на экране размещались сразу несколько приложений" + "Вернуться из меню приложения в режим полного экрана" "Выполняйте несколько задач одновременно" "Перетащите сюда другое приложение, чтобы использовать разделение экрана." "Чтобы переместить приложение, дважды нажмите рядом с ним." @@ -129,8 +132,18 @@ "Открыть меню" "Развернуть на весь экран" "Свернуть" - "Изменить размер приложения нельзя." + "Приложение нельзя сюда переместить" "Развернуть" "Привязать слева" "Привязать справа" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index ed762699bc49..6682b017f2cc 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -97,6 +97,9 @@ "කැමරා ගැටලුද?\nයළි සවි කිරීමට තට්ටු කරන්න" "එය විසඳුවේ නැතිද?\nප්‍රතිවර්තනය කිරීමට තට්ටු කරන්න" "කැමරා ගැටලු නොමැතිද? ඉවත දැමීමට තට්ටු කරන්න" + "යෙදුම් මෙනුව විවෘත කිරීමට තට්ටු කරන්න" + "යෙදුම් කිහිපයක් එකට පෙන්වීමට තට්ටු කරන්න" + "යෙදුම් මෙනුවෙන් පූර්ණ තිරය වෙත ආපසු යන්න" "බලන්න සහ තවත් දේ කරන්න" "බෙදුම් තිරය සඳහා වෙනත් යෙදුමකට අදින්න" "යෙදුමක් නැවත ස්ථානගත කිරීමට පිටතින් දෙවරක් තට්ටු කරන්න" @@ -126,15 +129,21 @@ "කවුළු කළමනාකරණය කරන්න" "වසන්න" "මෙනුව වසන්න" - - + "මෙනුව විවෘත කරන්න" "තිරය උපරිම කරන්න" "ස්නැප් තිරය" - "මෙම යෙදුම ප්‍රතිප්‍රමාණ කළ නොහැක" - + "යෙදුම මෙතැනට ගෙන යා නොහැක" + "විහිදන්න" + "වමට ස්නැප් කරන්න" + "දකුණට ස්නැප් කරන්න" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index 529a6932c9ce..96e54f1caa68 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -97,6 +97,9 @@ "Problémy s kamerou?\nKlepnutím znova upravte." "Nevyriešilo sa to?\nKlepnutím sa vráťte." "Nemáte problémy s kamerou? Klepnutím zatvoríte." + "Klepnúť a otvoriť tak ponuku aplikácií" + "Klepnúť a zobraziť tak viacero aplikácií naraz" + "Prejsť späť na celú obrazovku z ponuky aplikácií" "Zobrazte si a zvládnite toho viac" "Rozdelenú obrazovku môžete použiť presunutím do inej aplikácie" "Dvojitým klepnutím mimo aplikácie zmeníte jej pozíciu" @@ -126,15 +129,21 @@ "Správa okien" "Zavrieť" "Zavrieť ponuku" - - + "Otvoriť ponuku" "Maximalizovať obrazovku" "Zobraziť polovicu obrazovky" - "Veľkosť tejto aplikácie sa nedá zmeniť" - + "Aplikácia sa sem nedá presunúť" + "Maximalizovať" + "Prichytiť vľavo" + "Prichytiť vpravo" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index 280346d0559a..66c9b26de54e 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -97,6 +97,9 @@ "Težave s fotoaparatom?\nDotaknite se za vnovično prilagoditev" "To ni odpravilo težave?\nDotaknite se za povrnitev" "Nimate težav s fotoaparatom? Dotaknite se za opustitev." + "Dotaknite se, če želite odpreti meni aplikacije" + "Dotaknite se, če želite prikazati več aplikacij hkrati" + "Nazaj v celozaslonski način iz menija aplikacije" "Oglejte si in naredite več" "Za razdeljeni zaslon povlecite sem še eno aplikacijo." "Dvakrat se dotaknite zunaj aplikacije, če jo želite prestaviti." @@ -129,8 +132,18 @@ "Odpri meni" "Maksimiraj zaslon" "Pripni zaslon" - "Velikosti te aplikacije ni mogoče spremeniti" + "Aplikacije ni mogoče premakniti sem" "Maksimiraj" "Pripni levo" "Pripni desno" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index a4a7e744c426..6e49999545a8 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -97,6 +97,9 @@ "Ka probleme me kamerën?\nTrokit për ta ripërshtatur" "Nuk u rregullua?\nTrokit për ta rikthyer" "Nuk ka probleme me kamerën? Trokit për ta shpërfillur." + "Trokit për të hapur menynë e aplikacionit" + "Trokit për të shfaqur disa aplikacone bashkë" + "Kthehu tek ekrani i plotë nga menyja e aplikacionit" "Shiko dhe bëj më shumë" "Zvarrite në një aplikacion tjetër për ekranin e ndarë" "Trokit dy herë jashtë një aplikacioni për ta ripozicionuar" @@ -126,15 +129,21 @@ "Menaxho dritaret" "Mbyll" "Mbyll menynë" - - + "Hap menynë" "Maksimizo ekranin" "Regjistro ekranin" - "Përmasat e këtij aplikacioni nuk mund të ndryshohen" - + "Aplikacioni nuk mund të zhvendoset këtu" + "Maksimizo" + "Zhvendos majtas" + "Zhvendos djathtas" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index 9545ccf7a810..bd2fb8c442f3 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -97,6 +97,9 @@ "Имате проблема са камером?\nДодирните да бисте поново уклопили" "Проблем није решен?\nДодирните да бисте вратили" "Немате проблема са камером? Додирните да бисте одбацили." + "Додирните да бисте отворили мени апликације" + "Додирните да бисте приказали више апликација заједно" + "Вратите се из менија апликације на приказ преко целог екрана" "Видите и урадите више" "Превуците другу апликацију да бисте користили подељени екран" "Двапут додирните изван апликације да бисте променили њену позицију" @@ -126,15 +129,21 @@ "Управљајте прозорима" "Затворите" "Затворите мени" - - + "Отворите мени" "Повећај екран" "Уклопи екран" - "Величина ове апликације не може да се промени" - + "Апликација не може да се премести овде" + "Увећајте" + "Прикачите лево" + "Прикачите десно" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index aa74bdef0140..2184ac6bfca7 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -97,6 +97,9 @@ "Problem med kameran?\nTryck för att anpassa på nytt" "Löstes inte problemet?\nTryck för att återställa" "Inga problem med kameran? Tryck för att ignorera." + "Tryck för att öppna appmenyn" + "Tryck för att visa flera appar tillsammans" + "Återgå till helskärm från appmenyn" "Se och gör mer" "Dra till en annan app för att dela upp skärmen" "Tryck snabbt två gånger utanför en app för att flytta den" @@ -129,8 +132,18 @@ "Öppna menyn" "Maximera skärmen" "Fäst skärmen" - "Det går inte att ändra storlek på appen" + "Det går inte att flytta appen hit" "Utöka" "Fäst till vänster" "Fäst till höger" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index c6ce023a5ca7..6068bf00a6df 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -97,6 +97,9 @@ "Je, kuna hitilafu za kamera?\nGusa ili urekebishe" "Umeshindwa kurekebisha?\nGusa ili urejeshe nakala ya awali" "Je, hakuna hitilafu za kamera? Gusa ili uondoe." + "Gusa ili ufungue menyu ya programu" + "Gusa ili uonyeshe programu nyingi kwa pamoja" + "Rudi kwenye skrini nzima katika menyu ya programu" "Angalia na ufanye zaidi" "Buruta katika programu nyingine ili utumie skrini iliyogawanywa" "Gusa mara mbili nje ya programu ili uihamishe" @@ -126,15 +129,21 @@ "Dhibiti Windows" "Funga" "Funga Menyu" - - + "Fungua Menyu" "Panua Dirisha kwenye Skrini" "Panga Madirisha kwenye Skrini" - "Huwezi kubadilisha ukubwa wa programu hii" - + "Imeshindwa kuhamishia programu hapa" + "Panua" + "Telezesha kushoto" + "Telezesha kulia" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index 2c2f31978b0f..a14abac75245 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -97,6 +97,9 @@ "கேமரா தொடர்பான சிக்கல்களா?\nமீண்டும் பொருத்த தட்டவும்" "சிக்கல்கள் சரிசெய்யப்படவில்லையா?\nமாற்றியமைக்க தட்டவும்" "கேமரா தொடர்பான சிக்கல்கள் எதுவும் இல்லையா? நிராகரிக்க தட்டவும்." + "ஆப்ஸ் மெனுவைத் திறக்க தட்டவும்" + "பல ஆப்ஸை ஒன்றாகக் காட்ட தட்டவும்" + "ஆப்ஸ் மெனுவில் இருந்து முழுத்திரைக்குச் செல்லும்" "பலவற்றைப் பார்த்தல் மற்றும் செய்தல்" "திரைப் பிரிப்புக்கு மற்றொரு ஆப்ஸை இழுக்கலாம்" "ஆப்ஸை இடம் மாற்ற அதன் வெளியில் இருமுறை தட்டலாம்" @@ -126,15 +129,21 @@ "சாளரங்களை நிர்வகிக்கலாம்" "மூடும்" "மெனுவை மூடும்" - - + "மெனுவைத் திறக்கும்" "திரையைப் பெரிதாக்கு" "திரையை ஸ்னாப் செய்" - "இந்த ஆப்ஸின் அளவை மாற்ற முடியாது" - + "ஆப்ஸை இங்கே நகர்த்த முடியாது" + "பெரிதாக்கும்" + "இடதுபுறம் நகர்த்தும்" + "வலதுபுறம் நகர்த்தும்" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 8691c9d5aa26..84e76a8cc361 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -97,6 +97,9 @@ "కెమెరా సమస్యలు ఉన్నాయా?\nరీఫిట్ చేయడానికి ట్యాప్ చేయండి" "దాని సమస్యను పరిష్కరించలేదా?\nపూర్వస్థితికి మార్చడానికి ట్యాప్ చేయండి" "కెమెరా సమస్యలు లేవా? తీసివేయడానికి ట్యాప్ చేయండి." + "యాప్ మెనూని తెరవడానికి ట్యాప్ చేయండి" + "పలు యాప్‌లను కలిపి చూడటానికి ట్యాప్ చేయండి" + "యాప్ మెనూ నుండి ఫుల్ స్క్రీన్‌కు తిరిగి రండి" "చూసి, మరిన్ని చేయండి" "స్ప్లిట్ స్క్రీన్ కోసం మరొక యాప్‌లోకి లాగండి" "యాప్ స్థానాన్ని మార్చడానికి దాని వెలుపల డబుల్-ట్యాప్ చేయండి" @@ -126,15 +129,21 @@ "విండోలను మేనేజ్ చేయండి" "మూసివేయండి" "మెనూను మూసివేయండి" - - + "మెనూను తెరవండి" "స్క్రీన్ సైజ్‌ను పెంచండి" "స్క్రీన్‌ను స్నాప్ చేయండి" - "ఈ యాప్ సైజ్‌ను మార్చడం సాధ్యపడదు" - + "యాప్‌ను ఇక్కడకి తరలించడం సాధ్యం కాదు" + "మ్యాగ్జిమైజ్ చేయండి" + "ఎడమ వైపున స్నాప్ చేయండి" + "కుడి వైపున స్నాప్ చేయండి" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index 07e141601d08..856893f83955 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -97,6 +97,9 @@ "หากพบปัญหากับกล้อง\nแตะเพื่อแก้ไข" "หากไม่ได้แก้ไข\nแตะเพื่อเปลี่ยนกลับ" "หากไม่พบปัญหากับกล้อง แตะเพื่อปิด" + "แตะเพื่อเปิดเมนูแอป" + "แตะเพื่อแสดงแอปหลายรายการพร้อมกัน" + "กลับไปที่เต็มหน้าจอจากเมนูแอป" "รับชมและทำสิ่งต่างๆ ได้มากขึ้น" "ลากไปไว้ในแอปอื่นเพื่อแยกหน้าจอ" "แตะสองครั้งด้านนอกแอปเพื่อเปลี่ยนตำแหน่ง" @@ -126,15 +129,21 @@ "จัดการหน้าต่าง" "ปิด" "ปิดเมนู" - - + "เปิดเมนู" "ขยายหน้าจอให้ใหญ่สุด" "สแนปหน้าจอ" - "ปรับขนาดแอปนี้ไม่ได้" - + "ย้ายแอปมาที่นี่ไม่ได้" + "ขยายใหญ่สุด" + "จัดพอดีกับทางซ้าย" + "จัดพอดีกับทางขวา" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index 477700e7bbdf..dc92efd8e18f 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -97,6 +97,9 @@ "May mga isyu sa camera?\nI-tap para i-refit" "Hindi ito naayos?\nI-tap para i-revert" "Walang isyu sa camera? I-tap para i-dismiss." + "I-tap para buksan ang menu ng app" + "I-tap para ipakita nang magkakasama ang maraming app" + "Bumalik sa fullscreen mula sa menu ng app" "Tumingin at gumawa ng higit pa" "Mag-drag ng isa pang app para sa split screen" "Mag-double tap sa labas ng app para baguhin ang posisyon nito" @@ -126,15 +129,21 @@ "Pamahalaan ang Mga Window" "Isara" "Isara ang Menu" - - + "Buksan ang Menu" "I-maximize ang Screen" "I-snap ang Screen" - "Hindi nare-resize ang app na ito" - + "Hindi mailipat dito ang app" + "I-maximize" + "I-snap pakaliwa" + "I-snap pakanan" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index b0c253965970..e206cd6cd10c 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -97,6 +97,9 @@ "Kameranızda sorun mu var?\nDüzeltmek için dokunun" "Bu işlem sorunu düzeltmedi mi?\nİşlemi geri almak için dokunun" "Kameranızda sorun yok mu? Kapatmak için dokunun." + "Uygulama menüsünü açmak için dokunun" + "Birden fazla uygulamayı birlikte göstermek için dokunun" + "Uygulama menüsünden tam ekrana dönün" "Daha fazlasını görün ve yapın" "Bölünmüş ekran için başka bir uygulamayı sürükleyin" "Yeniden konumlandırmak için uygulamanın dışına iki kez dokunun" @@ -126,15 +129,21 @@ "Pencereleri yönet" "Kapat" "Menüyü kapat" - - + "Menüyü aç" "Ekranı Büyüt" "Ekranın Yarısına Tuttur" - "Bu uygulama yeniden boyutlandırılamaz" - + "Uygulama buraya taşınamıyor" + "Ekranı kapla" + "Sola tuttur" + "Sağa tuttur" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index dd64c6642104..90a3bc33b3e2 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -97,6 +97,9 @@ "Проблеми з камерою?\nНатисніть, щоб пристосувати" "Проблему не вирішено?\nНатисніть, щоб скасувати зміни" "Немає проблем із камерою? Торкніться, щоб закрити." + "Натисніть, щоб відкрити меню додатка" + "Натисніть, щоб переглянути кілька додатків одночасно" + "Повернутися з меню додатка в повноекранний режим" "Більше простору та можливостей" "Щоб перейти в режим розділення екрана, перетягніть сюди інший додаток" "Щоб перемістити додаток, двічі торкніться області поза ним" @@ -126,15 +129,21 @@ "Керувати вікнами" "Закрити" "Закрити меню" - - + "Відкрити меню" "Розгорнути екран" "Зафіксувати екран" - "Розмір вікна цього додатка не можна змінити" - + "Сюди не можна перемістити додаток" + "Розгорнути" + "Закріпити ліворуч" + "Закріпити праворуч" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index aa311c2978c8..2006b0ba6929 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -97,6 +97,9 @@ "کیمرے کے مسائل؟\nدوبارہ فٹ کرنے کیلئے تھپتھپائیں" "یہ حل نہیں ہوا؟\nلوٹانے کیلئے تھپتھپائیں" "کوئی کیمرے کا مسئلہ نہیں ہے؟ برخاست کرنے کیلئے تھپتھپائیں۔" + "ایپ مینو کھولنے کیلئے تھپتھپائیں" + "متعدد ایپس ایک ساتھ دکھانے کیلئے تھپتھپائیں" + "ایپ مینو سے مکمل اسکرین پر واپس جائیں" "دیکھیں اور بہت کچھ کریں" "اسپلٹ اسکرین کے ليے دوسری ایپ میں گھسیٹیں" "کسی ایپ کی پوزیشن تبدیل کرنے کے لیے اس ایپ کے باہر دو بار تھپتھپائیں" @@ -126,15 +129,21 @@ "‏‫Windows کا نظم کریں" "بند کریں" "مینیو بند کریں" - - + "مینو کھولیں" "اسکرین کو بڑا کریں" "اسکرین کا اسناپ شاٹ لیں" - "اس ایپ کا سائز تبدیل نہیں کیا جا سکتا" - + "ایپ کو یہاں منتقل نہیں کیا جا سکتا" + "بڑا کریں" + "دائیں منتقل کریں" + "بائیں منتقل کریں" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index cd0ca82ff563..4b163f79f970 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -97,6 +97,9 @@ "Kamera nosozmi?\nQayta moslash uchun bosing" "Tuzatilmadimi?\nQaytarish uchun bosing" "Kamera muammosizmi? Yopish uchun bosing." + "Ilova menyusini ochish uchun bosing" + "Bir nechta ilovani birga chiqarish uchun bosing" + "Ilova menyusidan butun ekranga qayting" "Yana boshqa amallar" "Ekranni ikkiga ajratish uchun boshqa ilovani bu yerga torting" "Qayta joylash uchun ilova tashqarisiga ikki marta bosing" @@ -129,8 +132,18 @@ "Menyuni ochish" "Ekranni yoyish" "Ekranni biriktirish" - "Bu ilova hajmini oʻzgartirish imkonsiz" + "Ilova bu yerga surilmaydi" "Yoyish" "Chapga tortish" "Oʻngga tortish" + + + + + + + + + + diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index abac3fe824bb..db86498130d8 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -97,6 +97,9 @@ "Có vấn đề với máy ảnh?\nHãy nhấn để sửa lỗi" "Bạn chưa khắc phục vấn đề?\nHãy nhấn để hủy bỏ" "Không có vấn đề với máy ảnh? Hãy nhấn để đóng." + "Nhấn để mở trình đơn ứng dụng" + "Nhấn để hiển thị nhiều ứng dụng cùng lúc" + "Quay lại chế độ toàn màn hình từ trình đơn ứng dụng" "Xem và làm được nhiều việc hơn" "Kéo một ứng dụng khác vào để chia đôi màn hình" "Nhấn đúp bên ngoài ứng dụng để đặt lại vị trí" @@ -126,15 +129,21 @@ "Quản lý cửa sổ" "Đóng" "Đóng trình đơn" - - + "Mở Trình đơn" "Mở rộng màn hình" "Điều chỉnh kích thước màn hình" - "Không thể đổi kích thước của ứng dụng này" - + "Không di chuyển được ứng dụng đến đây" + "Phóng to tối đa" + "Di chuyển nhanh sang trái" + "Di chuyển nhanh sang phải" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index 5a61decdcfb9..ebf4b038b098 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -97,6 +97,9 @@ "相机有问题?\n点按即可整修" "没有解决此问题?\n点按即可恢复" "相机没有问题?点按即可忽略。" + "点按可打开应用菜单" + "点按可同时显示多个应用" + "从应用菜单可返回到全屏" "查看和处理更多任务" "拖入另一个应用,即可使用分屏模式" "在某个应用外连续点按两次,即可调整它的位置" @@ -126,15 +129,21 @@ "管理窗口" "关闭" "关闭菜单" - - + "打开菜单" "最大化屏幕" "屏幕快照" - "无法调整此应用的大小" - + "无法将应用移至此处" + "最大化" + "贴靠左侧" + "贴靠右侧" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index e1c303e198bb..f1d12fce0103 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -97,6 +97,9 @@ "相機有問題?\n輕按即可修正" "未能修正問題?\n輕按即可還原" "相機冇問題?㩒一下就可以即可閂咗佢。" + "輕按即可開啟應用程式選單" + "輕按即可同時顯示多個應用程式" + "從應用程式選單返回全螢幕" "瀏覽更多內容及執行更多操作" "拖入另一個應用程式即可分割螢幕" "在應用程式外輕按兩下即可調整位置" @@ -126,15 +129,21 @@ "管理視窗" "關閉" "關閉選單" - - + "打開選單" "畫面最大化" "貼齊畫面" - "此應用程式無法調整大小" - + "應用程式無法移至這裡" + "最大化" + "貼齊左邊" + "貼齊右邊" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index 97e36c300a4a..b5c28d347acb 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -97,6 +97,9 @@ "相機有問題嗎?\n輕觸即可修正" "未修正問題嗎?\n輕觸即可還原" "相機沒問題嗎?輕觸即可關閉。" + "輕觸即可開啟應用程式選單" + "輕觸即可一次顯示多個應用程式" + "從應用程式選單返回全螢幕" "瀏覽更多內容及執行更多操作" "拖進另一個應用程式即可使用分割畫面模式" "在應用程式外輕觸兩下即可調整位置" @@ -126,15 +129,21 @@ "管理視窗" "關閉" "關閉選單" - - + "開啟選單" "畫面最大化" "貼齊畫面" - "這個應用程式無法調整大小" - + "應用程式無法移至此處" + "最大化" + "靠左對齊" + "靠右對齊" + + + + + - + - + diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index 74c7169fefa3..f54d0ed01ea8 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -97,6 +97,9 @@ "Izinkinga zekhamera?\nThepha ukuze uyilinganise kabusha" "Akuyilungisanga?\nThepha ukuze ubuyele" "Azikho izinkinga zekhamera? Thepha ukuze ucashise." + "Thepha ukuze uvule imenyu ye-app" + "Thepha ukuze ubonise ama-app amaningi ndawonye" + "Buyela esikrinini esigcwele ukusuka kumenyu ye-app" "Bona futhi wenze okuningi" "Hudula kwenye i-app mayelana nokuhlukanisa isikrini" "Thepha kabili ngaphandle kwe-app ukuze uyimise kabusha" @@ -126,15 +129,21 @@ "Phatha Amawindi" "Vala" "Vala Imenyu" - - + "Vula Imenyu" "Khulisa Isikrini Sifike Ekugcineni" "Thwebula Isikrini" - "Le app ayikwazi ukushintshwa usayizi" - + "I-app ayikwazi ukuhanjiswa lapha" + "Khulisa" + "Chofoza kwesobunxele" + "Chofoza kwesokudla" + + + + + - + - + -- GitLab From 2381676404a66de3c34c59d2a60a3c379249fdda Mon Sep 17 00:00:00 2001 From: Android Culprit Assistant Date: Mon, 7 Oct 2024 18:24:00 +0000 Subject: [PATCH 138/447] Revert "Add landscape layout for keyguard pattern view" This revert was created by Android Culprit Assistant. The culprit was identified in the following culprit search session (http://go/aca-get/0143d72a-0edb-4c8f-801e-03136595aa25). Bug: 371647585 Change-Id: Ib66c7485b4076f64df83326d8f463ede9d9c9ed6 Signed-off-by: boq-android-culprit-assistant@system.gserviceaccount.com --- .../layout-land/keyguard_pattern_view.xml | 100 ------------------ 1 file changed, 100 deletions(-) delete mode 100644 packages/SystemUI/res-keyguard/layout-land/keyguard_pattern_view.xml diff --git a/packages/SystemUI/res-keyguard/layout-land/keyguard_pattern_view.xml b/packages/SystemUI/res-keyguard/layout-land/keyguard_pattern_view.xml deleted file mode 100644 index 8a77d88a7e83..000000000000 --- a/packages/SystemUI/res-keyguard/layout-land/keyguard_pattern_view.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -- GitLab From 1d12c72318732286356de541f85d0745c025364f Mon Sep 17 00:00:00 2001 From: Android Culprit Assistant Date: Mon, 7 Oct 2024 18:24:00 +0000 Subject: [PATCH 139/447] Revert "Add landscape layouts for keyguard sim pin and puk" This revert was created by Android Culprit Assistant. The culprit was identified in the following culprit search session (http://go/aca-get/0143d72a-0edb-4c8f-801e-03136595aa25). Bug: 371647585 Change-Id: I88900b6a857a0dd8eb4cbd8bc5376631b254df7e Signed-off-by: boq-android-culprit-assistant@system.gserviceaccount.com --- .../layout-land/keyguard_sim_pin_view.xml | 221 ----------------- .../layout-land/keyguard_sim_puk_view.xml | 223 ------------------ .../KeyguardSimPinViewControllerTest.kt | 5 +- 3 files changed, 2 insertions(+), 447 deletions(-) delete mode 100644 packages/SystemUI/res-keyguard/layout-land/keyguard_sim_pin_view.xml delete mode 100644 packages/SystemUI/res-keyguard/layout-land/keyguard_sim_puk_view.xml diff --git a/packages/SystemUI/res-keyguard/layout-land/keyguard_sim_pin_view.xml b/packages/SystemUI/res-keyguard/layout-land/keyguard_sim_pin_view.xml deleted file mode 100644 index 4b8b63fe9396..000000000000 --- a/packages/SystemUI/res-keyguard/layout-land/keyguard_sim_pin_view.xml +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/SystemUI/res-keyguard/layout-land/keyguard_sim_puk_view.xml b/packages/SystemUI/res-keyguard/layout-land/keyguard_sim_puk_view.xml deleted file mode 100644 index 9012856c7bb4..000000000000 --- a/packages/SystemUI/res-keyguard/layout-land/keyguard_sim_puk_view.xml +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt index 7031b2be8028..7151c429acf9 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt @@ -80,9 +80,8 @@ class KeyguardSimPinViewControllerTest : SysuiTestCase() { `when`(telephonyManager.createForSubscriptionId(anyInt())).thenReturn(telephonyManager) `when`(telephonyManager.supplyIccLockPin(anyString())).thenReturn(mock()) simPinView = - LayoutInflater.from(context) - .inflate(R.layout.keyguard_sim_pin_view, null) - .requireViewById(R.id.keyguard_sim_pin_view) as KeyguardSimPinView + LayoutInflater.from(context).inflate(R.layout.keyguard_sim_pin_view, null) + as KeyguardSimPinView val fakeFeatureFlags = FakeFeatureFlags() val keyguardKeyboardInteractor = KeyguardKeyboardInteractor(FakeKeyboardRepository()) -- GitLab From ef58d112dda8becab4ed0f51a7cda2137d3ddd4a Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 7 Oct 2024 11:24:06 -0700 Subject: [PATCH 140/447] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I22078f461ef1fa223cca12bd734dbd1bc1970ba3 --- .../res/values-af/strings.xml | 18 +++++++++++------ .../res/values-am/strings.xml | 18 +++++++++++------ .../res/values-ar/strings.xml | 18 +++++++++++------ .../res/values-as/strings.xml | 18 +++++++++++------ .../res/values-az/strings.xml | 18 +++++++++++------ .../res/values-b+sr+Latn/strings.xml | 18 +++++++++++------ .../res/values-be/strings.xml | 18 +++++++++++------ .../res/values-bg/strings.xml | 18 +++++++++++------ .../res/values-bn/strings.xml | 18 +++++++++++------ .../res/values-bs/strings.xml | 18 +++++++++++------ .../res/values-ca/strings.xml | 18 ++++++++++------- .../res/values-cs/strings.xml | 18 +++++++++++------ .../res/values-da/strings.xml | 18 +++++++++++------ .../res/values-de/strings.xml | 18 +++++++++++------ .../res/values-el/strings.xml | 18 +++++++++++------ .../res/values-en-rAU/strings.xml | 18 +++++++++++------ .../res/values-en-rCA/strings.xml | 12 +++++------ .../res/values-en-rGB/strings.xml | 18 +++++++++++------ .../res/values-en-rIN/strings.xml | 18 +++++++++++------ .../res/values-en-rXC/strings.xml | 12 +++++------ .../res/values-es-rUS/strings.xml | 18 +++++++++++------ .../res/values-es/strings.xml | 18 +++++++++++------ .../res/values-et/strings.xml | 18 +++++++++++------ .../res/values-eu/strings.xml | 18 +++++++++++------ .../res/values-fa/strings.xml | 18 +++++++++++------ .../res/values-fi/strings.xml | 18 +++++++++++------ .../res/values-fr-rCA/strings.xml | 18 +++++++++++------ .../res/values-fr/strings.xml | 18 +++++++++++------ .../res/values-gl/strings.xml | 18 +++++++++++------ .../res/values-gu/strings.xml | 18 +++++++++++------ .../res/values-hi/strings.xml | 18 +++++++++++------ .../res/values-hr/strings.xml | 18 +++++++++++------ .../res/values-hu/strings.xml | 18 +++++++++++------ .../res/values-hy/strings.xml | 18 +++++++++++------ .../res/values-in/strings.xml | 18 +++++++++++------ .../res/values-is/strings.xml | 18 +++++++++++------ .../res/values-it/strings.xml | 18 +++++++++++------ .../res/values-iw/strings.xml | 18 +++++++++++------ .../res/values-ja/strings.xml | 12 +++++------ .../res/values-ka/strings.xml | 12 +++++------ .../res/values-kk/strings.xml | 18 +++++++++++------ .../res/values-km/strings.xml | 18 +++++++++++------ .../res/values-kn/strings.xml | 18 +++++++++++------ .../res/values-ko/strings.xml | 18 +++++++++++------ .../res/values-ky/strings.xml | 18 +++++++++++------ .../res/values-lo/strings.xml | 12 +++++------ .../res/values-lt/strings.xml | 18 +++++++++++------ .../res/values-lv/strings.xml | 18 +++++++++++------ .../res/values-mk/strings.xml | 18 +++++++++++------ .../res/values-ml/strings.xml | 18 +++++++++++------ .../res/values-mn/strings.xml | 18 +++++++++++------ .../res/values-mr/strings.xml | 18 +++++++++++------ .../res/values-ms/strings.xml | 12 +++++------ .../res/values-my/strings.xml | 20 ++++++++++++------- .../res/values-nb/strings.xml | 18 +++++++++++------ .../res/values-ne/strings.xml | 18 +++++++++++------ .../res/values-nl/strings.xml | 18 +++++++++++------ .../res/values-or/strings.xml | 18 +++++++++++------ .../res/values-pa/strings.xml | 18 +++++++++++------ .../res/values-pl/strings.xml | 18 +++++++++++------ .../res/values-pt-rBR/strings.xml | 18 +++++++++++------ .../res/values-pt-rPT/strings.xml | 18 +++++++++++------ .../res/values-pt/strings.xml | 18 +++++++++++------ .../res/values-ro/strings.xml | 18 +++++++++++------ .../res/values-ru/strings.xml | 18 +++++++++++------ .../res/values-si/strings.xml | 18 +++++++++++------ .../res/values-sk/strings.xml | 18 +++++++++++------ .../res/values-sl/strings.xml | 12 +++++------ .../res/values-sq/strings.xml | 18 +++++++++++------ .../res/values-sr/strings.xml | 18 +++++++++++------ .../res/values-sv/strings.xml | 12 +++++------ .../res/values-sw/strings.xml | 18 +++++++++++------ .../res/values-ta/strings.xml | 18 +++++++++++------ .../res/values-te/strings.xml | 18 +++++++++++------ .../res/values-th/strings.xml | 18 +++++++++++------ .../res/values-tl/strings.xml | 18 +++++++++++------ .../res/values-tr/strings.xml | 18 +++++++++++------ .../res/values-uk/strings.xml | 18 +++++++++++------ .../res/values-ur/strings.xml | 18 +++++++++++------ .../res/values-uz/strings.xml | 18 +++++++++++------ .../res/values-vi/strings.xml | 18 +++++++++++------ .../res/values-zh-rCN/strings.xml | 18 +++++++++++------ .../res/values-zh-rHK/strings.xml | 18 +++++++++++------ .../res/values-zh-rTW/strings.xml | 18 +++++++++++------ .../res/values-zu/strings.xml | 18 +++++++++++------ 85 files changed, 972 insertions(+), 512 deletions(-) diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml index 798e7d5b083f..6a241b776aef 100644 --- a/packages/CompanionDeviceManager/res/values-af/strings.xml +++ b/packages/CompanionDeviceManager/res/values-af/strings.xml @@ -25,17 +25,23 @@ "Laat <strong>%1$s</strong> toe om <strong>%2$s</strong> te bestuur?" "toestel" "Hierdie app sal toegang tot hierdie toestemmings op jou %1$s hê" - "Gee <strong>%1$s</strong> toestemming om jou %2$s se apps na <strong>%3$s</strong&gt te stroom?" - "%1$s sal toegang hê tot enigiets wat sigbaar is of gespeel word op die %2$s, insluitend oudio, foto’s, wagwoorde en boodskappe.<br/><br/>%1$s sal apps na %3$s kan stroom totdat jy toegang tot hierdie toestemming verwyder." - "%1$s versoek toestemming namens jou %2$s om apps tussen jou toestelle te vertoon en te stroom" + + + + + + "Gee <strong>%1$s</strong> toegang tot hierdie inligting op jou %2$s" "%1$s versoek tans namens jou %2$s toegang tot jou %3$s se foto’s, media en kennisgewings" - "Gee <strong>%1$s</strong> toestemming om jou %2$s se apps en stelselkenmerke na <strong>%3$s</strong> te stroom?" - "%1$s sal toegang hê tot enigiets wat sigbaar is of gespeel word op jou %2$s, insluitend oudio, foto’s, betaalinligting, wagwoorde en boodskappe.<br/><br/>%1$s sal apps en stelselkenmerke na %3$s kan stroom totdat jy toegang tot hierdie toestemming verwyder." - "%1$s versoek tans namens jou %2$s toestemming om apps en ander stelselkenmerke tussen jou toestelle te stroom" + + + + + + "toestel" "Hierdie app sal inligting kan sinkroniseer, soos die naam van iemand wat bel, tussen jou foon en die gekose toestel" "Laat toe" diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml index 59e1f03a3716..a9f5ed261a72 100644 --- a/packages/CompanionDeviceManager/res/values-am/strings.xml +++ b/packages/CompanionDeviceManager/res/values-am/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong> <strong>%2$s</strong>ን እንዲያስተዳድር ይፈቅዳሉ?" "መሣሪያ" "ይህ መተግበሪያ በእርስዎ %1$s ላይ እነዚህን ፈቃዶች እንዲደርስ ይፈቀድለታል" - "<strong>%1$s</strong> የእርስዎን %2$s መተግበሪያዎች ወደ <strong>%3$s</strong>? በዥረት እንዲለቅ ይፍቀዱ" - "%1$s ኦዲዮ፣ ፎቶዎች፣ የይለፍ ቃላት እና መልዕክቶችን ጨምሮ በ%2$s ላይ የሚታየውን ወይም የሚጫወተውን ማንኛውንም ነገር መዳረሻ ይኖረዋል።<br/><br/>%1$s የዚህን መዳረሻ እስኪያስወግዱ ድረስ መተግበሪያዎችን ወደ %3$s በዥረት መልቀቅ ይችላል።" - "%1$s የእርስዎን %2$s በመወከል በመሣሪያዎችዎ መካከል ለማሳየት እና መተግበሪያዎችን በዥረት ለመልቀቅ ፈቃድ እየጠየቀ ነው" + + + + + + "<strong>%1$s</strong> ይህን መረጃ ከእርስዎ %2$s እንዲደርስ ይፍቀዱ" "%1$s የእርስዎን %3$s ፎቶዎች፣ ሚዲያ እና ማሳወቂያዎች ለመድረስ የእርስዎን %2$s ወክሎ ፈቃድ እየጠየቀ ነው" - "<strong>%1$s</strong> የእርስዎን %2$s መተግበሪያዎች እና የሥርዓት ባህሪያት ወደ <strong>%3$s</strong>? በዥረት እንዲለቅ ይፍቀዱ" - "%1$s ኦዲዮ፣ ፎቶዎች፣ የክፍያ መረጃ፣ የይለፍ ቃላት እና መልዕክቶችን ጨምሮ በእርስዎ %2$s ላይ የሚታየውን ወይም የሚጫወተውን የማንኛውም ነገር መዳረሻ ይኖረዋል።<br/><br/>%1$s የዚህን መዳረሻ እስኪያስወግዱ ድረስ መተግበሪያዎችን እና የሥርዓት ባህሪያትን ወደ %3$s በዥረት መልቀቅ ይችላል።" - "%1$s የእርስዎን %2$s በመወከል በመሣሪያዎችዎ መካከል መተግበሪያዎችን እና ሌሎች የሥርዓት ባህሪያትን በዥረት ለመልቀቅ ፈቃድ እየጠየቀ ነው" + + + + + + "መሣሪያ" "ይህ መተግበሪያ እንደ የሚደውል ሰው ስም ያለ መረጃን በስልክዎ እና በተመረጠው መሣሪያ መካከል ማስመር ይችላል" "ፍቀድ" diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml index 89c7efb3ae7d..ce68ee1ef366 100644 --- a/packages/CompanionDeviceManager/res/values-ar/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml @@ -25,17 +25,23 @@ "‏هل تريد السماح لتطبيق <strong>%1$s</strong> بإدارة <strong>%2$s</strong>؟" "جهاز" "سيتم السماح لهذا التطبيق باستخدام هذه الأذونات على %1$s" - "‏هل تريد السماح لتطبيق <strong>%1$s</strong> ببث التطبيقات من %2$s إلى %3$s؟" - "‏سيتمكّن \"%1$s\" من الوصول إلى كل المحتوى المعروض أو الذي يتم تشغيله على %2$s، بما في ذلك الملفات الصوتية والصور وكلمات المرور والرسائل.<br/><br/>سيتمكّن \"%1$s\" من بث التطبيقات إلى %3$s إلى أن توقف إمكانية استخدام هذا الإذن." - "يطلب \"%1$s\" الحصول على إذن نيابةً عن %2$s لعرض التطبيقات وبثها بين أجهزتك" + + + + + + "‏هل تريد السماح لتطبيق <strong>%1$s</strong> بالوصول إلى هذه المعلومات من %2$s؟" "يطلب \"%1$s\" الحصول على إذن نيابةً عن %2$s للوصول إلى الصور والوسائط والإشعارات في %3$s" - "هل تريد السماح لجهاز %1$s ببث التطبيقات وميزات النظام من %2$s إلى %3$s؟" - "‏سيتمكّن \"%1$s\" من الوصول إلى كل المحتوى المعروض أو الذي يتم تشغيله على %2$s، بما في ذلك الملفات الصوتية والصور ومعلومات الدفع وكلمات المرور والرسائل.<br/><br/>سيتمكّن \"%1$s\" من بث التطبيقات وميزات النظام إلى %3$s إلى أن توقف إمكانية استخدام هذا الإذن." - "يطلب \"%1$s\" الحصول على إذن نيابةً عن %2$s لبثّ التطبيقات وميزات النظام الأخرى بين أجهزتك" + + + + + + "جهاز" "سيتمكّن هذا التطبيق من مزامنة المعلومات، مثل اسم المتصل، بين هاتفك والجهاز المحدّد." "السماح" diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml index 3d252ca615ed..7376cd066d00 100644 --- a/packages/CompanionDeviceManager/res/values-as/strings.xml +++ b/packages/CompanionDeviceManager/res/values-as/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong>ক <strong>%2$s</strong> পৰিচালনা কৰিবলৈ দিবনে?" "ডিভাইচ" "এই এপ্‌টোক আপোনাৰ %1$sত এই অনুমতিসমূহ এক্সেছ কৰিবলৈ অনুমতি দিয়া হ’ব" - "<strong>%1$s</strong>ক আপোনাৰ %2$sৰ এপ্‌সমূহ <strong>%3$s</strong>ত ষ্ট্ৰীম কৰিবলৈ দিবনে?" - "%1$s%2$sত দৃশ্যমান হোৱা বা প্লে’ কৰা অডিঅ’, ফট’ পাছৱৰ্ড আৰু বাৰ্তাকে ধৰি যিকোনো বস্তু এক্সেছ কৰিব পাৰিব।<br/><br/>%1$sএ আপুনি এই অনুমতিৰ এক্সেছ আঁতৰাই নিদিয়া পৰ্যন্ত %3$sত এপ্‌সমূহ ষ্ট্ৰীম কৰিব পাৰিব।" - "%1$sএ আপোনাৰ %2$sৰ হৈ আপোনাৰ ডিভাইচসমূহৰ মাজত এপ্‌সমূহ দেখুৱাবলৈ আৰু ষ্ট্ৰীম কৰিবলৈ অনুমতি বিচাৰি অনুৰোধ জনাইছে" + + + + + + "<strong>%1$s</strong>ক আপোনাৰ %2$sৰ পৰা এই তথ্যখিনি এক্সেছ কৰিবলৈ দিয়ক" "%1$sএ আপোনাৰ %2$sৰ হৈ আপোনাৰ %3$sৰ ফট’, মিডিয়া আৰু জাননী এক্সেছ কৰাৰ বাবে অনুমতি বিচাৰি অনুৰোধ জনাইছে" - "<strong>%1$s</strong>ক আপোনাৰ %2$sৰ এপ্‌সমূহ আৰু ছিষ্টেমৰ সুবিধাসমূহ <strong>%3$s</strong>ত ষ্ট্ৰীম কৰিবলৈ দিবনে?" - "%1$sএ আপোনাৰ %2$sত দৃশ্যমান বা প্লে’ কৰা অডিঅ’, ফট’ পৰিশোধৰ তথ্য, পাছৱৰ্ড আৰু বাৰ্তাকে ধৰি যিকোনো বস্তু এক্সেছ কৰিব পাৰিব।<br/><br/>%1$sএ আপুনি এই অনুমতিৰ এক্সেছ আঁতৰাই নিদিয়া পৰ্যন্ত %3$sত এপ্‌সমূহ আৰু ছিষ্টেমৰ সুবিধাসমূহ ষ্ট্ৰীম কৰিব পাৰিব।" - "%1$sএ আপোনাৰ %2$sৰ হৈ আপোনাৰ ডিভাইচসমূহৰ মাজত এপ্‌সমূহ আৰু আন ছিষ্টেমৰ সুবিধাসমূহ ষ্ট্ৰীম কৰিবলৈ অনুমতি বিচাৰি অনুৰোধ জনাইছে" + + + + + + "ডিভাইচ" "এই এপ্‌টোৱে আপোনাৰ ফ’ন আৰু বাছনি কৰা ডিভাইচটোৰ মাজত কল কৰোঁতাৰ নামৰ দৰে তথ্য ছিংক কৰিব পাৰিব" "অনুমতি দিয়ক" diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml index 2a636a95bf01..dd720935fdb9 100644 --- a/packages/CompanionDeviceManager/res/values-az/strings.xml +++ b/packages/CompanionDeviceManager/res/values-az/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong> tətbiqinə <strong>%2$s</strong> cihazını idarə etmək icazəsi verilsin?" "cihazda" "Bu tətbiq %1$s cihazında bu icazələrə daxil ola biləcək" - "<strong>%1$s</strong> üçün %2$s tətbiqlərini <strong>%3$s</strong> cihazına sinxronlaşdırmaq icazəsi verilsin?" - "%1$s audio, foto, parol və mesajlar daxil olmaqla %2$s cihazında görünən və ya oxudulan kontentə giriş əldə edəcək.<br/><br/>Siz bu icazəyə girişi silənə qədər %1$stətbiqləri %3$s cihazına yayımlaya biləcək." - "%1$s tətbiqləri göstərmək və cihazlar arasında yayımlamaq üçün %2$s adından icazə tələb edir" + + + + + + "<strong>%1$s</strong> tətbiqinə %2$s cihazından əldə edilən bu məlumata giriş icazəsi verin" "%1$s %3$s üzrə foto, media və bildirişlərə daxil olmaq üçün %2$s adından icazə tələb edir" - "<strong>%1$s</strong> üçün %2$s tətbiq və sistem funksiyalarını <strong>%3$s</strong> cihazına yayımlamaq icazəsi verilsin?" - "%1$s audio, foto, ödəniş məlumatı, parol və mesajlar daxil olmaqla %2$s cihazında görünən və ya işə salınan kontentə giriş əldə edəcək.<br/><br/>Siz bu icazəyə girişi silənə qədər %1$s tətbiq və sistem funksiyalarını %3$s cihazına yayımlaya biləcək." - "%1$s cihazlar arasında tətbiqləri və digər sistem funksiyalarını yayımlamaq üçün %2$s adından icazə tələb edir" + + + + + + "cihaz" "Tətbiq zəng edənin adı kimi məlumatları telefon ilə seçilmiş cihaz arasında sinxronlaşdıracaq" "İcazə verin" diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml index 010b59ae6b71..2200cecd0256 100644 --- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml @@ -25,17 +25,23 @@ "Želite li da dozvolite da <strong>%1$s</strong> upravlja uređajem <strong>%2$s</strong>?" "uređaj" "Ovoj aplikaciji će biti dozvoljeno da pristupa ovim dozvolama na uređaju %1$s" - "Želite li da dozvolite da <strong>%1$s</strong> strimuje aplikacije uređaja %2$s na <strong>%3$s</strong>?" - "%1$s će imati pristup svemu što se vidi ili pušta na uređaju %2$s, uključujući zvuk, slike, lozinke i poruke.<br/><br/>%1$s će moći da strimuje aplikacije na %3$s dok ne uklonite pristup ovoj dozvoli." - "%1$s traži dozvolu u ime uređaja %2$s da prikazuje i strimuje aplikacije između uređaja" + + + + + + "Dozvolite da <strong>%1$s</strong> pristupa ovim informacijama sa uređaja %2$s" "%1$s traži dozvolu u ime uređaja %2$s da pristupa slikama, medijskom sadržaju i obaveštenjima sa uređaja %3$s" - "Želite li da dozvolite da <strong>%1$s</strong> strimuje aplikacije i sistemske funkcije uređaja %2$s na <strong>%3$s</strong>?" - "%1$s će imati pristup svemu što se vidi ili pušta na uređaju %2$s, uključujući zvuk, slike, informacije o plaćanju, lozinke i poruke.<br/><br/>%1$s će moći da strimuje aplikacije i sistemske funkcije na %3$s dok ne uklonite pristup ovoj dozvoli." - "%1$s traži dozvolu u ime uređaja %2$s da strimuje aplikacije i druge sistemske funkcije između uređaja" + + + + + + "uređaj" "Ova aplikacija će moći da sinhronizuje podatke, poput imena osobe koja upućuje poziv, između telefona i odabranog uređaja" "Dozvoli" diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml index 5cc26a7f7bb4..7eca403fd5f0 100644 --- a/packages/CompanionDeviceManager/res/values-be/strings.xml +++ b/packages/CompanionDeviceManager/res/values-be/strings.xml @@ -25,17 +25,23 @@ "Дазволіць праграме <strong>%1$s</strong> кіраваць прыладай <strong>%2$s</strong>?" "прылада" "Гэта праграма будзе мець на вашай прыладзе тыпу \"%1$s\" наступныя дазволы" - "Дазволіць праграме <strong>%1$s</strong> трансліраваць праграмы прылады тыпу \"%2$s\" на прыладу <strong>%3$s</strong>?" - "Праграма \"%1$s\" будзе мець доступ да ўсяго, што паказваецца ці прайграецца на прыладзе тыпу \"%2$s\", у тым ліку да аўдыя, фота, пароляў і паведамленняў.<br/><br/>Праграма \"%1$s\" зможа трансліраваць праграмы на прыладу \"%3$s\", пакуль вы не адклічаце гэты дазвол." - "Праграма \"%1$s\" запытвае дазвол ад імя вашай прылады \"%2$s\" на паказ і трансляцыю праграм паміж прыладамі" + + + + + + "Дазвольце праграме <strong>%1$s</strong> мець доступ да гэтай інфармацыі з прылады тыпу \"%2$s\"" "Праграма \"%1$s\" запытвае дазвол ад імя вашай прылады \"%2$s\" на доступ да фота, медыяфайлаў і апавяшчэнняў на прыладзе тыпу \"%3$s\"" - "Дазволіць прыладзе <strong>%1$s</strong> трансліраваць праграмы і сістэмныя функцыі прылады тыпу \"%2$s\" на прыладу <strong>%3$s</strong>?" - "Праграма \"%1$s\" будзе мець доступ да ўсяго, што паказваецца ці прайграецца на прыладзе тыпу \"%2$s\", у тым ліку да аўдыя, фота, пароляў і паведамленняў.<br/><br/>Праграма \"%1$s\" зможа трансліраваць праграмы і сістэмныя функцыі на прыладу \"%3$s\", пакуль вы не адклічаце гэты дазвол." - "Праграма \"%1$s\" запытвае дазвол ад імя вашай прылады \"%2$s\" на трансляцыю праграм і іншых сістэмных функцый паміж прыладамі" + + + + + + "прылада" "Гэта праграма зможа сінхранізаваць інфармацыю (напрыклад, імя таго, хто звоніць) паміж тэлефонам і выбранай прыладай" "Дазволіць" diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml index 747a071699fb..3ebf375cdbee 100644 --- a/packages/CompanionDeviceManager/res/values-bg/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml @@ -25,17 +25,23 @@ "Разрешавате ли на <strong>%1$s</strong> да управлява устройството <strong>%2$s</strong>?" "устройство" "Това приложение ще има достъп до следните разрешения за вашите %1$s" - "Да се разреши ли на <strong>%1$s</strong> да предава поточно към <strong>%3$s</strong> приложенията на устройството ви от тип %2$s?" - "%1$s ще има достъп до всичко, което се показва или възпроизвежда на устройството ви от тип %2$s, включително аудио, снимки, пароли и съобщения.<br/><br/>%1$s ще може да предава поточно приложения към устройството ви %3$s, докато не премахнете това разрешение." - "%1$s иска разрешение от името на ваше устройство (%2$s) да показва и да предава поточно приложения между устройствата ви" + + + + + + "Разрешете на <strong>%1$s</strong> да осъществява достъп до тази информация от вашия %2$s" "%1$s иска разрешение от името на ваше устройство (%2$s) за достъп до снимките, мултимедията и известията на вашия %3$s" - "Да се разреши ли на <strong>%1$s</strong> да предава поточно към <strong>%3$s</strong> приложенията и системните функции на устройството ви от тип %2$s?" - "%1$s ще има достъп до всичко, което се показва или възпроизвежда на устройството ви от тип %2$s, включително аудио, снимки, данни за плащане, пароли и съобщения.<br/><br/>%1$s ще може да предава поточно приложения и системни функции към устройството ви %3$s, докато не премахнете това разрешение." - "%1$s иска разрешение от името на ваше устройство (%2$s) да предава поточно приложения и други системни функции между устройствата ви" + + + + + + "устройство" "Това приложение ще може да синхронизира различна информация, като например името на обаждащия се, между телефона ви и избраното устройство" "Разрешаване" diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml index ef9fddda2e05..d2a0353c9c9b 100644 --- a/packages/CompanionDeviceManager/res/values-bn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml @@ -25,17 +25,23 @@ "আপনি কি <strong>%1$s</strong> ম্যানেজ করার জন্য <strong>%2$s</strong>-কে অনুমতি দেবেন?" "ডিভাইস" "%1$s-এ এইসব অনুমতি অ্যাক্সেস করার জন্য এই অ্যাপকে অনুমতি দেওয়া হবে" - "আপনার %2$s-এর অ্যাপ <strong>%3$s</strong>?-এ স্ট্রিম করার জন্য <strong>%1$s</strong>-কে অনুমতি দেবেন?" - "অডিও, ফটো, পাসওয়ার্ড ও মেসেজ সহ %2$s-এ দেখা ও চালানো যায় এমন সব কিছু %1$s অ্যাক্সেস করতে পারবে।<br/><br/>আপনি এই অনুমতি না সরানো পর্যন্ত %1$s, %3$s-এ অ্যাপ স্ট্রিম করতে পারবে।" - "আপনার বিভিন্ন ডিভাইসের মধ্যে অ্যাপ, ডিসপ্লে এবং স্ট্রিম করার জন্য আপনার %2$s-এর হয়ে %1$s অনুমতি চাইছে" + + + + + + "আপনার %2$s থেকে এই তথ্য অ্যাক্সেস করার জন্য <strong>%1$s</strong>-কে অনুমতি দিন" "আপনার %3$s-এর ফটো, মিডিয়া ও বিজ্ঞপ্তি অ্যাক্সেস করার জন্য, আপনার %2$s-এর হয়ে %1$s অনুমতি চাইছে" - "আপনার %2$s-এর অ্যাপ ও সিস্টেমের ফিচার <strong>%3$s</strong>?-এ স্ট্রিম করার জন্য <strong>%1$s</strong>-কে অনুমতি দেবেন?" - "অডিও, ফটো, পেমেন্টের তথ্য, পাসওয়ার্ড ও মেসেজ সহ আপনার %2$s-এ দেখা ও চালানো যায় এমন সব কিছু %1$s অ্যাক্সেস করতে পারবে।<br/><br/>আপনি এই অনুমতি না সরানো পর্যন্ত %1$s, %3$s-এ অ্যাপ ও সিস্টেমের ফিচার স্ট্রিম করতে পারবে।" - "আপনার বিভিন্ন ডিভাইসের মধ্যে অ্যাপ ও সিস্টেমের অন্যান্য ফিচার স্ট্রিম করার জন্য, আপনার %2$s-এর হয়ে %1$s অনুমতি চাইছে" + + + + + + "ডিভাইস" "এই অ্যাপ, আপনার ফোন এবং বেছে নেওয়া ডিভাইসের মধ্যে তথ্য সিঙ্ক করতে পারবে, যেমন কোনও কলারের নাম" "অনুমতি দিন" diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml index 69ae96f8547a..84316f299808 100644 --- a/packages/CompanionDeviceManager/res/values-bs/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml @@ -25,17 +25,23 @@ "Dozvoliti aplikaciji <strong>%1$s</strong> da upravlja uređajem <strong>%2$s</strong>?" "uređaj" "Aplikaciji će biti dozvoljen pristup ovim odobrenjima koje sadržava vaš %1$s" - "Dozvoliti aplikaciji <strong>%1$s</strong> da prenosi aplikacije koje sadržava vaš %2$s na uređaju <strong>%3$s</strong>?" - "%1$s će imati pristup svemu što %2$s reproducira ili je vidljivo na njemu, uključujući zvukove, fotografije, lozinke i poruke.<br/><br/>%1$s će moći prenositi aplikacije na uređaju %3$s dok ne uklonite pristup ovom odobrenju." - "Aplikacija %1$s traži odobrenje u ime vašeg uređaja %2$s da prikazuje i prenosi aplikacije između vaših uređaja" + + + + + + "Dozvolite aplikaciji <strong>%1$s</strong> da pristupa ovim informacijama koje sadržava vaš %2$s" "Aplikacija %1$s traži odobrenje u ime vašeg uređaja %2$s da pristupa fotografijama, medijima i obavještenjima koje sadržava vaš %3$s" - "Dozvoliti uređaju <strong>%1$s</strong> da prenosi aplikacije i funkcije sistema koje sadržava vaš %2$s na uređaju <strong>%3$s</strong>?" - "%1$s će imati pristup svemu što %2$s reproducira ili je vidljivo na njemu, uključujući zvukove, fotografije, podatke o plaćanju, lozinke i poruke.<br/><br/>%1$s će moći prenositi aplikacije i funkcije sistema na uređaju %3$s dok ne uklonite pristup ovom odobrenju." - "Aplikacija %1$s traži odobrenje u ime vašeg uređaja %2$s da prenosi aplikacije i druge funkcije sistema između vaših uređaja" + + + + + + "uređaj" "Ova aplikacija će moći sinhronizirati informacije, kao što je ime osobe koja upućuje poziv, između vašeg telefona i odabranog uređaja" "Dozvoli" diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml index f8c408437572..8b115f74b3b5 100644 --- a/packages/CompanionDeviceManager/res/values-ca/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml @@ -25,19 +25,23 @@ "Permet que <strong>%1$s</strong> gestioni <strong>%2$s</strong>" "dispositiu" "Aquesta aplicació podrà accedir a aquests permisos del %1$s" - "Vols permetre que <strong>%1$s</strong> reprodueixi en continu les aplicacions del %2$s a <strong>%3$s<strong>?" - "%1$s podrà accedir a qualsevol cosa que sigui visible o que es reprodueixi al %2$s, inclosos àudios, fotos, contrasenyes i missatges.<br/><br/>%1$s podrà reproduir en continu aplicacions a %3$s fins que suprimeixis l\'accés a aquest permís." - "%1$s demana permís en nom del teu dispositiu %2$s per mostrar i reproduir en continu aplicacions entre els dispositius" + + + + + + "Permet que <strong>%1$s</strong> accedeixi a aquesta informació del %2$s" "%1$s demana permís en nom del teu dispositiu %2$s per accedir a les fotos, el contingut multimèdia i les notificacions del %3$s" - "Vols permetre que <strong>%1$s</strong> reprodueixi en continu les aplicacions i les funcions del sistema del %2$s a %3$s?" - - + + + + + - "%1$s demana permís en nom del teu dispositiu %2$s per reproduir en continu aplicacions i altres funcions del sistema entre els dispositius" "dispositiu" "Aquesta aplicació podrà sincronitzar informació, com ara el nom d\'algú que truca, entre el teu telèfon i el dispositiu triat" "Permet" diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml index 04e73800570b..7bd6e38a919b 100644 --- a/packages/CompanionDeviceManager/res/values-cs/strings.xml +++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml @@ -25,17 +25,23 @@ "Povolit aplikaci <strong>%1$s</strong> spravovat zařízení <strong>%2$s</strong>?" "zařízení" "Tato aplikace bude mít na zařízení typu %1$s přístup k následujícím oprávněním" - "Povolit aplikaci <strong>%1$s</strong> streamovat aplikace na zařízení typu %2$s do zařízení <strong>%3$s</strong>?" - "Aplikace %1$s bude mít přístup ke všemu, co na zařízení typu %2$s zobrazíte nebo přehrajete, včetně zvuku, fotek, hesel a zpráv.<br/><br/>Aplikace %1$s bude moct streamovat aplikace do zařízení typu %3$s, dokud přístup k tomuto oprávnění neodeberete." - "Aplikace %1$s požaduje za vaše zařízení %2$s oprávnění k zobrazení a streamování obsahu mezi zařízeními" + + + + + + "Povolte aplikaci <strong>%1$s</strong> přístup k těmto informacím z vašeho zařízení typu %2$s" "Aplikace %1$s požaduje za vaše zařízení %2$s oprávnění k přístupu k fotkám, médiím a oznámením na zařízení typu %3$s" - "Povolit aplikaci <strong>%1$s</strong> streamovat aplikace a systémové funkce ze zařízení typu %2$s do zařízení <strong>%3$s</strong>?" - "Aplikace %1$s bude mít přístup ke všemu, co na zařízení typu %2$s zobrazíte nebo přehrajete, včetně zvuku, fotek, platebních údajů, hesel a zpráv.<br/><br/>Aplikace %1$s bude moct streamovat aplikace a systémové funkce do zařízení typu %3$s, dokud přístup k tomuto oprávnění neodeberete." - "Aplikace %1$s požaduje za vaše zařízení %2$s oprávnění ke streamování aplikací a dalších systémových funkcí mezi zařízeními" + + + + + + "zařízení" "Tato aplikace bude moci synchronizovat údaje, jako je jméno volajícího, mezi vaším telefonem a vybraným zařízením" "Povolit" diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml index d948804ae36a..4180ef5baa7d 100644 --- a/packages/CompanionDeviceManager/res/values-da/strings.xml +++ b/packages/CompanionDeviceManager/res/values-da/strings.xml @@ -25,17 +25,23 @@ "Vil du tillade, at <strong>%1$s</strong> administrerer <strong>%2$s</strong>?" "enhed" "Denne app får adgang til disse tilladelser på din %1$s" - "Vil du give <strong>%1$s</strong> tilladelse til at streame apps fra din %2$s til <strong>%3$s</strong>?" - "%1$s får adgang til alt, der er synligt eller afspilles på din %2$s, herunder lyd, billeder, adgangskoder og beskeder.<br/><br/>%1$s kan streame apps til %3$s, indtil du fjerner adgangen til denne tilladelse." - "%1$s anmoder om tilladelse på vegne af din %2$s til at vise og streame apps mellem dine enheder" + + + + + + "Giv <strong>%1$s</strong> adgang til disse oplysninger fra din %2$s" "%1$s anmoder om tilladelse på vegne af din %2$s til at få adgang til billeder, medier og notifikationer på din %3$s" - "Vil du give <strong>%1$s</strong> tilladelse til at streame apps og systemfunktioner fra din %2$s til <strong>%3$s</strong>?" - "%1$s får adgang til alt, der er synligt eller afspilles på din %2$s, herunder lyd, billeder, betalingsoplysninger, adgangskoder og beskeder.<br/><br/>%1$s kan streame apps og systemfunktioner til %3$s, indtil du fjerner adgangen til denne tilladelse." - "%1$s anmoder om tilladelse på vegne af din %2$s til at streame apps og andre systemfunktioner mellem dine enheder" + + + + + + "enhed" "Denne app vil kunne synkronisere oplysninger som f.eks. navnet på en person, der ringer, mellem din telefon og den valgte enhed" "Tillad" diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml index 8d65f68475fc..725a42d92b59 100644 --- a/packages/CompanionDeviceManager/res/values-de/strings.xml +++ b/packages/CompanionDeviceManager/res/values-de/strings.xml @@ -25,17 +25,23 @@ "Zulassen, dass <strong>%1$s</strong> das Gerät <strong>%2$s</strong> verwalten darf?" "Gerät" "Diese App darf dann auf diese Berechtigungen auf deinem Gerät (%1$s) zugreifen:" - "<strong>%1$s</strong> erlauben, die Apps auf deinem Gerät (%2$s) auf <strong>%3$s</strong> zu streamen?" - "%1$s hat dann Zugriff auf alle Inhalte, die auf deinem Gerät (%2$s) sichtbar sind oder abgespielt werden, einschließlich Audioinhalten, Fotos, Zahlungsinformationen, Passwörter und Nachrichten.<br/><br/>%1$s kann so lange Apps auf „%3$s“ streamen, bis du diese Berechtigung entfernst." - "%1$s bittet im Namen von „%2$s“ um die Berechtigung, Apps zwischen deinen Geräten anzuzeigen und zu streamen" + + + + + + "<strong>%1$s</strong> Zugriff auf diese Informationen von deinem Gerät (%2$s) gewähren" "%1$s bittet im Namen von „%2$s“ um die Berechtigung, auf die Fotos, Medien und Benachrichtigungen auf deinem Gerät (%3$s) zuzugreifen" - "<strong>%1$s</strong> erlauben, die Apps und Systemfunktionen auf deinem Gerät (%2$s) auf <strong>%3$s</strong> zu streamen?" - "%1$s hat dann Zugriff auf alle Inhalte, die auf deinem Gerät (%2$s) sichtbar sind oder abgespielt werden, einschließlich Audioinhalten, Fotos, Zahlungsinformationen, Passwörter und Nachrichten.<br/><br/>%1$s kann so lange Apps und Systemfunktionen auf „%3$s“ streamen, bis du diese Berechtigung entfernst." - "%1$s bittet im Namen von „%2$s“ um die Berechtigung, Apps und andere Systemfunktionen zwischen deinen Geräten zu streamen" + + + + + + "Gerät" "Diese App kann dann Daten wie den Namen eines Anrufers zwischen deinem Smartphone und dem ausgewählten Gerät synchronisieren" "Zulassen" diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml index 4a186d52dc03..57aebc3a90aa 100644 --- a/packages/CompanionDeviceManager/res/values-el/strings.xml +++ b/packages/CompanionDeviceManager/res/values-el/strings.xml @@ -25,17 +25,23 @@ "Να επιτρέπεται στην εφαρμογή <strong>%1$s</strong> να διαχειρίζεται τη συσκευή <strong>%2$s</strong> ;" "συσκευή" "Αυτή η εφαρμογή θα μπορεί να έχει πρόσβαση σε αυτές τις άδειες στη συσκευή %1$s" - "Να επιτρέπεται στην εφαρμογή <strong>%1$s</strong> να κάνει ροή των εφαρμογών της συσκευής %2$s στη συσκευή <strong>%3$s</strong>;" - "Η εφαρμογή %1$s θα έχει πρόσβαση σε οτιδήποτε είναι ορατό ή αναπαράγεται στη συσκευή %2$s, συμπεριλαμβανομένων ήχων, φωτογραφιών, κωδικών πρόσβασης και μηνυμάτων.<br/><br/>Η εφαρμογή %1$s θα μπορεί να κάνει ροή εφαρμογών στη συσκευή %3$s, μέχρι να καταργήσετε την πρόσβαση σε αυτή την άδεια." - "Η εφαρμογή %1$s ζητά άδεια εκ μέρους της συσκευής %2$s για προβολή και ροή εφαρμογών μεταξύ των συσκευών σας" + + + + + + "Να επιτρέπεται στην εφαρμογή <strong>%1$s</strong> η πρόσβαση σε αυτές τις πληροφορίες από τη συσκευή σας %2$s." "Η εφαρμογή %1$s ζητά άδεια εκ μέρους της συσκευής σας %2$s, για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις της συσκευής %3$s" - "Να επιτρέπεται στη συσκευή <strong>%1$s</strong> να κάνει ροή των εφαρμογών και των λειτουργιών συστήματος της συσκευής %2$s στη συσκευή <strong>%3$s</strong>;" - "Η εφαρμογή %1$s θα έχει πρόσβαση σε οτιδήποτε είναι ορατό ή αναπαράγεται στη συσκευή %2$s, συμπεριλαμβανομένων ήχων, φωτογραφιών, στοιχείων πληρωμής, κωδικών πρόσβασης και μηνυμάτων.<br/><br/>Η εφαρμογή %1$s θα μπορεί να κάνει ροή εφαρμογών και λειτουργιών συστήματος στη συσκευή %3$s, μέχρι να καταργήσετε την πρόσβαση σε αυτή την άδεια." - "Η εφαρμογή %1$s ζητά άδεια εκ μέρους της συσκευής σας %2$s για ροή εφαρμογών και άλλων λειτουργιών συστήματος μεταξύ των συσκευών σας" + + + + + + "συσκευή" "Αυτή η εφαρμογή θα μπορεί να συγχρονίζει πληροφορίες μεταξύ του τηλεφώνου και της επιλεγμένης συσκευής σας, όπως το όνομα ενός ατόμου που σας καλεί." "Να επιτρέπεται" diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml index 346758a9518f..0a8542819ed5 100644 --- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml @@ -25,17 +25,23 @@ "Allow <strong>%1$s</strong> to manage <strong>%2$s</strong>?" "device" "This app will be allowed to access these permissions on your %1$s" - "Allow <strong>%1$s</strong> to stream your %2$s\'s apps to <strong>%3$s</strong>?" - "%1$s will have access to anything that\'s visible or played on the %2$s, including audio, photos, passwords and messages.<br/><br/>%1$s will be able to stream apps to %3$s until you remove access to this permission." - "%1$s is requesting permission on behalf of your %2$s to display and stream apps between your devices" + + + + + + "Allow <strong>%1$s</strong> to access this information from your %2$s" "%1$s is requesting permission on behalf of your %2$s to access your %3$s\'s photos, media and notifications" - "Allow <strong>%1$s</strong> to stream your %2$s\'s apps and system features to <strong>%3$s</strong>?" - "%1$s will have access to anything that\'s visible or played on your %2$s, including audio, photos, payment info, passwords and messages.<br/><br/>%1$s will be able to stream apps and system features to %3$s until you remove access to this permission." - "%1$s is requesting permission on behalf of your %2$s to stream apps and other system features between your devices" + + + + + + "device" "This app will be able to sync info, like the name of someone calling, between your phone and the chosen device" "Allow" diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml index 5716476d5fa3..c40018ffe862 100644 --- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml @@ -25,17 +25,17 @@ "Allow <strong>%1$s</strong> to manage <strong>%2$s</strong>?" "device" "This app will be allowed to access these permissions on your %1$s" - "Allow <strong>%1$s</strong> to stream your %2$s’s apps to <strong>%3$s</strong>?" - "%1$s will have access to anything that’s visible or played on the %2$s, including audio, photos, passwords, and messages.<br/><br/>%1$s will be able to stream apps to %3$s until you remove access to this permission." - "%1$s is requesting permission on behalf of your %2$s to display and stream apps between your devices" + "Allow <strong>%1$s</strong> to stream your %2$s’s apps and system features to <strong>%3$s</strong>?" + "%1$s will have access to anything that’s visible or played on your %2$s, including audio, photos, payment info, passwords, and messages.<br/><br/>%1$s will be able to stream apps to %3$s until you remove access to this permission." + "%1$s is requesting permission on behalf of %2$s to stream apps and system features from your %3$s" "Allow <strong>%1$s</strong> to access this information from your %2$s" "%1$s is requesting permission on behalf of your %2$s to access your %3$s’s photos, media, and notifications" - "Allow <strong>%1$s</strong> to stream your %2$s’s apps and system features to <strong>%3$s</strong>?" - "%1$s will have access to anything that’s visible or played on your %2$s, including audio, photos, payment info, passwords, and messages.<br/><br/>%1$s will be able to stream apps and system features to %3$s until you remove access to this permission." - "%1$s is requesting permission on behalf of your %2$s to stream apps and other system features between your devices" + "Allow <strong>%1$s</strong> to stream your %2$s’s apps to <strong>%3$s</strong>?" + "%1$s will have access to anything that’s visible or played on %3$s, including audio, photos, payment info, passwords, and messages.<br/><br/>%1$s will be able to stream apps to %3$s until you remove access to this permission." + "%1$s is requesting permission on behalf of %2$s to stream apps from your %3$s" "device" "This app will be able to sync info, like the name of someone calling, between your phone and the chosen device" "Allow" diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml index 346758a9518f..0a8542819ed5 100644 --- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml @@ -25,17 +25,23 @@ "Allow <strong>%1$s</strong> to manage <strong>%2$s</strong>?" "device" "This app will be allowed to access these permissions on your %1$s" - "Allow <strong>%1$s</strong> to stream your %2$s\'s apps to <strong>%3$s</strong>?" - "%1$s will have access to anything that\'s visible or played on the %2$s, including audio, photos, passwords and messages.<br/><br/>%1$s will be able to stream apps to %3$s until you remove access to this permission." - "%1$s is requesting permission on behalf of your %2$s to display and stream apps between your devices" + + + + + + "Allow <strong>%1$s</strong> to access this information from your %2$s" "%1$s is requesting permission on behalf of your %2$s to access your %3$s\'s photos, media and notifications" - "Allow <strong>%1$s</strong> to stream your %2$s\'s apps and system features to <strong>%3$s</strong>?" - "%1$s will have access to anything that\'s visible or played on your %2$s, including audio, photos, payment info, passwords and messages.<br/><br/>%1$s will be able to stream apps and system features to %3$s until you remove access to this permission." - "%1$s is requesting permission on behalf of your %2$s to stream apps and other system features between your devices" + + + + + + "device" "This app will be able to sync info, like the name of someone calling, between your phone and the chosen device" "Allow" diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml index 346758a9518f..0a8542819ed5 100644 --- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml @@ -25,17 +25,23 @@ "Allow <strong>%1$s</strong> to manage <strong>%2$s</strong>?" "device" "This app will be allowed to access these permissions on your %1$s" - "Allow <strong>%1$s</strong> to stream your %2$s\'s apps to <strong>%3$s</strong>?" - "%1$s will have access to anything that\'s visible or played on the %2$s, including audio, photos, passwords and messages.<br/><br/>%1$s will be able to stream apps to %3$s until you remove access to this permission." - "%1$s is requesting permission on behalf of your %2$s to display and stream apps between your devices" + + + + + + "Allow <strong>%1$s</strong> to access this information from your %2$s" "%1$s is requesting permission on behalf of your %2$s to access your %3$s\'s photos, media and notifications" - "Allow <strong>%1$s</strong> to stream your %2$s\'s apps and system features to <strong>%3$s</strong>?" - "%1$s will have access to anything that\'s visible or played on your %2$s, including audio, photos, payment info, passwords and messages.<br/><br/>%1$s will be able to stream apps and system features to %3$s until you remove access to this permission." - "%1$s is requesting permission on behalf of your %2$s to stream apps and other system features between your devices" + + + + + + "device" "This app will be able to sync info, like the name of someone calling, between your phone and the chosen device" "Allow" diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml index 6c6a000e19ff..80b02cbd490a 100644 --- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml @@ -25,17 +25,17 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‎Allow <strong>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</strong> to manage <strong>‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎</strong>?‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎device‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎This app will be allowed to access these permissions on your ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‎‎‎‎Allow <strong>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</strong> to stream your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎’s apps to <strong>‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎</strong>?‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ will have access to anything that’s visible or played on the ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎, including audio, photos, passwords, and messages.<br/><br/>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ will be able to stream apps to ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ until you remove access to this permission.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ to display and stream apps between your devices‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎Allow <strong>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</strong> to stream your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎’s apps and system features to <strong>‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎</strong>?‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ will have access to anything that’s visible or played on your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎, including audio, photos, payment info, passwords, and messages.<br/><br/>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ will be able to stream apps to ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ until you remove access to this permission.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ is requesting permission on behalf of ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ to stream apps and system features from your ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎Allow <strong>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</strong> to access this information from your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ to access your ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎’s photos, media, and notifications‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎‏‎‎‎‎Allow <strong>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</strong> to stream your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎’s apps and system features to <strong>‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎</strong>?‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ will have access to anything that’s visible or played on your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎, including audio, photos, payment info, passwords, and messages.<br/><br/>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ will be able to stream apps and system features to ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ until you remove access to this permission.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‏‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ to stream apps and other system features between your devices‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‎Allow <strong>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</strong> to stream your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎’s apps to <strong>‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎</strong>?‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ will have access to anything that’s visible or played on ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎, including audio, photos, payment info, passwords, and messages.<br/><br/>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ will be able to stream apps to ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ until you remove access to this permission.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ is requesting permission on behalf of ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ to stream apps from your ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎device‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎This app will be able to sync info, like the name of someone calling, between your phone and the chosen device‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎Allow‎‏‎‎‏‎" diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml index 63d57c40aa5a..9f6219274258 100644 --- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml +++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml @@ -25,17 +25,23 @@ "Permite que <strong>%1$s</strong> administre <strong>%2$s</strong>?" "dispositivo" "Esta app podrá acceder a los siguientes permisos en tu %1$s" - "¿Quieres permitir que <strong>%1$s</strong> transmita las apps de %2$s a <strong>%3$s</strong>?" - "%1$s tendrá acceso a todo el contenido visible o que se reproduzca en %2$s, lo que incluye audio, fotos, contraseñas y mensajes.<br/><br/>%1$s podrá transmitir apps a %3$s hasta que se quite el acceso a este permiso." - "%1$s solicita tu permiso en nombre de %2$s para mostrar y transmitir apps entre dispositivos" + + + + + + "Permite que <strong>%1$s</strong> acceda a esta información de tu %2$s" "%1$s solicita tu permiso en nombre de %2$s para acceder a las fotos, el contenido multimedia y las notificaciones de tu %3$s" - "¿Quieres permitir que <strong>%1$s</strong> transmita las apps y las funciones del sistema de %2$s a <strong>%3$s</strong>?" - "%1$s tendrá acceso a todo el contenido visible o que se reproduzca en tu %2$s, lo que incluye audio, fotos, información de pago, contraseñas y mensajes.<br/><br/>%1$s podrá transmitir apps y funciones del sistema a %3$s hasta que se quite el acceso a este permiso." - "%1$s solicita tu permiso en nombre de %2$s para transmitir apps y otras funciones del sistema entre dispositivos" + + + + + + "dispositivo" "Esta app podrá sincronizar información, como el nombre de la persona que llama, entre el teléfono y el dispositivo elegido" "Permitir" diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml index f929d24fa081..44474b96b44c 100644 --- a/packages/CompanionDeviceManager/res/values-es/strings.xml +++ b/packages/CompanionDeviceManager/res/values-es/strings.xml @@ -25,17 +25,23 @@ "¿Permitir que <strong>%1$s</strong> gestione <strong>%2$s</strong>?" "dispositivo" "Esta aplicación podrá acceder a estos permisos de tu %1$s" - "¿Permitir que <strong>%1$s</strong> emita las aplicaciones de tu %2$s en <strong>%3$s</strong>?" - "%1$s tendrá acceso a todo lo que se vea o se reproduzca en tu %2$s, incluidos audio, fotos, contraseñas y mensajes.<br/><br/>%1$s podrá emitir aplicaciones en %3$s hasta que quites el acceso a este permiso." - "%1$s está pidiendo permiso en nombre de tu %2$s para mostrar y emitir aplicaciones en otros dispositivos tuyos" + + + + + + "Permitir que <strong>%1$s</strong> acceda a esta información de tu %2$s" "%1$s está pidiendo permiso en nombre de tu %2$s para acceder a las fotos, los archivos multimedia y las notificaciones de tu %3$s" - "¿Permitir que <strong>%1$s</strong> emita las aplicaciones y funciones del sistema de tu%2$s en <strong>%3$s</strong>?" - "%1$s tendrá acceso a todo lo que se vea o se reproduzca en tu %2$s, incluidos audio, fotos, información para pagos, contraseñas y mensajes.<br/><br/>%1$s podrá emitir aplicaciones y funciones del sistema en %3$s hasta que quites el acceso a este permiso." - "%1$s está pidiendo permiso en nombre de tu %2$s para emitir aplicaciones y otras funciones del sistema en otros dispositivos tuyos" + + + + + + "dispositivo" "Esta aplicación podrá sincronizar información (por ejemplo, el nombre de la persona que te llama) entre tu teléfono y el dispositivo que elijas" "Permitir" diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml index 5fcadcc9774e..a1cb0c6e857d 100644 --- a/packages/CompanionDeviceManager/res/values-et/strings.xml +++ b/packages/CompanionDeviceManager/res/values-et/strings.xml @@ -25,17 +25,23 @@ "Lubage rakendusel <strong>%1$s</strong> hallata seadet <strong>%2$s</strong>?" "seade" "Sellel rakendusel lubatakse juurde pääseda nendele lubadele, mille asukoht on teie %1$s" - "Kas lubate rakendusel <strong>%1$s</strong> voogesitada seadmes <strong>%3$s</strong> rakendusi, mille asukoht on teie %2$s?" - "%1$s saab juurdepääsu kõigele, mida teie %2$s saab kuvada või esitada sh heli, fotod, paroolid ja sõnumid.<br/><br/>%1$s saab voogesitada rakendusi ja süsteemifunktsioone seadmes %3$s, kuni eemaldate juurdepääsu sellele loale." - "Rakendus %1$s taotleb teie seadme %2$s nimel luba teie seadmete vahel rakendusi kuvada ja voogesitada" + + + + + + "Lubage rakendusel <strong>%1$s</strong> pääseda juurde sellele teabele, mille asukoht on teie %2$s" "Rakendus %1$s taotleb teie seadme %2$s nimel luba pääseda juurde fotodele, meediale ja märguannetele, mille asukoht on teie %3$s" - "Kas lubate rakendusel <strong>%1$s</strong> voogesitada seadmes <strong>%3$s</strong> rakendusi ja süsteemifunktsioone, mille asukoht on teie %2$s?" - "%1$s saab juurdepääsu kõigele, mida teie %2$s saab kuvada või esitada, sh heli, fotod, makseteave, paroolid ja sõnumid.<br/><br/>%1$s saab voogesitada rakendusi ja süsteemifunktsioone seadmes %3$s, kuni eemaldate juurdepääsu sellele loale." - "Rakendus %1$s taotleb teie seadme %2$s nimel luba voogesitada teie seadmete vahel rakendusi ja muid süsteemifunktsioone" + + + + + + "seade" "See rakendus saab sünkroonida teavet, näiteks helistaja nime, teie telefoni ja valitud seadme vahel" "Luba" diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml index 46da125399aa..f88af3ce76e5 100644 --- a/packages/CompanionDeviceManager/res/values-eu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml @@ -25,17 +25,23 @@ "<strong>%2$s</strong> kudeatzeko baimena eman nahi diozu <strong>%1$s</strong> aplikazioari?" "gailua" "Baimen hauek izango ditu aplikazioak %1$s erabiltzean:" - "<strong>%1$s</strong> aplikazioari zure %2$s gailuko aplikazioak %3$s gailura zuzenean igortzeko baimena eman nahi diozu?" - "%1$s aplikazioak %2$s gailuan ikusgai dagoen edo erreproduzitzen den eduki guztia atzitu ahal izango du, audioa, argazkiak, pasahitzak eta mezuak barne.<br/><br/>%1$s %3$s gailura aplikazioak zuzenean igortzeko gai izango da, baimen hori kentzen diozun arte." - "Aplikazioak gailuen artean bistaratzeko eta zuzenean igortzeko baimena eskatzen ari da %1$s, %2$s gailuaren izenean" + + + + + + "Eman informazioa %2$s gailutik hartzeko baimena <strong>%1$s</strong> aplikazioari" "%3$s gailuko argazkiak, multimedia-edukia eta jakinarazpenak atzitzeko baimena eskatzen ari da %1$s, %2$s gailuaren izenean" - "<strong>%1$s</strong> aplikazioari zure %2$s gailuko aplikazioak eta sistemaren eginbideak %3$s gailura zuzenean igortzeko baimena eman nahi diozu?" - "%1$s aplikazioak %2$s gailuan ikusgai dagoen edo erreproduzitzen den eduki guztia atzitu ahal izango du, audioa, argazkiak, ordainketa-informazioa, pasahitzak eta mezuak barne.<br/><br/>%1$s %3$s gailura aplikazioak eta sistemaren eginbideak zuzenean igortzeko gai izango da, baimen hori kentzen diozun arte." - "Aplikazioak eta sistemaren beste eginbide batzuk zure gailuen artean igortzeko baimena eskatzen ari da %1$s, %2$s gailuaren izenean" + + + + + + "gailua" "Telefonoaren eta hautatutako gailuaren artean informazioa sinkronizatzeko gai izango da aplikazioa (esate baterako, deitzaileen izenak)" "Eman baimena" diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml index 6a651d9738f0..9066c6a1cb7c 100644 --- a/packages/CompanionDeviceManager/res/values-fa/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml @@ -25,17 +25,23 @@ "‏به <strong>%1$s</strong> اجازه داده شود <strong>%2$s</strong> را مدیریت کند؟" "دستگاه" "این برنامه قادر خواهد بود به این اجازه‌ها در %1$s شما دسترسی پیدا کند" - "‏به <strong>%1$s</strong> اجازه می‌دهید برنامه‌های %2$s را در <strong>%3$s</strong> جاری‌سازی کند؟" - "‏‫%1$s به هرچیزی که در %2$s نمایان است یا پخش می‌شود، ازجمله صداها، عکس‌ها، گذرواژه‌ها، و پیام‌ها دسترسی خواهد داشت.<br/><br/>تا زمانی‌که دسترسی به این اجازه را حذف نکنید، %1$s می‌تواند برنامه‌ها را در %3$s جاری‌سازی کند." - "‫%1$s ازطرف %2$s اجازه می‌خواهد برنامه‌ها را بین دستگاه‌های شما نمایش دهد و جاری‌سازی کند" + + + + + + "‏اجازه دادن به <strong>%1$s</strong> برای دسترسی به این اطلاعات در %2$s شما" "‫%1$s ازطرف %2$s اجازه می‌خواهد به عکس‌ها، رسانه‌ها، و اعلان‌های %3$s شما دسترسی پیدا کند" - "‏به <strong>%1$s</strong> اجازه می‌دهید برنامه‌ها و ویژگی‌های سیستم %2$s را در <strong>%3$s</strong> جاری‌سازی کند؟" - "‏‫%1$s به هرچیزی که در %2$s شما نمایان است یا پخش می‌شود، ازجمله صداها، عکس‌ها، اطلاعات پرداخت، گذرواژه‌ها، و پیام‌ها دسترسی خواهد داشت.<br/><br/>تا زمانی‌که دسترسی به این اجازه را حذف نکنید، %1$s می‌تواند برنامه‌ها و ویژگی‌های سیستم را در %3$s جاری‌سازی کند." - "‫%1$s ازطرف %2$s اجازه می‌خواهد برنامه‌ها و دیگر ویژگی‌های سیستم را بین دستگاه‌های شما جاری‌سازی کند" + + + + + + "دستگاه" "این برنامه مجاز می‌شود اطلاعتی مثل نام شخصی را که تماس می‌گیرد بین تلفن شما و دستگاه انتخاب‌شده همگام‌سازی کند" "اجازه دادن" diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml index 5626f0a788aa..e155077142b0 100644 --- a/packages/CompanionDeviceManager/res/values-fi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml @@ -25,17 +25,23 @@ "Salli, että <strong>%1$s</strong> saa ylläpitää laitetta: <strong>%2$s</strong>" "laite" "Sovellus saa käyttää näitä lupia %1$s" - "Saako <strong>%1$s</strong> striimata %2$s olevia sovelluksia laitteelle (<strong>%3$s</strong>)?" - "%1$s saa pääsyn kaikkeen %2$s näkyvään tai pelattavaan sisältöön, mukaan lukien audioon, kuviin, salasanoihin ja viesteihin.<br/><br/>%1$s voi striimata sovelluksia laitteelle (%3$s), kunnes poistat luvan." - "%1$s pyytää laitteesi (%2$s) puolesta lupaa näyttää ja striimata sovelluksia laitteidesi välillä" + + + + + + "Salli, että <strong>%1$s</strong> saa pääsyn näihin %2$s oleviin tietoihin" "%1$s pyytää laitteesi (%2$s) puolesta lupaa päästä %3$s oleviin kuviin, mediaan ja ilmoituksiin" - "Saako <strong>%1$s</strong> striimata %2$s olevia sovelluksia ja järjestelmäominaisuuksia laitteelle (<strong>%3$s</strong>)?" - "%1$s saa pääsyn kaikkeen %2$s näkyvään tai pelattavaan sisältöön, mukaan lukien audioon, kuviin, maksutietoihin, salasanoihin ja viesteihin.<br/><br/>%1$s voi striimata sovelluksia ja järjestelmäominaisuuksia laitteelle (%3$s), kunnes poistat luvan." - "%1$s pyytää laitteesi (%2$s) puolesta lupaa striimata sovelluksia ja muita järjestelmän ominaisuuksia laitteidesi välillä" + + + + + + "laite" "Sovellus voi synkronoida tietoja (esimerkiksi soittajan nimen) puhelimesi ja valitun laitteen välillä" "Salli" diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml index 61a8b735fd6d..b5de650d356b 100644 --- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml @@ -25,17 +25,23 @@ "Autoriser <strong>%1$s</strong> à gérer <strong>%2$s</strong>?" "appareil" "Cette appli pourra accéder à ces autorisations sur votre %1$s" - "Autoriser <strong>%1$s</strong> à diffuser les applis de votre %2$s vers <strong>%3$s</strong>?" - "%1$s aura accès à tout ce qui est visible ou lu sur votre%2$s, y compris le contenu audio, les photos, les mots de passe et les messages.<br/><br/>%1$s pourra diffuser des applis vers %3$s jusqu\'à ce que vous retiriez l\'accès à cette autorisation." - "%1$s demande l\'autorisation au nom de votre %2$s pour afficher et diffuser des applis entre vos appareils" + + + + + + "Autoriser <strong>%1$s</strong> à accéder à ces informations à partir de votre %2$s" "%1$s demande l\'autorisation au nom de votre %2$s pour accéder aux photos, aux fichiers multimédias et aux notifications de votre %3$s" - "Autoriser <strong>%1$s</strong> à diffuser les applis et les fonctionnalités du système de votre %2$s vers <strong>%3$s</strong>?" - "%1$s aura accès à tout ce qui est visible ou lu sur votre %2$s, y compris le contenu audio, les photos, les infos de paiement, les mots de passe et les messages.<br/><br/>%1$s pourra diffuser des applis et des fonctionnalités du système vers %3$s jusqu\'à ce que vous retiriez l\'accès à cette autorisation." - "%1$s demande l\'autorisation au nom de votre %2$s pour diffuser des applis et d\'autres fonctionnalités du système entre vos appareils" + + + + + + "appareil" "Cette appli pourra synchroniser des informations, comme le nom de l\'appelant, entre votre téléphone et l\'appareil sélectionné" "Autoriser" diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml index b3193648a00f..b4933ee2279f 100644 --- a/packages/CompanionDeviceManager/res/values-fr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml @@ -25,17 +25,23 @@ "Autoriser <strong>%1$s</strong> à gérer <strong>%2$s</strong> ?" "appareil" "Cette appli sera autorisée à accéder à ces autorisations sur votre %1$s" - "Autoriser <strong>%1$s</strong> à caster les applis de votre %2$s sur <strong>%3$s</strong> ?" - "%1$s aura accès à tout ce qui est visible ou lu sur votre %2$s, y compris les contenus audio, les photos, les mots de passe et les messages.<br/><br/>%1$s pourra caster des applis sur %3$s jusqu\'à ce que vous supprimiez l\'accès à cette autorisation." - "%1$s demande l\'autorisation au nom de votre %2$s pour afficher et caster des applis d\'un appareil à l\'autre" + + + + + + "Autoriser <strong>%1$s</strong> à accéder à ces informations depuis votre %2$s" "%1$s demande l\'autorisation au nom de votre %2$s pour accéder aux photos, multimédias et notifications de votre %3$s" - "Autoriser <strong>%1$s</strong> à caster les applis et les fonctionnalités système de votre %2$s sur <strong>%3$s</strong> ?" - "%1$s aura accès à tout ce qui est visible ou lu sur votre %2$s, y compris les contenus audio, les photos, les infos de paiement, les mots de passe et les messages.<br/><br/>%1$s pourra caster des applis et des fonctionnalités système sur %3$s jusqu\'à ce que vous supprimiez l\'accès à cette autorisation." - "%1$s demande l\'autorisation au nom de votre %2$s pour caster des applis et d\'autres fonctionnalités système d\'un appareil à l\'autre" + + + + + + "appareil" "Cette appli pourra synchroniser des infos, comme le nom de l\'appelant, entre votre téléphone et l\'appareil choisi" "Autoriser" diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml index ccab521efd76..85bfdc0f33a5 100644 --- a/packages/CompanionDeviceManager/res/values-gl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml @@ -25,17 +25,23 @@ "Queres permitir que <strong>%1$s</strong> xestione o dispositivo (<strong>%2$s</strong>)?" "dispositivo" "Esta aplicación poderá acceder a estes permisos do dispositivo (%1$s)" - "Queres permitir que <strong>%1$s</strong> emita as aplicacións do dispositivo (%2$s) en <strong>%3$s</strong>?" - "%1$s terá acceso a todo o que se vexa ou reproduza no dispositivo (%2$s), como audio, fotos, contrasinais e mensaxes.<br/><br/>%1$s poderá emitir aplicacións en %3$s ata que quites o acceso a este permiso." - "%1$s está solicitando permiso en nome do teu dispositivo (%2$s) para mostrar e emitir aplicacións entre dispositivos" + + + + + + "Permitir que <strong>%1$s</strong> acceda a esta información do dispositivo (%2$s)" "%1$s está solicitando permiso en nome do teu dispositivo (%2$s) para acceder ás fotos, ao contido multimedia e ás notificacións do seguinte aparello: %3$s" - "Queres permitir que <strong>%1$s</strong> emita as aplicacións e as funcións do sistema do dispositivo (%2$s) en <strong>%3$s</strong>?" - "%1$s terá acceso a todo o que se vexa ou reproduza no dispositivo (%2$s), como audio, fotos, contrasinais e mensaxes.<br/><br/>%1$s poderá emitir aplicacións e outras funcións do sistema en %3$s ata que quites o acceso a este permiso." - "%1$s está solicitando permiso en nome do teu dispositivo (%2$s) para emitir aplicacións e outras funcións do sistema entre dispositivos" + + + + + + "dispositivo" "Esta aplicación poderá sincronizar información (por exemplo, o nome de quen chama) entre o teléfono e o dispositivo escollido" "Permitir" diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml index 816717b784a4..9effe2ce2226 100644 --- a/packages/CompanionDeviceManager/res/values-gu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong>ને <strong>%2$s</strong> મેનેજ કરવા માટે મંજૂરી આપીએ?" "ડિવાઇસ" "આ ઍપને તમારા %1$s પર આ પરવાનગીઓ ઍક્સેસ કરવાની મંજૂરી મળશે" - "શું <strong>%1$s</strong>ને %2$sની ઍપને <strong>%3$s</strong> પર સ્ટ્રીમ કરવાની મંજૂરી આપીએ?" - "%1$sની પાસે એવી બધી બાબતોનો ઍક્સેસ રહેશે જે %2$s પર જોઈ શકાતી કે ચલાવી શકાતી હોય, જેમાં ઑડિયો, ફોટા, પાસવર્ડ અને મેસેજ શામેલ છે.<br/><br/>%1$s ત્યાં સુધી ઍપને %3$s પર સ્ટ્રીમ કરી શકશે, જ્યાં સુધી તમે આ પરવાનગીનો ઍક્સેસ કાઢી નહીં નાખો." - "તમારા એક ડિવાઇસ પરથી બીજા ડિવાઇસ પર ઍપને ડિસ્પ્લે તેમજ સ્ટ્રીમ કરવા માટે, %1$s તમારા %2$s વતી પરવાનગી માગી રહી છે" + + + + + + "તમારા %2$sમાંથી આ માહિતી ઍક્સેસ કરવા માટે, <strong>%1$s</strong>ને મંજૂરી આપો" "%1$s તમારા %2$s વતી તમારા %3$sના ફોટા, મીડિયા અને નોટિફિકેશન ઍક્સેસ કરવાની પરવાનગીની વિનંતી કરી રહી છે" - "શું <strong>%1$s</strong>ને %2$sની ઍપ અને સિસ્ટમની સુવિધાઓને <strong>%3$s</strong> પર સ્ટ્રીમ કરવાની મંજૂરી આપીએ?" - "%1$sની પાસે એવી બધી બાબતોનો ઍક્સેસ રહેશે જે %2$s પર જોઈ શકાતી કે ચલાવી શકાતી હોય, જેમાં ઑડિયો, ફોટા, ચુકવણીની માહિતી, પાસવર્ડ અને મેસેજ શામેલ છે.<br/><br/>%1$s ત્યાં સુધી ઍપ અને સિસ્ટમની સુવિધાઓને %3$s પર સ્ટ્રીમ કરી શકશે, જ્યાં સુધી તમે આ પરવાનગીનો ઍક્સેસ કાઢી નહીં નાખો." - "%1$s તમારા ડિવાઇસ વચ્ચે ઍપ અને સિસ્ટમની અન્ય સુવિધાઓ સ્ટ્રીમ કરવા તમારા %2$s વતી પરવાનગીની વિનંતી કરી રહી છે" + + + + + + "ડિવાઇસ" "આ ઍપ તમારા ફોન અને પસંદ કરેલા ડિવાઇસ વચ્ચે, કૉલ કરનાર કોઈ વ્યક્તિનું નામ જેવી માહિતી સિંક કરી શકશે" "મંજૂરી આપો" diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml index b5a40e95fb0f..2a08e0030f8f 100644 --- a/packages/CompanionDeviceManager/res/values-hi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml @@ -25,17 +25,23 @@ "क्या <strong>%1$s</strong> को <strong>%2$s</strong> मैनेज करने की अनुमति देनी है?" "डिवाइस" "यह ऐप्लिकेशन, आपके %1$s पर इन अनुमतियों को ऐक्सेस कर पाएगा" - "क्या <strong>%1$s</strong> को आपके %2$s के ऐप्लिकेशन <strong>%3$s</strong> पर स्ट्रीम करने की अनुमति देनी है?" - "%1$s के पास ऐसे किसी भी कॉन्टेंट का ऐक्सेस होगा जो इस %2$s पर दिखता है या चलाया जाता है. इसमें ऑडियो, फ़ोटो, पासवर्ड, और मैसेज भी शामिल हैं.<br/><br/>.%1$s, %3$s पर तब तक ऐप्लिकेशन स्ट्रीम कर पाएगा, जब तक आप यह अनुमति हटा न दें." - "आपके %2$s की ओर से %1$s, आपके डिवाइस में मौजूद ऐप्लिकेशन को अन्य डिवाइसों पर दिखाने और स्ट्रीम करने की अनुमति मांग रहा है" + + + + + + "<strong>%1$s</strong> को आपके %2$s की यह जानकारी ऐक्सेस करने दें" "आपके %2$s की ओर से %1$s, आपके %3$s में मौजूद फ़ोटो, मीडिया, और सूचनाओं को ऐक्सेस करने की अनुमति मांग रहा है" - "क्या <strong>%1$s</strong> को आपके %2$s के ऐप्लिकेशन और सिस्टम की सुविधाओं को <strong>%3$s</strong> पर स्ट्रीम करने की अनुमति देनी है?" - "%1$s के पास ऐसे किसी भी कॉन्टेंट का ऐक्सेस होगा जो आपके %2$s पर दिखता है या चलाया जाता है. इसमें ऑडियो, फ़ोटो, पेमेंट की जानकारी, पासवर्ड, और मैसेज भी शामिल हैं.<br/><br/>%1$s, %3$s पर तब ऐप्लिकेशन और सिस्टम की सुविधाओं को स्ट्रीम कर सकेगा, जब तक आप यह अनुमति हटा न दें." - "आपके %2$s की ओर से %1$s, आपके डिवाइस में मौजूद ऐप्लिकेशन और सिस्टम की अन्य सुविधाओं को आपके दूसरे डिवाइसों पर स्ट्रीम करने की अनुमति मांग रहा है" + + + + + + "डिवाइस" "यह ऐप्लिकेशन, आपके फ़ोन और चुने हुए डिवाइस के बीच जानकारी सिंक करेगा. जैसे, कॉल करने वाले व्यक्ति का नाम" "अनुमति दें" diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml index 2d94b6766d7f..6b3e20419be5 100644 --- a/packages/CompanionDeviceManager/res/values-hr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml @@ -25,17 +25,23 @@ "Dopustiti aplikaciji <strong>%1$s</strong> da upravlja uređajem <strong>%2$s</strong>?" "uređaj" "Aplikacija će moći pristupati ovim dopuštenjima na vašem uređaju %1$s" - "Želite li dopustiti aplikaciji <strong>%1$s</strong> da streama aplikacije uređaja %2$s na uređaj <strong>%3$s</strong>?" - "Aplikacija %1$s imat će pristup svemu što je vidljivo ili se reproducira na uređaju %2$s, uključujući zvuk, fotografije, zaporke i poruke.<br/><br/>Aplikacija %1$s moći će streamati aplikacije na uređaj %3$s dok ne uklonite pristup za to dopuštenje." - "Aplikacija %1$s zahtijeva dopuštenje u ime vašeg uređaja %2$s za prikaz i streaming aplikacija s jednog uređaja na drugi" + + + + + + "Omogućite aplikaciji <strong>%1$s</strong> da pristupa informacijama s vašeg uređaja %2$s" "Aplikacija %1$s zahtijeva dopuštenje u ime vašeg uređaja %2$s za pristup fotografijama, medijskim sadržajima i obavijestima na uređaju %3$s" - "Želite li dopustiti uređaju <strong>%1$s</strong> da streama aplikacije i značajke sustava uređaja %2$s na uređaj <strong>%3$s</strong>?" - "Aplikacija %1$s imat će pristup svemu što je vidljivo ili se reproducira na vašem uređaju %2$s, uključujući zvuk, fotografije, informacije o plaćanju, zaporke i poruke.<br/><br/>Aplikacija %1$s moći će streamati aplikacije i značajke sustava na uređaj %3$s dok ne uklonite pristup za to dopuštenje." - "Aplikacija %1$s zahtjeva dopuštenja u ime vašeg uređaja %2$s za stream aplikacija i drugih značajki sustava između vaših uređaja" + + + + + + "uređaj" "Ta će aplikacija moći sinkronizirati podatke između vašeg telefona i odabranog uređaja, primjerice ime pozivatelja" "Dopusti" diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml index b63f8ab80f42..31d98283fed6 100644 --- a/packages/CompanionDeviceManager/res/values-hu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml @@ -25,17 +25,23 @@ "Engedélyezi, hogy a(z) <strong>%1$s</strong> kezelje a következő eszközt: <strong>%2$s</strong>?" "eszköz" "Az alkalmazás hozzáférhet majd ezekhez az engedélyekhez a következőn: %1$s" - "Engedélyezi a(z) <strong>%1$s</strong> számára a(z) %2$s alkalmazásainak streamelését a következőre: <strong>%3$s</strong>?" - "A(z) %1$s hozzáférhet a(z) %2$s minden látható vagy lejátszható tartalmához, így az audiotartalmakhoz, fényképekhez, jelszavakhoz és üzenetekhez is.<br/><br/>Amíg Ön el nem távolítja az ehhez az engedélyhez való hozzáférést, a(z) %1$s képes lesz majd az alkalmazások és a rendszerfunkciók %3$s eszközre való streamelésére." - "A(z) %1$s engedélyt kér a(z) %2$s nevében az alkalmazások eszközök közötti megjelenítéséhez és streameléséhez." + + + + + + "Engedélyezi a(z) <strong>%1$s</strong> alkalmazás számára az ehhez az információhoz való hozzáférést a(z) %2$s esetén" "A(z) %1$s engedélyt kér a(z) %2$s nevében a(z) %3$s fotóihoz, médiatartalmaihoz és értesítéseihez való hozzáféréshez" - "Engedélyezi a(z) <strong>%1$s</strong> számára a(z) %2$s alkalmazásainak és rendszerfunkcióinak streamelését a következőre: <strong>%3$s</strong>?" - "A(z) %1$s hozzáférhet a(z) %2$s minden látható vagy lejátszható tartalmához, így az audiotartalmakhoz, fényképekhez, fizetési adatokhoz, jelszavakhoz és üzenetekhez is.<br/><br/>Amíg Ön el nem távolítja az ehhez az engedélyhez való hozzáférést, a(z) %1$s képes lesz majd az alkalmazások és a rendszerfunkciók %3$s eszközre való streamelésére." - "A(z) %1$s engedélyt kér a(z) %2$s nevében az alkalmazások és más rendszerfunkcióknak eszközök közötti streameléséhez" + + + + + + "eszköz" "Ez az alkalmazás képes lesz szinkronizálni az olyan információkat a telefon és a kiválasztott eszköz között, mint például a hívó fél neve." "Engedélyezés" diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml index f90a324383ac..a4238c0ef46c 100644 --- a/packages/CompanionDeviceManager/res/values-hy/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml @@ -25,17 +25,23 @@ "Թույլատրե՞լ <strong>%1$s</strong> հավելվածին կառավարել <strong>%2$s</strong> սարքը" "սարք" "Այս հավելվածը կստանա հետևյալ թույլտվությունները ձեր %1$sում" - "Թույլատրե՞լ <strong>%1$s</strong> հավելվածին հեռարձակել ձեր %2$sի հավելվածները <strong>%3$s</strong> սարքին։" - "%1$s հավելվածին հասանելի կլինի ձեր %2$sում ցուցադրվող կամ նվագարկվող բովանդակությունը՝ ներառյալ աուդիոն, լուսանկարները, գաղտնաբառերը և հաղորդագրությունները։<br/><br/>%1$s հավելվածը կկարողանա հավելվածներ հեռարձակել %3$s սարքին, քանի դեռ չեք չեղարկել այս թույլտվությունը։" - "%1$s հավելվածը ձեր %2$s սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար" + + + + + + "Թույլատրեք <strong>%1$s</strong> հավելվածին օգտագործել այս տեղեկությունները ձեր %2$sից" "%1$s հավելվածը ձեր %2$s սարքի անունից թույլտվություն է խնդրում՝ ձեր %3$sի լուսանկարները, մեդիաֆայլերն ու ծանուցումները տեսնելու համար" - "Թույլատրե՞լ <strong>%1$s</strong> սարքին հեռարձակել ձեր %2$sի հավելվածները և համակարգի գործառույթները <strong>%3$s</strong> սարքին։" - "%1$s հավելվածին հասանելի կլինի ձեր %2$sում ցուցադրվող կամ նվագարկվող բովանդակությունը՝ ներառյալ աուդիոն, լուսանկարները, վճարային տեղեկությունները, գաղտնաբառերը և հաղորդագրությունները։<br/><br/>%1$s հավելվածը կկարողանա հավելվածներ և համակարգի գործառույթներ հեռարձակել %3$s սարքին, քանի դեռ չեք չեղարկել այս թույլտվությունը։" - "%1$s հավելվածը ձեր %2$s սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար" + + + + + + "սարք" "Այս հավելվածը կկարողանա համաժամացնել ձեր հեռախոսի և ընտրված սարքի տվյալները, օր․՝ զանգողի անունը" "Թույլատրել" diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml index 7a9f4854cfab..2ee4e89a448d 100644 --- a/packages/CompanionDeviceManager/res/values-in/strings.xml +++ b/packages/CompanionDeviceManager/res/values-in/strings.xml @@ -25,17 +25,23 @@ "Izinkan <strong>%1$s</strong> mengelola <strong>%2$s</strong>?" "perangkat" "Aplikasi ini akan diizinkan mengakses izin ini di %1$s Anda" - "Izinkan <strong>%1$s</strong> men-streaming aplikasi %2$s ke <strong>%3$s</strong>?" - "%1$s akan memiliki akses ke apa pun yang ditampilkan atau diputar di %2$s, termasuk audio, foto, sandi, dan pesan.<br/><br/>%1$s akan dapat men-streaming aplikasi ke %3$s hingga Anda menghapus izin ini." - "%1$s meminta izin atas nama %2$s untuk menampilkan dan men-streaming aplikasi di antara perangkat Anda" + + + + + + "Izinkan <strong>%1$s</strong> untuk mengakses informasi ini dari %2$s Anda" "%1$s meminta izin atas nama %2$s untuk mengakses foto, media, dan notifikasi %3$s Anda" - "Izinkan <strong>%1$s</strong> men-streaming aplikasi dan fitur sistem %2$s ke <strong>%3$s</strong>?" - "%1$s akan memiliki akses ke apa pun yang ditampilkan atau diputar di %2$s, termasuk audio, foto, info pembayaran, sandi, dan pesan.<br/><br/>%1$s akan dapat men-streaming aplikasi dan fitur sistem ke %3$s hingga Anda menghapus izin ini." - "%1$s meminta izin atas nama %2$s untuk men-streaming aplikasi dan fitur sistem lainnya di antara perangkat Anda" + + + + + + "perangkat" "Aplikasi ini akan dapat menyinkronkan info, seperti nama penelepon, antara ponsel dan perangkat yang dipilih" "Izinkan" diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml index 3a4170675bec..d86f5da3f3fa 100644 --- a/packages/CompanionDeviceManager/res/values-is/strings.xml +++ b/packages/CompanionDeviceManager/res/values-is/strings.xml @@ -25,17 +25,23 @@ "Leyfa <strong>%1$s</strong> að stjórna <strong>%2$s</strong>?" "tæki" "Þetta forrit fær aðgang að eftirfarandi heimildum í %1$s" - "Leyfa <strong>%1$s</strong> að streyma forritum í %2$s í ;strong>%3$s</strong>?" - "%1$s fær aðgang að öllu sem er sýnilegt eða spilað í %2$s, þ.m.t. hljóði, myndum, greiðsluupplýsingum, aðgangsorðum og skilaboðum.<br/><br/>%1$s getur streymt forritum í %3$s þar til þú fjarlægir aðgang að þessari heimild." - "%1$s biður um heimild fyrir %2$s til að birta og streyma forritum á milli tækjanna þinna" + + + + + + "Veita <strong>%1$s</strong> aðgang að þessum upplýsingum úr %2$s" "%1$s biður um heimild fyrir %2$s vegna aðgangs að myndum, margmiðlunarefni og tilkynningum í %3$s" - "Leyfa <strong>%1$s</strong> að streyma forritum og kerfiseiginleikum í %2$s í <strong>%3$s</strong>?" - "%1$s fær aðgang að öllu sem er sýnilegt eða spilað í %2$s, þ.m.t. hljóði, myndum, greiðsluupplýsingum, aðgangsorðum og skilaboðum.<br/><br/>%1$s getur streymt forritum og kerfiseiginleikum í %3$s þar til þú fjarlægir aðgang að þessari heimild." - "%1$s biður um heimild fyrir %2$s til að streyma forritum og öðrum kerfiseiginleikum á milli tækjanna þinna" + + + + + + "tæki" "Þetta forrit mun geta samstillt upplýsingar, t.d. nafn þess sem hringir, á milli símans og valins tækis" "Leyfa" diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml index b85ce64857e0..2fdcaf0d9852 100644 --- a/packages/CompanionDeviceManager/res/values-it/strings.xml +++ b/packages/CompanionDeviceManager/res/values-it/strings.xml @@ -25,17 +25,23 @@ "Vuoi consentire all\'app <strong>%1$s</strong> di gestire <strong>%2$s</strong>?" "dispositivo" "Questa app potrà accedere alle seguenti autorizzazioni %1$s:" - "Consentire all\'app <strong>%1$s</strong> di riprodurre in streaming le app %2$s su <strong>%3$s</strong>?" - "%1$s avrà accesso a tutti i contenuti visibili o riprodotti %2$s, inclusi audio, foto, password e messaggi.<br/><br/>%1$s sarà in grado di riprodurre in streaming le app su %3$s finché non rimuoverai l\'accesso a questa autorizzazione." - "%1$s richiede per conto di %2$s l\'autorizzazione a mostrare e riprodurre in streaming app tra i dispositivi" + + + + + + "Consenti all\'app <strong>%1$s</strong> di accedere a queste informazioni %2$s" "%1$s richiede per conto di %2$s l\'autorizzazione ad accedere a foto, contenuti multimediali e notifiche %3$s" - "Consentire all\'app <strong>%1$s</strong> di riprodurre in streaming le app e le funzionalità di sistema %2$s su <strong>%3$s</strong>?" - "%1$s avrà accesso a tutti i contenuti visibili o riprodotti %2$s, inclusi audio, foto, dati di pagamento, password e messaggi.<br/><br/>%1$s sarà in grado di riprodurre in streaming app e funzionalità di sistema su %3$s finché non rimuoverai l\'accesso a questa autorizzazione." - "%1$s richiede per conto di %2$s l\'autorizzazione a riprodurre in streaming app e altre funzionalità di sistema tra i dispositivi" + + + + + + "dispositivo" "Questa app potrà sincronizzare informazioni, ad esempio il nome di un chiamante, tra il telefono e il dispositivo scelto" "Consenti" diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml index 8148f564da8d..2efb77e31905 100644 --- a/packages/CompanionDeviceManager/res/values-iw/strings.xml +++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml @@ -25,17 +25,23 @@ "‏מתן הרשאה לאפליקציה ‎<strong>%1$s</strong&g;‎‏ לנהל את ‎<strong>%2$s</strong>‎‏" "מכשיר" "האפליקציה הזו תוכל לגשת להרשאות האלה ב%1$s שלך" - "‏לאשר לאפליקציית <strong>%1$s</strong> לשדר את האפליקציות של ה%2$s ל-<strong>%3$s</strong>?" - "‏לאפליקציה %1$s תהיה גישה לכל מה שרואים או מפעילים ב%2$s, כולל אודיו, תמונות, סיסמאות והודעות.<br/><br/>לאפליקציה %1$s תהיה אפשרות לשדר אפליקציות ל-%3$s עד שהגישה להרשאה הזו תוסר." - "האפליקציה %1$s מבקשת הרשאה ל-%2$s כדי להציג ולשדר אפליקציות בין המכשירים שלך" + + + + + + "‏מתן אישור לאפליקציה <strong>%1$s</strong> לגשת למידע הזה מה%2$s שלך" "האפליקציה %1$s מבקשת הרשאה ל-%2$s כדי לגשת לתמונות, למדיה ולהתראות ב%3$s" - "‏לאשר ל-<strong>%1$s</strong> לשדר אפליקציות ותכונות מערכת אחרות של ה%2$s למכשיר <strong>%3$s</strong>?" - "‏לאפליקציה %1$s תהיה גישה לכל מה שרואים או מפעילים ב%2$s, כולל אודיו, תמונות, פרטי תשלום, סיסמאות והודעות.<br/><br/>לאפליקציה %1$s תהיה אפשרות לשדר אפליקציות ותכונות מערכת ל-%3$s עד שהגישה להרשאה הזו תוסר." - "האפליקציה %1$s מבקשת הרשאה ל%2$s כדי לשדר אפליקציות ותכונות מערכת אחרות בין המכשירים שלך" + + + + + + "מכשיר" "האפליקציה הזו תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, מהטלפון שלך למכשיר שבחרת" "יש אישור" diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml index 173a72f0b63d..639e8bca45a5 100644 --- a/packages/CompanionDeviceManager/res/values-ja/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml @@ -25,17 +25,17 @@ "<strong>%1$s</strong> に <strong>%2$s</strong> の管理を許可しますか?" "デバイス" "このアプリは、%1$sの以下の権限にアクセスできるようになります" - "%2$s のアプリを <strong>%3$s</strong> にストリーミングすることを <strong>%1$s</strong> に許可しますか?" - "%1$s は、音声、写真、パスワード、メッセージを含め、%2$sで表示、再生されるすべてのコンテンツにアクセスできるようになります。<br/><br/>この権限へのアクセス権を削除するまで、%1$s%3$s にアプリをストリーミングできます。" - "%1$s%2$s に代わってデバイス間でアプリを表示およびストリーミングする権限をリクエストしています" + "%2$s のアプリとシステム機能を <strong>%3$s</strong> にストリーミングすることを <strong>%1$s</strong> に許可しますか?" + "%1$s は、音声、写真、お支払い情報、パスワード、メッセージを含め、%2$s で表示、再生されるすべてのコンテンツにアクセスできるようになります。<br/><br/>この権限へのアクセス権を削除するまで、%1$s%3$s にアプリをストリーミングできます。" + "%1$s%2$s に代わって、アプリやシステム機能を %3$s からストリーミングする権限をリクエストしています" "%2$sのこの情報へのアクセスを <strong>%1$s</strong> に許可" "%1$s%2$s に代わって%3$sの写真、メディア、通知にアクセスする権限をリクエストしています" - "%2$s のアプリとシステム機能を <strong>%3$s</strong> にストリーミングすることを <strong>%1$s</strong> に許可しますか?" - "%1$s は、音声、写真、お支払い情報、パスワード、メッセージを含め、%2$sで表示、再生されるすべてのコンテンツにアクセスできるようになります。<br/><br/>この権限へのアクセス権を削除するまで、%1$s%3$s にアプリとシステム機能をストリーミングできます。" - "%1$s%2$s に代わって、アプリやその他のシステム機能をデバイス間でストリーミングする権限をリクエストしています" + "%2$s のアプリを <strong>%3$s</strong> にストリーミングすることを <strong>%1$s</strong> に許可しますか?" + "%1$s は、音声、写真、お支払い情報、パスワード、メッセージを含め、%3$s で表示、再生されるすべてのコンテンツにアクセスできるようになります。<br/><br/>この権限へのアクセス権を削除するまで、%1$s%3$s にアプリをストリーミングできます。" + "%1$s%2$s に代わって、アプリを %3$s からストリーミングする権限をリクエストしています" "デバイス" "このアプリは、あなたのスマートフォンと選択したデバイスとの間で、通話相手の名前などの情報を同期できるようになります" "許可" diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml index 507d13c2c7e0..949d64b821c0 100644 --- a/packages/CompanionDeviceManager/res/values-ka/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml @@ -25,17 +25,17 @@ "ნება დართეთ <strong>%1$s-ს</strong> მართოს <strong>%2$s</strong>?" "მოწყობილობა" "ეს აპი შეძლებს წვდომას თქვენს %1$s-ზე არსებულ ამ ნებართვებზე" - "გსურთ <strong>%1$s</strong>-ს მისცეთ თქვენი %2$s-ის აპების სტრიმინგის საშუალება <strong>%3$s</strong>-ზე?" - "%1$s-ს ექნება წვდომა ყველაფერზე, რაც ჩანს ან უკრავს %2$s-ზე, მათ შორის, აუდიოზე, ფოტოებზე, პაროლებსა და შეტყობინებებზე.<br/><br/>%1$s შეძლებს აპების სტრიმინგს %3$s-ზე მანამ, სანამ თქვენ არ გააუქმებთ წვდომას ამ ნებართვაზე." - "%1$s ითხოვს ნებართვას თქვენი (%2$s) სახელით, რათა წარმოაჩინოს და მოახდინოს აპების სტრიმინგი თქვენს მოწყობილობებს შორის" + "გსურთ, <strong>%1$s</strong>-ს მისცეთ თქვენი %2$s-ის აპებისა და სისტემის ფუნქციების სტრიმინგის საშუალება <strong>%3$s</strong>-ზე?" + "%1$s მიიღებს წვდომას ყველაფერზე, რაც ჩანს ან უკრავს თქვენს %2$s-ზე, მათ შორის, აუდიოზე, ფოტოებზე, გადახდის ინფორმაციაზე, პაროლებსა და შეტყობინებებზე.<br/><br/>%1$s შეძლებს აპების სტრიმინგს %3$s-ზე მანამ, სანამ თქვენ არ გააუქმებთ წვდომას ამ ნებართვაზე." + "%1$s ითხოვს ნებართვას %2$s-ის სახელით აპებისა და სისტემური ფუნქციების სტრიმინგისთვის თქვენი %3$s-იდან" "<strong>%1$s</strong>-ის წვდომის დაშვება თქვენს %2$s-ში არსებულ ამ ინფორმაციაზე" "%1$s ითხოვს ნებართვას თქვენი (%2$s) სახელით, რათა მოიპოვოს წვდომა თქვენი %3$s-ის ფოტოებზე, მედიასა და შეტყობინებებზე" - "გსურთ <strong>%1$s</strong>-ს მისცეთ თქვენი %2$s-ის აპებისა და სისტემის ფუნქციების სტრიმინგის საშუალება <strong>%3$s</strong>-ზე?" - "%1$s-ს ექნება წვდომა ყველაფერზე, რაც ჩანს ან უკრავს თქვენს %2$s-ზე, მათ შორის, აუდიოზე, ფოტოებზე, გადახდის ინფორმაციაზე, პაროლებსა და შეტყობინებებზე.<br/><br/>%1$s შეძლებს აპებისა და სისტემის ფუნქციების სტრიმინგს %3$s-ზე მანამ, სანამ თქვენ არ გააუქმებთ წვდომას ამ ნებართვაზე." - "%1$s ითხოვს ნებართვას თქვენი (%2$s) სახელით, რათა მოახდინოს აპებისა და სისტემის სხვა ფუნქციების სტრიმინგი თქვენს მოწყობილობებს შორის" + "გსურთ, <strong>%1$s</strong>-ს მისცეთ თქვენი %2$s-ის აპების სტრიმინგის საშუალება <strong>%3$s</strong>-ზე?" + "%1$s მიიღებს წვდომას ყველაფერზე, რაც ჩანს ან უკრავს %3$s-ზე, მათ შორის, აუდიოზე, ფოტოებზე, პაროლებსა და შეტყობინებებზე.<br/><br/>%1$s შეძლებს აპების სტრიმინგს %3$s-ზე მანამ, სანამ თქვენ არ გააუქმებთ წვდომას ამ ნებართვაზე." + "%1$s ითხოვს ნებართვას %2$s-ის სახელით აპების სტრიმინგისთვის თქვენი %3$s-იდან" "მოწყობილობა" "ეს აპი შეძლებს ინფორმაციის სინქრონიზებას თქვენს ტელეფონსა და თქვენ მიერ არჩეულ მოწყობილობას შორის, მაგალითად, იმ ადამიანის სახელის, რომელიც გირეკავთ" "დაშვება" diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml index 16a02dcde559..f392c1050006 100644 --- a/packages/CompanionDeviceManager/res/values-kk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong> қолданбасына <strong>%2$s</strong> құрылғысын басқаруға рұқсат беру керек пе?" "құрылғы" "Бұл қолданба құрылғыда (%1$s) осы рұқсаттарды пайдалана алады." - "<strong>%1$s</strong> қолданбасына құрылғыңыздағы (%2$s) қолданбаларды <strong>%3$s</strong> құрылғысына трансляциялауға рұқсат берілсін бе?" - "%1$s қолданбасы құрылғыда (%2$s) көрінетін не ойнатылатын барлық контентті (аудиофайлдарды, фотосуреттерді, құпия сөздер мен хабарларды қоса алғанда) пайдалана алады.<br/><br/>Осы рұқсатты өшірмесеңіз, %1$s қолданбасы құрылғысына (%3$s) қолданбаларды трансляциялай алады." - "%1$s қолданбасы %2$s атынан құрылғыларыңыздың арасында қолданбаларды көрсетуге және трансляциялауға рұқсат сұрайды." + + + + + + "<strong>%1$s</strong> қолданбасына құрылғыңыздағы (%2$s) осы ақпаратты пайдалануға рұқсат беріңіз." "%1$s қолданбасы %2$s атынан құрылғыңыздағы (%3$s) фотосуреттерді, медиафайлдар мен хабарландыруларды пайдалануға рұқсат сұрайды." - "<strong>%1$s</strong> қолданбасына құрылғыңыздағы (%2$s) қолданбалар мен жүйе функцияларын <strong>%3$s</strong> құрылғысына трансляциялауға рұқсат берілсін бе?" - "%1$s қолданбасы құрылғыңызда (%2$s) көрінетін не ойнатылатын барлық контентті (аудиофайлдарды, фотосуреттерді, төлем туралы ақпаратты, құпия сөздер мен хабарларды қоса алғанда) пайдалана алады.<br/><br/>Осы рұқсатты өшірмесеңіз, %1$s қолданбасы құрылғыға (%3$s) қолданбаларды және жүйе функцияларын трансляциялай алады." - "%1$s қолданбасы %2$s атынан құрылғыларыңыздың арасында қолданбаларды және басқа жүйе функцияларын трансляциялауға рұқсат сұрайды." + + + + + + "құрылғы" "Бұл қолданба телефон мен таңдалған құрылғы арасында деректі (мысалы, қоңырау шалушының атын) синхрондай алады." "Рұқсат беру" diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml index e59db722dc64..149c62440309 100644 --- a/packages/CompanionDeviceManager/res/values-km/strings.xml +++ b/packages/CompanionDeviceManager/res/values-km/strings.xml @@ -25,17 +25,23 @@ "អនុញ្ញាតឱ្យ <strong>%1$s</strong> គ្រប់គ្រង <strong>%2$s</strong> ឬ?" "ឧបករណ៍" "កម្មវិធីនេះ​នឹងត្រូវបានអនុញ្ញាតឱ្យ​ចូលប្រើការអនុញ្ញាតទាំងនេះ​នៅលើ %1$s របស់អ្នក" - "អនុញ្ញាតឱ្យ <strong>%1$s</strong> ផ្សាយកម្មវិធីលើ %2$s របស់អ្នកទៅ <strong>%3$s</strong> ឬ?" - "%1$s នឹងមានសិទ្ធិចូលប្រើអ្វីៗដែលអាចមើលឃើញ ឬត្រូវបានចាក់នៅលើ %2$s រួមទាំងសំឡេង រូបថត ពាក្យសម្ងាត់ និងសារ។<br/><br/>%1$s នឹងអាចផ្សាយកម្មវិធី %3$s រហូតទាល់តែអ្នកដកសិទ្ធិចូលប្រើការអនុញ្ញាតនេះចេញ។" - "%1$s កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ %2$s របស់អ្នក ដើម្បីបង្ហាញ និងផ្សាយកម្មវិធីរវាងឧបករណ៍នានារបស់អ្នក" + + + + + + "អនុញ្ញាតឱ្យ <strong>%1$s</strong> ចូលប្រើព័ត៌មាននេះពី %2$s របស់អ្នក" "%1$s កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ %2$s របស់អ្នក ដើម្បីចូលប្រើរូបថត មេឌៀ និងការជូនដំណឹងរបស់ %3$s អ្នក" - "អនុញ្ញាតឱ្យ <strong>%1$s</strong> ផ្សាយមុខងារប្រព័ន្ធ និងកម្មវិធីលើ %2$s របស់អ្នកទៅ <strong>%3$s</strong> ឬ?" - "%1$s នឹងមានសិទ្ធិចូលប្រើអ្វីៗដែលអាចមើលឃើញ ឬត្រូវបានចាក់នៅលើ %2$s របស់អ្នក រួមទាំងសំឡេង រូបថត ព័ត៌មាននៃការទូទាត់ប្រាក់ ពាក្យសម្ងាត់ និងសារ។<br/><br/>%1$s នឹងអាចផ្សាយកម្មវិធី និងមុខងារប្រព័ន្ធទៅ %3$s រហូតទាល់តែអ្នកដកសិទ្ធិចូលប្រើការអនុញ្ញាតនេះចេញ។" - "%1$s កំពុងស្នើសុំ​ការអនុញ្ញាតជំនួសឱ្យ %2$s របស់អ្នក ដើម្បីផ្សាយកម្មវិធី និងមុខងារប្រព័ន្ធផ្សេងទៀតរវាងឧបករណ៍របស់អ្នក" + + + + + + "ឧបករណ៍" "កម្មវិធីនេះនឹងអាច​ធ្វើសមកាលកម្មព័ត៌មាន ដូចជាឈ្មោះមនុស្សដែលហៅទូរសព្ទជាដើម​ រវាងឧបករណ៍ដែលបានជ្រើសរើស និងទូរសព្ទរបស់អ្នក" "អនុញ្ញាត" diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml index ea7d8242b174..df7f4f461219 100644 --- a/packages/CompanionDeviceManager/res/values-kn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml @@ -25,17 +25,23 @@ "<strong>%2$s</strong>? ನಿರ್ವಹಿಸಲು <strong>%1$s</strong> ಗೆ ಅನುಮತಿಸಬೇಕೇ?" "ಸಾಧನ" "ನಿಮ್ಮ %1$s ನಲ್ಲಿ ಈ ಅನುಮತಿಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್‌ ಮಾಡಲು ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಅನುಮತಿಸಲಾಗುತ್ತದೆ" - "ನಿಮ್ಮ %2$s ನ ಆ್ಯಪ್‌ಗಳನ್ನು %3$s ಗೆ ಸ್ಟ್ರೀಮ್ ಮಾಡಲು %1$s ಗೆ ಅನುಮತಿಸಬೇಕೇ?" - "ನಿಮ್ಮ %2$s ನಲ್ಲಿನ ಆಡಿಯೋ, ಫೋಟೋಗಳು, ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಮತ್ತು ಸಂದೇಶಗಳು ಸೇರಿದಂತೆ %1$s ನಲ್ಲಿ ಗೋಚರಿಸುವ ಅಥವಾ ಪ್ಲೇ ಆಗುವ ಯಾವುದಕ್ಕೂ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ನೀವು ಈ ಅನುಮತಿಗೆ %3$s ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ತೆಗೆದುಹಾಕುವವರೆಗೆ %1$s ಗೆ ಆ್ಯಪ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ." - "ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್‌ಗಳನ್ನು ಪ್ರದರ್ಶಿಸಲು ಮತ್ತು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ %2$s ಪರವಾಗಿ %1$s ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸುತ್ತಿದೆ" + + + + + + "ನಿಮ್ಮ %2$s ನಿಂದ ಈ ಮಾಹಿತಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್‌ ಮಾಡಲು %1$s ಗೆ ಅನುಮತಿಸಿ" "ನಿಮ್ಮ %3$s ನ ಫೋಟೋಗಳು, ಮೀಡಿಯಾ ಮತ್ತು ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್‌ ಮಾಡಲು ನಿಮ್ಮ %2$s ಪರವಾಗಿ %1$s ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸುತ್ತಿದೆ" - "ನಿಮ್ಮ %2$s ನ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಸಿಸ್ಟಮ್ ಫೀಚರ್‌ಗಳನ್ನು %3$s ಗೆ ಸ್ಟ್ರೀಮ್ ಮಾಡಲು %1$s ಗೆ ಅನುಮತಿಸಬೇಕೇ?" - "ನಿಮ್ಮ %2$s ನಲ್ಲಿನ ಆಡಿಯೋ, ಫೋಟೋಗಳು, ಪಾವತಿ ಮಾಹಿತಿ, ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಮತ್ತು ಸಂದೇಶಗಳು ಸೇರಿದಂತೆ ನಿಮ್ಮ %1$s ನಲ್ಲಿ ಗೋಚರಿಸುವ ಅಥವಾ ಪ್ಲೇ ಆಗುವ ಯಾವುದಕ್ಕೂ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ನೀವು ಈ ಅನುಮತಿಗೆ %3$s ಆ್ಯಕ್ಸೆಸ್‌ ಅನ್ನು ತೆಗೆದುಹಾಕುವವರೆಗೆ %1$s ಗೆ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಸಿಸ್ಟಮ್ ಫೀಚರ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ ." - "%1$s ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಇತರ ಸಿಸ್ಟಮ್ ಫೀಚರ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ %2$s ಪರವಾಗಿ ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸುತ್ತಿದೆ" + + + + + + "ಸಾಧನ" "ಮೊಬೈಲ್ ಫೋನ್ ಮತ್ತು ಆಯ್ಕೆಮಾಡಿದ ಸಾಧನದ ನಡುವೆ, ಕರೆ ಮಾಡುವವರ ಹೆಸರಿನಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಈ ಆ್ಯಪ್‌ಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ" "ಅನುಮತಿಸಿ" diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml index 4ff768e5a1e5..0192eea3d644 100644 --- a/packages/CompanionDeviceManager/res/values-ko/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong>에서 <strong>%2$s</strong> 기기를 관리하도록 허용하시겠습니까?" "기기" "앱이 %1$s에서 이러한 권한에 액세스할 수 있게 됩니다." - "<strong>%1$s</strong>에서 %2$s의 앱을 <strong>%3$s</strong> 기기로 스트리밍하도록 허용하시겠습니까?" - "%1$s에서 오디오, 사진, 비밀번호, 메시지 등 %2$s에 표시되거나 해당 기기에서 재생되는 모든 항목에 액세스할 수 있습니다.<br/><br/>이 권한에 대한 액세스를 삭제할 때까지 %1$s에서 %3$s 기기로 앱을 스트리밍할 수 있습니다." - "%1$s에서 %2$s 대신 기기 간에 앱을 표시하고 스트리밍할 수 있는 권한을 요청하고 있습니다." + + + + + + "<strong>%1$s</strong> 앱이 %2$s에서 이 정보에 액세스하도록 허용합니다." "%1$s에서 %2$s 대신 %3$s의 사진, 미디어, 알림에 액세스할 수 있는 권한을 요청하고 있습니다." - "<strong>%1$s</strong>에서 %2$s의 앱 및 시스템 기능을 <strong>%3$s</strong> 기기로 스트리밍하도록 허용하시겠습니까?" - "%1$s에서 오디오, 사진, 결제 정보, 비밀번호, 메시지 등 %2$s에 표시되거나 해당 기기에서 재생되는 모든 항목에 액세스할 수 있습니다.<br/><br/>이 권한에 대한 액세스를 삭제할 때까지 %1$s에서 %3$s 기기로 앱 및 시스템 기능을 스트리밍할 수 있습니다." - "%1$s에서 %2$s 대신 기기 간에 앱 및 다른 시스템 기능을 스트리밍할 권한을 요청하고 있습니다." + + + + + + "기기" "이 앱에서 휴대전화와 선택한 기기 간에 정보(예: 발신자 이름)를 동기화할 수 있게 됩니다." "허용" diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml index 3e265a2678bc..d74436f03d28 100644 --- a/packages/CompanionDeviceManager/res/values-ky/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong> колдонмосуна <strong>%2$s</strong> түзмөгүн тескөөгө уруксат бересизби?" "түзмөк" "Бул колдонмого %1$s түзмөгүңүздө төмөнкүлөрдү аткарууга уруксат берилет" - "<strong>%1$s</strong> колдонмосуна %2$s түзмөгүңүздөгү колдонмолорду <strong>%3$s</strong> түзмөгүнө алып ойнотууга уруксат бересизби?" - "%1$s %2$s түзмөгүндө көрүнгөн же ойнотулган бардык нерселерге, анын ичинде аудио, сүрөттөр, сырсөздөр жана билдирүүлөргө кире алат.<br/><br/>Бул уруксатты алып салмайынча, %1$s колдонмолорду %3$s түзмөгүнө алып ойното алат." - "%1$s колдонмосу %2$s түзмөгүңүздүн атынан түзмөктөрдүн ортосунда колдонмолорду көрсөтүү жана алып ойнотуу үчүн уруксат сурап жатат" + + + + + + "<strong>%1$s</strong> колдонмосуна %2$s түзмөгүңүздөгү ушул маалыматты көрүүгө уруксат бериңиз" "%1$s колдонмосу %2$s түзмөгүңүздүн атынан %3$s сүрөттөрүн, медиа файлдарын жана билдирмелерин колдонууга уруксат сурап жатат" - "<strong>%1$s</strong> түзмөгүнө %2$s түзмөгүндөгү колдонмолорду жана тутумдун функцияларын <strong>%3$s</strong> түзмөгүндө алып ойнотууга уруксат бересизби?" - "%1$s %2$s түзмөгүңүздө көрүнгөн же ойнотулган бардык нерселерге, анын ичинде аудио, сүрөттөр, төлөм маалыматы, сырсөздөр жана билдирүүлөргө кире алат.<br/><br/>Бул уруксатты алып салмайынча, %1$s %3$s түзмөгүндөгү колдонмолорду жана тутум функцияларын алып ойното алат." - "%1$s %2$s түзмөгүңүздүн атынан түзмөктөрдүн ортосунда колдонмолорду жана тутумдун башка функцияларын алып ойнотууга уруксат сурап жатат" + + + + + + "түзмөк" "Бул колдонмо маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын телефон жана тандалган түзмөк менен шайкештирет" "Ооба" diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml index 2917c3ea81d7..f8da499e63ba 100644 --- a/packages/CompanionDeviceManager/res/values-lo/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml @@ -25,17 +25,17 @@ "ອະນຸຍາດ <strong>%1$s</strong> ຈັດການ <strong>%2$s</strong> ບໍ?" "ອຸປະກອນ" "ແອັບນີ້ຈະໄດ້ຮັບສິດເຂົ້າເຖິງການອະນຸຍາດເຫຼົ່ານີ້ຢູ່ %1$s ຂອງທ່ານ" - "ອະນຸຍາດໃຫ້ <strong>%1$s</strong> ສະຕຣີມແອັບຂອງ %2$s ຂອງທ່ານໄປຫາ <strong>%3$s</strong> ບໍ?" - "%1$s ຈະມີສິດເຂົ້າເຖິງທຸກຢ່າງທີ່ປາກົດ ຫຼື ຫຼິ້ນຢູ່ %2$s, ເຊິ່ງຮວມທັງສຽງ, ຮູບພາບ, ລະຫັດຜ່ານ ແລະ ຂໍ້ຄວາມ.<br/><br/>%1$s ຈະສາມາດສະຕຣີມແອັບໄປຫາ %3$s ໄດ້ຈົນກວ່າທ່ານຈະລຶບສິດເຂົ້າເຖິງການອະນຸຍາດນີ້ອອກ." - "%1$s ກໍາລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ %2$s ຂອງທ່ານເພື່ອສະແດງ ແລະ ສະຕຣີມແອັບລະຫວ່າງອຸປະກອນຕ່າງໆຂອງທ່ານ" + "ອະນຸຍາດໃຫ້ <strong>%1$s</strong> ສະຕຣີມແອັບ ແລະ ຄຸນສົມບັດຂອງລະບົບຂອງ %2$s ຂອງທ່ານໄປຫາ <strong>%3$s</strong> ບໍ?" + "%1$s ຈະມີສິດເຂົ້າເຖິງທຸກຢ່າງທີ່ປາກົດ ຫຼື ຫຼິ້ນຢູ່ %2$s ຂອງທ່ານ, ເຊິ່ງຮວມທັງສຽງ, ຮູບພາບ, ຂໍ້ມູນການຈ່າຍເງິນ ລະຫັດຜ່ານ ແລະ ຂໍ້ຄວາມ.<br/><br/>%1$s ຈະສາມາດສະຕຣີມແອັບໄປຫາ %3$s ໄດ້ຈົນກວ່າທ່ານຈະລຶບສິດເຂົ້າເຖິງການອະນຸຍາດນີ້ອອກ." + "%1$s ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມ %2$s ເພື່ອສະຕຣີມແອັລ ແລະ ຄຸນສົມບັດລະບົບຈາກ %3$s ຂອງທ່ານ" "ອະນຸຍາດໃຫ້ <strong>%1$s</strong> ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກ %2$s ຂອງທ່ານ" "%1$s ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ %2$s ຂອງທ່ານເພື່ອເຂົ້າເຖິງຮູບພາບ, ສື່ ແລະ ການແຈ້ງເຕືອນໃນ %3$s ຂອງທ່ານ" - "ອະນຸຍາດໃຫ້ <strong>%1$s</strong> ສະຕຣີມແອັບ ແລະ ຄຸນສົມບັດຂອງລະບົບຂອງ %2$s ຂອງທ່ານໄປຫາ <strong>%3$s</strong> ບໍ?" - "%1$s ຈະມີສິດເຂົ້າເຖິງທຸກຢ່າງທີ່ປາກົດ ຫຼື ຫຼິ້ນຢູ່ %2$s ຂອງທ່ານ, ເຊິ່ງຮວມທັງສຽງ, ຮູບພາບ, ຂໍ້ມູນການຈ່າຍເງິນ ລະຫັດຜ່ານ ແລະ ຂໍ້ຄວາມ.<br/><br/>%1$s ຈະສາມາດສະຕຣີມແອັບ ແລະ ຄຸນສົມບັດຂອງລະບົບໄປຫາ %3$s ໄດ້ຈົນກວ່າທ່ານຈະລຶບສິດເຂົ້າເຖິງການອະນຸຍາດນີ້ອອກ." - "%1$s ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ %2$s ຂອງທ່ານເພື່ອສະຕຣີມແອັບ ແລະ ຄຸນສົມບັດອື່ນໆຂອງລະບົບລະຫວ່າງອຸປະກອນຕ່າງໆຂອງທ່ານ" + "ອະນຸຍາດໃຫ້ <strong>%1$s</strong> ສະຕຣີມແອັບຂອງ %2$s ຂອງທ່ານໄປຫາ <strong>%3$s</strong> ບໍ?" + "%1$s ຈະມີສິດເຂົ້າເຖິງທຸກຢ່າງທີ່ປາກົດ ຫຼື ຫຼິ້ນຢູ່ %3$s, ເຊິ່ງຮວມທັງສຽງ, ຮູບພາບ, ຂໍ້ມູນການຈ່າຍເງິນ, ລະຫັດຜ່ານ ແລະ ຂໍ້ຄວາມ.<br/><br/>%1$s ຈະສາມາດສະຕຣີມແອັບໄປຫາ %3$s ໄດ້ຈົນກວ່າທ່ານຈະລຶບສິດເຂົ້າເຖິງການອະນຸຍາດນີ້ອອກ." + "%1$s ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມ %2$s ເພື່ອສະຕຣີມແອັບຈາກ %3$s ຂອງທ່ານ" "ອຸປະກອນ" "ແອັບນີ້ຈະສາມາດຊິ້ງຂໍ້ມູນ ເຊັ່ນ: ຊື່ຂອງຄົນທີ່ໂທເຂົ້າ, ລະຫວ່າງໂທລະສັບຂອງທ່ານ ແລະ ອຸປະກອນທີ່ເລືອກໄວ້ໄດ້" "ອະນຸຍາດ" diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml index a1b5cd9c0c50..8a6a564c39a7 100644 --- a/packages/CompanionDeviceManager/res/values-lt/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml @@ -25,17 +25,23 @@ "Leisti <strong>%1$s</strong> valdyti <strong>%2$s</strong>?" "įrenginio" "Šiai programai bus leidžiama pasiekti toliau nurodytus leidimus jūsų %1$s." - "Leisti programai <strong>%1$s</strong> srautu perduoti %2$s programas į <strong>%3$s</strong>?" - "Programa „%1$s“ galės pasiekti visą „%2$s“ matomą ar leidžiamą turinį, įskaitant garso įrašus, nuotraukas, slaptažodžius ir pranešimus.<br/><br/>Programa „%1$s“ galės perduoti srautu programas į „%3$s“, kol pašalinsite prieigą prie šio leidimo." - "Programa „%1$s“ prašo leidimo jūsų „%2$s“ vardu, kad galėtų rodyti ir srautu perduoti programas iš vieno įrenginio į kitą" + + + + + + "Leisti programai <strong>%1$s</strong> pasiekti šią informaciją iš jūsų %2$s" "Programa „%1$s“ prašo leidimo jūsų „%2$s“ vardu, kad galėtų pasiekti %3$s nuotraukas, mediją ir pranešimus" - "Leisti programai <strong>%1$s</strong> srautu perduoti %2$s programas ir sistemos funkcijas į <strong>%3$s</strong>?" - "Programa „%1$s“ galės pasiekti visą %2$s matomą ar leidžiamą turinį, įskaitant garso įrašus, nuotraukas, mokėjimo informaciją, slaptažodžius ir pranešimus.<br/><br/>Programa „%1$s“ galės perduoti srautu programas ir sistemos funkcijas į „%3$s“, kol pašalinsite prieigą prie šio leidimo." - "Programa „%1$s“ prašo leidimo jūsų „%2$s“ vardu, kad galėtų srautu perduoti programas ir kitas sistemos funkcijas iš vieno įrenginio į kitą" + + + + + + "įrenginys" "Ši programa galės sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, su jūsų telefonu ir pasirinktu įrenginiu" "Leisti" diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml index 880b981336bf..26f0968d9e50 100644 --- a/packages/CompanionDeviceManager/res/values-lv/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml @@ -25,17 +25,23 @@ "Vai atļaut lietotnei <strong>%1$s</strong> piekļūt ierīcei <strong>%2$s</strong>?" "ierīce" "Šī lietotne drīkstēs piekļūt norādītajām %1$s atļaujām." - "Vai atļaut lietotnei <strong>%1$s</strong> straumēt %2$s lietotnes ierīcē <strong>%3$s</strong>?" - "%1$s varēs piekļūt visam %2$s ekrānā parādītajam vai atskaņotajam saturam, tostarp audio, fotoattēliem, parolēm un ziņojumiem.<br/><br/>%1$s varēs straumēt lietotnes ierīcē %3$s, līdz noņemsiet piekļuvi šai atļaujai." - "Lietotne %1$s pieprasa atļauju attēlot un straumēt lietotnes starp jūsu ierīcēm šīs ierīces vārdā: %2$s" + + + + + + "Vai atļaut lietotnei <strong>%1$s</strong> piekļūt šai informācijai no jūsu %2$s?" "Lietotne %1$s pieprasa atļauju piekļūt jūsu %3$s fotoattēliem, multivides saturam un paziņojumiem šīs ierīces vārdā: %2$s." - "Vai atļaut lietotnei <strong>%1$s</strong> straumēt %2$s lietotnes un sistēmas funkcijas ierīcē <strong>%3$s</strong>?" - "%1$s varēs piekļūt visam %2$s ekrānā parādītajam vai atskaņotajam saturam, tostarp audio, fotoattēliem, maksājumu informācijai, parolēm un ziņojumiem.<br/><br/>%1$s varēs straumēt lietotnes un sistēmas funkcijas ierīcē %3$s, līdz noņemsiet piekļuvi šai atļaujai." - "Lietotne %1$s pieprasa atļauju straumēt lietotnes un citas sistēmas funkcijas starp jūsu ierīcēm šīs ierīces vārdā: %2$s." + + + + + + "ierīce" "Šī lietotne varēs sinhronizēt informāciju (piemēram, zvanītāja vārdu) starp jūsu tālruni un izvēlēto ierīci" "Atļaut" diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml index 219f9d14f64c..c0e48b32b1a5 100644 --- a/packages/CompanionDeviceManager/res/values-mk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml @@ -25,17 +25,23 @@ "Ќе дозволите <strong>%1$s</strong> да управува со <strong>%2$s</strong>?" "уред" "Апликацијава ќе може да пристапува до овие дозволи на %1$s" - "Да се дозволи <strong>%1$s</strong> да ги стримува апликациите од %2$s на <strong>%3$s</strong>?" - "%1$s ќе има пристап до сè што е видливо или репродуцирано на %2$s, including вклучувајќи ги и аудиото, фотографиите, лозинките и пораките.<br/><br/>%1$s ќе може да стримува апликации на %3$s додека не ја повлечете дозволава." - "%1$s бара дозвола во име на вашиот %2$s за да прикажува и стримува апликации меѓу вашите уреди" + + + + + + "Дозволете <strong>%1$s</strong> да пристапува до овие податоци на %2$s" "%1$s бара дозвола во име на вашиот %2$s за да пристапува до фотографиите, аудиовизуелните содржини и известувањата на %3$s" - "Да се дозволи <strong>%1$s</strong> да ги стримува апликациите и системските функции од %2$s на <strong>%3$s</strong>?" - "%1$s ќе има пристап до сè што е видливо или репродуцирано на %2$s, вклучувајќи ги и аудиото, фотографиите, податоците за плаќање, лозинките и пораките.<br/><br/>%1$s ќе може да стримува апликации и системски функции на %3$s додека не ја повлечете дозволава." - "%1$s бара дозвола во име на вашиот %2$s за да стримува апликации и други системски функции на вашите уреди" + + + + + + "уред" "Оваа апликација ќе може да ги синхронизира податоците како што се имињата на јавувачите помеѓу вашиот телефон и избраниот уред" "Дозволи" diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml index 199f7827c82a..2439adc48bb8 100644 --- a/packages/CompanionDeviceManager/res/values-ml/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml @@ -25,17 +25,23 @@ "<strong>%2$s</strong>? മാനേജ് ചെയ്യാൻ, <strong>%1$s</strong> എന്നതിനെ അനുവദിക്കുക" "ഉപകരണം" "നിങ്ങളുടെ %1$s എന്നതിൽ ഇനിപ്പറയുന്ന അനുമതികൾ ആക്‌സസ് ചെയ്യാൻ ഈ ആപ്പിനെ അനുവദിക്കും" - "നിങ്ങളുടെ %2$s എന്നതിന്റെ ആപ്പുകൾ <strong>%3$s</strong> എന്നതിലേക്ക് സ്ട്രീം ചെയ്യാൻ <strong>%1$s</strong> എന്നതിനെ അനുവദിക്കണോ?" - "ഓഡിയോ, ഫോട്ടോകൾ, പാസ്‌വേഡുകൾ, സന്ദേശങ്ങൾ എന്നിവ ഉൾപ്പെടെ %2$s എന്നതിൽ ദൃശ്യമാകുന്നതോ പ്ലേ ചെയ്യുന്നതോ എല്ലാ എല്ലാത്തിലേക്കും %1$s എന്നതിന് ആക്സസ് ഉണ്ടായിരിക്കും.<br/><br/>നിങ്ങൾ ഈ അനുമതിയിലേക്കുള്ള ആക്സസ് നീക്കം ചെയ്യുന്നത് വരെ %1$s എന്നതിന് %3$s എന്നതിലേക്ക് ആപ്പുകൾ സ്ട്രീം ചെയ്യാനാകും." - "നിങ്ങളുടെ ഉപകരണങ്ങൾക്കിടയിൽ ആപ്പുകൾ സ്ട്രീം ചെയ്യാനും പ്രദർശിപ്പിക്കാനും നിങ്ങളുടെ %2$s എന്ന ഉപകരണത്തിന് വേണ്ടി %1$s അനുമതി അഭ്യർത്ഥിക്കുന്നു" + + + + + + "നിങ്ങളുടെ %2$s എന്നതിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്‌സസ് ചെയ്യാൻ <strong>%1$s</strong> എന്നതിനെ അനുവദിക്കുക" "നിങ്ങളുടെ %3$s എന്നതിലെ ഫോട്ടോകൾ, മീഡിയ, അറിയിപ്പുകൾ എന്നിവ ആക്സസ് ചെയ്യാൻ %2$s എന്ന ഉപകരണത്തിന് വേണ്ടി %1$s അനുമതി അഭ്യർത്ഥിക്കുന്നു" - "നിങ്ങളുടെ %2$s എന്നതിന്റെ ആപ്പുകളും സിസ്റ്റം ഫീച്ചറുകളും <strong>%3$s</strong> എന്നതിലേക്ക് സ്ട്രീം ചെയ്യാൻ <strong>%1$s</strong> എന്നതിനെ അനുവദിക്കണോ?" - "ഓഡിയോ, ഫോട്ടോകൾ, പാസ്‌വേഡുകൾ, സന്ദേശങ്ങൾ എന്നിവ ഉൾപ്പെടെ %2$s എന്നതിൽ ദൃശ്യമാകുന്നതോ പ്ലേ ചെയ്യുന്നതോ എല്ലാ എല്ലാത്തിലേക്കും %1$s എന്നതിന് ആക്സസ് ഉണ്ടായിരിക്കും.<br/><br/>നിങ്ങൾ ഈ അനുമതിയിലേക്കുള്ള ആക്സസ് നീക്കം ചെയ്യുന്നത് വരെ %1$s എന്നതിന് %3$s എന്നതിലേക്ക് ആപ്പുകളും മറ്റ് സിസ്റ്റം ഫീച്ചറുകളും സ്ട്രീം ചെയ്യാനാകും." - "നിങ്ങളുടെ ഉപകരണങ്ങളിൽ ഒന്നിൽ നിന്ന് അടുത്തതിലേക്ക് ആപ്പുകളും മറ്റ് സിസ്റ്റം ഫീച്ചറുകളും സ്ട്രീം ചെയ്യാൻ %2$s എന്ന ഉപകരണത്തിന് വേണ്ടി %1$s എന്നത് അനുമതി അഭ്യർത്ഥിക്കുന്നു" + + + + + + "ഉപകരണം" "വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ ഫോണിനും തിരഞ്ഞെടുത്ത ഉപകരണത്തിനും ഇടയിൽ സമന്വയിപ്പിക്കുന്നതിന് ഈ ആപ്പിന് കഴിയും" "അനുവദിക്കുക" diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml index 94f862c08e78..543bdfa03eed 100644 --- a/packages/CompanionDeviceManager/res/values-mn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong>-д <strong>%2$s</strong>-г удирдахыг зөвшөөрөх үү?" "төхөөрөмж" "Энэ аппад таны %1$s дээрх эдгээр зөвшөөрөлд хандахыг зөвшөөрнө" - "<strong>%1$s</strong>-д таны %2$s-н аппуудыг <strong>%3$s</strong>-д дамжуулахыг зөвшөөрөх үү?" - "%1$s аудио, зураг, нууц үг, мессеж зэрэг %2$s дээр харагдаж эсвэл тоглуулж буй аливаа зүйлд хандах эрхтэй болно.<br/><br/>%1$s таныг энэ зөвшөөрлийн хандалтыг хасах хүртэл %3$s-д апп дамжуулах боломжтой байх болно." - "%1$s таны %2$s-н өмнөөс таны төхөөрөмжүүдийн хооронд апп үзүүлж, дамжуулах зөвшөөрлийг хүсэж байна" + + + + + + "<strong>%1$s</strong>-д таны %2$s-н энэ мэдээлэлд хандахыг зөвшөөрнө үү" "%1$s таны %2$s-н өмнөөс %3$s-н зураг, медиа, мэдэгдэлд хандах зөвшөөрлийг хүсэж байна" - "<strong>%1$s</strong>-д таны %2$s-н апп болон системийн онцлогуудыг <strong>%3$s</strong>-д дамжуулахыг зөвшөөрөх үү?" - "%1$s аудио, зураг, төлбөрийн мэдээлэл, нууц үг, мессеж зэрэг таны %2$s дээр харагдаж эсвэл тоглуулж буй аливаа зүйлд хандах эрхтэй байх болно.<br/><br/>%1$s таныг энэ зөвшөөрлийн хандалтыг хасах хүртэл %3$s-д апп болон системийн онцлогуудыг дамжуулах боломжтой байх болно." - "%1$s таны %2$s-н өмнөөс таны төхөөрөмжүүдийн хооронд апп болон системийн бусад онцлогийг дамжуулах зөвшөөрлийг хүсэж байна" + + + + + + "төхөөрөмж" "Энэ апп залгаж буй хүний нэр зэрэг мэдээллийг таны утас болон сонгосон төхөөрөмжийн хооронд синк хийх боломжтой болно" "Зөвшөөрөх" diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml index c758d29871bd..6a7e10ef8212 100644 --- a/packages/CompanionDeviceManager/res/values-mr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong> ला <strong>%2$s</strong> व्यवस्थापित करण्याची अनुमती द्यायची आहे?" "डिव्हाइस" "या अ‍ॅपला तुमच्या %1$s वर या परवानग्या अ‍ॅक्सेस करण्याची अनुमती दिली जाईल" - "<strong>%1$s</strong> ला तुमच्या %2$s अ‍ॅप्स <strong>%3$s</strong>वर स्ट्रीम करण्याची अनुमती द्यायची आहे का?" - "%1$s ला ऑडिओ, फोटो, पासवर्ड आणि मेसेज यांसह %2$s वर दिसणाऱ्या किंवा प्ले होणाऱ्या सर्व गोष्टींचा अ‍ॅक्सेस असेल.<br/><br/>तुम्ही या परवानगीचा अ‍ॅक्सेस काढून टाकेपर्यंत %1$s हे %3$s वर ॲप्स स्ट्रीम करू शकेल." - "तुमच्या डिव्हाइसदरम्यान ॲप्स दाखवण्यासाठी आणि स्ट्रीम करण्यासाठी %1$s हे तुमच्या %2$s च्या वतीने परवानगीची विनंती करत आहे" + + + + + + "<strong>%1$s</strong> ला ही माहिती तुमच्या %2$s वरून अ‍ॅक्सेस करण्यासाठी अनुमती द्या" "तुमच्या %3$s मधील फोटो, मीडिया आणि नोटिफिकेशन अ‍ॅक्सेस करण्यासाठी %1$s हे तुमच्या %2$s च्या वतीने परवानगीची विनंती करत आहे" - "<strong>%1$s</strong> ला तुमच्या %2$s अ‍ॅप्स आणि सिस्टीमची वैशिष्ट्ये <strong>%3$s</strong>वर स्ट्रीम करण्याची अनुमती द्यायची आहे का?" - "%1$s ला ऑडिओ, फोटो, पेमेंट माहिती, पासवर्ड आणि मेसेज यांसह तुमच्या %2$s वर दिसणाऱ्या किंवा प्ले होणाऱ्या सर्व गोष्टींचा अ‍ॅक्सेस असेल.<br/><br/>तुम्ही या परवानगीचा अ‍ॅक्सेस काढून टाकेपर्यंत %1$s हे ॲप्स आणि सिस्टीमची वैशिष्ट्ये %3$s वर स्ट्रीम करू शकेल." - "तुमच्या डिव्हाइसदरम्यान ॲप्स आणि इतर सिस्टीम वैशिष्‍ट्ये स्ट्रीम करण्यासाठी %1$s हे तुमच्या %2$s च्या वतीने परवानगीची विनंती करत आहे" + + + + + + "डिव्हाइस" "हे ॲप तुमचा फोन आणि निवडलेल्या डिव्‍हाइसदरम्यान कॉल करत असलेल्‍या एखाद्या व्यक्तीचे नाव यासारखी माहिती सिंक करू शकेल" "अनुमती द्या" diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml index 424b815b5ce3..13916b7c84ab 100644 --- a/packages/CompanionDeviceManager/res/values-ms/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml @@ -25,17 +25,17 @@ "Benarkan <strong>%1$s</strong> mengurus <strong>%2$s</strong>?" "peranti" "Apl ini akan dibenarkan untuk mengakses kebenaran yang berikut pada %1$s anda" - "Benarkan <strong>%1$s</strong> untuk menstrim apl %2$s anda kepada <strong>%3$s</strong>?" - "%1$s akan mendapat akses kepada semua perkara yang dipaparkan atau dimainkan pada %2$s, termasuk audio, foto, kata laluan dan mesej.<br/><br/>%1$s akan dapat menstrim apl kepada %3$s sehingga anda mengalih keluar akses kepada kebenaran ini." - "%1$s meminta kebenaran bagi pihak %2$s anda untuk memaparkan dan menstrim apl antara peranti anda" + "Benarkan <strong>%1$s</strong> untuk menstrim apl dan ciri sistem %2$s anda kepada <strong>%3$s</strong>?" + "%1$s akan mendapat akses kepada semua perkara yang dipaparkan atau dimainkan pada %2$s anda, termasuk audio, foto, maklumat pembayaran, kata laluan dan mesej.<br/><br/>%1$s akan dapat menstrim apl kepada %3$s sehingga anda mengalih keluar akses kepada kebenaran ini." + "%1$s meminta kebenaran bagi pihak %2$s untuk menstrim apl dan ciri sistem daripada %3$s anda" "Benarkan <strong>%1$s</strong> untuk mengakses maklumat ini daripada %2$s anda" "%1$s sedang meminta kebenaran bagi pihak %2$s anda untuk mengakses foto, media dan pemberitahuan %3$s anda" - "Benarkan <strong>%1$s</strong> untuk menstrim apl dan ciri sistem %2$s anda kepada <strong>%3$s</strong>?" - "%1$s akan mendapat akses kepada semua perkara yang dipaparkan atau dimainkan pada %2$s anda, termasuk audio, foto, maklumat pembayaran, kata laluan dan mesej.<br/><br/>%1$s akan dapat menstrim apl dan ciri sistem kepada %3$s sehingga anda mengalih keluar akses kepada kebenaran ini." - "%1$s sedang meminta kebenaran bagi pihak %2$s anda untuk menstrim apl dan ciri sistem lain antara peranti anda" + "Benarkan <strong>%1$s</strong> untuk menstrim apl %2$s anda kepada <strong>%3$s</strong>?" + "%1$s akan mendapat akses kepada semua perkara yang dipaparkan atau dimainkan pada %3$s, termasuk audio, foto, maklumat pembayaran, kata laluan dan mesej.<br/><br/>%1$s akan dapat menstrim apl kepada %3$s sehingga anda mengalih keluar akses kepada kebenaran ini." + "%1$s meminta kebenaran bagi pihak %2$s untuk menstrim apl daripada %3$s anda" "peranti" "Apl ini akan dapat menyegerakkan maklumat seperti nama individu yang memanggil, antara telefon anda dengan peranti yang dipilih" "Benarkan" diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml index 6185f314111c..dea62f69fa9c 100644 --- a/packages/CompanionDeviceManager/res/values-my/strings.xml +++ b/packages/CompanionDeviceManager/res/values-my/strings.xml @@ -25,17 +25,23 @@ "<strong>%2$s</strong> ကို <strong>%1$s</strong> အား စီမံခွင့်ပြုမလား။" "စက်" "သင့် %1$s တွင် ၎င်းခွင့်ပြုချက်များရယူရန် ဤအက်ပ်ကိုခွင့်ပြုမည်" - "<strong>%1$s</strong> အား သင့် %2$s ၏ အက်ပ်များကို <strong>%3$s</strong> တွင် တိုက်ရိုက်ဖွင့်ခွင့်ပြုမလား။" - "%1$s သည် အသံ၊ ဓာတ်ပုံ၊ စကားဝှက်နှင့် မက်ဆေ့ဂျ်များအပါအဝင် %2$s တွင် မြင်နိုင်သော (သို့) ဖွင့်ထားသော အရာအားလုံးကို သုံးခွင့်ရှိပါမည်။<br/><br/>ဤခွင့်ပြုချက်သုံးခွင့်ကို သင်မဖယ်ရှားမချင်း %1$s သည် အက်ပ်များကို %3$s တွင် တိုက်ရိုက်ဖွင့်နိုင်ပါမည်။" - "%1$s သည် သင့်စက်များအကြား အက်ပ်များ ပြပြီး တိုက်ရိုက်ဖွင့်ရန် %2$s ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်" + + + + + + "<strong>%1$s</strong> အား သင့် %2$s မှ ဤအချက်အလက်ကို သုံးခွင့်ပြုမည်" "%1$s သည် သင့် %3$s ၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များသုံးရန် %2$s ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်" - "<strong>%1$s</strong> အား သင့် %2$s ၏ အက်ပ်နှင့် စနစ်တူးလ်များကို <strong>%3$s</strong> တွင် တိုက်ရိုက်ဖွင့်ခွင့်ပြုမလား။" - "%1$s သည် အသံ၊ ဓာတ်ပုံ၊ ငွေချေအချက်အလက်၊ စကားဝှက်နှင့် မက်ဆေ့ဂျ်များအပါအဝင် သင့် %2$s တွင် မြင်နိုင်သော (သို့) ဖွင့်ထားသော အရာအားလုံးကို သုံးခွင့်ရှိပါမည်။<br/><br/>ဤခွင့်ပြုချက်သုံးခွင့်ကို သင်မဖယ်ရှားမချင်း %1$s သည် အက်ပ်နှင့် စနစ်တူးလ်များကို %3$s တွင် တိုက်ရိုက်ဖွင့်နိုင်ပါမည်။" - "%1$s သည် သင့်စက်များအကြား အက်ပ်နှင့် အခြားစနစ်တူးလ်များ တိုက်ရိုက်ဖွင့်ရန် %2$s ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်" + + + + + + "စက်" "ဤအက်ပ်သည် သင့်ဖုန်းနှင့် ရွေးထားသောစက်အကြား ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်နိုင်ပါမည်" "ခွင့်ပြုရန်" @@ -61,7 +67,7 @@ "ဖုန်းခေါ်ဆိုမှတ်တမ်းကို ဖတ်နိုင်၊ ရေးနိုင်သည်" "SMS မက်ဆေ့ဂျ်များ ပို့နိုင်၊ ကြည့်နိုင်သည်" "သင့်အဆက်အသွယ်များကို ဝင်ကြည့်နိုင်သည်" - "သင့်ပြက္ခဒိန်ကို ဝင်ကြည့်နိုင်သည်" + "သင့်ပြက္ခဒိန်အား ဝင်သုံးနိုင်သည်" "အသံသွင်းနိုင်သည်" "အနီးတစ်ဝိုက်ရှိ စက်များ၏ ဆက်စပ်နေရာကို ရှာခြင်း၊ ချိတ်ဆက်ခြင်းနှင့် သတ်မှတ်ခြင်းတို့ လုပ်နိုင်သည်" "အဆက်အသွယ်၊ မက်ဆေ့ဂျ်နှင့် ဓာတ်ပုံများကဲ့သို့ အချက်အလက်များအပါအဝင် အကြောင်းကြားချက်အားလုံးကို ဖတ်နိုင်သည်" diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml index 00700ec7f97e..9a40b6bb3d32 100644 --- a/packages/CompanionDeviceManager/res/values-nb/strings.xml +++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml @@ -25,17 +25,23 @@ "Vil du la <strong>%1$s</strong> administrere <strong>%2$s</strong>?" "enheten" "Denne appen får disse tillatelsene på %1$s" - "Vil du la <strong>%1$s</strong> strømme apper fra %2$s til <strong>%3$s</strong>?" - "%1$s får tilgang til alt som vises eller spilles av på %2$s, inkludert lyd, bilder, passord og meldinger.<br/><br/>%1$s får muligheten til å strømme apper til %3$s frem til du fjerner tilgangen til denne tillatelsen." - "%1$s ber om tillatelse til å vise og strømme apper mellom enhetene dine, på vegne av %2$s" + + + + + + "Vil du gi <strong>%1$s</strong> tilgang til denne informasjonen fra %2$s?" "%1$s ber om tilgang til bilder, medieinnhold og varsler fra %2$s på vegne av %3$s" - "Vil du la <strong>%1$s</strong> strømme apper og systemfunksjoner fra %2$s til <strong>%3$s</strong>?" - "%1$s får tilgang til alt som vises eller spilles av på %2$s, inkludert lyd, bilder, betalingsopplysninger, passord og meldinger.<br/><br/>%1$s får muligheten til å strømme apper og systemfunksjoner til %3$s frem til du fjerner tilgangen til denne tillatelsen." - "%1$s ber om tillatelse til å strømme apper og andre systemfunksjoner mellom enhetene dine på vegne av %2$s" + + + + + + "enhet" "Denne appen kan synkronisere informasjon som navnet til noen som ringer, mellom telefonen og den valgte enheten" "Tillat" diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml index 1af4d85f905a..fdd011b4e4a6 100644 --- a/packages/CompanionDeviceManager/res/values-ne/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong> लाई <strong>%2$s</strong> व्यवस्थापन गर्ने अनुमति दिने हो?" "डिभाइस" "तपाईंको %1$s मा यो एपलाई निम्न अनुमति दिइने छ:" - "Allow <strong>%1$s</strong> लाई तपाईंको %2$s मा भएका एपहरू <strong>%3$s</strong> मा स्ट्रिम गर्न दिने हो?" - "%1$s ले तपाईंको %2$s मा देखिने वा प्ले गरिने अडियो, फोटो, पासवर्ड र म्यासेजलगायतका सबै कुरा एक्सेस गर्न सक्ने छ।<br/><br/>तपाईंले यो अनुमति रद्द नगरेसम्म %1$s ले एपहरू %3$s मा स्ट्रिम गर्न पाइराख्ने छ।" - "%1$s तपाईंको डिभाइस %2$s को तर्फबाट तपाईंका कुनै एउटा डिभाइसबाट अर्को डिभाइसमा एप देखाउने तथा स्ट्रिम गर्ने अनुमति माग्दै छ" + + + + + + "<strong>%1$s</strong> लाई तपाईंको %2$s मा भएको यो जानकारी एक्सेस गर्ने अनुमति दिनुहोस्" "%1$s तपाईंको डिभाइस %2$s को तर्फबाट तपाईंको %3$s मा भएका फोटो, मिडिया र सूचनाहरू एक्सेस गर्ने अनुमति माग्दै छ" - "<strong>%1$s</strong> लाई तपाईंको %2$s मा भएका एप तथा सिस्टमका सुविधाहरू <strong>%3$s</strong> मा स्ट्रिम गर्न दिने हो?" - "%1$s ले तपाईंको %2$s मा देखिने वा प्ले गरिने अडियो, फोटो, भुक्तानीसम्बन्धी जानकारी, पासवर्ड र म्यासेजलगायतका सबै कुरा एक्सेस गर्न सक्ने छ।<br/><br/>तपाईंले यो अनुमति रद्द नगरेसम्म %1$s ले एप तथा सिस्टमका सुविधाहरू %3$s मा स्ट्रिम गर्न पाइराख्ने छ।" - "%1$s तपाईंको डिभाइस %2$s को तर्फबाट तपाईंका कुनै एउटा डिभाइसबाट अर्को डिभाइसमा एप र सिस्टमका अन्य सुविधाहरूमा स्ट्रिम गर्ने अनुमति माग्दै छ" + + + + + + "यन्त्र" "यो एपले तपाईंको फोन र तपाईंले छनौट गर्ने डिभाइसका बिचमा कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्न सक्ने छ।" "अनुमति दिनुहोस्" diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml index ad1cfe0d0b1b..d71e8c16f182 100644 --- a/packages/CompanionDeviceManager/res/values-nl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong> toestaan <strong>%2$s</strong> te beheren?" "apparaat" "Deze app krijgt toegang tot deze rechten op je %1$s" - "<strong>%1$s</strong> toestaan om apps van je %2$s naar <strong>%3$s</strong> te streamen?" - "%1$s krijgt toegang tot alles wat zichtbaar is of wordt afgespeeld op je %2$s, waaronder audio, foto\'s, wachtwoorden en berichten.<br/><br/>%1$s kan apps naar %3$s streamen totdat je dit recht verwijdert." - "%1$s vraagt namens jouw %2$s toestemming om apps tussen je apparaten weer te geven en te streamen" + + + + + + "<strong>%1$s</strong> toegang geven tot deze informatie op je %2$s?" "%1$s vraagt namens jouw %2$s toegang tot de foto\'s, media en meldingen van je %3$s" - "<strong>%1$s</strong> toestaan om apps en systeemfuncties van je %2$s naar <strong>%3$s</strong> te streamen?" - "%1$s krijgt toegang tot alles wat zichtbaar is of wordt afgespeeld op je %2$s, waaronder audio, foto\'s, betalingsgegevens, wachtwoorden en berichten.<br/><br/>%1$s kan apps en systeemfuncties naar %3$s streamen totdat je dit recht verwijdert." - "%1$s vraagt namens jouw %2$s toestemming om apps en andere systeemfuncties te streamen tussen je apparaten" + + + + + + "apparaat" "Deze app kan informatie, zoals de naam van iemand die belt, synchroniseren tussen je telefoon en het gekozen apparaat" "Toestaan" diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml index 58c64768dd21..1e8ed0bbb661 100644 --- a/packages/CompanionDeviceManager/res/values-or/strings.xml +++ b/packages/CompanionDeviceManager/res/values-or/strings.xml @@ -25,17 +25,23 @@ "<strong>%2$s</strong>କୁ ପରିଚାଳନା କରିବା ପାଇଁ <strong>%1$s</strong>କୁ ଅନୁମତି ଦେବେ?" "ଡିଭାଇସ" "ଆପଣଙ୍କ %1$sରେ ଏହି ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଆଯିବ" - "ଆପଣଙ୍କ %2$sର ଆପ୍ସକୁ <strong>%3$s</strong>ରେ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <strong>%1$s</strong>କୁ ଅନୁମତି ଦେବେ?" - "ଅଡିଓ, ଫଟୋ, ପାସୱାର୍ଡ ଏବଂ ମେସେଜ ସମେତ %2$sରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ %1$sର ଆକ୍ସେସ ରହିବ।<br/><br/>ଆପଣ ଏହି ଅନୁମତିକୁ ଆକ୍ସେସ କାଢ଼ି ନଦେବା ପର୍ଯ୍ୟନ୍ତ %1$s %3$sରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ ସକ୍ଷମ ହେବ।" - "ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଡିସପ୍ଲେ ଏବଂ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ %1$s ଆପଣଙ୍କର %2$s ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି" + + + + + + "ଆପଣଙ୍କ %2$sରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong>%1$s</strong>କୁ ଅନୁମତି ଦିଅନ୍ତୁ" "ଆପଣଙ୍କ %3$sର ଫଟୋ, ମିଡିଆ ଏବଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ %1$s ଆପଣଙ୍କର %2$s ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି" - "ଆପଣଙ୍କ %2$sର ଆପ୍ସ ଏବଂ ସିଷ୍ଟମ ଫିଚରଗୁଡ଼ିକୁ <strong>%3$s</strong>ରେ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <strong>%1$s</strong>କୁ ଅନୁମତି ଦେବେ?" - "ଅଡିଓ, ଫଟୋ, ପେମେଣ୍ଟ ସୂଚନା, ପାସୱାର୍ଡ ଏବଂ ମେସେଜ ସମେତ ଆପଣଙ୍କ %2$sରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ %1$sର ଆକ୍ସେସ ରହିବ।<br/><br/>ଆପଣ ଏହି ଅନୁମତିକୁ ଆକ୍ସେସ କାଢ଼ି ନଦେବା ପର୍ଯ୍ୟନ୍ତ %1$s %3$sରେ ଆପ୍ସ ଏବଂ ସିଷ୍ଟମ ଫିଚରଗୁଡ଼ିକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ ସକ୍ଷମ ହେବ।" - "ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସ ଏବଂ ଅନ୍ୟ ସିଷ୍ଟମ ଫିଚରଗୁଡ଼ିକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ %1$s ଆପଣଙ୍କର %2$s ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି" + + + + + + "ଡିଭାଇସ୍" "ଆପଣଙ୍କ ଫୋନ ଏବଂ ବଛାଯାଇଥିବା ଡିଭାଇସ ମଧ୍ୟରେ, କଲ କରୁଥିବା ଯେ କୌଣସି ବ୍ୟକ୍ତିଙ୍କ ନାମ ପରି ସୂଚନା ସିଙ୍କ କରିବାକୁ ଏହି ଆପ ସକ୍ଷମ ହେବ" "ଅନୁମତି ଦିଅନ୍ତୁ" diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml index d80c667c1ed2..94a858496f76 100644 --- a/packages/CompanionDeviceManager/res/values-pa/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml @@ -25,17 +25,23 @@ "ਕੀ <strong>%1$s</strong> ਨੂੰ <strong>%2$s</strong> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?" "ਡੀਵਾਈਸ" "ਇਸ ਐਪ ਨੂੰ ਤੁਹਾਡੇ %1$s \'ਤੇ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ" - "ਕੀ <strong>%1$s</strong> ਨੂੰ ਤੁਹਾਡੇ %2$sਦੀਆਂ ਐਪਾਂ ਨੂੰ <strong>%3$s</strong> \'ਤੇ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?" - "%1$s ਕੋਲ ਆਡੀਓ, ਫ਼ੋਟੋਆਂ, ਪਾਸਵਰਡਾਂ ਅਤੇ ਸੁਨੇਹਿਆਂ ਸਮੇਤ, %2$s \'ਤੇ ਦਿਖਾਈ ਦੇਣ ਵਾਲੀ ਜਾਂ ਚਲਾਈ ਜਾਣ ਵਾਲੀ ਕਿਸੇ ਵੀ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ।<br/><br/>ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇਸ ਇਜਾਜ਼ਤ ਤੱਕ ਪਹੁੰਚ ਨੂੰ ਹਟਾ ਨਹੀਂ ਦਿੰਦੇ, ਉਦੋਂ ਤੱਕ %1$s, %3$s \'ਤੇ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰ ਸਕੇਗੀ।" - "%1$s ਤੁਹਾਡੇ %2$s ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਦਿਖਾਉਣ ਅਤੇ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ" + + + + + + "<strong>%1$s</strong> ਨੂੰ ਤੁਹਾਡੇ %2$s ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ" "%1$s ਤੁਹਾਡੇ %2$s ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ %3$s ਦੀਆਂ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ" - "ਕੀ <strong>%1$s</strong> ਨੂੰ ਤੁਹਾਡੇ %2$s ਦੀਆਂ ਐਪਾਂ ਨੂੰ <strong>%3$s</strong> \'ਤੇ ਸਟ੍ਰੀਮ ਕਰਨ ਅਤੇ ਸਿਸਟਮ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?" - "%1$s ਕੋਲ ਆਡੀਓ, ਫ਼ੋਟੋਆਂ, ਪਾਸਵਰਡਾਂ ਅਤੇ ਸੁਨੇਹਿਆਂ ਸਮੇਤ ਤੁਹਾਡੇ %2$s \'ਤੇ ਦਿਖਾਈ ਦੇਣ ਵਾਲੀ ਜਾਂ ਚਲਾਈ ਜਾਣ ਵਾਲੀ ਕਿਸੇ ਵੀ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ।<br/><br/>ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇਸ ਇਜਾਜ਼ਤ ਤੱਕ ਪਹੁੰਚ ਨੂੰ ਹਟਾ ਨਹੀਂ ਦਿੰਦੇ, ਉਦੋਂ ਤੱਕ %1$s, %3$s \'ਤੇ ਐਪਾਂ ਅਤੇ ਸਿਸਟਮ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰ ਸਕੇਗੀ।" - "%1$s ਤੁਹਾਡੇ %2$s ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਅਤੇ ਹੋਰ ਸਿਸਟਮ ਸੰਬੰਧੀ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ" + + + + + + "ਡੀਵਾਈਸ" "ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ ਅਤੇ ਚੁਣੇ ਗਏ ਡੀਵਾਈਸ ਵਿਚਕਾਰ ਕਾਲਰ ਦੇ ਨਾਮ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਿੰਕ ਕਰ ਸਕੇਗੀ" "ਆਗਿਆ ਦਿਓ" diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml index 42a05b4fd2aa..949957dae84e 100644 --- a/packages/CompanionDeviceManager/res/values-pl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml @@ -25,17 +25,23 @@ "Zezwolić na dostęp aplikacji <strong>%1$s</strong> do urządzenia <strong>%2$s</strong>?" "urządzenie" "Aplikacja będzie miała dostęp do tych uprawnień na Twoim urządzeniu (%1$s)" - "Zezwolić aplikacji <strong>%1$s</strong> na strumieniowanie aplikacji na %2$s na urządzenie <strong>%3$s</strong>?" - "Aplikacja %1$s będzie miała dostęp do wszystkiego, co jest widoczne i odtwarzane na %2$s, w tym do dźwięku, zdjęć, haseł i wiadomości.<br/><br/>Aplikacja %1$s będzie mogła strumieniować aplikacje na urządzenie %3$s, dopóki nie usuniesz dostępu do tego uprawnienia." - "Aplikacja %1$s prosi w imieniu urządzenia %2$s o pozwolenie na wyświetlanie i strumieniowanie aplikacji między Twoimi urządzeniami" + + + + + + "Zezwól aplikacji <strong>%1$s</strong> na dostęp do tych informacji na Twoim %2$s" "Aplikacja %1$s prosi w imieniu urządzenia %2$s o uprawnienia dotyczące dostępu do zdjęć, multimediów i powiadomień na %3$s" - "Zezwolić aplikacji <strong>%1$s</strong> na strumieniowanie aplikacji i funkcji systemowych na %2$s na urządzenie <strong>%3$s</strong>?" - "Aplikacja %1$s będzie miała dostęp do wszystkiego, co jest widoczne i odtwarzane na %2$s, w tym do dźwięku, zdjęć, danych do płatności, haseł i wiadomości.<br/><br/>Aplikacja %1$s będzie mogła strumieniować aplikacje i funkcje systemowe na urządzenie %3$s, dopóki nie usuniesz dostępu do tego uprawnienia." - "Aplikacja %1$s prosi w imieniu urządzenia %2$s o pozwolenie na strumieniowanie aplikacji i innych funkcji systemowych między Twoimi urządzeniami" + + + + + + "urządzenie" "Ta aplikacja może synchronizować informacje takie jak imię i nazwisko osoby dzwoniącej między Twoim telefonem i wybranym urządzeniem" "Zezwól" diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml index 1ef96354e460..cce096871838 100644 --- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml @@ -25,17 +25,23 @@ "Permitir que o app <strong>%1$s</strong> gerencie o dispositivo <strong>%2$s</strong>?" "dispositivo" "O app poderá acessar estas permissões no seu %1$s" - "Permitir que o app <strong>%1$s</strong> faça streaming dos aplicativos do seu %2$s para o <strong>%3$s</strong>?" - "O app %1$s terá acesso a tudo que estiver visível ou for aberto no %2$s, incluindo áudios, fotos, senhas e mensagens.<br/><br/>O app %1$s poderá fazer streaming de aplicativos para o %3$s até que você remova o acesso a essa permissão." - "O app %1$s está pedindo permissão em nome do seu %2$s para mostrar e fazer streaming de apps entre seus dispositivos" + + + + + + "Permitir que o app <strong>%1$s</strong> acesse essas informações do seu %2$s" "O app %1$s está pedindo permissão em nome do seu %2$s para acessar fotos, mídia e notificações do seu %3$s" - "Permitir que <strong>%1$s</strong> faça streaming dos apps e recursos do sistema do seu %2$s para o <strong>%3$s</strong>?" - "O app %1$s terá acesso a tudo que estiver visível ou for aberto no %2$s, incluindo áudios, fotos, informações de pagamento, senhas e mensagens.<br/><br/>O app %1$s poderá fazer streaming de aplicativos e recursos do sistema para o %3$s até que você remova o acesso a essa permissão." - "O app %1$s está pedindo permissão em nome do seu %2$s para fazer streaming de aplicativos e outros recursos do sistema entre seus dispositivos" + + + + + + "dispositivo" "O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido" "Permitir" diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml index 8a464e3804d6..1443b137a9a6 100644 --- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml @@ -25,17 +25,23 @@ "Permita que a app <strong>%1$s</strong> faça a gestão do dispositivo <strong>%2$s</strong>" "dispositivo" "Esta app vai poder aceder a estas autorizações no seu %1$s" - "Permitir que a app <strong>%1$s</strong> faça stream das apps do seu %2$spara o dispositivo <strong>%3$s</strong>?" - "A app %1$s vai ter acesso a tudo o que seja visível ou reproduzido no dispositivo %2$s, incluindo áudio, fotos, palavras-passe e mensagens.<br/><br/>A app %1$s vai poder fazer stream de apps para o dispositivo %3$s até remover o acesso a esta autorização." - "A app %1$s está a pedir autorização em nome do seu dispositivo %2$s para apresentar e fazer stream de apps entre os seus dispositivos" + + + + + + "Permita que a app <strong>%1$s</strong> aceda a estas informações do seu %2$s" "A app %1$s está a pedir autorização em nome do seu dispositivo %2$s para aceder às fotos, ao conteúdo multimédia e às notificações do seu %3$s" - "Permitir que o dispositivo <strong>%1$s</strong> faça stream das apps e funcionalidades do sistema do seu %2$s para o dispositivo <strong>%3$s</strong>?" - "A app %1$s vai ter acesso a tudo o que seja visível ou reproduzido no seu %2$s, incluindo áudio, fotos, informações de pagamento, palavras-passe e mensagens.<br/><br/>A app %1$s vai poder fazer stream de apps e funcionalidades do sistema para o dispositivo %3$s até remover o acesso a esta autorização." - "A app %1$s está a pedir autorização em nome do seu dispositivo %2$s para fazer stream de apps e outras funcionalidades do sistema entre os seus dispositivos" + + + + + + "dispositivo" "Esta app vai poder sincronizar informações, como o nome do autor de uma chamada, entre o telemóvel e o dispositivo escolhido" "Permitir" diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml index 1ef96354e460..cce096871838 100644 --- a/packages/CompanionDeviceManager/res/values-pt/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml @@ -25,17 +25,23 @@ "Permitir que o app <strong>%1$s</strong> gerencie o dispositivo <strong>%2$s</strong>?" "dispositivo" "O app poderá acessar estas permissões no seu %1$s" - "Permitir que o app <strong>%1$s</strong> faça streaming dos aplicativos do seu %2$s para o <strong>%3$s</strong>?" - "O app %1$s terá acesso a tudo que estiver visível ou for aberto no %2$s, incluindo áudios, fotos, senhas e mensagens.<br/><br/>O app %1$s poderá fazer streaming de aplicativos para o %3$s até que você remova o acesso a essa permissão." - "O app %1$s está pedindo permissão em nome do seu %2$s para mostrar e fazer streaming de apps entre seus dispositivos" + + + + + + "Permitir que o app <strong>%1$s</strong> acesse essas informações do seu %2$s" "O app %1$s está pedindo permissão em nome do seu %2$s para acessar fotos, mídia e notificações do seu %3$s" - "Permitir que <strong>%1$s</strong> faça streaming dos apps e recursos do sistema do seu %2$s para o <strong>%3$s</strong>?" - "O app %1$s terá acesso a tudo que estiver visível ou for aberto no %2$s, incluindo áudios, fotos, informações de pagamento, senhas e mensagens.<br/><br/>O app %1$s poderá fazer streaming de aplicativos e recursos do sistema para o %3$s até que você remova o acesso a essa permissão." - "O app %1$s está pedindo permissão em nome do seu %2$s para fazer streaming de aplicativos e outros recursos do sistema entre seus dispositivos" + + + + + + "dispositivo" "O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido" "Permitir" diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml index cb0572ddf197..528a73fd607d 100644 --- a/packages/CompanionDeviceManager/res/values-ro/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml @@ -25,17 +25,23 @@ "Permiți ca <strong>%1$s</strong> să gestioneze <strong>%2$s</strong>?" "dispozitiv" "Aplicația va putea să acceseze următoarele permisiuni pe %1$s" - "Permiți ca <strong>%1$s</strong> să redea în stream aplicații de pe %2$s pe <strong>%3$s</strong>?" - "%1$s va avea acces la tot conținutul vizibil sau redat pe %2$s, inclusiv conținut audio, fotografii, parole și mesaje.<br/><br/>%1$s va putea să redea în stream aplicații pe %3$s până când elimini accesul la această permisiune." - "%1$s solicită permisiunea pentru %2$s de a afișa și a reda în stream aplicații între dispozitive" + + + + + + "Permite ca <strong>%1$s</strong> să acceseze aceste informații de pe %2$s" "%1$s solicită permisiunea pentru %2$s de a accesa fotografiile, conținutul media și notificările de pe %3$s" - "Permiți ca <strong>%1$s</strong> să redea în stream aplicații și funcții de sistem de pe %2$s pe <strong>%3$s</strong>?" - "%1$s va avea acces la tot conținutul vizibil sau redat pe %2$s, inclusiv conținut audio, fotografii, informații de plată, parole și mesaje.<br/><br/>%1$s va putea să redea în stream aplicații și funcții de sistem pe %3$s până când elimini accesul la această permisiune." - "%1$s solicită permisiunea pentru %2$s de a reda în stream aplicații și alte funcții de sistem între dispozitive" + + + + + + "dispozitiv" "Aplicația va putea să sincronizeze informații, cum ar fi numele unui apelant, între telefonul tău și dispozitivul ales" "Permite" diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml index f2e03677faf7..6d21bebc5012 100644 --- a/packages/CompanionDeviceManager/res/values-ru/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml @@ -25,17 +25,23 @@ "Разрешить приложению <strong>%1$s</strong> управлять устройством <strong>%2$s</strong>?" "устройстве" "Это приложение получит указанные разрешения на вашем устройстве (%1$s)." - "Разрешить приложению <strong>%1$s</strong> транслировать приложения с вашего устройства (%2$s) на устройство <strong>%3$s</strong>?" - "У приложения \"%1$s\" будет доступ ко всему, что показывается или воспроизводится на устройстве (%2$s), включая аудиофайлы, фотографии, пароли и сообщения.<br/><br/>Приложение \"%1$s\" сможет транслировать приложения на устройство \"%3$s\", пока вы не отзовете разрешение." - "Приложение \"%1$s\" от имени вашего устройства \"%2$s\" запрашивает разрешение транслировать приложения между устройствами." + + + + + + "Разрешить приложению <strong>%1$s</strong> доступ к этой информации с вашего устройства (%2$s)?" "Приложение \"%1$s\" от имени вашего устройства \"%2$s\" запрашивает разрешение на доступ к фотографиям, медиаконтенту и уведомлениям на устройстве (%3$s)." - "Разрешить устройству <strong>%1$s</strong> транслировать приложения и системные функции с вашего устройства (%2$s) на устройство <strong>%3$s</strong>?" - "У приложения \"%1$s\" будет доступ ко всему, что показывается или воспроизводится на вашем устройстве (%2$s), включая аудиофайлы, фотографии, платежные данные, пароли и сообщения.<br/><br/>Приложение \"%1$s\" сможет транслировать приложения и системные функции на устройство \"%3$s\", пока вы не отзовете разрешение." - "Приложение \"%1$s\" от имени вашего устройства \"%2$s\" запрашивает разрешение транслировать приложения и системные функции между устройствами." + + + + + + "устройство" "Приложение сможет синхронизировать информацию между телефоном и выбранным устройством, например данные из журнала звонков." "Разрешить" diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml index 0b2369a089fa..e8b119759f7b 100644 --- a/packages/CompanionDeviceManager/res/values-si/strings.xml +++ b/packages/CompanionDeviceManager/res/values-si/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong> හට <strong>%2$s</strong> කළමනා කිරීමට ඉඩ දෙන්න ද?" "උපාංගය" "මෙම යෙදුමට ඔබේ %1$s මත මෙම අවසර වෙත ප්‍රවේශ වීමට ඉඩ දෙනු ඇත" - "ඔබේ %2$s හි යෙදුම් <strong>%3$s</strong> වෙත ප්‍රවාහ කිරීමට <strong>%1$s</strong> හට ඉඩ දෙන්න ද?" - "%1$s හට ශ්‍රව්‍ය, ඡායාරූප, මුරපද සහ පණිවිඩ ඇතුළුව %2$s හි දෘශ්‍යමාන හෝ වාදනය වන ඕනෑම දෙයකට ප්‍රවේශය ඇත.<br/><br/>ඔබ මෙම අවසරයට ප්‍රවේශය ඉවත් කරන තෙක් %1$s හට %3$s වෙත යෙදුම් ප්‍රවාහ කිරීමට හැකි වනු ඇත." - "ඔබේ උපාංග අතර යෙදුම් සංදර්ශනය කිරීමට සහ ප්‍රවාහ කිරීමට %1$s ඔබේ %2$s වෙනුවෙන් අවසර ඉල්ලා සිටියි" + + + + + + "<strong>%1$s</strong> හට ඔබේ %2$s වෙතින් මෙම තොරතුරු වෙත ප්‍රවේශ වීමට ඉඩ දෙන්න" "%1$s ඔබේ %2$s වෙනුවෙන් ඔබේ %3$s හි ඡායාරූප, මාධ්‍ය, සහ දැනුම්දීම් වෙත ප්‍රවේශ වීමට අවසරය ඉල්ලමින් සිටියි" - "ඔබේ %2$s හි යෙදුම් සහ පද්ධති විශේෂාංග <strong>%3$s</strong> වෙත ප්‍රවාහ කිරීමට <strong>%1$s</strong> හට ඉඩ දෙන්න ද?" - "%1$s හට ශ්‍රව්‍ය, ඡායාරූප, ගෙවීම් තොරතුරු, මුරපද සහ පණිවිඩ ඇතුළුව ඔබේ %2$s හි දෘශ්‍යමාන හෝ වාදනය වන ඕනෑම දෙයකට ප්‍රවේශය ඇත.<br/><br/>ඔබ මෙම අවසරයට ප්‍රවේශය ඉවත් කරන තෙක් %1$s හට යෙදුම් සහ පද්ධති විශේෂාංග %3$s වෙත ප්‍රවාහ කිරීමට හැකි වනු ඇත." - "%1$s ඔබේ %2$s වෙනුවෙන් ඔබේ උපාංග අතර යෙදුම් සහ අනෙකුත් පද්ධති විශේෂාංග ප්‍රවාහ කිරීමට අවසර ඉල්ලයි" + + + + + + "උපාංගය" "මෙම යෙදුමට ඔබේ දුරකථනය සහ තෝරා ගත් උපාංගය අතර, අමතන කෙනෙකුගේ නම වැනි, තතු සමමුහුර්ත කිරීමට හැකි වනු ඇත" "ඉඩ දෙන්න" diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml index 2819a92a6efb..41afcd525e42 100644 --- a/packages/CompanionDeviceManager/res/values-sk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml @@ -25,17 +25,23 @@ "Chcete povoliť aplikácii <strong>%1$s</strong> spravovať zariadenie <strong>%2$s</strong>?" "zariadenie" "Táto aplikácia bude mať prístup k týmto povoleniam v zariadení %1$s" - "Chcete povoliť aplikácii <strong>%1$s</strong> streamovať aplikácie zo zariadenia %2$s do zariadenia <strong>%3$s</strong>?" - "Aplikácia %1$s bude mať prístup k všetkému, čo sa zobrazuje alebo prehráva v zariadení %2$s vrátane zvuku, fotiek, hesiel a správ.<br/><br/>Aplikácia %1$s bude môcť streamovať aplikácie do zariadenia %3$s, kým prístup k tomuto povoleniu neodstránite." - "Aplikácia %1$s vyžaduje pre zariadenie %2$s povolenie zobrazovať a streamovať aplikácie medzi zariadeniami" + + + + + + "Povoľte aplikácii <strong>%1$s</strong> prístup k týmto informáciám zo zariadenia %2$s" "Aplikácia %1$s vyžaduje pre zariadenie %2$s povolenie na prístup k fotkám, médiám a upozorneniam zariadenia %3$s" - "Chcete povoliť zariadeniu <strong>%1$s</strong> streamovať aplikácie a funkcie systému zo zariadenia %2$s do zariadenia <strong>%3$s</strong>?" - "Aplikácia %1$s bude mať prístup k všetkému, čo sa zobrazuje alebo prehráva v zariadení %2$s vrátane zvuku, fotiek, platobných údajov, hesiel a správ.<br/><br/>Aplikácia %1$s bude môcť streamovať aplikácie a funkcie systému do zariadenia %3$s, kým prístup k tomuto povoleniu neodstránite." - "Aplikácia %1$s vyžaduje pre zariadenie %2$s povolenie streamovať aplikácie a ďalšie funkcie systému medzi zariadeniami" + + + + + + "zariadenie" "Táto aplikácia bude môcť synchronizovať informácie, napríklad meno volajúceho, medzi telefónom a vybraným zariadením" "Povoliť" diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml index 3e4f8dbc2c90..2c1edcd01899 100644 --- a/packages/CompanionDeviceManager/res/values-sl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml @@ -25,17 +25,17 @@ "Želite aplikaciji <strong>%1$s</strong> dovoliti upravljanje naprave <strong>%2$s</strong>?" "naprava" "Ta aplikacija bo lahko dostopala do teh dovoljenj v napravi »%1$s«." - "Ali aplikaciji <strong>%1$s</strong> dovolite, da pretočno predvaja aplikacije naprave »%2$s« v napravi <strong>%3$s</strong>?" - "Aplikacija %1$s bo imela dostop do vsega, kar je prikazano ali se predvaja v napravi »%2$s«, vključno z zvokom, fotografijami, gesli in sporočili.<br/><br/>Aplikacija %1$s bo lahko pretočno predvajala aplikacije v napravo »%3$s«, dokler ne odstranite dostopa do tega dovoljenja." - "Aplikacija %1$s v imenu naprave »%2$s« zahteva dovoljenje za prikaz in pretočno predvajanje aplikacij v vaših napravah." + "Ali aplikaciji <strong>%1$s</strong> dovolite, da pretočno predvaja aplikacije in sistemske funkcije naprave %2$s v napravi <strong>%3$s</strong>?" + "Aplikacija %1$s bo imela dostop do vsega, kar je prikazano ali se predvaja v vaši napravi %2$s, vključno z zvokom, fotografijami, podatki za plačilo, gesli in sporočili.<br/><br/>Aplikacija %1$s bo lahko pretočno predvajala aplikacije v napravo %3$s, dokler ne odstranite dostopa do tega dovoljenja." + "Aplikacija %1$s v imenu naprave %2$s zahteva dovoljenje za pretočno predvajanje aplikacij in sistemskih funkcij iz naprave %3$s" "Dovolite, da <strong>%1$s</strong> dostopa do teh podatkov v vaši napravi »%2$s«." "Aplikacija %1$s v imenu naprave »%2$s« zahteva dovoljenje za dostop do fotografij, predstavnosti in obvestil v napravi »%3$s«." - "Ali napravi <strong>%1$s</strong> dovolite, da pretočno predvaja aplikacije in sistemske funkcije naprave »%2$s« v napravi <strong>%3$s</strong>?" - "Aplikacija %1$s bo imela dostop do vsega, kar je prikazano ali se predvaja v napravi »%2$s«, vključno z zvokom, fotografijami, podatki za plačilo, gesli in sporočili.<br/><br/>Aplikacija %1$s bo lahko pretočno predvajala aplikacije in sistemske funkcije v napravo »%3$s«, dokler ne odstranite dostopa do tega dovoljenja." - "Aplikacija %1$s v imenu naprave »%2$s« zahteva dovoljenje za pretočno predvajanje aplikacij in drugih sistemskih funkcij v vaših napravah." + "Ali aplikaciji <strong>%1$s</strong> dovolite, da pretočno predvaja aplikacije naprave %2$s v napravi <strong>%3$s</strong>?" + "Aplikacija %1$s bo imela dostop do vsega, kar je prikazano ali se predvaja v napravi %3$s, vključno z zvokom, fotografijami, podatki za plačilo, gesli in sporočili.<br/><br/>Aplikacija %1$s bo lahko pretočno predvajala aplikacije v napravo %3$s, dokler ne odstranite dostopa do tega dovoljenja." + "Aplikacija %1$s v imenu naprave %2$s zahteva dovoljenje za pretočno predvajanje aplikacij iz naprave %3$s" "naprava" "Ta aplikacija bo lahko sinhronizirala podatke, na primer ime klicatelja, v telefonu in izbrani napravi." "Dovoli" diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml index 9d52281f16e1..14acdf0d3158 100644 --- a/packages/CompanionDeviceManager/res/values-sq/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml @@ -25,17 +25,23 @@ "Të lejohet që <strong>%1$s</strong> të menaxhojë <strong>%2$s</strong>?" "pajisje" "Këtij aplikacioni do t\'i lejohet qasja te këto leje te %1$s" - "Të lejohet që <strong>%1$s</strong> të transmetojë aplikacionet nga %2$s te <strong>%3$s</strong>?" - "%1$s do të ketë qasje te çdo gjë që është e dukshme ose që luhet te %2$s, duke përfshirë audion, fotografitë, fjalëkalimet dhe mesazhet.<br/><br/>%1$s do të mund t\'i transmetojë aplikacionet në %3$s derisa ta heqësh qasjen për këtë leje." - "%1$s po kërkon leje në emër të %2$s për të shfaqur dhe transmetuar aplikacionet mes pajisjeve të tua" + + + + + + "Lejo që <strong>%1$s</strong> të ketë qasje në këto informacione te %2$s" "%1$s po kërkon leje në emër të %2$s për të marrë qasje te fotografitë, media dhe njoftimet te %3$s" - "Të lejohet që <strong>%1$s</strong> të transmetojë aplikacionet dhe veçoritë e sistemit nga %2$s te <strong>%3$s</strong>?" - "%1$s do të ketë qasje te çdo gjë që është e dukshme ose që luhet te %2$s, 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 në %3$s derisa ta heqësh qasjen për këtë leje." - "%1$s po kërkon leje në emër të %2$s për të transmetuar aplikacione dhe veçori të tjera të sistemit ndërmjet pajisjeve të tua" + + + + + + "pajisja" "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." "Lejo" diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml index 69af8ab6a3dd..3f1420b0ec8f 100644 --- a/packages/CompanionDeviceManager/res/values-sr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml @@ -25,17 +25,23 @@ "Желите ли да дозволите да <strong>%1$s</strong> управља уређајем <strong>%2$s</strong>?" "уређај" "Овој апликацији ће бити дозвољено да приступа овим дозволама на уређају %1$s" - "Желите ли да дозволите да <strong>%1$s</strong> стримује апликације уређаја %2$s на <strong>%3$s</strong>?" - "%1$s ће имати приступ свему што се види или пушта на уређају %2$s, укључујући звук, слике, лозинке и поруке.<br/><br/>%1$s ће моћи да стримује апликације на %3$s док не уклоните приступ овој дозволи." - "%1$s тражи дозволу у име уређаја %2$s да приказује и стримује апликације између уређаја" + + + + + + "Дозволите да <strong>%1$s</strong> приступа овим информацијама са уређаја %2$s" "%1$s тражи дозволу у име уређаја %2$s да приступа сликама, медијском садржају и обавештењима са уређаја %3$s" - "Желите ли да дозволите да <strong>%1$s</strong> стримује апликације и системске функције уређаја %2$s на <strong>%3$s</strong>?" - "%1$s ће имати приступ свему што се види или пушта на уређају %2$s, укључујући звук, слике, информације о плаћању, лозинке и поруке.<br/><br/>%1$s ће моћи да стримује апликације и системске функције на %3$s док не уклоните приступ овој дозволи." - "%1$s тражи дозволу у име уређаја %2$s да стримује апликације и друге системске функције између уређаја" + + + + + + "уређај" "Ова апликација ће моћи да синхронизује податке, попут имена особе која упућује позив, између телефона и одабраног уређаја" "Дозволи" diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml index 6ec27d224e92..cb7b7094fa1d 100644 --- a/packages/CompanionDeviceManager/res/values-sv/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml @@ -25,17 +25,17 @@ "Tillåt att <strong>%1$s</strong> hanterar <strong>%2$s</strong>" "enhet" "Appen får åtkomst till dessa behörigheter på din %1$s" - "Vill du tillåta <strong>%1$s</strong> att streama appar på din %2$s till <strong>%3$s</strong>?" - "%1$s får åtkomst till allt som visas eller spelas upp på din %2$s, inklusive ljud, foton, lösenord och meddelanden.<br/><br/>%1$s kan streama appar till %3$s tills du tar bort åtkomsten till den här behörigheten." - "%1$s begär behörighet för din %2$s att visa och streama appar mellan dina enheter" + "Vill du tillåta <strong>%1$s</strong> att streama appar och systemfunktioner på din %2$s till <strong>%3$s</strong>?" + "%1$s får åtkomst till allt som visas eller spelas upp på din %2$s, inklusive ljud, foton, betalningsuppgifter, lösenord och meddelanden.<br/><br/>%1$s kan streama appar till %3$s tills du tar bort åtkomsten till den här behörigheten." + "%1$s begär behörighet för %2$s att streama appar och systemfunktioner från din %3$s" "Ge <strong>%1$s</strong> åtkomst till denna information på din %2$s" "%1$s begär behörighet för din %2$s att få åtkomst till foton, mediefiler och aviseringar på din %3$s" - "Vill du tillåta <strong>%1$s</strong> att streama appar och systemfunktioner på din %2$s till <strong>%3$s</strong>?" - "%1$s får åtkomst till allt som visas eller spelas upp på din %2$s, inklusive ljud, foton, betalningsuppgifter, lösenord och meddelanden.<br/><br/>%1$s kan streama appar och systemfunktioner till %3$s tills du tar bort åtkomsten till den här behörigheten." - "%1$s begär behörighet för din %2$s att streama appar och andra systemfunktioner mellan dina enheter" + "Vill du tillåta <strong>%1$s</strong> att streama appar på din %2$s till <strong>%3$s</strong>?" + "%1$s får åtkomst till allt som visas eller spelas upp på %3$s, inklusive ljud, foton, betalningsuppgifter, lösenord och meddelanden.<br/><br/>%1$s kan streama appar till %3$s tills du tar bort åtkomsten till den här behörigheten." + "%1$s begär behörighet för %2$s att streama appar från din %3$s" "enhet" "Den här appen kommer att kunna synkronisera information mellan telefonen och den valda enheten, till exempel namnet på någon som ringer" "Tillåt" diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml index 8efcb2ba0f8d..ca8fd2257922 100644 --- a/packages/CompanionDeviceManager/res/values-sw/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml @@ -25,17 +25,23 @@ "Ungependa kuruhusu <strong>%1$s</strong> idhibiti <strong>%2$s</strong>?" "kifaa" "Programu hii itaruhusiwa kufikia ruhusa hizi kwenye %1$s yako" - "Ungependa kuruhusu <strong>%1$s</strong> itiririshe programu za %2$s yako kwenye <strong>%3$s</strong>?" - "%1$s itafikia chochote kinachoonekana au kuchezwa kwenye %2$s, ikiwa ni pamoja na sauti, picha, manenosiri na ujumbe.<br/><br/>%1$s itaweza kutiririsha programu kwenye %3$s hadi utakapoondoa ruhusa hii." - "Programu ya %1$s inaomba ruhusa kwa niaba ya %2$s yako ili ionyeshe na kutiririsha programu kati ya vifaa vyako" + + + + + + "Ruhusu <strong>%1$s</strong> ifikie maelezo haya kutoka kwenye %2$s yako" "Programu ya %1$s inaomba ruhusa kwa niaba ya %2$s yako ili ifikie picha, maudhui na arifa za %3$s yako" - "Ungependa kuruhusu <strong>%1$s</strong> itiririshe programu na vipengele vya mfumo vya %2$s yako kwenye <strong>%3$s</strong>?" - "%1$s itafikia chochote kinachoonekana au kuchezwa kwenye %2$s yako, ikiwa ni pamoja na sauti, picha, maelezo ya malipo, manenosiri na ujumbe.<br/><br/>%1$s itaweza kutiririsha programu na vipengele vya mfumo kwenye %3$s hadi utakapoondoa ruhusa hii." - "Programu ya %1$s inaomba ruhusa kwa niaba ya %2$s yako ili itiririshe programu na vipengele vingine vya mfumo kati ya vifaa vyako" + + + + + + "kifaa" "Programu hii itaweza kusawazisha maelezo, kama vile jina la mtu anayepiga simu, kati ya simu yako na kifaa ulichochagua" "Ruhusu" diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml index 1a59c09c73a4..76e6410e8d32 100644 --- a/packages/CompanionDeviceManager/res/values-ta/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml @@ -25,17 +25,23 @@ "<strong>%2$s</strong&gt சாதனத்தை நிர்வகிக்க <strong>%1$s</strong> ஆப்ஸை அனுமதிக்கவா?" "சாதனம்" "உங்கள் %1$s சாதனத்தில் இந்த அனுமதிகளை அணுக இந்த ஆப்ஸ் அனுமதிக்கப்படும்" - "உங்கள் %2$s சாதனத்தின் ஆப்ஸை <strong>%3$s</strong> சாதனத்தில் ஸ்ட்ரீம் செய்ய <strong>%1$s</strong> ஆப்ஸை அனுமதிக்கவா?" - "ஆடியோ, படங்கள், கடவுச்சொற்கள், மெசேஜ்கள் உட்பட %2$s சாதனத்தில் காட்டப்படுகின்ற/பிளே செய்யப்படுகின்ற அனைத்தையும் %1$s அணுகும்.<br/><br/>இந்த அனுமதிக்கான அணுகலை நீங்கள் அகற்றும் வரை %3$s சாதனத்தில் ஆப்ஸை %1$s ஸ்ட்ரீம் செய்ய முடியும்." - "உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸைக் காட்சிப்படுத்தவும் ஸ்ட்ரீம் செய்யவும் உங்கள் %2$s சார்பாக %1$s அனுமதி கேட்கிறது" + + + + + + "உங்கள் %2$s சாதனத்தில் உள்ள இந்தத் தகவல்களை அணுக, <strong>%1$s</strong> ஆப்ஸை அனுமதிக்கவும்" "உங்கள் %3$s சாதனத்தில் உள்ள படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை அணுக உங்கள் %2$s சார்பாக %1$s அனுமதி கேட்கிறது" - "உங்கள் %2$s சாதனத்தின் ஆப்ஸையும் சிஸ்டம் அம்சங்களையும் <strong>%3$s</strong> சாதனத்தில் ஸ்ட்ரீம் செய்ய <strong>%1$s</strong> சாதனத்தை அனுமதிக்கவா?" - "ஆடியோ, படங்கள், பேமெண்ட் தகவல்கள், கடவுச்சொற்கள், மெசேஜ்கள் உட்பட %2$s சாதனத்தில் காட்டப்படுகின்ற/பிளே செய்யப்படுகின்ற அனைத்தையும் %1$s அணுகும்.<br/><br/>இந்த அனுமதிக்கான அணுகலை நீங்கள் அகற்றும் வரை %3$s சாதனத்தில் ஆப்ஸையும் சிஸ்டம் அம்சங்களையும் %1$s ஸ்ட்ரீம் செய்ய முடியும்." - "உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸையும் பிற சிஸ்டம் அம்சங்களையும் ஸ்ட்ரீம் செய்ய உங்கள் %2$s சார்பாக %1$s அனுமதி கேட்கிறது" + + + + + + "சாதனம்" "அழைப்பவரின் பெயர் போன்ற தகவலை உங்கள் மொபைல் மற்றும் தேர்வுசெய்த சாதனத்திற்கு இடையில் இந்த ஆப்ஸால் ஒத்திசைக்க முடியும்" "அனுமதி" diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml index 63d86fc724ad..2d3f2f3a89be 100644 --- a/packages/CompanionDeviceManager/res/values-te/strings.xml +++ b/packages/CompanionDeviceManager/res/values-te/strings.xml @@ -25,17 +25,23 @@ "<strong>%2$s</strong>‌ను మేనేజ్ చేయడానికి <strong>%1$s</strong>‌ను అనుమతించాలా?" "పరికరం" "మీ %1$s‌లో ఈ అనుమతులను యాక్సెస్ చేయడానికి ఈ యాప్ అనుమతించబడుతుంది" - "మీ %2$s యాప్‌లను <strong>%3$s</strong>‌కు స్ట్రీమ్ చేయడానికి <strong>%1$s</strong>‌ను అనుమతించాలా?" - "ఆడియో, ఫోటోలు, పాస్‌వర్డ్‌లు, మెసేజ్‌లతో సహా మీ %2$s‌లో కనిపించే లేదా ప్లే అయ్యే దేనికైనా %1$s‌కు యాక్సెస్ ఉంటుంది.<br/><br/>మీరు ఈ అనుమతికి యాక్సెస్‌ను తీసివేసే వరకు %1$s %3$s‌కు యాప్‌లను స్ట్రీమ్ చేయగలదు." - "మీ పరికరాలలో యాప్‌లను డిస్‌ప్లే చేయడానికి, స్ట్రీమ్ చేయడానికి %1$s మీ%2$s తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది" + + + + + + "మీ %2$s నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి <strong>%1$s</strong>‌ను అనుమతించండి" "మీ %3$s ఫోటోలను, మీడియాను, ఇంకా నోటిఫికేషన్‌లను యాక్సెస్ చేయడానికి %1$s మీ %2$s తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది" - "మీ %2$s యాప్‌లను, సిస్టమ్ ఫీచర్‌లను <strong>%3$s</strong>‌కు స్ట్రీమ్ చేయడానికి <strong>%1$s</strong>‌ను అనుమతించాలా?" - "ఆడియో, ఫోటోలు, పేమెంట్ సమాచారం, పాస్‌వర్డ్‌లతో సహా మీ %2$s‌లో కనిపించే లేదా ప్లే అయ్యే దేనికైనా %1$s‌కు యాక్సెస్ ఉంటుంది.<br/><br/>మీరు ఈ అనుమతికి యాక్సెస్‌ను తీసివేసే వరకు %1$s %3$s‌కు యాప్‌లను, సిస్టమ్ ఫీచర్‌లను స్ట్రీమ్ చేయగలదు." - "మీ పరికరాలలో యాప్‌లను, ఇతర సిస్టమ్ ఫీచర్‌లను స్ట్రీమ్ చేయడానికి %1$s మీ %2$s తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది" + + + + + + "పరికరం" "కాల్ చేస్తున్న వారి పేరు వంటి సమాచారాన్ని ఈ యాప్ మీ ఫోన్ కు, ఎంచుకున్న పరికరానికీ మధ్య సింక్ చేయగలుగుతుంది" "అనుమతించండి" diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml index eb9a6edbe3d6..c15718620d55 100644 --- a/packages/CompanionDeviceManager/res/values-th/strings.xml +++ b/packages/CompanionDeviceManager/res/values-th/strings.xml @@ -25,17 +25,23 @@ "อนุญาตให้ <strong>%1$s</strong> จัดการ <strong>%2$s</strong> ไหม" "อุปกรณ์" "แอปนี้จะได้รับสิทธิ์ดังต่อไปนี้ใน%1$sของคุณ" - "อนุญาตให้ <strong>%1$s</strong> สตรีมแอปใน%2$sของคุณไปยัง <strong>%3$s</strong> ไหม" - "%1$s จะมีสิทธิ์เข้าถึงทุกอย่างที่ปรากฏหรือเล่นบน%2$s ซึ่งรวมถึงเสียง รูปภาพ รหัสผ่าน และข้อความ<br/><br/>%1$s จะสามารถสตรีมแอปไปยัง %3$s ได้จนกว่าคุณจะนำสิทธิ์เข้าถึงนี้ออก" - "%1$s กำลังขอสิทธิ์ในนามของ %2$s เพื่อแสดงและสตรีมแอประหว่างอุปกรณ์ต่างๆ ของคุณ" + + + + + + "อนุญาตให้ <strong>%1$s</strong> เข้าถึงข้อมูลนี้จาก%2$sของคุณ" "%1$s กำลังขอสิทธิ์ในนามของ %2$s เพื่อเข้าถึงรูปภาพ สื่อ และการแจ้งเตือนใน%3$sของคุณ" - "อนุญาตให้ <strong>%1$s</strong> สตรีมแอปและฟีเจอร์ของระบบใน%2$sของคุณไปยัง <strong>%3$s</strong> ไหม" - "%1$s จะมีสิทธิ์เข้าถึงทุกอย่างที่ปรากฏหรือเล่นบน%2$s ซึ่งรวมถึงเสียง รูปภาพ ข้อมูลการชำระเงิน รหัสผ่าน และข้อความ<br/><br/>%1$s จะสามารถสตรีมแอปและฟีเจอร์ของระบบไปยัง %3$s ได้จนกว่าคุณจะนำสิทธิ์เข้าถึงนี้ออก" - "%1$s กำลังขอสิทธิ์ในนามของ %2$s เพื่อสตรีมแอปและฟีเจอร์อื่นๆ ของระบบระหว่างอุปกรณ์" + + + + + + "อุปกรณ์" "แอปนี้จะสามารถซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา ระหว่างโทรศัพท์ของคุณและอุปกรณ์ที่เลือกไว้ได้" "อนุญาต" diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml index bce6c7ce5d9b..ffa91b19d83f 100644 --- a/packages/CompanionDeviceManager/res/values-tl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml @@ -25,17 +25,23 @@ "Payagan ang <strong>%1$s</strong> na pamahalaan ang <strong>%2$s</strong>?" "device" "Papayagan ang app na ito na ma-access ang mga pahintulot na ito sa iyong %1$s" - "Payagan ang <strong>%1$s</strong> na i-stream ang mga app ng iyong %2$s sa <strong>%3$s</strong>?" - "Magkakaroon ang %1$s ng access sa kahit anong nakikita o pine-play sa %2$s, kasama na ang audio, mga larawan, password, at mensahe.<br/><br/>Magagawa ng %1$s na mag-stream ng mga app sa %3$s hanggang sa alisin mo ang access sa pahintulot na ito." - "Humihiling ng pahintulot ang %1$s para sa iyong %2$s na makapagpakita at makapag-stream ng mga app sa mga device mo" + + + + + + "Payagan ang <strong>%1$s</strong> na i-access ang impormasyong ito sa iyong %2$s" "Humihiling ng pahintulot ang %1$s para sa iyong %2$s na ma-access ang mga larawan, media, at notification ng %3$s mo" - "Payagan ang <strong>%1$s</strong> na i-stream ang mga app at feature ng system ng iyong %2$s’ sa <strong>%3$s</strong>?" - "Magkakaroon ng access ang %1$s sa kahit anong nakikita o pine-play sa iyong %2$s, kasama ang audio, mga larawan, impormasyon sa pagbabayad, mga password, at mga mensahe.<br/><br/>Magagawa ng %1$s na mag-stream ng mga app sa %3$s hanggang sa alisin mo ang access sa pahintulot na ito." - "Humihiling ng pahintulot ang %1$s para sa iyong %2$s na mag-stream ng mga app at iba pang feature ng system sa pagitan ng mga device mo" + + + + + + "device" "Magagawa ng app na ito na mag-sync ng impormasyon, tulad ng pangalan ng isang taong tumatawag, sa pagitan ng iyong telepono at ng napiling device" "Payagan" diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml index 131f2e330354..44d6bf7da32c 100644 --- a/packages/CompanionDeviceManager/res/values-tr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong> uygulamasına <strong>%2$s</strong> cihazını yönetmesi için izin verilsin mi?" "Cihaz" "Bu uygulamanın %1$s cihazınızda şu izinlere erişmesine izin verilecek:" - "<strong>%1$s</strong> adlı uygulamanın %2$s cihazınızdaki uygulamaları <strong>%3$s</strong> cihazına aktarmasına izin verilsin mi?" - "%1$s; ses, fotoğraflar, şifreler ve mesajlar da dahil olmak üzere %2$s cihazında görünen veya oynatılan her şeye erişebilecek.<br/><br/>%1$s siz bu iznin erişimini kaldırana kadar uygulamaları %3$s cihazına aktarabilecek." - "%1$s, cihazlarınız arasında uygulamaları göstermek ve aktarmak için %2$s cihazınız adına izin istiyor" + + + + + + "<strong>%1$s</strong> uygulamasının, %2$s cihazınızdaki bu bilgilere erişmesine izin verin" "%1$s, %3$s içindeki fotoğraf, medya ve bildirimlere erişmek için %2$s cihazınız adına izin istiyor" - "<strong>%1$s</strong> adlı uygulamanın %2$s cihazınızdaki uygulamaları ve sistem özelliklerini <strong>%3$s</strong> cihazına aktarmasına izin verilsin mi?" - "%1$s; ses, fotoğraflar, ödeme bilgileri, şifreler ve mesajlar da dahil olmak üzere %2$s cihazınızda 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 %3$s cihazına aktarabilecek." - "%1$s, cihazlarınız arasında uygulamaları ve diğer sistem özelliklerini aktarmak için %2$s cihazınız adına izin istiyor" + + + + + + "cihaz" "Bu uygulama, arayan kişinin adı gibi bilgileri telefonunuz ve seçili cihaz arasında senkronize edebilir" "İzin ver" diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml index f170d3cc15e0..1d248b6570fc 100644 --- a/packages/CompanionDeviceManager/res/values-uk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml @@ -25,17 +25,23 @@ "Дозволити додатку <strong>%1$s</strong> керувати пристроєм <strong>%2$s</strong>?" "пристрій" "Цей додаток матиме доступ до перелічених нижче дозволів на вашому %1$s" - "Дозволити додатку <strong>%1$s</strong> транслювати додатки на вашому %2$s на пристрій <strong>%3$s</strong>?" - "Додаток %1$s матиме доступ до контенту, що відображається чи відтворюється на %2$s, зокрема до аудіо, фото, паролів і повідомлень.<br/><br/>Додаток %1$s зможе транслювати додатки на пристрої \"%3$s\", поки ви не скасуєте цей дозвіл." - "Додаток %1$s від імені вашого пристрою \"%2$s\" запитує дозвіл на відображення й транслювання додатків на ваших пристроях" + + + + + + "Дозвольте додатку <strong>%1$s</strong> доступ до цієї інформації на вашому %2$s" "Додаток %1$s від імені вашого пристрою \"%2$s\" запитує дозвіл на доступ до фотографій, медіафайлів і сповіщень на вашому %3$s" - "Дозволити пристрою <strong>%1$s</strong> транслювати додатки й системні функції на %2$s на пристрій <strong>%3$s</strong>?" - "Додаток %1$sматиме доступ до контенту, що відображається чи відтворюється на вашому %2$s, зокрема до аудіо, фото, платіжної інформації, паролів і повідомлень.<br/><br/>Додаток %1$s зможе транслювати додатки й системні функції на %3$s, поки ви не скасуєте цей дозвіл." - "Додаток %1$s від імені вашого пристрою \"%2$s\" запитує дозвіл на транслювання додатків й інших системних функцій на ваших пристроях" + + + + + + "пристрій" "Цей додаток зможе синхронізувати інформацію (наприклад, ім’я абонента, який викликає) між телефоном і вибраним пристроєм" "Дозволити" diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml index fd6537e98304..64732e814d00 100644 --- a/packages/CompanionDeviceManager/res/values-ur/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml @@ -25,17 +25,23 @@ "‏<strong>%1$s</strong> کو <strong>%2$s</strong> کا نظم کرنے کی اجازت دیں؟" "آلہ" "اس ایپ کو آپ کے %1$s پر ان اجازتوں تک رسائی کی اجازت ہوگی" - "‏<strong>%1$s</strong> کو آپ کے %2$s کی ایپس کو %3$s پر سلسلہ بندی کرنے کی اجازت دیں؟" - "‏%1$s کو %2$s پر دکھائی دینے والی یا چلائی جانے والی کسی بھی چیز تک رسائی حاصل ہوگی، بشمول آڈیو، تصاویر، پاس ورڈز اور پیغامات۔<br/><br/>%1$s %3$s پر اس وقت تک ایپس کی سلسلہ بندی کر سکے گی جب تک آپ اس اجازت تک رسائی کو ہٹا نہیں دیتے۔" - "%1$s ایپ آپ کے %2$s کی جانب سے آپ کے آلات کے درمیان ایپس کو ڈسپلے اور اسٹریم کرنے کے لیے اجازت کی درخواست کر رہی ہے" + + + + + + "‏‎<strong>%1$s</strong>‎ کو آپ کے %2$s سے ان معلومات تک رسائی حاصل کرنے کی اجازت دیں" "%1$s ایپ آپ کے %2$s کی جانب سے آپ کے %3$s کی تصاویر، میڈیا اور اطلاعات تک رسائی کی اجازت کی درخواست کر رہی ہے" - "‏‎<strong>%1$s</strong>‎ کو آپ کے %2$s کی ایپس اور سسٹم کی خصوصیات کو ‎<strong>%3$s</strong>‎ پر سلسلہ بندی کرنے کی اجازت دیں؟" - "‏%1$s کو آپ کے %2$s پر دکھائی دینے والی یا چلائی جانے والی کسی بھی چیز تک رسائی حاصل ہوگی، بشمول آڈیو، تصاویر، ادائیگی کی معلومات، پاس ورڈز اور پیغامات۔;lt;br/><br/&gt&%1$s %3$s پر اس وقت تک ایپس اور سسٹم کی خصوصیات کی سلسلہ بندی کر سکے گی جب تک آپ اس اجازت تک رسائی کو ہٹا نہیں دیتے۔" - "%1$s ایپ آپ کے %2$s کی جانب سے آپ کے آلات کے درمیان ایپس اور سسٹم کی دیگر خصوصیات کی سلسلہ بندی کرنے کی اجازت کی درخواست کر رہی ہے" + + + + + + "آلہ" "یہ ایپ آپ کے فون اور منتخب کردہ آلے کے درمیان معلومات، جیسے کسی کال کرنے والے کے نام، کی مطابقت پذیری کر سکے گی" "اجازت دیں" diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml index f7a1ef7883d7..4b0c48a181b0 100644 --- a/packages/CompanionDeviceManager/res/values-uz/strings.xml +++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml @@ -25,17 +25,23 @@ "<strong>%1$s</strong> ilovasiga <strong>%2$s</strong> qurilmasini boshqarish uchun ruxsat berilsinmi?" "qurilma" "Bu ilova %1$s qurilmasida quyidagi ruxsatlarni oladi" - "<strong>%1$s</strong> %2$sdagi ilovalarni <strong>%3$s</strong> qurilmasiga striming qilishiga ruxsat berasizmi?" - "%1$s %2$sda koʻrinadigan yoki ijro etiladigan hamma narsaga, jumladan, audio, rasmlar, parollar va xabarlarga kirish huquqini oladi.<br/><br/>Bu ruxsatni olib tashlamaguningizcha, %1$s ilovalarni %3$s qurilmasiga striming qila oladi." - "%1$s ilovasi %2$s nomidan ilovalarni koʻrsatish va striming qilishga ruxsat soʻramoqda" + + + + + + "<strong>%1$s</strong> ilovasiga %2$sdagi ushbu maʼlumot uchun ruxsat bering" "%1$s ilovasi %2$s nomidan %3$sdagi suratlar, media va bildirishnomalarga kirish uchun ruxsat soʻramoqda" - "<strong>%1$s</strong> %2$sdagi ilovalar va tizim funksiyalarini <strong>%3$s</strong> qurilmasiga striming qilishiga ruxsat berasizmi?" - "%1$s %2$sda koʻrinadigan yoki ijro etiladigan hamma narsaga, jumladan, audio, rasmlar, toʻlov axboroti, parollar va xabarlarga kirish huquqini oladi.<br/><br/>Bu ruxsatni olib tashlamaguningizcha, %1$s ilovalarni va tizim funksiyalarini %3$s qurilmasiga striming qila oladi." - "%1$s qurilmalaringiz orasida ilovalar va boshqa tizim funksiyalarini striming qilish uchun %2$s nomidan ruxsat soʻramoqda" + + + + + + "qurilma" "Bu ilova telefoningiz va tanlangan qurilmada chaqiruvchining ismi kabi maʼlumotlarni sinxronlay oladi" "Ruxsat" diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml index e668a6915b88..0b65172e9980 100644 --- a/packages/CompanionDeviceManager/res/values-vi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml @@ -25,17 +25,23 @@ "Cho phép <strong>%1$s</strong> quản lý <strong>%2$s</strong>?" "thiết bị" "Ứng dụng này sẽ được phép dùng những quyền sau trên %1$s của bạn" - "Cho phép <strong>%1$s</strong> truyền trực tuyến các ứng dụng trên %2$s của bạn đến <strong>%3$s</strong>?" - "%1$s sẽ có quyền truy cập vào mọi nội dung hiển thị hoặc phát trên %2$s, bao gồm cả âm thanh, ảnh, mật khẩu và tin nhắn.<br/><br/>%1$s sẽ có thể truyền trực tuyến các ứng dụng đến %3$s cho đến khi bạn thu hồi quyền này." - "%1$s đang yêu cầu quyền thay cho %2$s để hiển thị và truyền trực tuyến các ứng dụng giữa các thiết bị của bạn" + + + + + + "Cho phép <strong>%1$s</strong> truy cập vào thông tin này trên %2$s của bạn" "%1$s đang yêu cầu quyền thay cho %2$s để truy cập vào ảnh, nội dung nghe nhìn và thông báo trên %3$s của bạn" - "Cho phép <strong>%1$s</strong> truyền trực tuyến các ứng dụng và tính năng của hệ thống trên %2$s của bạn đến <strong>%3$s</strong>?" - "%1$s sẽ có quyền truy cập vào mọi nội dung hiển thị hoặc phát trên %2$s của bạn, bao gồm cả âm thanh, ảnh, thông tin thanh toán, mật khẩu và tin nhắn.<br/><br/>%1$s sẽ có thể truyền trực tuyến các ứng dụng và tính năng của hệ thống đến %3$s cho đến khi bạn thu hồi quyền này." - "%1$s đang yêu cầu quyền thay cho %2$s để truyền trực tuyến các ứng dụng và những tính năng khác của hệ thống giữa các thiết bị của bạn" + + + + + + "thiết bị" "Ứng dụng này sẽ đồng bộ hoá thông tin (ví dụ: tên người gọi) giữa điện thoại của bạn và thiết bị bạn chọn" "Cho phép" diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml index 8adb16009174..80e2d50b9735 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml @@ -25,17 +25,23 @@ "允许<strong>%1$s</strong>管理<strong>%2$s</strong>?" "设备" "该应用将能获得您%1$s上的以下权限" - "允许<strong>%1$s</strong>将您%2$s上的应用流式传输到<strong>%3$s</strong>吗?" - "“%1$s”将能访问%2$s上可见或播放的任何内容,包括音频、照片、密码和消息。<br/><br/>“%1$s”能将应用流式传输到“%3$s”,除非您撤消此访问权限。" - "“%1$s”正代表您的“%2$s”请求在设备之间显示和流式传输应用" + + + + + + "允许<strong>%1$s</strong>访问您%2$s中的这项信息" "“%1$s”正代表您的“%2$s”请求访问您%3$s上的照片、媒体内容和通知" - "允许<strong>%1$s</strong>将您%2$s上的应用和系统功能流式传输到<strong>%3$s</strong>吗?" - "“%1$s”将能访问您%2$s上可见或播放的任何内容,包括音频、照片、付款信息、密码和消息。<br/><br/>“%1$s”能将应用和系统功能流式传输到“%3$s”,除非您撤消此访问权限。" - "“%1$s”正代表您的“%2$s”请求在设备之间流式传输应用和其他系统功能" + + + + + + "设备" "此应用将能在您的手机和所选设备之间同步信息,例如来电者的姓名" "允许" diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml index fee37dd834b9..cfb14220d07b 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml @@ -25,17 +25,23 @@ "要允許「%1$s」<strong></strong>管理「%2$s」<strong></strong>嗎?" "裝置" "此應用程式將可在%1$s上取得以下權限" - "要允許「%1$s」串流%2$s應用程式內容至「%3$s」嗎?" - "「%1$s」將能存取%2$s上顯示或播放的任何內容,包括音訊、相片、密碼和訊息。<br/><br/>「%1$s」將能串流應用程式內容至「%3$s」,直至你移除此存取權限為止。" - "「%1$s」正在代表「%2$s」要求權限,以便在裝置間顯示和串流應用程式的內容" + + + + + + "允許「%1$s」在%2$s上存取這項資料" "「%1$s」正在代表「%2$s」要求權限,以便存取%3$s上的相片、媒體和通知" - "要允許「%1$s」串流%2$s應用程式內容和系統功能至「%3$s」嗎?" - "「%1$s」將能存取%2$s上顯示或播放的任何內容,包括音訊、相片、付款資料、密碼和訊息。<br/><br/>「%1$s」將能串流應用程式內容和系統功能至「%3$s」,直至你移除此存取權限為止。" - "「%1$s」正在代表「%2$s」要求權限,以便在裝置間串流應用程式內容和其他系統功能" + + + + + + "裝置" "此應用程式將可同步手機和所選裝置的資訊,例如來電者的名稱" "允許" diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml index 28a3baf0c3bf..490d1bd7b556 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml @@ -25,17 +25,23 @@ "要允許「%1$s」<strong></strong>管理「%2$s」<strong></strong>嗎?" "裝置" "這個應用程式將可取得%1$s上的這些權限" - "要允許「%1$s」<strong></strong>將%2$s的應用程式串流傳輸到 <strong>%3$s</strong> 嗎?" - "「%1$s」將可存取%2$s顯示或播放的所有內容,包括音訊、相片、密碼和訊息。<br/><br/>「%1$s」可將應用程式串流傳輸到 %3$s,直到你移除這個權限為止。" - "「%1$s」正在代表你的 %2$s 要求必要權限,以便在裝置間顯示及串流傳輸應用程式" + + + + + + "允許「%1$s」<strong></strong>存取%2$s中的這項資訊" "「%1$s」正在代表你的 %2$s 要求必要權限,以便存取%3$s上的相片、媒體和通知" - "要允許「%1$s」<strong></strong>將%2$s的應用程式和系統功能串流傳輸到 <strong>%3$s</strong> 嗎?" - "「%1$s」將可存取%2$s顯示或播放的所有內容,包括音訊、相片、付款資訊、密碼和訊息。<br/><br/>「%1$s」可將應用程式和系統功能串流傳輸到 %3$s,直到你移除這個權限為止。" - "「%1$s」正在代表 %2$s 要求必要權限,以便在裝置間串流傳輸應用程式和其他系統功能" + + + + + + "裝置" "這個應用程式將可在手機和指定裝置間同步資訊,例如來電者名稱" "允許" diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml index 5966f8b1625a..3003fb84418c 100644 --- a/packages/CompanionDeviceManager/res/values-zu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml @@ -25,17 +25,23 @@ "Vumela i-<strong>%1$s</strong> ukuthi ifinyelele i-<strong>%2$s</strong>" "idivayisi" "Le-app izovunyelwa ukufinyelela lezi zimvume ku-%1$s yakho" - "Vumela <strong>i-%1$s</strong> ukuze isakaze ama-app e-%2$s yakho <strong>ku-%3$s</strong>?" - "I-%1$s izokwazi ukufinyelela kunoma yini ebonakalayo noma edlalwayo ku-%2$s, okuhlanganisa umsindo, izithombe, amaphasiwedi, nemilayezo.<br/><br/>I-%1$s izokwazi ukusakaza ama-app ku-%3$s uze ususe ukufinyelela kule mvume." - "I-%1$s icela imvume esikhundleni se-%2$s yakho yokubonisa nokusakaza ama-app phakathi kwamadivayisi wakho" + + + + + + "Vumela <strong>i-%1$s</strong> ukuze ifinyelele lolu lwazi ukusuka ku-%2$s yakho" "I-%1$s icela imvume esikhundleni se-%2$s yakho ukuze ifinyelele izithombe ze-%3$s yakho, imidiya nezaziso" - "Vumela <strong>i-%1$s</strong> ukuze isakaze ama-app e-%2$s yakho nezakhi zesistimu <strong>ku-%3$s</strong>?" - "I-%1$s izokwazi ukufinyelela kunoma yini ebonakalayo noma edlalwayo ku-%2$s yakho, okuhlanganisa umsindo, izithombe, ulwazi lokukhokha, amaphasiwedi, nemilayezo.<br/><br/>I-%1$s izokwazi ukusakaza ama-app nezakhi zesistimu ku-%3$s uze ususe ukufinyelela kule mvume." - "I-%1$s icela imvume esikhundleni se-%2$s yakho ukuze isakaze ama-app nezinye zakhi zesistimu phakathi kwamadivayisi wakho" + + + + + + "idivayisi" "Le app izokwazi ukuvumelanisa ulwazi, njengegama lomuntu othile ofonayo, phakathi kwefoni yakho nedivayisi ekhethiwe" "Vumela" -- GitLab From c59ea36be72647786b696814a64391fa914ed6d8 Mon Sep 17 00:00:00 2001 From: Prabir Pradhan Date: Mon, 7 Oct 2024 18:26:11 +0000 Subject: [PATCH 141/447] Revert "An optimization for Pointer Location for drawing the trace" This reverts commit c8c41e4868e42cf9a64d0a86376fe2301800f6a6. Reason for revert: b/370635820 Change-Id: Ia9a56c9181800f18d499346fd5d0399083816be7 --- .../internal/widget/PointerLocationView.java | 175 +++++++++--------- 1 file changed, 86 insertions(+), 89 deletions(-) diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java index c0a7383c9f06..e65b4b65945f 100644 --- a/core/java/com/android/internal/widget/PointerLocationView.java +++ b/core/java/com/android/internal/widget/PointerLocationView.java @@ -16,19 +16,14 @@ package com.android.internal.widget; -import static java.lang.Float.NaN; - import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; -import android.graphics.Bitmap; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.Insets; import android.graphics.Paint; import android.graphics.Paint.FontMetricsInt; import android.graphics.Path; -import android.graphics.PorterDuff; import android.graphics.RectF; import android.graphics.Region; import android.hardware.input.InputManager; @@ -70,14 +65,11 @@ public class PointerLocationView extends View implements InputDeviceListener, private static final PointerState EMPTY_POINTER_STATE = new PointerState(); public static class PointerState { - private float mCurrentX = NaN; - private float mCurrentY = NaN; - private float mPreviousX = NaN; - private float mPreviousY = NaN; - private float mFirstX = NaN; - private float mFirstY = NaN; - private boolean mPreviousPointIsHistorical; - private boolean mCurrentPointIsHistorical; + // Trace of previous points. + private float[] mTraceX = new float[32]; + private float[] mTraceY = new float[32]; + private boolean[] mTraceCurrent = new boolean[32]; + private int mTraceCount; // True if the pointer is down. @UnsupportedAppUsage @@ -104,20 +96,31 @@ public class PointerLocationView extends View implements InputDeviceListener, public PointerState() { } - public void addTrace(float x, float y, boolean isHistorical) { - if (Float.isNaN(mFirstX)) { - mFirstX = x; - } - if (Float.isNaN(mFirstY)) { - mFirstY = y; + public void clearTrace() { + mTraceCount = 0; + } + + public void addTrace(float x, float y, boolean current) { + int traceCapacity = mTraceX.length; + if (mTraceCount == traceCapacity) { + traceCapacity *= 2; + float[] newTraceX = new float[traceCapacity]; + System.arraycopy(mTraceX, 0, newTraceX, 0, mTraceCount); + mTraceX = newTraceX; + + float[] newTraceY = new float[traceCapacity]; + System.arraycopy(mTraceY, 0, newTraceY, 0, mTraceCount); + mTraceY = newTraceY; + + boolean[] newTraceCurrent = new boolean[traceCapacity]; + System.arraycopy(mTraceCurrent, 0, newTraceCurrent, 0, mTraceCount); + mTraceCurrent= newTraceCurrent; } - mPreviousX = mCurrentX; - mPreviousY = mCurrentY; - mCurrentX = x; - mCurrentY = y; - mPreviousPointIsHistorical = mCurrentPointIsHistorical; - mCurrentPointIsHistorical = isHistorical; + mTraceX[mTraceCount] = x; + mTraceY[mTraceCount] = y; + mTraceCurrent[mTraceCount] = current; + mTraceCount += 1; } } @@ -146,12 +149,6 @@ public class PointerLocationView extends View implements InputDeviceListener, private final SparseArray mPointers = new SparseArray(); private final PointerCoords mTempCoords = new PointerCoords(); - // Draw the trace of all pointers in the current gesture in a separate layer - // that is not cleared on every frame so that we don't have to re-draw the - // entire trace on each frame. - private final Bitmap mTraceBitmap; - private final Canvas mTraceCanvas; - private final Region mSystemGestureExclusion = new Region(); private final Region mSystemGestureExclusionRejected = new Region(); private final Path mSystemGestureExclusionPath = new Path(); @@ -200,10 +197,6 @@ public class PointerLocationView extends View implements InputDeviceListener, mPathPaint.setARGB(255, 0, 96, 255); mPathPaint.setStyle(Paint.Style.STROKE); - mTraceBitmap = Bitmap.createBitmap(getResources().getDisplayMetrics().widthPixels, - getResources().getDisplayMetrics().heightPixels, Bitmap.Config.ARGB_8888); - mTraceCanvas = new Canvas(mTraceBitmap); - configureDensityDependentFactors(); mSystemGestureExclusionPaint = new Paint(); @@ -263,7 +256,7 @@ public class PointerLocationView extends View implements InputDeviceListener, protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mTextPaint.getFontMetricsInt(mTextMetrics); - mHeaderBottom = mHeaderPaddingTop - mTextMetrics.ascent + mTextMetrics.descent + 2; + mHeaderBottom = mHeaderPaddingTop-mTextMetrics.ascent+mTextMetrics.descent+2; if (false) { Log.i("foo", "Metrics: ascent=" + mTextMetrics.ascent + " descent=" + mTextMetrics.descent @@ -276,7 +269,6 @@ public class PointerLocationView extends View implements InputDeviceListener, // Draw an oval. When angle is 0 radians, orients the major axis vertically, // angles less than or greater than 0 radians rotate the major axis left or right. private RectF mReusableOvalRect = new RectF(); - private void drawOval(Canvas canvas, float x, float y, float major, float minor, float angle, Paint paint) { canvas.save(Canvas.MATRIX_SAVE_FLAG); @@ -293,8 +285,6 @@ public class PointerLocationView extends View implements InputDeviceListener, protected void onDraw(Canvas canvas) { final int NP = mPointers.size(); - canvas.drawBitmap(mTraceBitmap, 0, 0, null); - if (!mSystemGestureExclusion.isEmpty()) { mSystemGestureExclusionPath.reset(); mSystemGestureExclusion.getBoundaryPath(mSystemGestureExclusionPath); @@ -313,9 +303,32 @@ public class PointerLocationView extends View implements InputDeviceListener, // Pointer trace. for (int p = 0; p < NP; p++) { final PointerState ps = mPointers.valueAt(p); - float lastX = ps.mCurrentX, lastY = ps.mCurrentY; - if (!Float.isNaN(lastX) && !Float.isNaN(lastY)) { + // Draw path. + final int N = ps.mTraceCount; + float lastX = 0, lastY = 0; + boolean haveLast = false; + boolean drawn = false; + mPaint.setARGB(255, 128, 255, 255); + for (int i=0; i < N; i++) { + float x = ps.mTraceX[i]; + float y = ps.mTraceY[i]; + if (Float.isNaN(x) || Float.isNaN(y)) { + haveLast = false; + continue; + } + if (haveLast) { + canvas.drawLine(lastX, lastY, x, y, mPathPaint); + final Paint paint = ps.mTraceCurrent[i - 1] ? mCurrentPointPaint : mPaint; + canvas.drawPoint(lastX, lastY, paint); + drawn = true; + } + lastX = x; + lastY = y; + haveLast = true; + } + + if (drawn) { // Draw velocity vector. mPaint.setARGB(255, 255, 64, 128); float xVel = ps.mXVelocity * (1000 / 60); @@ -340,7 +353,7 @@ public class PointerLocationView extends View implements InputDeviceListener, Math.max(getHeight(), getWidth()), mTargetPaint); // Draw current point. - int pressureLevel = (int) (ps.mCoords.pressure * 255); + int pressureLevel = (int)(ps.mCoords.pressure * 255); mPaint.setARGB(255, pressureLevel, 255, 255 - pressureLevel); canvas.drawPoint(ps.mCoords.x, ps.mCoords.y, mPaint); @@ -411,7 +424,8 @@ public class PointerLocationView extends View implements InputDeviceListener, .append(" / ").append(mMaxNumPointers) .toString(), 1, base, mTextPaint); - if ((mCurDown && ps.mCurDown) || Float.isNaN(ps.mCurrentX)) { + final int count = ps.mTraceCount; + if ((mCurDown && ps.mCurDown) || count == 0) { canvas.drawRect(itemW, mHeaderPaddingTop, (itemW * 2) - 1, bottom, mTextBackgroundPaint); canvas.drawText(mText.clear() @@ -423,8 +437,8 @@ public class PointerLocationView extends View implements InputDeviceListener, .append("Y: ").append(ps.mCoords.y, 1) .toString(), 1 + itemW * 2, base, mTextPaint); } else { - float dx = ps.mCurrentX - ps.mFirstX; - float dy = ps.mCurrentY - ps.mFirstY; + float dx = ps.mTraceX[count - 1] - ps.mTraceX[0]; + float dy = ps.mTraceY[count - 1] - ps.mTraceY[0]; canvas.drawRect(itemW, mHeaderPaddingTop, (itemW * 2) - 1, bottom, Math.abs(dx) < mVC.getScaledTouchSlop() ? mTextBackgroundPaint : mTextLevelPaint); @@ -551,9 +565,9 @@ public class PointerLocationView extends View implements InputDeviceListener, .append(" TouchMinor=").append(coords.touchMinor, 3) .append(" ToolMajor=").append(coords.toolMajor, 3) .append(" ToolMinor=").append(coords.toolMinor, 3) - .append(" Orientation=").append((float) (coords.orientation * 180 / Math.PI), 1) + .append(" Orientation=").append((float)(coords.orientation * 180 / Math.PI), 1) .append("deg") - .append(" Tilt=").append((float) ( + .append(" Tilt=").append((float)( coords.getAxisValue(MotionEvent.AXIS_TILT) * 180 / Math.PI), 1) .append("deg") .append(" Distance=").append(coords.getAxisValue(MotionEvent.AXIS_DISTANCE), 1) @@ -584,7 +598,6 @@ public class PointerLocationView extends View implements InputDeviceListener, mCurNumPointers = 0; mMaxNumPointers = 0; mVelocity.clear(); - mTraceCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); if (mAltVelocity != null) { mAltVelocity.clear(); } @@ -633,8 +646,7 @@ public class PointerLocationView extends View implements InputDeviceListener, logCoords("Pointer", action, i, coords, id, event); } if (ps != null) { - ps.addTrace(coords.x, coords.y, true); - updateDrawTrace(ps); + ps.addTrace(coords.x, coords.y, false); } } } @@ -647,8 +659,7 @@ public class PointerLocationView extends View implements InputDeviceListener, logCoords("Pointer", action, i, coords, id, event); } if (ps != null) { - ps.addTrace(coords.x, coords.y, false); - updateDrawTrace(ps); + ps.addTrace(coords.x, coords.y, true); ps.mXVelocity = mVelocity.getXVelocity(id); ps.mYVelocity = mVelocity.getYVelocity(id); if (mAltVelocity != null) { @@ -691,26 +702,13 @@ public class PointerLocationView extends View implements InputDeviceListener, if (mActivePointerId == id) { mActivePointerId = event.getPointerId(index == 0 ? 1 : 0); } - ps.addTrace(Float.NaN, Float.NaN, true); + ps.addTrace(Float.NaN, Float.NaN, false); } } invalidate(); } - private void updateDrawTrace(PointerState ps) { - mPaint.setARGB(255, 128, 255, 255); - float x = ps.mCurrentX; - float y = ps.mCurrentY; - float lastX = ps.mPreviousX; - float lastY = ps.mPreviousY; - if (!Float.isNaN(x) && !Float.isNaN(y) && !Float.isNaN(lastX) && !Float.isNaN(lastY)) { - mTraceCanvas.drawLine(lastX, lastY, x, y, mPathPaint); - Paint paint = ps.mPreviousPointIsHistorical ? mPaint : mCurrentPointPaint; - mTraceCanvas.drawPoint(lastX, lastY, paint); - } - } - @Override public boolean onTouchEvent(MotionEvent event) { onPointerEvent(event); @@ -769,7 +767,7 @@ public class PointerLocationView extends View implements InputDeviceListener, return true; default: return KeyEvent.isGamepadButton(keyCode) - || KeyEvent.isModifierKey(keyCode); + || KeyEvent.isModifierKey(keyCode); } } @@ -889,7 +887,7 @@ public class PointerLocationView extends View implements InputDeviceListener, public FasterStringBuilder append(int value, int zeroPadWidth) { final boolean negative = value < 0; if (negative) { - value = -value; + value = - value; if (value < 0) { append("-2147483648"); return this; @@ -975,27 +973,26 @@ public class PointerLocationView extends View implements InputDeviceListener, private ISystemGestureExclusionListener mSystemGestureExclusionListener = new ISystemGestureExclusionListener.Stub() { - @Override - public void onSystemGestureExclusionChanged(int displayId, - Region systemGestureExclusion, - Region systemGestureExclusionUnrestricted) { - Region exclusion = Region.obtain(systemGestureExclusion); - Region rejected = Region.obtain(); - if (systemGestureExclusionUnrestricted != null) { - rejected.set(systemGestureExclusionUnrestricted); - rejected.op(exclusion, Region.Op.DIFFERENCE); - } - Handler handler = getHandler(); - if (handler != null) { - handler.post(() -> { - mSystemGestureExclusion.set(exclusion); - mSystemGestureExclusionRejected.set(rejected); - exclusion.recycle(); - invalidate(); - }); - } - } - }; + @Override + public void onSystemGestureExclusionChanged(int displayId, Region systemGestureExclusion, + Region systemGestureExclusionUnrestricted) { + Region exclusion = Region.obtain(systemGestureExclusion); + Region rejected = Region.obtain(); + if (systemGestureExclusionUnrestricted != null) { + rejected.set(systemGestureExclusionUnrestricted); + rejected.op(exclusion, Region.Op.DIFFERENCE); + } + Handler handler = getHandler(); + if (handler != null) { + handler.post(() -> { + mSystemGestureExclusion.set(exclusion); + mSystemGestureExclusionRejected.set(rejected); + exclusion.recycle(); + invalidate(); + }); + } + } + }; @Override protected void onConfigurationChanged(Configuration newConfig) { -- GitLab From 7479ec6aee5cb7b202872aaed7390f4e6b9c027c Mon Sep 17 00:00:00 2001 From: Liefu Liu Date: Tue, 24 Sep 2024 21:12:22 -0700 Subject: [PATCH 142/447] Added the DefaultAccount.getEligibleCloudAccounts API Bug: 352313110,364637693,359957924 Fix: 359957924 Test: added new test Flag: android.provider.new_default_account_api_enabled API-Coverage-Bug: 369343261 modified: core/api/system-current.txt modified: core/java/android/provider/ContactsContract.java Change-Id: I00961ea46bdf716309554dcb7be3294670a27dcd --- core/api/system-current.txt | 1 + .../android/provider/ContactsContract.java | 51 ++++++++++--------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 8a0b1bac2651..1b180e9b8579 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -11956,6 +11956,7 @@ package android.provider { } @FlaggedApi("android.provider.new_default_account_api_enabled") public static final class ContactsContract.RawContacts.DefaultAccount { + method @FlaggedApi("android.provider.new_default_account_api_enabled") @NonNull @RequiresPermission(android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS) public static java.util.List getEligibleCloudAccounts(@NonNull android.content.ContentResolver); method @FlaggedApi("android.provider.new_default_account_api_enabled") @RequiresPermission(allOf={android.Manifest.permission.READ_CONTACTS, android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS}) public static int getNumberOfMovableLocalContacts(@NonNull android.content.ContentResolver); method @FlaggedApi("android.provider.new_default_account_api_enabled") @RequiresPermission(allOf={android.Manifest.permission.READ_CONTACTS, android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS}) public static int getNumberOfMovableSimContacts(@NonNull android.content.ContentResolver); method @FlaggedApi("android.provider.new_default_account_api_enabled") @RequiresPermission(allOf={android.Manifest.permission.WRITE_CONTACTS, android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS}) public static void moveLocalContactsToCloudDefaultAccount(@NonNull android.content.ContentResolver); diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index e65f0d2214b6..98d58d0c991f 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -3359,6 +3359,33 @@ public final class ContactsContract { SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD, null, extras); } + /** + * Get a list of cloud accounts that is eligible to set as default account with state of + * {@link DefaultAccountAndState#DEFAULT_ACCOUNT_STATE_CLOUD}. May be empty but never + * null. + * + * @param resolver content resolver to query. + * @return a of cloud accounts that is eligible to set as default account with state of + * {@link DefaultAccountAndState#DEFAULT_ACCOUNT_STATE_CLOUD}. + * @throws RuntimeException if the query fails. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS) + @FlaggedApi(Flags.FLAG_NEW_DEFAULT_ACCOUNT_API_ENABLED) + @SystemApi + public static @NonNull List getEligibleCloudAccounts( + @NonNull ContentResolver resolver) { + Bundle response = nullSafeCall(resolver, ContactsContract.AUTHORITY_URI, + QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD, null, null); + List result = response.getParcelableArrayList( + KEY_ELIGIBLE_DEFAULT_ACCOUNTS, Account.class); + if (result == null) { + return new ArrayList<>(); + } + return result; + } + /** @@ -9339,30 +9366,6 @@ public final class ContactsContract { */ public static final String KEY_DEFAULT_ACCOUNT = "key_default_account"; - /** - * Key in the Bundle for the default account state. - * - * @hide - */ - public static final String KEY_DEFAULT_ACCOUNT_STATE = - "key_default_contacts_account_state"; - - /** - * The method to invoke in order to set the default account. - * - * @hide - */ - public static final String SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD = - "setDefaultAccountForNewContacts"; - - /** - * The method to invoke in order to query the default account. - * - * @hide - */ - public static final String QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD = - "queryDefaultAccountForNewContacts"; - /** * Get the account that is set as the default account for new contacts, which should be * initially selected when creating a new contact on contact management apps. -- GitLab From 7edc95c32aeb65a71874d6d15e500e1a30834a94 Mon Sep 17 00:00:00 2001 From: Pablo Gamito Date: Mon, 7 Oct 2024 11:17:50 +0000 Subject: [PATCH 143/447] Ensure WMShell protolog viewer config is available on device when required Currently, this file is only added to Google SysUI app, which means that we can't use ProtoLog in aosp builds which is causing issues. The require rule only applies to installed modules and is not propagated on static dependencies. Bug: 371524079 Flag: EXEMPT updating build rules Test: m droid with aosp target, flash and check `/system_ext/etc/wmshell.protolog.pb` is on the device Change-Id: Id1fbd5cf9716af45f8872a35e98d6cbb4f5f8f50 --- libs/WindowManager/Shell/Android.bp | 12 ++++++++---- packages/SystemUI/Android.bp | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp index a796eccd53ba..cee7b418710e 100644 --- a/libs/WindowManager/Shell/Android.bp +++ b/libs/WindowManager/Shell/Android.bp @@ -233,10 +233,6 @@ android_library { // *.kt sources are inside a filegroup. "kotlin-annotations", ], - required: [ - "wmshell.protolog.json.gz", - "wmshell.protolog.pb", - ], flags_packages: [ "com_android_wm_shell_flags", ], @@ -245,3 +241,11 @@ android_library { plugins: ["dagger2-compiler"], use_resource_processor: true, } + +java_defaults { + name: "wmshell_defaults", + required: [ + "wmshell.protolog.json.gz", + "wmshell.protolog.pb", + ], +} diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index bd7067bc1293..1f10eadd115b 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -1022,6 +1022,7 @@ android_app { defaults: [ "platform_app_defaults", "SystemUI_optimized_defaults", + "wmshell_defaults", ], static_libs: [ "SystemUI-core", -- GitLab From f5d0a8fa846847705091b0839e937c0de84a5f0f Mon Sep 17 00:00:00 2001 From: My Name Date: Fri, 4 Oct 2024 12:08:28 -0700 Subject: [PATCH 144/447] Update carrier label margin in setDisplayCutout The carrier label sometimes is misplaced after reboot. It's because the `onConfigurationChanged` function which sets the carrier label margin is not always called immediately after reboot. Fixing the issue by updating the margin inside `setDisplayCutout`. Test: manually verified Flag: EXEMPT bugfix Fixes: b/349507081 Change-Id: Id77987238e789a90d30f7605240bc5fb8302646f --- .../phone/KeyguardStatusBarView.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java index 178c31839154..6a77988e5feb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java @@ -182,14 +182,8 @@ public class KeyguardStatusBarView extends RelativeLayout { mCarrierLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize( com.android.internal.R.dimen.text_size_small_material)); - lp = (MarginLayoutParams) mCarrierLabel.getLayoutParams(); + updateCarrierLabelMargin(); - int marginStart = calculateMargin( - getResources().getDimensionPixelSize(R.dimen.keyguard_carrier_text_margin), - mPadding.left); - lp.setMarginStart(marginStart); - - mCarrierLabel.setLayoutParams(lp); updateKeyguardStatusBarHeight(); } @@ -203,6 +197,15 @@ public class KeyguardStatusBarView extends RelativeLayout { setLayoutParams(lp); } + private void updateCarrierLabelMargin() { + MarginLayoutParams lp = (MarginLayoutParams) mCarrierLabel.getLayoutParams(); + int marginStart = calculateMargin( + getResources().getDimensionPixelSize(R.dimen.keyguard_carrier_text_margin), + mPadding.left); + lp.setMarginStart(marginStart); + mCarrierLabel.setLayoutParams(lp); + } + void loadDimens() { Resources res = getResources(); mSystemIconsSwitcherHiddenExpandedMargin = res.getDimensionPixelSize( @@ -334,6 +337,7 @@ public class KeyguardStatusBarView extends RelativeLayout { RelativeLayout.LayoutParams lp = (LayoutParams) mCarrierLabel.getLayoutParams(); lp.addRule(RelativeLayout.START_OF, R.id.status_icon_area); + updateCarrierLabelMargin(); lp = (LayoutParams) mStatusIconArea.getLayoutParams(); lp.removeRule(RelativeLayout.RIGHT_OF); @@ -366,6 +370,7 @@ public class KeyguardStatusBarView extends RelativeLayout { lp = (LayoutParams) mCarrierLabel.getLayoutParams(); lp.addRule(RelativeLayout.START_OF, R.id.cutout_space_view); + updateCarrierLabelMargin(); lp = (LayoutParams) mStatusIconArea.getLayoutParams(); lp.addRule(RelativeLayout.RIGHT_OF, R.id.cutout_space_view); -- GitLab From 9ffa3c6da3bc603bb1aa7c317c43b63c286fcc06 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 7 Oct 2024 11:51:03 -0700 Subject: [PATCH 145/447] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I0b241fc2417d98cce57c77307f380f1f96b2834a --- packages/Shell/res/values-kn/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/Shell/res/values-kn/strings.xml b/packages/Shell/res/values-kn/strings.xml index 56448f73d9c2..18d0f341ad92 100644 --- a/packages/Shell/res/values-kn/strings.xml +++ b/packages/Shell/res/values-kn/strings.xml @@ -28,7 +28,7 @@ "ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಇಲ್ಲದೇ ಬಗ್ ವರದಿ ಹಂಚಿಕೊಳ್ಳಲು ಆಯ್ಕೆಮಾಡಿ, ಅಥವಾ ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಪೂರ್ತಿಯಾಗುವ ತನಕ ಕಾಯಿರಿ" "ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಇಲ್ಲದೇ ನಿಮ್ಮ ಬಗ್ ವರದಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಟ್ಯಾಪ್ ಮಾಡಿ ಅಥವಾ ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಪೂರ್ತಿಯಾಗುವವರೆಗೂ ನಿರೀಕ್ಷಿಸಿ" "ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಇಲ್ಲದೇ ನಿಮ್ಮ ಬಗ್ ವರದಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಟ್ಯಾಪ್ ಮಾಡಿ ಅಥವಾ ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಪೂರ್ತಿಯಾಗುವವರೆಗೂ ನಿರೀಕ್ಷಿಸಿ" - "ನೀವು ಸೂಕ್ಷ್ಮ ಎಂದು ಪರಿಗಣಿಸಿರುವ ಯಾವುದೇ ಡೇಟಾ ಒಳಗೊಂಡಿರುವ ಸಿಸ್ಟಂನ ಹಲವಾರು ಲಾಗ್ ಫೈಲ್‌ಗಳಿಂದ ಡೇಟಾವನ್ನು ದೋಷದ ವರದಿಗಳು ಒಳಗೊಂಡಿವೆ (ಉದಾಹರಣೆಗೆ ಅಪ್ಲಿಕೇಶನ್-ಬಳಕೆ ಮತ್ತು ಸ್ಥಳ ಮಾಹಿತಿ). ನೀವು ನಂಬಿಕೆ ಇರಿಸಿರುವ ಜನರು ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್‌ಗಳೊಂದಿಗೆ ಮಾತ್ರ ದೋಷದ ವರದಿಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಿ." + "ನೀವು ಸೂಕ್ಷ್ಮ ಎಂದು ಪರಿಗಣಿಸಿರುವ ಯಾವುದೇ ಡೇಟಾ ಒಳಗೊಂಡಿರುವ ಸಿಸ್ಟಂನ ಹಲವಾರು ಲಾಗ್ ಫೈಲ್‌ಗಳಿಂದ ಡೇಟಾವನ್ನು ದೋಷದ ವರದಿಗಳು ಒಳಗೊಂಡಿವೆ (ಉದಾಹರಣೆಗೆ ಆ್ಯಪ್-ಬಳಕೆ ಮತ್ತು ಸ್ಥಳ ಮಾಹಿತಿ). ನೀವು ನಂಬಿಕೆ ಇರಿಸಿರುವ ಜನರು ಮತ್ತು ಆ್ಯಪ್‌ಗಳೊಂದಿಗೆ ಮಾತ್ರ ದೋಷದ ವರದಿಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಿ." "ಮತ್ತೊಮ್ಮೆ ತೋರಿಸಬೇಡ" "ದೋಷ ವರದಿಗಳು" "ಬಗ್‌ ವರದಿ ಫೈಲ್‌‌ ಅನ್ನು ಓದಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ" -- GitLab From 079079154f596794992a3d230d9c9767ec5e03e3 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 7 Oct 2024 11:52:47 -0700 Subject: [PATCH 146/447] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I8f110906b0e98cca331a710d626830f6ebd8c37f --- .../accessibility/accessibilitymenu/res/values-fa/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fa/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fa/strings.xml index 49d8f6965540..cf6f0120bff0 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fa/strings.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fa/strings.xml @@ -26,6 +26,6 @@ "دکمه‌های بزرگ" "افزایش اندازه «دکمه‌های منوی دسترس‌پذیری»" "راهنما" - "روشنایی %1$s %%" - "بلندی صدای موسیقی %1$s %%" + "‏روشنایی ‎%%%1$s" + "‏بلندی صدای موسیقی ‎%%%1$s" -- GitLab From 2da67abea9e290f37867dc89076a425397a2b39d Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 7 Oct 2024 11:54:00 -0700 Subject: [PATCH 147/447] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I2470fcf7b8da09691bba8e7275fad2d431cddecc --- packages/SystemUI/res/values-af/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-am/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-ar/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-as/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-az/strings.xml | 45 +++++++++++------ .../SystemUI/res/values-b+sr+Latn/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-be/strings.xml | 47 +++++++++++------- packages/SystemUI/res/values-bg/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-bn/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-bs/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-ca/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-cs/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-da/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-de/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-el/strings.xml | 44 +++++++++++------ .../SystemUI/res/values-en-rAU/strings.xml | 44 +++++++++++------ .../SystemUI/res/values-en-rCA/strings.xml | 28 ++++++----- .../SystemUI/res/values-en-rGB/strings.xml | 43 +++++++++++------ .../SystemUI/res/values-en-rIN/strings.xml | 44 +++++++++++------ .../SystemUI/res/values-en-rXC/strings.xml | 28 ++++++----- .../SystemUI/res/values-es-rUS/strings.xml | 46 +++++++++++------- packages/SystemUI/res/values-es/strings.xml | 46 +++++++++++------- packages/SystemUI/res/values-et/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-eu/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-fa/strings.xml | 46 +++++++++++------- packages/SystemUI/res/values-fi/strings.xml | 44 +++++++++++------ .../SystemUI/res/values-fr-rCA/strings.xml | 47 +++++++++++------- packages/SystemUI/res/values-fr/strings.xml | 46 +++++++++++------- packages/SystemUI/res/values-gl/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-gu/strings.xml | 46 +++++++++++------- packages/SystemUI/res/values-hi/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-hr/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-hu/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-hy/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-in/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-is/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-it/strings.xml | 46 +++++++++++------- packages/SystemUI/res/values-iw/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-ja/strings.xml | 31 ++++++------ packages/SystemUI/res/values-ka/strings.xml | 31 ++++++------ packages/SystemUI/res/values-kk/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-km/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-kn/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-ko/strings.xml | 48 ++++++++++++------- packages/SystemUI/res/values-ky/strings.xml | 46 +++++++++++------- packages/SystemUI/res/values-lo/strings.xml | 31 ++++++------ packages/SystemUI/res/values-lt/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-lv/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-mk/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-ml/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-mn/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-mr/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-ms/strings.xml | 35 +++++++------- packages/SystemUI/res/values-my/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-nb/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-ne/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-nl/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-or/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-pa/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-pl/strings.xml | 44 +++++++++++------ .../SystemUI/res/values-pt-rBR/strings.xml | 47 +++++++++++------- .../SystemUI/res/values-pt-rPT/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-pt/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-ro/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-ru/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-si/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-sk/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-sl/strings.xml | 31 ++++++------ packages/SystemUI/res/values-sq/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-sr/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-sv/strings.xml | 31 ++++++------ packages/SystemUI/res/values-sw/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-ta/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-te/strings.xml | 48 ++++++++++++------- packages/SystemUI/res/values-th/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-tl/strings.xml | 46 +++++++++++------- packages/SystemUI/res/values-tr/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-uk/strings.xml | 45 +++++++++++------ packages/SystemUI/res/values-ur/strings.xml | 46 +++++++++++------- packages/SystemUI/res/values-uz/strings.xml | 48 ++++++++++++------- packages/SystemUI/res/values-vi/strings.xml | 44 +++++++++++------ .../SystemUI/res/values-zh-rCN/strings.xml | 44 +++++++++++------ .../SystemUI/res/values-zh-rHK/strings.xml | 46 +++++++++++------- .../SystemUI/res/values-zh-rTW/strings.xml | 44 +++++++++++------ packages/SystemUI/res/values-zu/strings.xml | 45 +++++++++++------ 85 files changed, 2395 insertions(+), 1293 deletions(-) diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index a9f9fafd505f..0f411ca5bfea 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -440,7 +440,8 @@ "Aan" "Op • %1$s" "Af" - "Stel op" + + "Bestuur in instellings" "{count,plural, =0{Geen aktiewe modusse nie}=1{{mode} is aktief}other{# modusse is aktief}}" "Jy sal nie deur geluide en vibrasies gepla word nie, behalwe deur wekkers, herinneringe, geleenthede en bellers wat jy spesifiseer. Jy sal steeds enigiets hoor wat jy kies om te speel, insluitend musiek, video\'s en speletjies." @@ -573,8 +574,7 @@ "Gesprekke" "Vee alle stil kennisgewings uit" "Kennisgewings onderbreek deur Moenie Steur Nie" - - + "{count,plural,offset:1 =0{Geen kennisgewings nie}=1{Kennisgewings is deur {mode} onderbreek}=2{Kennisgewings is deur {mode} en een ander modus onderbreek}other{Kennisgewings is deur {mode} en # ander modusse onderbreek}}" "Begin nou" "Geen kennisgewings nie" "Geen nuwe kennisgewings nie" @@ -706,6 +706,7 @@ "Wys demonstrasiemodus" "Ethernet" "Wekker" + "%1$s is aan" "Wallet" "Stel op om vinniger, veiliger aankope met jou foon te doen" "Wys alles" @@ -1405,26 +1406,38 @@ "Leer raakpaneelgebare" "Navigeer met jou sleutelbord en raakpaneel" "Leer raakpaneelgebare, kortpadsleutels en meer" - "Teruggebaar" - "Tuisgebaar" + + + + "Bekyk onlangse apps" "Klaar" "Gaan terug" - "Swiep enige plek op die raakpaneel links of regs met drie vingers om terug te gaan.\n\nJy kan ook die kortpadsleutelhandeling + Esc hiervoor gebruik." - "Knap gedaan!" + + + + "Jy het die Gaan Terug-gebaar voltooi." "Gaan na tuisskerm" - "Swiep enige tyd van die onderkant van jou skerm af op met drie vingers om na jou tuisskerm toe te gaan." - "Mooi so!" - "Jy het die Gaan na Tuisskerm-gebaar voltooi." + + + + + + "Bekyk onlangse apps" - "Swiep op en hou met drie vingers op jou raakpaneel." + + "Knap gedaan!" "Jy het die Bekyk Onlangse Apps-gebaar voltooi." - "Handelingsleutel" - "Druk die handelingsleutel op jou sleutelbord om toegang tot jou apps te kry." - "Geluk!" - "Jy het die Handelingsleutel-gebaar voltooi.\n\nHandeling + / wys al die kortpaaie wat vir jou beskikbaar is." + + + + + + + + "Sleutelbordlig" "Vlak %1$d van %2$d" "Huiskontroles" @@ -1436,6 +1449,7 @@ "Druk die handelingsleutel op jou sleutelbord om al jou apps te bekyk" "Gewysig" "Ontsluit om te kyk" + "Kontekstuele opvoeding" "Gebruik jou raakpaneel om terug te gaan" "Swiep links of regs met drie vingers. Tik om meer gebare te leer." "Gebruik jou raakpaneel om na die tuisskerm toe te gaan" diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 704bdcaa108a..553142448330 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -440,7 +440,8 @@ "በርቷል" "በርቷል • %1$s" "ጠፍቷል" - "አዋቅር" + + "በቅንብሮች ውስጥ አስተዳድር" "{count,plural, =0{ምንም ገቢር ሁነታዎች የሉም}=1{{mode} ገቢር ነው}one{# ሁኔታ ገቢር ነው}other{# ሁኔታዎች ገቢር ናቸው}}" "እርስዎ ከወሰንዋቸው ማንቂያዎች፣ አስታዋሾች፣ ክስተቶች እና ደዋዮች በስተቀር፣ በድምጾች እና ንዝረቶች አይረበሹም። ሙዚቃ፣ ቪዲዮዎች እና ጨዋታዎች ጨምሮ ለመጫወት የሚመርጡትን ማንኛውም ነገር አሁንም ይሰማሉ።" @@ -573,8 +574,7 @@ "ውይይቶች" "ሁሉንም ጸጥ ያሉ ማሳወቂያዎችን ያጽዱ" "ማሳወቂያዎች በአትረብሽ ባሉበት ቆመዋል" - - + "{count,plural,offset:1 =0{ምንም ማሳወቂያዎች የሉም}=1{ማሳወቂያዎች በ{mode} ባሉበት ቆመዋል}=2{ማሳወቂያዎች በ{mode} እና አንድ ሌላ ሁነታ ባሉበት ቆመዋል}one{ማሳወቂያዎች በ{mode} እና # ሌላ ሁነታ ባሉበት ቆመዋል}other{ማሳወቂያዎች በ{mode} እና # ሌላ ሁነታዎች ባሉበት ቆመዋል}}" "አሁን ጀምር" "ምንም ማሳወቂያ የለም" "ምንም አዲስ ማሳወቂያዎች የሉም" @@ -706,6 +706,7 @@ "ማሳያ ሁነታን አሳይ" "ኤተርኔት" "ማንቂያ" + "%1$s በርቷል" "Wallet" "በስልክዎ በመጠቀም ፈጣን እና የበለጠ ደህንነቱ በተጠበቀ መንገድ ግዢዎችን ለመፈጸም ዝግጁ ይሁኑ" "ሁሉንም አሳይ" @@ -1405,26 +1406,38 @@ "የመዳሰሻ ሰሌዳ ምልክቶችን ይወቁ" "የእርስዎን የቁልፍ ሰሌዳ እና የመዳሰሻ ሰሌዳ በመጠቀም ያስሱ" "የመዳሰሻ ሰሌዳ ምልክቶችን፣ የቁልፍ ሰሌዳ አቋራጮችን እና ሌሎችን ይወቁ" - "የተመለስ ምልክት" - "የቤት ምልክት" + + + + "የቅርብ ጊዜ መተግበሪያዎችን አሳይ" "ተከናውኗል" "ወደኋላ ተመለስ" - "ወደኋላ ለመመለስ የመዳሰሻ ሰሌዳው ላይ የትኛውም ቦታ በሦስት ጣቶች ወደግራ ወይም ወደቀኝ ያንሸራትቱ።\n\nእንዲሁም የቁልፍ ሰሌዳ አቋራጭ + ESC ለዚህ መጠቀም ይችላሉ።" - "ጥሩ ሠርተዋል!" + + + + "ወደኋላ የመመለስ ምልክትን አጠናቅቀዋል።" "ወደ መነሻ ሂድ" - "በማንኛውም ጊዜ ወደ መነሻ ማያ ገፅዎ ለመሄድ ከማያ ገፅዎ ታች በሦስት ጣቶች ወደላይ ያሸብልሉ።" - "አሪፍ!" - "ወደ መነሻ ሂድ ምልክትን አጠናቅቀዋል።" + + + + + + "የቅርብ ጊዜ መተግበሪያዎችን አሳይ" - "የመዳሰሻ ሰሌዳዎ ላይ ሦስት ጣቶችን በመጠቀም ወደ ላይ ያንሸራትቱ እና ይያዙ።" + + "ጥሩ ሠርተዋል!" "የቅርብ ጊዜ መተግበሪያዎች አሳይ ምልክትን አጠናቅቀዋል።" - "የተግባር ቁልፍ" - "መተግበሪያዎችዎን ለመድረስ በቁልፍ ሰሌዳዎ ላይ የእርምጃ ቁልፉን ይጫኑ።" - "እንኳን ደስ አለዎት!" - "የተግባር ቁልፍ ምልክቱን አጠናቅቀዋል።\n\nእርምጃ + / ለእርስዎ ተገኚ የሆኑትን አቋራጮች በሙሉ ያሳያል።" + + + + + + + + "የቁልፍ ሰሌዳ የጀርባ ብርሃን" "ደረጃ %1$d ከ %2$d" "የቤት ውስጥ ቁጥጥሮች" @@ -1436,6 +1449,7 @@ "ሁሉንም መተግበሪያዎችዎን ለማየት በቁልፍ ሰሌዳዎ ላይ ያለውን የተግባር ቁልፍ ይጫኑ" "ጽሁፍ ተቀይሯል" "ለመመልከት ይክፈቱ" + "የዓውድ ትምህርት" "ለመመለስ የመዳሰሻ ሰሌዳዎን ይጠቀሙ" "ሦስት ጣቶችን በመጠቀም ወደ ግራ ወይም ወደ ቀኝ ያንሸራትቱ። ምልክቶችን የበለጠ ለማወቅ መታ ያድርጉ።" "ወደ መነሻ ለመመለስ የመዳሰሻ ሰሌዳዎን ይጠቀሙ" diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 8ed225df457b..091b58e9f414 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -440,7 +440,8 @@ "مفعَّل" "مفعّل • %1$s" "غير مفعَّل" - "إعداد" + + "الإدارة في الإعدادات" "{count,plural, =0{ما مِن أوضاع مفعَّلة}=1{الوضع \"{mode}\" مفعَّل}two{وضعان مفعَّلان}few{‫# أوضاع مفعَّلة}many{‫# وضعًا مفعَّلاً}other{‫# وضع مفعَّل}}" "لن يتم إزعاجك بالأصوات والاهتزاز، باستثناء المُنبِّهات والتذكيرات والأحداث والمتصلين الذين تحددهم. وسيظل بإمكانك سماع أي عناصر أخرى تختار تشغيلها، بما في ذلك الموسيقى والفيديوهات والألعاب." @@ -573,8 +574,7 @@ "المحادثات" "محو جميع الإشعارات الصامتة" "تم إيقاف الإشعارات مؤقتًا وفقًا لإعداد \"عدم الإزعاج\"" - - + "{count,plural,offset:1 =0{ما مِن إشعارات}=1{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\"}=2{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" ووضع واحد آخر}few{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" و# أوضاع أخرى}many{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" و# وضعًا آخر}other{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" و# وضع آخر}}" "البدء الآن" "ما مِن إشعارات" "ما مِن إشعارات جديدة" @@ -706,6 +706,7 @@ "عرض الوضع التجريبي" "إيثرنت" "المنبّه" + "وضع \"%1$s\" مفعَّل" "‏محفظة Google" "يمكنك إعداد طريقة دفع لإجراء عمليات شراء بسرعة وأمان أكبر باستخدام هاتفك." "عرض الكل" @@ -1405,26 +1406,38 @@ "تعرَّف على إيماءات لوحة اللمس" "التنقّل باستخدام لوحة المفاتيح ولوحة اللمس" "تعرَّف على إيماءات لوحة اللمس واختصارات لوحة المفاتيح والمزيد" - "إيماءة الرجوع" - "إيماءة الانتقال إلى الشاشة الرئيسية" + + + + "عرض التطبيقات المستخدَمة مؤخرًا" "تم" "رجوع" - "‏للرجوع، مرِّر سريعًا لليمين أو لليسار باستخدام ثلاثة أصابع في أي مكان على لوحة اللمس.\n\nيمكنك أيضًا الرجوع باستخدام اختصار لوحة المفاتيح \"مفتاح الإجراء + ESC\"." - "أحسنت" + + + + "لقد أكملت التدريب على إيماءة الرجوع." "الانتقال إلى الشاشة الرئيسية" - "للانتقال إلى الشاشة الرئيسية في أي وقت، مرِّر سريعًا من أسفل الشاشة إلى أعلاها بثلاثة أصابع." - "أحسنت" - "لقد أكملت التدريب على إيماءة الانتقال إلى الشاشة الرئيسية." + + + + + + "عرض التطبيقات المستخدَمة مؤخرًا" - "مرِّر سريعًا للأعلى مع استمرار الضغط باستخدام ثلاثة أصابع على لوحة اللمس." + + "أحسنت." "لقد أكملْت الدليل التوجيهي على إيماءة \"عرض التطبيقات المستخدَمة مؤخرًا\"." - "مفتاح الإجراء" - "للوصول إلى التطبيقات، اضغط على مفتاح الإجراء في لوحة المفاتيح." - "تهانينا!" - "لقد أكملت التدريب على إيماءة مفتاح الإجراء.\n\nيؤدي الضغط على مفتاح الإجراء + / إلى عرض جميع الاختصارات المتاحة." + + + + + + + + "الإضاءة الخلفية للوحة المفاتيح" "‏مستوى الإضاءة: %1$d من %2$d" "إدارة المنزل آليًّا" @@ -1436,6 +1449,7 @@ "لعرض جميع التطبيقات، اضغط على مفتاح الإجراء في لوحة المفاتيح" "إشعار مخفي" "افتح القفل لعرض المعلومات" + "التعليم السياقي" "استخدِم لوحة اللمس للرجوع" "مرِّر سريعًا لليمين أو لليسار باستخدام 3 أصابع. انقر للتعرّف على المزيد من الإيماءات." "استخدِم لوحة اللمس للانتقال إلى الشاشة الرئيسية" diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 07c6f73c8975..bbaf97450cc2 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -440,7 +440,8 @@ "অন আছে" "অন আছে • %1$s" "অফ আছে" - "ছেট আপ কৰক" + + "ছেটিঙত পৰিচালনা কৰক" "{count,plural, =0{কোনো সক্ৰিয় ম’ড নাই}=1{{mode} সক্ৰিয় আছে}one{# টা ম’ড সক্ৰিয় আছে}other{# টা ম’ড সক্ৰিয় আছে}}" "আপুনি নিৰ্দিষ্ট কৰা এলাৰ্ম, ৰিমাইণ্ডাৰ, ইভেন্ট আৰু কল কৰোঁতাৰ বাহিৰে আন কোনো শব্দৰ পৰা আপুনি অসুবিধা নাপাব। কিন্তু, সংগীত, ভিডিঅ\' আৰু খেলসমূহকে ধৰি আপুনি প্লে কৰিব খোজা যিকোনো বস্তু তথাপি শুনিব পাৰিব।" @@ -573,8 +574,7 @@ "বাৰ্তালাপ" "আটাইবোৰ নীৰৱ জাননী মচক" "অসুবিধা নিদিব-ই জাননী পজ কৰিছে" - - + "{count,plural,offset:1 =0{কোনো জাননী নাই}=1{{mode}এ জাননী পজ কৰিছে}=2{{mode} আৰু আন এটা ম’ডে জাননী পজ কৰিছে}one{{mode} আৰু আন # টা ম’ডে জাননী পজ কৰিছে}other{{mode} আৰু আন # টা ম’ডে জাননী পজ কৰিছে}}" "এতিয়াই আৰম্ভ কৰক" "কোনো জাননী নাই" "কোনো নতুন জাননী নাই" @@ -706,6 +706,8 @@ "ডেম\' ম\'ড দেখুৱাওক" "ইথাৰনেট" "এলাৰ্ম" + + "ৱালেট" "আপোনাৰ ফ’নটোৰে দ্ৰুত তথা অধিক সুৰক্ষিত ক্ৰয় কৰিবলৈ ছেট আপ পাওক" "আটাইবোৰ দেখুৱাওক" @@ -1405,26 +1407,38 @@ "টাচ্চপেডৰ নিৰ্দেশসমূহ জানক" "আপোনাৰ কীব’ৰ্ড আৰু টাচ্চপেড ব্যৱহাৰ কৰি নেভিগে’ট কৰক" "টাচ্চপেডৰ নিৰ্দেশ, কীব’ৰ্ডৰ শ্বৰ্টকাট আৰু অধিকৰ বিষয়ে জানক" - "উভতি যাওক নিৰ্দেশ" - "গৃহ স্ক্ৰীনলৈ যোৱাৰ নিৰ্দেশ" + + + + "শেহতীয়া এপ্‌সমূহ চাওক" "হ’ল" "উভতি যাওক" - "উভতি যাবলৈ, টাচ্চপেডৰ যিকোনো স্থানত তিনিটা আঙুলি ব্যৱহাৰ কৰি বাওঁ বা সোঁফালে ছোৱাইপ কৰক।\n\nইয়াৰ বাবে আপুনি কীব’ৰ্ড শ্বৰ্টকাট কাৰ্য + ESC ব্যৱহাৰ কৰিবও পাৰে।" - "বঢ়িয়া!" + + + + "আপুনি উভতি যোৱাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে।" "গৃহ পৃষ্ঠালৈ যাওক" - "যিকোনো সময়তে আপোনাৰ গৃহ স্ক্ৰীনলৈ যাবলৈ, আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ তিনিটা আঙুলিৰে ছোৱাইপ কৰক।" - "সুন্দৰ!" - "আপুনি গৃহ স্ক্ৰীনলৈ উভতি যোৱাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে।" + + + + + + "শেহতীয়া এপ্‌সমূহ চাওক" - "আপোনাৰ টাচ্চপেডত তিনিটা আঙুলি ব্যৱহাৰ কৰি ওপৰলৈ ছোৱাইপ কৰি কিছু সময় ধৰি ৰাখক।" + + "বঢ়িয়া!" "আপুনি শেহতীয়া এপ্ চোৱাৰ নিৰ্দেশনাটো সম্পূৰ্ণ কৰিছে।" - "কাৰ্য কী" - "আপোনাৰ এপ্‌সমূহ এক্সেছ কৰিবলৈ আপোনাৰ কীব’ৰ্ডৰ কাৰ্য কীটোত টিপক।" - "অভিনন্দন!" - "আপুনি কাৰ্য কীৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে।\n\nকাৰ্য + /এ আপোনাৰ বাবে উপলব্ধ আটাইবোৰ শ্বৰ্টকাট দেখুৱায়।" + + + + + + + + "কীব’ৰ্ডৰ বেকলাইট" "%2$dৰ %1$d স্তৰ" "ঘৰৰ সা-সৰঞ্জামৰ নিয়ন্ত্ৰণ" @@ -1436,6 +1450,7 @@ "আপোনাৰ আটাইবোৰ এপ্‌ চাবলৈ আপোনাৰ কীব’ৰ্ডৰ কাৰ্য কীটোত টিপক" "সম্পাদনা কৰা হৈছে" "চাবলৈ আনলক কৰক" + "প্ৰাসংগিক শিক্ষা" "উভতি যাবলৈ আপোনাৰ টাচ্চপেড ব্যৱহাৰ কৰক" "তিনিটা আঙুলি ব্যৱহাৰ কৰি বাওঁফাললৈ বা সোঁফাললৈ ছোৱাইপ কৰক। অধিক নিৰ্দেশ শিকিবলৈ টিপক।" "গৃহপৃষ্ঠালৈ যাবলৈ আপোনাৰ টাচ্চপেড ব্যৱহাৰ কৰক" diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 551ec5cd436b..211a05d8b08d 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -440,7 +440,8 @@ "Aktiv" "Aktiv • %1$s" "Deaktiv" - "Ayarlayın" + + "Ayarlarda idarə edin" "{count,plural, =0{Aktiv rejim yoxdur}=1{{mode} aktivdir}other{# rejim aktivdir}}" "Seçdiyiniz siqnal, xatırladıcı, tədbir və zənglər istisna olmaqla səslər və vibrasiyalar Sizi narahat etməyəcək. Musiqi, video və oyunlar da daxil olmaqla oxutmaq istədiyiniz hər şeyi eşidəcəksiniz." @@ -573,8 +574,7 @@ "Söhbətlər" "Səssiz bildirişlərin hamısını silin" "Bildirişlər \"Narahat Etməyin\" rejimi tərəfindən dayandırıldı" - - + "{count,plural,offset:1 =0{Bildiriş yoxdur}=1{Bildirişlər {mode} tərəfindən dayandırıldı}=2{Bildirişlər {mode} və digər rejim tərəfindən dayandırıldı}other{Bildirişlər {mode} və # digər rejim tərəfindən dayandırıldı}}" "İndi başlayın" "Heç bir bildiriş yoxdur" "Yeni bildiriş yoxdur" @@ -706,6 +706,8 @@ "Demo rejimini göstərin" "Ethernet" "Zəngli saat" + + "Pulqabı" "Telefonunuzla daha sürətli və təhlükəsiz satınalmalar etmək üçün ayarlayın" "Hamısını göstər" @@ -1405,26 +1407,38 @@ "Taçped jestlərini öyrənin" "Klaviatura və taçpeddən istifadə edərək hərəkət edin" "Taçped jestləri, klaviatura qısayolları və s. haqqında öyrənin" - "Geri jesti" - "Əsas ekran jesti" + + + + "Son tətbiqlərə baxın" "Hazırdır" "Geri qayıdın" - "Geri getmək üçün taçpeddə istənilən yerdə üç barmaqla sola və ya sağa çəkin.\n\nBunun üçün Action + ESC klaviatura qısayolundan da istifadə edə bilərsiniz." - "Əla!" + + + + "Geri getmə jestini tamamladınız." "Ana ekrana qayıdın" - "İstənilən vaxt ana ekrana keçmək üçün ekranın aşağısından üç barmağınızla yuxarı çəkin." - "Əla!" - "Əsas ekrana keçid jestini tamamladınız." + + + + + + "Son tətbiqlərə baxın" - "Taçpeddə üç barmaq ilə yuxarı çəkib saxlayın." + + "Əla!" "Son tətbiqlərə baxmaq jestini tamamladınız." - "Fəaliyyət açarı" - "Tətbiqlərə daxil olmaq üçün klaviaturada fəaliyyət açarını basın." - "Təbriklər!" - "Fəaliyyət açarı jestini tamamladınız.\n\nFəaliyyət + / əlçatan bütün qısayolları göstərir." + + + + + + + + "Klaviatura işığı" "Səviyyə %1$d/%2$d" "Ev nizamlayıcıları" @@ -1436,6 +1450,7 @@ "Bütün tətbiqlərə baxmaq üçün klaviaturada fəaliyyət açarını basın" "Çıxarılıb" "Baxmaq üçün kiliddən çıxarın" + "Kontekstual təhsil" "Geri qayıtmaq üçün taçped istifadə edin" "Üç barmaqla sola və ya sağa çəkin. Daha çox jest öyrənmək üçün toxunun." "Ana səhifəyə keçmək üçün taçped istifadə edin" diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 20dee4603e7b..6064cc10c821 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -440,7 +440,8 @@ "Uključeno" "Uklj. • %1$s" "Isključeno" - "Podesi" + + "Upravljajte u podešavanjima" "{count,plural, =0{Nema aktivnih režima}=1{Aktivan je {mode} režim}one{Aktivan je # režim}few{Aktivna su # režima}other{Aktivno je # režima}}" "Neće vas uznemiravati zvukovi i vibracije osim za alarme, podsetnike, događaje i pozivaoce koje navedete. I dalje ćete čuti sve što odaberete da pustite, uključujući muziku, video snimke i igre." @@ -573,8 +574,7 @@ "Konverzacije" "Obrišite sva nečujna obaveštenja" "Obaveštenja su pauzirana režimom Ne uznemiravaj" - - + "{count,plural,offset:1 =0{Nema obaveštenja}=1{Obaveštenja je pauzirao {mode}}=2{Obaveštenja su pauzirali {mode} i još jedan režim}one{Obaveštenja su pauzirali {mode} i još # režim}few{Obaveštenja su pauzirali {mode} i još # režima}other{Obaveštenja su pauzirali {mode} i još # režima}}" "Započni" "Nema obaveštenja" "Nema novih obaveštenja" @@ -706,6 +706,7 @@ "Prikaži režim demonstracije" "Eternet" "Alarm" + "%1$s: uključeno" "Novčanik" "Obavite konfigurisanje da biste mogli brže i sigurnije da kupujete pomoću telefona" "Prikaži sve" @@ -1405,26 +1406,38 @@ "Naučite pokrete za tačped" "Krećite se pomoću tastature i tačpeda" "Naučite pokrete za tačped, tasterske prečice i drugo" - "Pokret za vraćanje" - "Pokret za početnu stranicu" + + + + "Prikaži nedavno korišćene aplikacije" "Gotovo" "Nazad" - "Da biste se vratili, prevucite ulevo sa tri prsta bilo gde na tačpedu.\n\nMožete da koristite i tastersku prečicu Alt + ESC za ovo." - "Odlično!" + + + + "Dovršili ste pokret za povratak." "Idi na početni ekran" - "Da biste otišli na početni ekran u bilo kom trenutku, prevucite nagore od dna ekrana pomoću tri prsta." - "Svaka čast!" - "Dovršili ste pokret za povratak na početnu stranicu." + + + + + + "Prikaži nedavno korišćene aplikacije" - "Prevucite nagore i zadržite pomoću tri prsta na tačpedu." + + "Odlično!" "Dovršili ste pokret za prikazivanje nedavno korišćenih aplikacija." - "Taster radnji" - "Da biste pristupili aplikacijama, pritisnite taster radnji na tastaturi." - "Čestitamo!" - "Dovršili ste pokret pomoću tastera radnji.\n\nRadnja + / prikazuje sve prečice koje su vam dostupne." + + + + + + + + "Pozadinsko osvetljenje tastature" "%1$d. nivo od %2$d" "Kontrole za dom" @@ -1436,6 +1449,7 @@ "Da biste pogledali sve aplikacije, pritisnite taster radnji na tastaturi" "Redigovano" "Otključajte za prikaz" + "Kontekstualno obrazovanje" "Koristite tačped da biste se vratili" "Prevucite ulevo ili udesno sa tri prsta. Dodirnite da biste videli više pokreta." "Koristite tačped da biste otišli na početni ekran" diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index ba0a8b422474..cdaca7efcde0 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -440,7 +440,8 @@ "Уключана" "Уключана • %1$s" "Выключана" - "Наладзіць" + + "Адкрыць налады" "{count,plural, =0{Актыўных рэжымаў няма}=1{Рэжым \"{mode}\" актыўны}one{# рэжым актыўны}few{# рэжымы актыўныя}many{# рэжымаў актыўныя}other{# рэжыму актыўныя}}" "Вас не будуць турбаваць гукі і вібрацыя, за выключэннем будзільнікаў, напамінаў, падзей і выбраных вамі абанентаў. Вы будзеце чуць усё, што ўключыце, у тым ліку музыку, відэа і гульні." @@ -573,8 +574,7 @@ "Размовы" "Выдаліць усе апавяшчэнні без гуку" "Паказ апавяшчэнняў прыпынены ў рэжыме \"Не турбаваць\"" - - + "{count,plural,offset:1 =0{Апавяшчэнняў няма}=1{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\"}=2{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ адным рэжымам}one{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжымам}few{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжымамі}many{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжымамі}other{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжыму}}" "Пачаць зараз" "Апавяшчэнняў няма" "Няма новых апавяшчэнняў" @@ -706,6 +706,8 @@ "Паказваць дэманстрацыйны рэжым" "Ethernet" "Будзільнік" + + "Кашалёк" "Наладзьце картку, каб рабіць больш хуткія і бяспечныя куплі з дапамогай тэлефона" "Паказаць усе" @@ -1405,26 +1407,38 @@ "Азнаёмцеся з жэстамі для сэнсарнай панэлі" "Навігацыя з дапамогай клавіятуры і сэнсарнай панэлі" "Азнаёмцеся з жэстамі для сэнсарнай панэлі, спалучэннямі клавіш і г. д." - "Жэст для вяртання на папярэдні экран" - "Жэст для вяртання на галоўны экран" + + + + "Прагляд нядаўніх праграм" "Гатова" "Назад" - "Каб вярнуцца, правядзіце трыма пальцамі ўлева ці ўправа ў любым месцы сэнсарнай панэлі.\n\nТаксама можна выкарыстоўваць спалучэнне \"клавіша дзеяння + ESC\"." - "Выдатная праца!" + + + + "Вы навучыліся рабіць жэст вяртання." "На галоўны экран" - "Каб у любы момант перайсці на галоўны экран, правядзіце па экране трыма пальцамі знізу ўверх." - "Выдатна!" - "Вы навучыліся рабіць жэст для пераходу на галоўны экран." + + + + + + "Прагляд нядаўніх праграм" - "Правядзіце па сэнсарнай панэлі трыма пальцамі ўверх і затрымайце пальцы." + + "Выдатная праца!" "Вы скончылі вывучэнне жэсту для прагляду нядаўніх праграм." - "Клавіша дзеяння" - "Каб атрымаць доступ да праграм, націсніце клавішу дзеяння на клавіятуры." - "Віншуем!" - "Вы навучыліся рабіць жэст з клавішай дзеяння.\n\nКалі націснуць клавішу дзеяння разам з \"/\", будуць паказаны ўсе даступныя спалучэнні клавіш." + + + + + + + + "Падсветка клавіятуры" "Узровень %1$d з %2$d" "Кіраванне домам" @@ -1436,6 +1450,7 @@ "Каб праглядзець усе праграмы, націсніце на клавішу дзеяння на клавіятуры" "Схавана" "Разблакіруйце экран, каб праглядзець" + "Кантэкстнае навучанне" "Выкарыстайце сэнсарную панэль для вяртання" "Правядзіце ўлева ці ўправа трыма пальцамі. Націсніце, каб азнаёміцца з іншымі жэстамі." "Выкарыстайце сэнсарную панэль для вяртання на галоўны экран" @@ -1445,7 +1460,7 @@ "Выкарыстайце клавіятуру для прагляду ўсіх праграм" "Можна націснуць на клавішу дзеяння ў любы момант. Націсніце, каб азнаёміцца з іншымі жэстамі." "Цяпер кіраваць дадатковым памяншэннем яркасці можна з дапамогай паўзунка яркасці" - "Цяпер вы можаце дадаткова зацямніць экран, яшчэ больш панізіўшы ўзровень яркасці.\n\nПаколькі гэта функцыя цяпер уваходзіць у склад паўзунка яркасці, хуткія каманды для дадатковага памяншэння яркасці былі выдалены." + "Цяпер вы можаце дадаткова зацямніць экран, яшчэ больш панізіўшы ўзровень яркасці.\n\nПаколькі гэта функцыя цяпер уваходзіць у склад паўзунка яркасці, хуткія каманды для дадатковага памяншэння яркасці будуць выдалены." "Выдаліць хуткія каманды для дадатковага памяншэння яркасці" "Хуткія каманды для дадатковага памяншэння яркасці выдалены" "Магчымасць падключэння" diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index bf558eb42708..79fc4b278527 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -440,7 +440,8 @@ "Вкл." "Вкл. • %1$s" "Изкл." - "Настройване" + + "Управление от настройките" "{count,plural, =0{Няма активни режими}=1{Режимът „{mode}“ е активен}other{# активни режима}}" "Няма да бъдете обезпокоявани от звуци и вибрирания освен от будилници, напомняния, събития и обаждания от посочени от вас контакти. Пак ще чувате всичко, което изберете да се пусне, включително музика, видеоклипове и игри." @@ -573,8 +574,7 @@ "Разговори" "Изчистване на всички беззвучни известия" "Известията са поставени на пауза от режима „Не безпокойте“" - - + "{count,plural,offset:1 =0{Няма известия}=1{Известията са поставени на пауза от {mode}}=2{Известията са поставени на пауза от {mode} и един друг режим}other{Известията са поставени на пауза от {mode} и # други режима}}" "Стартиране сега" "Няма известия" "Няма нови известия" @@ -706,6 +706,7 @@ "Показване на демонстрационния режим" "Ethernet" "Будилник" + "Режимът „%1$s“ е включен" "Портфейл" "Купувайте по-бързо и по-сигурно с телефона си" "Показване на всички" @@ -1405,26 +1406,38 @@ "Научете за жестовете със сензорния панел" "Навигирайте посредством клавиатурата и сензорния панел" "Научете за жестовете със сензорния панел, клавишните комбинации и др." - "Жест за връщане назад" - "Жест за преминаване към началния екран" + + + + "Преглед на скорошните приложения" "Готово" "Назад" - "За да се върнете назад, прекарайте три пръста наляво или надясно по сензорния панел.\n\nЗа целта можете също да използвате комбинацията с клавиша за действия + ESC." - "Отлично!" + + + + "Изпълнихте жеста за връщане назад." "Към началния екран" - "За да преминете към началния екран по всяко време, прекарайте три пръста нагоре от долната част на екрана." - "Чудесно!" - "Изпълнихте жеста за преминаване към началния екран." + + + + + + "Преглед на скорошните приложения" - "Плъзнете нагоре с три пръста по сензорния панел и задръжте." + + "Отлично!" "Изпълнихте жеста за преглед на скорошните приложения." - "Клавиш за действия" - "За да осъществите достъп до приложенията, натиснете клавиша за действия на клавиатурата си." - "Поздравления!" - "Изпълнихте жеста с клавиша за действия.\n\nНатискането на клавиша за действия и / показва всички налични клавишни комбинации." + + + + + + + + "Подсветка на клавиатурата" "Ниво %1$d от %2$d" "Контроли за дома" @@ -1436,6 +1449,7 @@ "За да прегледате всичките си приложения, натиснете клавиша за действия на клавиатурата си" "Скрито" "Отключете за преглед" + "Контекстуално обучение" "Използвайте сензорния панел, за да се върнете назад" "Плъзнете три пръста наляво или надясно. Докоснете, за да научите повече жестове." "Използвайте сензорния панел, за да преминете към началния екран" diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index cf55feb343e8..485221a76580 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -440,7 +440,8 @@ "চালু আছে" "চালু আছে • %1$s" "বন্ধ আছে" - "সেট-আপ করুন" + + "সেটিংসে গিয়ে ম্যানেজ করুন" "{count,plural, =0{কোনও মোড চালু নেই}=1{{mode} চালু আছে}one{# মোড চালু আছে}other{# মোড চালু আছে}}" "অ্যালার্ম, রিমাইন্ডার, ইভেন্ট, এবং আপনার নির্দিষ্ট করে দেওয়া ব্যক্তিদের কল ছাড়া অন্য কোনও আওয়াজ বা ভাইব্রেশন হবে না। তবে সঙ্গীত, ভিডিও, এবং গেম সহ আপনি যা কিছু চালাবেন তার আওয়াজ শুনতে পাবেন।" @@ -573,8 +574,7 @@ "কথোপকথন" "সব নীরব বিজ্ঞপ্তি মুছুন" "\'বিরক্ত করবে না\' দিয়ে বিজ্ঞপ্তি পজ করা হয়েছে" - - + "{count,plural,offset:1 =0{কোনও বিজ্ঞপ্তি নেই}=1{{mode}-এর জন্য বিজ্ঞপ্তি পজ করা হয়েছে}=2{{mode} ও অন্য আরেকটি মোডের জন্য বিজ্ঞপ্তি পজ করা হয়েছে}one{{mode} ও অন্য #টি মোডের জন্য বিজ্ঞপ্তি পজ করা হয়েছে}other{{mode} ও অন্য #টি মোডের জন্য বিজ্ঞপ্তি পজ করা হয়েছে}}" "এখন শুরু করুন" "কোনও বিজ্ঞপ্তি নেই" "নতুন কোনও বিজ্ঞপ্তি নেই" @@ -706,6 +706,7 @@ "ডেমো মোড দেখান" "ইথারনেট" "অ্যালার্ম" + "%1$s চালু আছে" "Wallet" "ফোন ব্যবহার করে আরও দ্রুত ও আরও নিরাপদে কেনাকাটা করার জন্য সেট-আপ করুন" "সবকটি দেখুন" @@ -1405,26 +1406,38 @@ "টাচপ্যাডের জেসচার সম্পর্কে জানুন" "আপনার কীবোর্ড এবং টাচপ্যাড ব্যবহার করে নেভিগেট করুন" "টাচপ্যাড জেসচার, কীবোর্ড শর্টকাট এবং আরও অনেক কিছু সম্পর্কে জানুন" - "ফিরে যাওয়ার জেসচার" - "হোমপেজে যাওয়ার জেসচার" + + + + "সম্প্রতি ব্যবহার করা হয়েছে এমন অ্যাপ দেখুন" "হয়ে গেছে" "ফিরে যান" - "ফিরে যেতে, টাচপ্যাডে যেকোনও জায়গায় তিনটি আঙুল দিয়ে বাঁদিক বা ডানদিকে সোয়াইপ করুন।\n\nএছাড়া, এটির জন্য আপনি কীবোর্ড শর্টকাট অ্যাকশন + ESC বোতাম প্রেস করতে পারবেন।" - "অসাধারণ!" + + + + "জেসচার ব্যবহার করে কীভাবে ফিরে যাওয়া যায় সেই সম্পর্কে আপনি জেনেছেন।" "হোমে যান" - "যেকোনও সময়ে আপনার হোম স্ক্রিনে যেতে, আপনার স্ক্রিনের একদম নিচের থেকে তিনটি আঙুল দিয়ে উপরের দিকে সোয়াইপ করুন।" - "সাবাস!" - "জেসচার ব্যবহার করে কীভাবে হোমে ফিরে যাওয়া যায় সেই সম্পর্কে আপনি জেনেছেন।" + + + + + + "সম্প্রতি ব্যবহার করা হয়েছে এমন অ্যাপ দেখুন" - "আপনার টাচপ্যাডে তিনটি আঙুল ব্যবহার করে উপরের দিকে সোয়াইপ করে ধরে রাখুন।" + + "অসাধারণ!" "সম্প্রতি ব্যবহার করা হয়েছে এমন অ্যাপের জেসচার দেখা সম্পূর্ণ করেছেন।" - "অ্যাকশন কী" - "আপনার অ্যাপ অ্যাক্সেস করতে, কীবোর্ডে অ্যাকশন কী প্রেস করুন" - "অভিনন্দন!" - "অ্যাকশন কী জেসচার সম্পর্কে আপনি জেনেছেন।\n\nঅ্যাকশন + / প্রেস করলে আপনার কাছে উপলভ্য থাকা সব শর্টকাট দেখতে পাবেন।" + + + + + + + + "কীবোর্ড ব্যাকলাইট" "%2$d-এর মধ্যে %1$d লেভেল" "হোম কন্ট্রোল" @@ -1436,6 +1449,7 @@ "আপনার সব অ্যাপ দেখতে, কীবোর্ডে অ্যাকশন কী প্রেস করুন" "রিড্যাক্ট করা হয়েছে" "দেখার জন্য আনলক করুন" + "প্রাসঙ্গিক শিক্ষা" "ফিরে যেতে টাচপ্যাড ব্যবহার করুন" "তিনটি আঙুলের ব্যবহার করে ডান বা বাঁদিকে সোয়াইপ করুন। আরও জেসচার সম্পর্কে জানতে ট্যাপ করুন।" "হোমে যেতে টাচপ্যাড ব্যবহার করুন" diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 679becec2b15..4c79f4879043 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -440,7 +440,8 @@ "Uključeno" "Uključeno • %1$s" "Isključeno" - "Postavite" + + "Upravljajte opcijom u postavkama" "{count,plural, =0{Nema aktivnih načina rada}=1{Način rada {mode} je aktivan}one{# način rada je aktivan}few{# načina rada su aktivna}other{# načina rada je aktivno}}" "Neće vas ometati zvukovi i vibracije, osim alarma, podsjetnika, događaja i pozivalaca koje odredite. I dalje ćete čuti sve što ste odabrali za reprodukciju, uključujući muziku, videozapise i igre." @@ -573,8 +574,7 @@ "Razgovori" "Obriši sva nečujna obavještenja" "Obavještenja su pauzirana načinom rada Ne ometaj" - - + "{count,plural,offset:1 =0{Nema obavještenja}=1{Obavještenja su pauzirana putem načina rada {mode}}=2{Obavještenja su pauzirana putem načina rada {mode} i još jednog načina rada}one{Obavještenja su pauzirana putem načina rada {mode} i još # načina rada}few{Obavještenja su pauzirana putem načina rada {mode} i još # načina rada}other{Obavještenja su pauzirana putem načina rada {mode} i još # načina rada}}" "Započni odmah" "Nema obavještenja" "Nema novih obavještenja" @@ -706,6 +706,7 @@ "Prikaži način rada za demonstraciju" "Ethernet" "Alarm" + "Način rada %1$s je uključen" "Novčanik" "Postavite aplikaciju za brže i sigurnije kupovine putem telefona" "Prikaži sve" @@ -1405,26 +1406,38 @@ "Saznajte više o pokretima na dodirnoj podlozi" "Krećite se pomoću tastature i dodirne podloge" "Saznajte više o pokretima na dodirnoj podlozi, prečicama tastature i drugim opcijama" - "Pokret za povratak" - "Pokret za povratak na početni ekran" + + + + "Prikaži nedavne aplikacije" "Gotovo" "Nazad" - "Da se vratite, prevucite ulijevo ili udesno s tri prsta bilo gdje na dodirnoj podlozi.\n\nZa ovo možete koristiti i radnju za prečicu i Esc na tastaturi." - "Sjajno!" + + + + "Savladali ste pokret za vraćanje." "Odlazak na početni ekran" - "Da odete na početni ekran bilo kada, prevucite s dna ekrana nagore s tri prsta." - "Lijepo!" - "Savladali ste pokret za odlazak na početni ekran." + + + + + + "Prikaz nedavnih aplikacija" - "Prevucite nagore i zadržite s tri prsta na dodirnoj podlozi." + + "Sjajno!" "Izvršili ste pokret za prikaz nedavnih aplikacija." - "Tipka radnji" - "Da pristupite aplikacijama, pritisnite tipku radnji na tastaturi." - "Čestitamo!" - "Savladali ste pokret za tipku radnji.\n\nRadnja + / prikazuje sve prečice koje su vam dostupne." + + + + + + + + "Pozadinsko osvjetljenje tastature" "%1$d. nivo od %2$d" "Kontrole za dom" @@ -1436,6 +1449,7 @@ "Da pregledate sve aplikacije, pritisnite tipku radnji na tastaturi" "Redigovano" "Otključajte da pregledate" + "Kontekstualno obrazovanje" "Koristite dodirnu podlogu da se vratite" "Prevucite ulijevo ili udesno s tri prsta. Dodirnite da saznate za više pokreta." "Koristite dodirnu podlogu da se vratite na početnu stranicu" diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index a0c0bf9defc8..1552c87fc181 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -440,7 +440,8 @@ "Activat" "Activat • %1$s" "Desactivat" - "Configura" + + "Gestiona a la configuració" "{count,plural, =0{No hi ha cap mode actiu}=1{{mode} està actiu}many{Hi ha # de modes actius}other{Hi ha # modes actius}}" "No t\'interromprà cap so ni cap vibració, tret dels de les alarmes, recordatoris, esdeveniments i trucades de les persones que especifiquis. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs." @@ -573,8 +574,7 @@ "Converses" "Esborra totes les notificacions silencioses" "Notificacions pausades pel mode No molestis" - - + "{count,plural,offset:1 =0{No hi ha cap notificació}=1{{mode} ha posat en pausa les notificacions}=2{{mode} i un altre mode han posat en pausa les notificacions}many{{mode} i # de modes més han posat en pausa les notificacions}other{{mode} i # modes més han posat en pausa les notificacions}}" "Comença ara" "No hi ha cap notificació" "No hi ha cap notificació nova" @@ -706,6 +706,7 @@ "Mostra el mode de demostració" "Ethernet" "Alarma" + "El mode %1$s està activat" "Wallet" "Configura una manera més ràpida i segura de fer compres amb el telèfon" "Mostra-ho tot" @@ -1405,26 +1406,38 @@ "Aprèn els gestos del ratolí tàctil" "Navega amb el teclat i el ratolí tàctil" "Aprèn els gestos del ratolí tàctil, les tecles de drecera i més" - "Gest Enrere" - "Gest Inici" + + + + "Mostra les aplicacions recents" "Fet" "Torna" - "Per tornar enrere, llisca cap a l\'esquerra o cap a la dreta amb tres dits en qualsevol lloc del ratolí tàctil.\n\nTambé pots utilitzar les tecles d\'accions de drecera+Esc." - "Ben fet!" + + + + "Has completat el gest per tornar enrere." "Ves a la pantalla d\'inici" - "Per anar a la pantalla d\'inici en qualsevol moment, fes lliscar tres dits cap amunt des de la part inferior de la pantalla." - "Molt bé!" - "Has completat el gest per anar a la pantalla d\'inici." + + + + + + "Mostra les aplicacions recents" - "Llisca cap amunt amb tres dits i mantén premut al ratolí tàctil." + + "Ben fet!" "Has completat el gest per veure les aplicacions recents." - "Tecla d\'acció" - "Per accedir a les aplicacions, prem la tecla d\'acció al teclat." - "Enhorabona!" - "Has completat el gest de la tecla d\'acció.\n\nTecla d\'acció+/ mostra totes les dreceres que tens disponibles." + + + + + + + + "Retroil·luminació del teclat" "Nivell %1$d de %2$d" "Controls de la llar" @@ -1436,6 +1449,7 @@ "Per veure totes les aplicacions, prem la tecla d\'acció al teclat" "Emmascarat" "Desbloqueja per veure" + "Educació contextual" "Utilitza el ratolí tàctil per tornar enrere" "Fes lliscar tres dits cap a l\'esquerra o cap a la dreta. Toca per aprendre més gestos." "Utilitza el ratolí tàctil per anar a la pantalla d\'inici" diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 107bac6b01a4..16895034b4f5 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -440,7 +440,8 @@ "Zapnuto" "Zapnuto • %1$s" "Vypnuto" - "Nastavit" + + "Spravovat v nastavení" "{count,plural, =0{Žádné aktivní}=1{Režim {mode} je aktivní}few{# režimy jsou aktivní}many{# režimu je aktivních}other{# režimů je aktivních}}" "Nebudou vás rušit zvuky ani vibrace s výjimkou budíků, upozornění, událostí a volajících, které zadáte. Nadále uslyšíte veškerý obsah, který si sami pustíte (např. hudba, videa nebo hry)." @@ -573,8 +574,7 @@ "Konverzace" "Vymazat všechna tichá oznámení" "Oznámení jsou pozastavena režimem Nerušit" - - + "{count,plural,offset:1 =0{Žádná oznámení}=1{Oznámení jsou pozastavená režimem {mode}}=2{Oznámení jsou pozastavená režimem {mode} a 1 dalším}few{Oznámení jsou pozastavená režimem {mode} a # dalšími}many{Oznámení jsou pozastavená režimem {mode} a # dalšího}other{Oznámení jsou pozastavená režimem {mode} a # dalšími}}" "Spustit" "Žádná oznámení" "Žádná nová oznámení" @@ -706,6 +706,7 @@ "Zobrazit ukázkový režim" "Ethernet" "Budík" + "Je zapnutý režim %1$s" "Peněženka" "Nastavte si rychlejší a bezpečnější platby pomocí telefonu" "Zobrazit vše" @@ -1405,26 +1406,38 @@ "Naučte se gesta touchpadu" "Navigujte pomocí klávesnice a touchpadu" "Naučte se gesta touchpadu, klávesové zkratky a další" - "Gesto zpět" - "Gesto domů" + + + + "Zobrazit nedávné aplikace" "Hotovo" "Zpět" - "Pokud se chcete vrátit zpět, stačí kdekoli na touchpadu přejet třemi prsty doleva nebo doprava.\n\nMůžete také použít klávesovou zkratku Akce + ESC." - "Výborně!" + + + + "Dokončili jste gesto pro přechod zpět." "Přejít na plochu" - "Na plochu přejdete kdykoli přejetím třemi prsty ze spodní části obrazovky nahoru." - "Skvělé!" - "Dokončili jste gesto pro přechod na plochu." + + + + + + "Zobrazit nedávné aplikace" - "Přejeďte po touchpadu třemi prsty nahoru a podržte je." + + "Výborně!" "Provedli jste gesto pro zobrazení nedávných aplikací." - "Akční klávesa" - "Přístup k aplikacím získáte stisknutím akční klávesy na klávesnici." - "Gratulujeme!" - "Dokončili jste gesto akční klávesy.\n\nAkce + / zobrazí všechny dostupné zkratky." + + + + + + + + "Podsvícení klávesnice" "Úroveň %1$d z %2$d" "Ovládání domácnosti" @@ -1436,6 +1449,7 @@ "Pokud chcete zobrazit všechny aplikace, stiskněte na klávesnici akční klávesu" "Odstraněno" "K zobrazení je potřeba zařízení odemknout" + "Kontextová výuka" "Návrat zpět pomocí touchpadu" "Přejeďte třemi prsty doleva nebo doprava. Další gesta zjistíte klepnutím." "Návrat domů pomocí touchpadu" diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 1ac75260f58d..729473c9450f 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -440,7 +440,8 @@ "Til" "Til • %1$s" "Fra" - "Konfigurer" + + "Administrer i indstillingerne" "{count,plural, =0{Ingen aktive tilstande}=1{{mode} er aktiv}one{# tilstand er aktiv}other{# tilstande er aktive}}" "Du bliver ikke forstyrret af lyde eller vibrationer, undtagen fra alarmer, påmindelser, begivenheder og opkald fra udvalgte personer, du selv angiver. Du kan stadig høre alt, du vælger at afspille, f.eks. musik, videoer og spil." @@ -573,8 +574,7 @@ "Samtaler" "Ryd alle lydløse notifikationer" "Notifikationer er sat på pause af Forstyr ikke" - - + "{count,plural,offset:1 =0{Ingen notifikationer}=1{Notifikationer er sat på pause af {mode}}=2{Notifikationer er sat på pause af {mode} og én anden tilstand}one{Notifikationer er sat på pause af {mode} og # anden tilstand}other{Notifikationer er sat på pause af {mode} og # andre tilstande}}" "Start nu" "Ingen notifikationer" "Ingen nye notifikationer" @@ -706,6 +706,7 @@ "Vis Demotilstand" "Ethernet" "Alarm" + "%1$s er aktiveret" "Wallet" "Bliv klar til at foretage hurtigere og mere sikre køb med din telefon" "Vis alle" @@ -1405,26 +1406,38 @@ "Se bevægelser på touchpladen" "Naviger ved hjælp af dit tastatur og din touchplade" "Se bevægelser på touchpladen, tastaturgenveje m.m." - "Bevægelse for at gå tilbage" - "Bevægelse for at gå til startskærm" + + + + "Se seneste apps" "Udfør" "Gå tilbage" - "Du kan gå tilbage ved at stryge mod venstre eller højre med tre fingre et vilkårligt sted på touchpladen.\n\nDu kan også bruge tastaturgenvejen Alt + Esc." - "Flot!" + + + + "Du har fuldført bevægelsen for Gå tilbage." "Gå til startskærmen" - "Du kan til enhver tid stryge opad med tre fingre fra bunden af skærmen, hvis du vil gå til startskærmen." - "Sådan!" - "Du har fuldført bevægelsen for Gå til startskærmen." + + + + + + "Se seneste apps" - "Stryg opad, og hold tre fingre på touchpladen." + + "Godt klaret!" "Du har udført bevægelsen for at se de seneste apps." - "Handlingstast" - "Du kan tilgå alle dine apps ved at trykke på handlingstasten på dit tastatur." - "Tillykke!" - "Du har fuldført bevægelsen for handlingstasten.\n\nHandling + / viser alle de tilgængelige genveje." + + + + + + + + "Tastaturets baggrundslys" "Niveau %1$d af %2$d" "Hjemmestyring" @@ -1436,6 +1449,7 @@ "Du kan se alle dine apps ved at trykke på handlingstasten på dit tastatur" "Skjult" "Lås op for at se" + "Kontekstbaseret uddannelse" "Brug din touchplade til at gå tilbage" "Stryg til venstre eller højre med tre fingre. Tryk for at lære flere bevægelser." "Brug din touchplade til at gå til startskærmen" diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 8f5a705bc196..655b7a2345ca 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -440,7 +440,8 @@ "An" "An • %1$s" "Aus" - "Einrichten" + + "In den Einstellungen verwalten" "{count,plural, =0{Keine aktiven Modi}=1{{mode} aktiv}other{# aktiv}}" "Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von dir festgelegten Personen. Du hörst jedoch weiterhin Sound, wenn du dir Musik anhörst, Videos ansiehst oder Spiele spielst." @@ -573,8 +574,7 @@ "Unterhaltungen" "Alle lautlosen Benachrichtigungen löschen" "Benachrichtigungen durch „Bitte nicht stören“ pausiert" - - + "{count,plural,offset:1 =0{Keine Benachrichtigungen}=1{Benachrichtigungen durch {mode} pausiert}=2{Benachrichtigungen durch {mode} und einen weiteren Modus pausiert}other{Benachrichtigungen durch {mode} und # weitere Modi pausiert}}" "Jetzt starten" "Keine Benachrichtigungen" "Keine neuen Benachrichtigungen" @@ -706,6 +706,8 @@ "Demomodus anzeigen" "Ethernet" "Weckruf" + + "Wallet" "Füge eine Zahlungsmethode hinzu, um noch schneller und sicherer mit deinem Smartphone zu bezahlen" "Alle anzeigen" @@ -1405,26 +1407,38 @@ "Informationen zu Touchpad-Gesten" "Navigation mit Tastatur und Touchpad" "Informationen zu Touchpad-Gesten, Tastenkombinationen und mehr" - "Touch-Geste „Zurück“" - "Touch-Geste „Startbildschirm“" + + + + "Letzte Apps aufrufen" "Fertig" "Zurück" - "Wenn du zurückgehen möchtest, wische an einer beliebigen Stelle des Touchpads mit drei Fingern nach links oder rechts.\n\nDu kannst stattdessen auch die Tastenkombination „Aktion“ + „ESC“ verwenden." - "Gut gemacht!" + + + + "Du hast den Schritt für die „Zurück“-Geste abgeschlossen." "Startbildschirm" - "Du kannst jederzeit zum Startbildschirm gehen, indem du mit drei Fingern vom unteren Displayrand nach oben wischst." - "Sehr gut!" - "Du hast den Schritt für die „Startbildschirm“-Geste abgeschlossen." + + + + + + "Letzte Apps aufrufen" - "Wische mit 3 Fingern nach oben und halte das Touchpad gedrückt." + + "Gut gemacht!" "Du hast das Tutorial für die Touch-Geste zum Aufrufen der zuletzt verwendeten Apps abgeschlossen." - "Aktionstaste" - "Wenn du auf deine Apps zugreifen möchtest, drücke auf der Tastatur die Aktionstaste." - "Glückwunsch!" - "Du hast den Schritt für die „Aktionstaste“-Geste abgeschlossen.\n\nAktion + / zeigt alle verfügbaren Tastenkombinationen." + + + + + + + + "Tastaturbeleuchtung" "Level %1$d von %2$d" "Smart-Home-Steuerung" @@ -1436,6 +1450,7 @@ "Wenn du alle deine Apps aufrufen möchtest, drücke auf der Tastatur die Aktionstaste" "Entfernt" "Zum Ansehen entsperren" + "Kontextbezogene Informationen" "Über das Touchpad zurückgehen" "Wische mit drei Fingern nach links oder rechts. Tippe für mehr Infos zu Touch-Gesten." "Über das Touchpad zum Startbildschirm zurückkehren" diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 183249bc3e16..3c99fbb3ce09 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -440,7 +440,8 @@ "Ενεργό" "Ενεργή • %1$s" "Ανενεργό" - "Ρύθμιση" + + "Διαχείριση στις ρυθμίσεις" "{count,plural, =0{Δεν υπάρχει ενεργή λειτουργία}=1{{mode} ενεργή λειτουργία}other{# ενεργές λειτουργίες}}" "Δεν θα ενοχλείστε από ήχους και δονήσεις, παρά μόνο από ξυπνητήρια, υπενθυμίσεις, συμβάντα και καλούντες που έχετε καθορίσει. Θα εξακολουθείτε να ακούτε όλο το περιεχόμενο που επιλέγετε να αναπαραγάγετε, συμπεριλαμβανομένης της μουσικής, των βίντεο και των παιχνιδιών." @@ -573,8 +574,7 @@ "Συζητήσεις" "Διαγραφή όλων των ειδοποιήσεων σε σίγαση" "Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία \"Μην ενοχλείτε\"" - - + "{count,plural,offset:1 =0{Δεν υπάρχουν ειδοποιήσεις}=1{Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία {mode}}=2{Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία {mode} και μία άλλη λειτουργία}other{Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία {mode} και # άλλες λειτουργίες}}" "Έναρξη τώρα" "Δεν υπάρχουν ειδοποιήσεις" "Δεν υπάρχουν νέες ειδοποιήσεις" @@ -706,6 +706,7 @@ "Εμφάνιση λειτουργίας επίδειξης" "Ethernet" "Ξυπνητήρι" + "Η λειτουργία %1$s είναι ενεργή" "Πορτοφόλι" "Ολοκληρώστε τη ρύθμιση για να κάνετε πιο γρήγορες και πιο ασφαλείς αγορές με το τηλέφωνό σας" "Εμφάνιση όλων" @@ -1405,26 +1406,38 @@ "Μάθετε κινήσεις επιφάνειας αφής" "Πλοήγηση με το πληκτρολόγιο και την επιφάνεια αφής" "Μάθετε κινήσεις επιφάνειας αφής, συντομεύσεις πληκτρολογίου και άλλα" - "Κίνηση επιστροφής" - "Κίνηση μετάβασης στην αρχική οθόνη" + + + + "Προβολή πρόσφατων εφαρμογών" "Τέλος" "Επιστροφή" - "Για να επιστρέψετε, σύρετε προς τα αριστερά ή προς τα δεξιά χρησιμοποιώντας τρία δάχτυλα σε οποιοδήποτε σημείο της επιφάνειας αφής.\n\nΜπορείτε επίσης να χρησιμοποιήσετε τη συντόμευση πληκτρολογίου Action + ESC." - "Μπράβο!" + + + + "Ολοκληρώσατε την κίνηση επιστροφής." "Αρχική" - "Για μετάβαση στην αρχική οθόνη ανά πάσα στιγμή, σύρετε προς τα επάνω με τρία δάχτυλα από το κάτω μέρος της οθόνης." - "Ωραία!" - "Ολοκληρώσατε την κίνηση μετάβασης στην αρχική οθόνη." + + + + + + "Προβολή πρόσφατων εφαρμογών" - "Σύρετε προς τα πάνω με τρία δάχτυλα στην επιφάνεια αφής και μην τα σηκώσετε." + + "Μπράβο!" "Ολοκληρώσατε την κίνηση για την προβολή πρόσφατων εφαρμογών." - "Πλήκτρο ενέργειας" - "Για να αποκτήσετε πρόσβαση στις εφαρμογές σας, πατήστε το πλήκτρο ενέργειας στο πληκτρολόγιό σας." - "Συγχαρητήρια!" - "Ολοκληρώσατε την κίνηση του κουμπιού ενέργειας.\n\nΗ ενέργεια + / εμφανίζει όλες τις διαθέσιμες συντομεύσεις." + + + + + + + + "Οπίσθιος φωτισμός πληκτρολογίου" "Επίπεδο %1$d από %2$d" "Οικιακοί έλεγχοι" @@ -1436,6 +1449,7 @@ "Για να δείτε όλες τις εφαρμογές, πιέστε το πλήκτρο ενέργειας στο πληκτρολόγιό σας" "Αποκρύφτηκε" "Ξεκλείδωμα για προβολή" + "Εκπαίδευση με βάση τα συμφραζόμενα" "Χρήση της επιφάνειας αφής για επιστροφή" "Σύρετε προς τα αριστερά ή τα δεξιά με τρία δάχτυλα. Πατήστε για να μάθετε περισσότερες κινήσεις." "Χρήση της επιφάνειας αφής για μετάβαση στην αρχική οθόνη" diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 9b7ae5da01ed..4570c0a35eff 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -440,7 +440,8 @@ "On" "On • %1$s" "Off" - "Set up" + + "Manage in settings" "{count,plural, =0{No active modes}=1{{mode} is active}other{# modes are active}}" "You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers you specify. You\'ll still hear anything you choose to play including music, videos and games." @@ -573,8 +574,7 @@ "Conversations" "Clear all silent notifications" "Notifications paused by Do Not Disturb" - - + "{count,plural,offset:1 =0{No notifications}=1{Notifications paused by {mode}}=2{Notifications paused by {mode} and one other mode}other{Notifications paused by {mode} and # other modes}}" "Start now" "No notifications" "No new notifications" @@ -706,6 +706,7 @@ "Show demo mode" "Ethernet" "Alarm" + "%1$s is on" "Wallet" "Get set up to make faster, more secure purchases with your phone" "Show all" @@ -1405,26 +1406,38 @@ "Learn touchpad gestures" "Navigate using your keyboard and touchpad" "Learn touchpad gestures, keyboards shortcuts and more" - "Back gesture" - "Home gesture" + + + + "View recent apps" "Done" "Go back" - "To go back, swipe left or right using three fingers anywhere on the touchpad.\n\nYou can also use the keyboard shortcut Action + Esc for this." - "Great work!" + + + + "You completed the go back gesture." "Go home" - "To go to your home screen at any time, swipe up with three fingers from the bottom of your screen." - "Nice!" - "You completed the go home gesture." + + + + + + "View recent apps" - "Swipe up and hold using three fingers on your touchpad." + + "Well done!" "You completed the view recent apps gesture." - "Action key" - "To access your apps, press the action key on your keyboard." - "Congratulations!" - "You completed the action key gesture.\n\nAction + / shows all the shortcuts that you have available." + + + + + + + + "Keyboard backlight" "Level %1$d of %2$d" "Home controls" @@ -1436,6 +1449,7 @@ "To view all your apps, press the action key on your keyboard" "Redacted" "Unlock to view" + "Contextual education" "Use your touchpad to go back" "Swipe left or right using three fingers. Tap to learn more gestures." "Use your touchpad to go home" diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 4fcc7a4eb550..3d33fa0b8400 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -440,7 +440,7 @@ "On" "On • %1$s" "Off" - "Set up" + "Not set" "Manage in settings" "{count,plural, =0{No active modes}=1{{mode} is active}other{# modes are active}}" "You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events, and callers you specify. You\'ll still hear anything you choose to play including music, videos, and games." @@ -705,6 +705,7 @@ "Show demo mode" "Ethernet" "Alarm" + "%1$s is on" "Wallet" "Get set up to make faster, more secure purchases with your phone" "Show all" @@ -1404,26 +1405,26 @@ "Learn touchpad gestures" "Navigate using your keyboard and touchpad" "Learn touchpad gestures, keyboards shortcuts, and more" - "Back gesture" - "Home gesture" + "Go back" + "Go home" "View recent apps" "Done" "Go back" - "To go back, swipe left or right using three fingers anywhere on the touchpad.\n\nYou can also use the keyboard shortcut Action + ESC for this." - "Great job!" + "Swipe left or right using three fingers on your touchpad" + "Nice!" "You completed the go back gesture." "Go home" - "To go to your home screen at any time, swipe up with three fingers from the bottom of your screen." - "Nice!" - "You completed the go home gesture." + "Swipe up with three fingers on your touchpad" + "Great job!" + "You completed the go home gesture" "View recent apps" - "Swipe up and hold using three fingers on your touchpad." + "Swipe up and hold using three fingers on your touchpad" "Great job!" "You completed the view recent apps gesture." - "Action key" - "To access your apps, press the action key on your keyboard." - "Congratulations!" - "You completed the action key gesture.\n\nAction + / shows all the shortcuts you have available." + "View all apps" + "Press the action key on your keyboard" + "Well done!" + "You completed the view all apps gesture" "Keyboard backlight" "Level %1$d of %2$d" "Home Controls" @@ -1435,6 +1436,7 @@ "To view all your apps, press the action key on your keyboard" "Redacted" "Unlock to view" + "Contextual education" "Use your touchpad to go back" "Swipe left or right using three fingers. Tap to learn more gestures." "Use your touchpad to go home" diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index cea405b7d18d..4570c0a35eff 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -440,7 +440,8 @@ "On" "On • %1$s" "Off" - "Set up" + + "Manage in settings" "{count,plural, =0{No active modes}=1{{mode} is active}other{# modes are active}}" "You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers you specify. You\'ll still hear anything you choose to play including music, videos and games." @@ -705,6 +706,7 @@ "Show demo mode" "Ethernet" "Alarm" + "%1$s is on" "Wallet" "Get set up to make faster, more secure purchases with your phone" "Show all" @@ -1404,26 +1406,38 @@ "Learn touchpad gestures" "Navigate using your keyboard and touchpad" "Learn touchpad gestures, keyboards shortcuts and more" - "Back gesture" - "Home gesture" + + + + "View recent apps" "Done" "Go back" - "To go back, swipe left or right using three fingers anywhere on the touchpad.\n\nYou can also use the keyboard shortcut Action + Esc for this." - "Great work!" + + + + "You completed the go back gesture." "Go home" - "To go to your home screen at any time, swipe up with three fingers from the bottom of your screen." - "Nice!" - "You completed the go home gesture." + + + + + + "View recent apps" - "Swipe up and hold using three fingers on your touchpad." + + "Well done!" "You completed the view recent apps gesture." - "Action key" - "To access your apps, press the action key on your keyboard." - "Congratulations!" - "You completed the action key gesture.\n\nAction + / shows all the shortcuts that you have available." + + + + + + + + "Keyboard backlight" "Level %1$d of %2$d" "Home controls" @@ -1435,8 +1449,7 @@ "To view all your apps, press the action key on your keyboard" "Redacted" "Unlock to view" - - + "Contextual education" "Use your touchpad to go back" "Swipe left or right using three fingers. Tap to learn more gestures." "Use your touchpad to go home" diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 9b7ae5da01ed..4570c0a35eff 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -440,7 +440,8 @@ "On" "On • %1$s" "Off" - "Set up" + + "Manage in settings" "{count,plural, =0{No active modes}=1{{mode} is active}other{# modes are active}}" "You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers you specify. You\'ll still hear anything you choose to play including music, videos and games." @@ -573,8 +574,7 @@ "Conversations" "Clear all silent notifications" "Notifications paused by Do Not Disturb" - - + "{count,plural,offset:1 =0{No notifications}=1{Notifications paused by {mode}}=2{Notifications paused by {mode} and one other mode}other{Notifications paused by {mode} and # other modes}}" "Start now" "No notifications" "No new notifications" @@ -706,6 +706,7 @@ "Show demo mode" "Ethernet" "Alarm" + "%1$s is on" "Wallet" "Get set up to make faster, more secure purchases with your phone" "Show all" @@ -1405,26 +1406,38 @@ "Learn touchpad gestures" "Navigate using your keyboard and touchpad" "Learn touchpad gestures, keyboards shortcuts and more" - "Back gesture" - "Home gesture" + + + + "View recent apps" "Done" "Go back" - "To go back, swipe left or right using three fingers anywhere on the touchpad.\n\nYou can also use the keyboard shortcut Action + Esc for this." - "Great work!" + + + + "You completed the go back gesture." "Go home" - "To go to your home screen at any time, swipe up with three fingers from the bottom of your screen." - "Nice!" - "You completed the go home gesture." + + + + + + "View recent apps" - "Swipe up and hold using three fingers on your touchpad." + + "Well done!" "You completed the view recent apps gesture." - "Action key" - "To access your apps, press the action key on your keyboard." - "Congratulations!" - "You completed the action key gesture.\n\nAction + / shows all the shortcuts that you have available." + + + + + + + + "Keyboard backlight" "Level %1$d of %2$d" "Home controls" @@ -1436,6 +1449,7 @@ "To view all your apps, press the action key on your keyboard" "Redacted" "Unlock to view" + "Contextual education" "Use your touchpad to go back" "Swipe left or right using three fingers. Tap to learn more gestures." "Use your touchpad to go home" diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 3c22ed163d31..3d157c7b7648 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -440,7 +440,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‏‏‏‎On‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎On • ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎Off‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‎Set up‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‎Not set‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎Manage in settings‎‏‎‎‏‎" "{count,plural, =0{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‎‏‏‎‎‎‎No active modes‎‏‎‎‏‎}=1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‎{mode}‎‏‎‎‏‏‏‎ is active‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‎‏‏‎‎‎‎# modes are active‎‏‎‎‏‎}}" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events, and callers you specify. You\'ll still hear anything you choose to play including music, videos, and games.‎‏‎‎‏‎" @@ -705,6 +705,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‎‎Show demo mode‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎Ethernet‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎Alarm‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ is on‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎Wallet‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‏‎‎Get set up to make faster, more secure purchases with your phone‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎Show all‎‏‎‎‏‎" @@ -1404,26 +1405,26 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‎‏‎‎Learn touchpad gestures‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‎Navigate using your keyboard and touchpad‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎Learn touchpad gestures, keyboards shortcuts, and more‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎Back gesture‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎Home gesture‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎Go back‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎Go home‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎View recent apps‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎Done‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎Go back‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎To go back, swipe left or right using three fingers anywhere on the touchpad.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎You can also use the keyboard shortcut Action + ESC for this.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎Great job!‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎Swipe left or right using three fingers on your touchpad‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎Nice!‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎‏‎‏‎‏‏‏‎You completed the go back gesture.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎Go home‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‏‎‎To go to your home screen at any time, swipe up with three fingers from the bottom of your screen.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‎Nice!‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎You completed the go home gesture.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎Swipe up with three fingers on your touchpad‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‎‎Great job!‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‎You completed the go home gesture‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎View recent apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎Swipe up and hold using three fingers on your touchpad.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‎‏‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎Swipe up and hold using three fingers on your touchpad‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎Great job!‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎You completed the view recent apps gesture.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‎Action key‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‎‎‏‏‏‎‎‎To access your apps, press the action key on your keyboard.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎Congratulations!‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎You completed the action key gesture.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Action + / shows all the shortcuts you have available.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‏‎View all apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎Press the action key on your keyboard‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‏‎Well done!‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎You completed the view all apps gesture‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎Keyboard backlight‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎Level %1$d of %2$d‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‎‎‎‏‎Home Controls‎‏‎‎‏‎" @@ -1435,6 +1436,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎‏‏‎‎‏‎‏‎‏‎‎To view all your apps, press the action key on your keyboard‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‎‎Redacted‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎Unlock to view‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‏‏‎‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‎Contextual education‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎Use your touchpad to go back‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎Swipe left or right using three fingers. Tap to learn more gestures.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‎‎‏‏‏‎‏‎Use your touchpad to go home‎‏‎‎‏‎" diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 88cedcf8f1d1..6c80a2c81954 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -440,7 +440,8 @@ "Activado" "Sí • %1$s" "Desactivado" - "Configurar" + + "Administrar en configuración" "{count,plural, =0{No hay modos activos}=1{{mode} está activo}many{# de modos están activos}other{# modos están activos}}" "No te molestarán los sonidos ni las vibraciones, excepto las alarmas, los recordatorios, los eventos y las llamadas de los emisores que especifiques. Podrás escuchar el contenido que reproduzcas, como música, videos y juegos." @@ -573,8 +574,7 @@ "Conversaciones" "Borrar todas las notificaciones silenciosas" "Notificaciones pausadas por el modo \"No interrumpir\"" - - + "{count,plural,offset:1 =0{No hay notificaciones}=1{{mode} pausó las notificaciones}=2{{mode} y un modo más pausaron las notificaciones}many{{mode} y # de modos más pausaron las notificaciones}other{{mode} y # modos más pausaron las notificaciones}}" "Comenzar ahora" "No hay notificaciones" "No hay notificaciones nuevas" @@ -706,6 +706,7 @@ "Ver en modo de demostración" "Ethernet" "Alarma" + "%1$s activado" "Billetera" "Prepárate para realizar compras rápidas y seguras con tu teléfono" "Mostrar todo" @@ -1405,26 +1406,38 @@ "Aprende los gestos del panel táctil" "Navega con el teclado y el panel táctil" "Aprende sobre los gestos del panel táctil, las combinaciones de teclas y mucho más" - "Gesto atrás" - "Gesto para ir a la pantalla principal" + + + + "Ver apps recientes" "Listo" "Atrás" - "Para volver, desliza tres dedos hacia la derecha o la izquierda en cualquier lugar del panel táctil.\n\nPara completar esta acción, también puedes usar la combinación de teclas Action + ESC." - "¡Bien hecho!" + + + + "Completaste el gesto para ir atrás." "Ir a la página principal" - "Para ir a la pantalla principal en cualquier momento, desliza hacia arriba desde la parte inferior de la pantalla con tres dedos." - "¡Muy bien!" - "Completaste el gesto para ir al inicio." + + + + + + "Ver apps recientes" - "Desliza hacia arriba con tres dedos en el panel táctil y mantenlos presionados." + + "¡Bien hecho!" "Completaste el gesto para ver las apps recientes." - "Tecla de acción" - "Para acceder a las apps, presiona la tecla de acción en el teclado." - "¡Felicitaciones!" - "Completaste el gesto de la tecla de acción.\n\nSi presionas las teclas Acción + /, se muestran todas las combinaciones de teclas disponibles." + + + + + + + + "Retroiluminación del teclado" "Nivel %1$d de %2$d" "Controles de la casa" @@ -1436,6 +1449,7 @@ "Para ver todas las apps, presiona la tecla de acción en el teclado" "Oculto" "Desbloquea el dispositivo para ver" + "Educación contextual" "Usa el panel táctil para ir hacia atrás" "Desliza hacia la izquierda o la derecha con tres dedos. Presiona para aprender más gestos." "Usa el panel táctil para ir a la pantalla principal" @@ -1445,7 +1459,7 @@ "Usa el teclado para ver todas las apps" "Presiona la tecla de acción en cualquier momento. Presiona para aprender más gestos." "La atenuación extra ahora es parte del control deslizante de brillo" - "Ahora puedes bajar el nivel del brillo de la pantalla para atenuarla aún más.\n\nComo esta función ahora es parte del control deslizante de brillo, se quitaron los accesos directos de atenuación extra." + "Ahora puedes bajar el nivel del brillo de la pantalla para atenuarla aún más.\n\nComo esta función ahora es parte del control deslizante de brillo, se quitaron los accesos directos a la atenuación extra." "Quitar accesos directos a la atenuación extra" "Se quitaron los accesos directos a la atenuación extra" "Conectividad" diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 63f4ae11a7f6..f77119e3b90a 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -440,7 +440,8 @@ "Activado" "Activado • %1$s" "Desactivado" - "Configurar" + + "Gestionar en los ajustes" "{count,plural, =0{No hay modos activos}=1{{mode} está activo}many{Hay # modos activos}other{Hay # modos activos}}" "No te molestarán los sonidos ni las vibraciones, excepto las alarmas, los recordatorios, los eventos y las llamadas que especifiques. Seguirás escuchando el contenido que quieras reproducir, como música, vídeos y juegos." @@ -573,8 +574,7 @@ "Conversaciones" "Borrar todas las notificaciones silenciosas" "Notificaciones pausadas por el modo No molestar" - - + "{count,plural,offset:1 =0{No hay notificaciones}=1{Notificaciones pausadas por {mode}}=2{Notificaciones pausadas por {mode} y un modo más}many{Notificaciones pausadas por {mode} y # modos más}other{Notificaciones pausadas por {mode} y # modos más}}" "Empezar ahora" "No hay notificaciones" "No hay notificaciones nuevas" @@ -706,6 +706,7 @@ "Mostrar modo Demo" "Ethernet" "Alarma" + "%1$s activado" "Wallet" "Configura un método de pago para comprar de forma más rápida y segura con tu teléfono" "Mostrar todo" @@ -1405,26 +1406,38 @@ "Aprende gestos del panel táctil" "Desplázate con el teclado y el panel táctil" "Aprende gestos del panel táctil, combinaciones de teclas y más" - "Gesto para volver" - "Gesto para ir al inicio" + + + + "Ver aplicaciones recientes" "Hecho" "Atrás" - "Para volver, desliza con tres dedos hacia la izquierda o la derecha en cualquier parte del panel táctil.\n\nTambién puedes hacerlo con la combinación de teclas asignada + Esc." - "¡Bien hecho!" + + + + "Has completado el gesto para volver." "Ir a Inicio" - "Para ir a la pantalla de inicio en cualquier momento, desliza hacia arriba con tres dedos desde la parte inferior de la pantalla." - "¡Muy bien!" - "Has completado el gesto para ir a la pantalla de inicio." + + + + + + "Ver aplicaciones recientes" - "Desliza tres dedos hacia arriba y mantén pulsado en el panel táctil." + + "¡Bien hecho!" "Has completado el gesto para ver las aplicaciones recientes." - "Tecla de acción" - "Para acceder a tus aplicaciones, pulsa la tecla de acción de tu teclado." - "¡Enhorabuena!" - "Has completado el gesto de la tecla de acción.\n\nLa combinación de teclas Acción + / muestra todas las combinaciones de teclas que tienes disponibles." + + + + + + + + "Retroiluminación del teclado" "Nivel %1$d de %2$d" "Controles de la casa" @@ -1436,6 +1449,7 @@ "Para ver todas tus aplicaciones, pulsa la tecla de acción de tu teclado" "Oculta" "Desbloquea para ver" + "Educación contextual" "Usa el panel táctil para volver atrás" "Desliza hacia la izquierda o hacia la derecha con tres dedos. Toca para aprender a usar más gestos." "Usa el panel táctil para ir a la pantalla de inicio" @@ -1445,7 +1459,7 @@ "Usa el teclado para ver todas las aplicaciones" "Pulsa la tecla de acción en cualquier momento. Toca para aprender a usar más gestos." "La atenuación extra ahora forma parte del control deslizante de brillo" - "Ahora puedes atenuar aún más tu pantalla reduciendo el nivel de brillo incluso más todavía.\n\nComo esta función ahora forma parte del control deslizante de brillo, se van a quitar los accesos directos de atenuación extra." + "Ahora puedes atenuar aún más tu pantalla reduciendo el nivel de brillo.\n\nComo esta función ahora forma parte del control deslizante de brillo, se van a quitar los accesos directos de atenuación extra." "Eliminar accesos directos de atenuación extra" "Accesos directos de atenuación extra eliminados" "Conectividad" diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 35d40120c802..3323a3f157db 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -440,7 +440,8 @@ "Sees" "Sees • %1$s" "Väljas" - "Seadistamine" + + "Seadetes halamine" "{count,plural, =0{Aktiivsed režiimid puuduvad}=1{{mode} on aktiivne}other{# režiimi on aktiivsed}}" "Helid ja värinad ei sega teid. Kuulete siiski enda määratud äratusi, meeldetuletusi, sündmusi ja helistajaid. Samuti kuulete kõike, mille esitamise ise valite, sh muusika, videod ja mängud." @@ -573,8 +574,7 @@ "Vestlused" "Kustuta kõik hääletud märguanded" "Režiim Mitte segada peatas märguanded" - - + "{count,plural,offset:1 =0{Märguandeid pole}=1{{mode} peatas märguanded}=2{{mode} ja veel üks režiim peatasid märguanded}other{{mode} ja veel # režiimi peatasid märguanded}}" "Alusta kohe" "Märguandeid pole" "Uusi märguandeid ei ole" @@ -706,6 +706,7 @@ "Kuva demorežiim" "Ethernet" "Äratus" + "%1$s on sisse lülitatud" "Wallet" "Seadistage kiirem ja turvalisem viis telefoniga ostmiseks" "Kuva kõik" @@ -1405,26 +1406,38 @@ "Õppige puuteplaadi liigutusi" "Navigeerige klaviatuuri ja puuteplaadi abil" "Õppige puuteplaadi liigutusi, klaviatuuri otseteid ja palju muud" - "Tagasiliikumisliigutus" - "Avakuvale liikumise liigutus" + + + + "Hiljutiste rakenduste vaatamine" "Valmis" "Tagasi" - "Tagasiliikumiseks pühkige puuteplaadil kolme sõrmega vasakule või paremale.\n\nSamuti saate selle jaoks kasutada klaviatuuri otseteed toiminguklahv + paoklahv." - "Väga hea!" + + + + "Tegite tagasiliikumise liigutuse." "Avalehele" - "Mis tahes ajal avakuvale liikumiseks pühkige kolme sõrmega ekraanikuva allosast üles." - "Hästi tehtud!" - "Tegite avakuvale minemise liigutuse." + + + + + + "Hiljutiste rakenduste vaatamine" - "Pühkige üles ja hoidke kolme sõrmega puuteplaadil." + + "Väga hea!" "Lõpetasite hiljutiste rakenduste vaatamise liigutuse." - "Toiminguklahv" - "Rakendustele juurdepääsemiseks vajutage klaviatuuril toiminguklahvi." - "Õnnitleme!" - "Tegite toiminguklahvi liigutuse.\n\nKombinatsiooni toiminguklahv + / vajutamisel kuvatakse kõik saadaolevad otseteed." + + + + + + + + "Klaviatuuri taustavalgustus" "Tase %1$d/%2$d" "Kodu juhtelemendid" @@ -1436,6 +1449,7 @@ "Kõigi oma rakenduste kuvamiseks vajutage klaviatuuril toiminguklahvi" "Peidetud" "Vaatamiseks avage" + "Kontekstipõhised õpetused" "Puuteplaadi kasutamine tagasiliikumiseks" "Pühkige kolme sõrmega vasakule või paremale. Puudutage žestide kohta lisateabe saamiseks." "Puuteplaadi kasutamine avakuvale liikumiseks" diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 7e0f203d0b0b..246c23085159 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -440,7 +440,8 @@ "Aktibatuta" "Aktibo • %1$s" "Desaktibatuta" - "Konfiguratu" + + "Kudeatu ezarpenetan" "{count,plural, =0{Ez dago modurik aktibo}=1{\"{mode}\" aktibo dago}other{# modu aktibo daude}}" "Gailuak ez du egingo ez soinurik ez dardararik, baina alarmak, gertaera eta abisuen tonuak, eta aukeratzen dituzun deitzaileen dei-tonuak joko ditu. Bestalde, zuk erreproduzitutako guztia entzungo duzu, besteak beste, musika, bideoak eta jokoak." @@ -573,8 +574,7 @@ "Elkarrizketak" "Garbitu soinurik gabeko jakinarazpen guztiak" "Ez molestatzeko moduak pausatu egin ditu jakinarazpenak" - - + "{count,plural,offset:1 =0{Ez dago jakinarazpenik}=1{Modu honek jakinarazpenak pausatu ditu: {mode}}=2{Modu honek eta beste modu batek jakinarazpenak pausatu dituzte: {mode}}other{Modu honek eta beste # moduk jakinarazpenak pausatu dituzte: {mode}}}" "Hasi" "Ez dago jakinarazpenik" "Ez dago jakinarazpen berririk" @@ -706,6 +706,8 @@ "Erakutsi demo modua" "Ethernet" "Alarma" + + "Diru-zorroa" "Konfiguratu erosketa bizkorrago eta seguruagoak egiteko telefonoarekin" "Erakutsi guztiak" @@ -1405,26 +1407,38 @@ "Ikasi ukipen-paneleko keinuak" "Nabigatu teklatua eta ukipen-panela erabilita" "Ikasi ukipen-paneleko keinuak, lasterbideak eta abar" - "Atzera egiteko keinua" - "Orri nagusira joateko keinua" + + + + "Ikusi azkenaldiko aplikazioak" "Eginda" "Egin atzera" - "Atzera egiteko, pasatu 3 hatz ezkerrera edo eskuinera ukipen-panelean.\n\nEkintza + Ihes lasterbidea ere erabil dezakezu horretarako." - "Bikain!" + + + + "Ikasi duzu atzera egiteko keinua." "Joan orri nagusira" - "Orri nagusira joateko, pasatu 3 hatz pantailaren behealdetik gora." - "Ederki!" - "Ikasi duzu hasierako pantailara joateko keinua." + + + + + + "Ikusi azkenaldiko aplikazioak" - "Pasatu 3 hatz gora eta eduki sakatuta ukipen-panelean." + + "Bikain!" "Osatu duzu azkenaldiko aplikazioak ikusteko keinua." - "Ekintza-tekla" - "Aplikazioak atzitzeko, sakatu teklatuko ekintza-tekla." - "Zorionak!" - "Ekintza-teklaren keinua egin duzu.\n\nEkintza + / sakatuz gero, erabilgarri dituzun lasterbide guztiak ikusiko dituzu." + + + + + + + + "Teklatuaren hondoko argia" "%1$d/%2$d maila" "Etxeko gailuen kontrola" @@ -1436,6 +1450,7 @@ "Aplikazio guztiak ikusteko, sakatu teklatuko ekintza-tekla" "Desitxuratuta" "Desblokeatu ikusteko" + "Testuinguruaren araberako hezkuntza" "Erabili ukipen-panela atzera egiteko" "Pasatu 3 hatz ezkerrera edo eskuinera. Sakatu keinu gehiago ikasteko." "Erabili ukipen-panela hasierako pantailara joateko" diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index e70d2bb1ba95..29a2739dd74f 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -440,7 +440,8 @@ "روشن" "روشن • %1$s" "خاموش" - "راه‌اندازی" + + "مدیریت در تنظیمات" "{count,plural, =0{حالت فعالی وجود ندارد}=1{‫{mode} فعال است}one{‫# حالت فعال است}other{‫# حالت فعال است}}" "به‌جز هشدارها، یادآوری‌ها، رویدادها و تماس‌گیرندگانی که خودتان مشخص می‌کنید، هیچ صدا و لرزشی نخواهید داشت. همچنان صدای مواردی را که پخش می‌کنید می‌شنوید (ازجمله صدای موسیقی، ویدیو و بازی)." @@ -573,8 +574,7 @@ "مکالمه‌ها" "پاک کردن همه اعلان‌های بی‌صدا" "اعلان‌ها توسط «مزاحم نشوید» موقتاً متوقف شدند" - - + "{count,plural,offset:1 =0{اعلانی موقتاً متوقف نشده است}=1{اعلان‌ها را «{mode}» موقتاً متوقف کرده است}=2{اعلان‌ها را «{mode}» و یک حالت دیگر موقتاً متوقف کرد‌اند}one{اعلان‌ها را «{mode}» و # حالت دیگر موقتاً متوقف کرده‌اند}other{اعلان‌ها را «{mode}» و # حالت دیگر موقتاً متوقف کرده‌اند}}" "اکنون شروع کنید" "اعلانی موجود نیست" "اعلان جدیدی وجود ندارد" @@ -706,6 +706,7 @@ "نمایش حالت نمایشی" "اترنت" "زنگ" + "%1$s روشن است" "کیف پول" "برای خرید سریع‌تر و امن‌تر با تلفن، راه‌اندازی کنید" "نمایش همه" @@ -1178,7 +1179,7 @@ "توقف پخش محتوا" "دستگاه‌های دردسترس برای خروجی صوتی." "میزان صدا" - "%1$d%%" + "‎%%%1$d" "بلندگوها و نمایشگرها" "دستگاه‌های پیشنهادی" "ورودی" @@ -1405,26 +1406,38 @@ "آشنایی با اشاره‌های صفحه لمسی" "پیمایش کردن بااستفاده از صفحه‌کلید و صفحه لمسی" "آشنایی با اشاره‌های صفحه لمسی، میان‌برهای صفحه‌کلید، و موارد دیگر" - "اشاره برگشت" - "اشاره صفحه اصلی" + + + + "مشاهده کردن برنامه‌های اخیر" "تمام" "برگشتن" - "برای برگشتن، در هر جایی از صفحه لمسی، با سه انگشت تند به‌چپ یا راست بکشید.\n\nبرای این کار می‌توانید از میان‌بر صفحه‌کلید «کنش + گریز» هم استفاده کنید." - "عالی بود!" + + + + "اشاره برگشت را تکمیل کردید." "رفتن به صفحه اصلی" - "برای رفتن به صفحه اصلی در هرزمانی، با سه انگشت از پایین صفحه‌نمایش تند به‌بالا بکشید." - "آفرین!" - "اشاره رفتن به صفحه اصلی را تکمیل کردید." + + + + + + "مشاهده کردن برنامه‌های اخیر" - "با سه انگشت روی صفحه لمسی تند به‌بالا بکشید و نگه دارید." + + "عالی است!" "اشاره مشاهده برنامه‌های اخیر را انجام دادید" - "دکمه کنش" - "برای دسترسی به برنامه‌هایتان، دکمه کنش در صفحه‌کلید را فشار دهید." - "تبریک!" - "اشاره دکمه کنش را تکمیل کردید.\n\n«کنش» + / همه میان‌برهای دردسترس را نمایش می‌دهد." + + + + + + + + "نور پس‌زمینه صفحه‌کلید" "‏سطح %1$d از %2$d" "کنترل خانه هوشمند" @@ -1436,6 +1449,7 @@ "برای مشاهده همه برنامه‌ها، دکمه کنش در صفحه‌کلید را فشار دهید" "محوشده" "برای مشاهده، قفل را باز کنید" + "آموزش زمینه‌ای" "برای برگشتن از صفحه لمسی استفاده کنید" "با سه انگشت تند به‌چپ یا راست بکشید. برای آشنایی با اشاره‌های بیشتر، تک‌ضرب بزنید." "برای رفتن به صفحه اصلی از صفحه لمسی استفاده کنید" diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index f6d43c1a91d1..e93ac1a51f72 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -440,7 +440,8 @@ "Päällä" "Päällä • %1$s" "Pois päältä" - "Ota käyttöön" + + "Muuta asetuksista" "{count,plural, =0{Ei aktiivisia tiloja}=1{{mode} on aktiivinen}other{# tilaa on aktiivisena}}" "Äänet ja värinät eivät häiritse sinua, paitsi jos ne ovat hälytyksiä, muistutuksia, tapahtumia tai määrittämiäsi soittajia. Kuulet edelleen kaiken valitsemasi sisällön, kuten musiikin, videot ja pelit." @@ -573,8 +574,7 @@ "Keskustelut" "Tyhjennä kaikki hiljaiset ilmoitukset" "Älä häiritse ‑tila keskeytti ilmoitukset" - - + "{count,plural,offset:1 =0{Ei ilmoituksia}=1{{mode} keskeytti ilmoitukset}=2{{mode} ja yksi muu tila keskeytti ilmoitukset}other{{mode} ja # muuta tilaa keskeytti ilmoitukset}}" "Aloita nyt" "Ei ilmoituksia" "Ei uusia ilmoituksia" @@ -706,6 +706,7 @@ "Näytä esittelytila" "Ethernet" "Herätys" + "%1$s on päällä" "Wallet" "Lisää maksutapa, niin voit maksaa nopeasti ja turvallisesti puhelimella" "Näytä kaikki" @@ -1405,26 +1406,38 @@ "Opettele kosketuslevyn eleitä" "Siirry käyttämällä näppäimistöä ja kosketuslevyä" "Opettele kosketuslevyn eleitä, pikanäppäimiä ja muuta" - "Takaisin-ele" - "Etusivu-ele" + + + + "Katso viimeisimmät sovellukset" "Valmis" "Takaisin" - "Jos haluat siirtyä takaisin, pyyhkäise kosketuslevyllä vasemmalle tai oikealle kolmella sormella.\n\nVoit myös käyttää pikanäppäinyhdistelmää toimintonäppäin + ESC." - "Hienoa!" + + + + "Olet oppinut Takaisin-eleen." "Siirry etusivulle" - "Voit siirtyä aloitusnäytölle milloin tahansa pyyhkäisemällä ylös näytön alareunasta kolmella sormella." - "Hienoa!" - "Olet oppinut aloitusnäytölle palaamiseleen." + + + + + + "Katso viimeisimmät sovellukset" - "Pyyhkäise ylös ja pidä kosketuslevyä painettuna kolmella sormella." + + "Hienoa!" "Olet oppinut Katso viimeisimmät sovellukset ‑eleen." - "Toimintonäppäin" - "Voit käyttää sovelluksia painamalla näppäimistön toimintonäppäintä." - "Onnittelut!" - "Olet oppinut toimintonäppäineleen.\n\nToiminto + / tuo esiin kaikki käytettävissä olevat pikakomennot." + + + + + + + + "Näppämistön taustavalo" "Taso %1$d/%2$d" "Kodin ohjaus" @@ -1436,6 +1449,7 @@ "Jos haluat nähdä kaikki sovellukset, paina näppäimistön toimintonäppäintä" "Sensuroitu" "Avaa lukitus ja katso tiedot" + "Kontekstuaalinen koulutus" "Takaisin siirtyminen kosketuslevyn avulla" "Pyyhkäise vasemmalle tai oikealle kolmella sormella. Lue lisää eleistä napauttamalla." "Aloitusnäytölle siirtyminen kosketuslevyn avulla" diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 1f6de9f6a4b1..c58ad93b8f07 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -440,7 +440,8 @@ "Activé" "Activé • %1$s" "Désactivé" - "Configurer" + + "Gérer dans les paramètres" "{count,plural, =0{Aucun mode actif}=1{Le mode {mode} est actif}one{# mode est actif}many{# de modes sont actifs}other{# modes sont actifs}}" "Vous ne serez pas dérangé par les sons et les vibrations, sauf pour les alarmes, les rappels, les événements et les appelants que vous sélectionnez. Vous entendrez tout ce que vous choisissez d\'écouter, y compris la musique, les vidéos et les jeux." @@ -573,8 +574,7 @@ "Conversations" "Effacer toutes les notifications silencieuses" "Les notifications sont suspendues par le mode Ne pas déranger" - - + "{count,plural,offset:1 =0{Aucune notification}=1{Notifications suspendues par {mode}}=2{Notifications suspendues par {mode} et un autre mode}one{Notifications suspendues par {mode} et # autre mode}many{Notifications suspendues par {mode} et # d\'autres modes}other{Notifications suspendues par {mode} et # autres modes}}" "Commencer" "Aucune notification" "Aucune nouvelle notification" @@ -706,6 +706,8 @@ "Afficher le mode Démo" "Ethernet" "Alarme" + + "Wallet" "Préparez-vous à faire des achats plus rapidement et de façon plus sûre avec votre téléphone" "Tout afficher" @@ -1405,26 +1407,38 @@ "Apprenez à utiliser les gestes du pavé tactile" "Naviguer à l\'aide de votre clavier et de votre pavé tactile" "Apprenez les gestes du pavé tactile, les raccourcis-clavier et bien plus encore" - "Geste de retour" - "Geste d\'accès à l\'écran d\'accueil" + + + + "Afficher les applis récentes" "OK" "Retour" - "Pour revenir en arrière, balayez vers la gauche ou la droite en utilisant trois doigts n\'importe où sur le pavé tactile.\n\nVous pouvez également utiliser le raccourci clavier Action+Échap." - "Bon travail!" + + + + "Vous avez appris le geste de retour en arrière." "Retour à la page d\'accueil" - "Pour accéder à votre écran d\'accueil à tout moment, balayez l\'écran du bas vers le haut avec trois doigts." - "Bien!" - "Vous avez appris le geste de retour à l\'écran d\'accueil." + + + + + + "Afficher les applis récentes" - "Balayez l\'écran vers le haut avec trois doigts et maintenez-les en place sur votre pavé tactile." + + "Bon travail!" "Vous avez effectué le geste pour afficher les applis récentes." - "Touche d\'action" - "Pour accéder à vos applis, appuyez sur la touche d\'action de votre clavier." - "Félicitations!" - "Vous avez terminé le geste de la touche d\'action.\n\nAction + / affiche tous les raccourcis dont vous disposez." + + + + + + + + "Rétroéclairage du clavier" "Niveau %1$d de %2$d" "Domotique" @@ -1436,6 +1450,7 @@ "Pour afficher toutes vos applis, appuyez sur la touche d\'action de votre clavier" "Supprimé" "Déverrouiller pour afficher" + "Enseignement contextuel" "Utiliser votre pavé tactile pour revenir en arrière" "Balayez vers la gauche ou vers la droite avec trois doigts. Touchez pour apprendre d\'autres gestes." "Utilisez votre pavé tactile pour accéder à l\'écran d\'accueil" @@ -1445,7 +1460,7 @@ "Utiliser votre clavier pour afficher toutes les applis" "Appuyez sur la touche d\'action à tout moment. Touchez pour apprendre d\'autres gestes." "La réduction supplémentaire de la luminosité fait désormais partie du curseur de luminosité" - "Vous pouvez désormais réduire la luminosité de l\'écran encore plus.\n\nÉtant donné que cette fonctionnalité fait désormais partie du curseur de luminosité, les raccourcis de la réduction supplémentaire de la luminosité sont retirés." + "Vous pouvez désormais réduire la luminosité de l\'écran encore plus.\n\nÉtant donné que cette fonctionnalité fait maintenant partie du curseur de luminosité, les raccourcis de la réduction supplémentaire de la luminosité sont retirés." "Retirer les raccourcis de la réduction supplémentaire de la luminosité" "Les raccourcis de la réduction supplémentaire de la luminosité ont été retirés" "Connectivité" diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index fbf5a6c7aced..cf1cae9dad04 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -197,7 +197,7 @@ "Authentifié" "Annuler l\'authentification" "Plus d\'options" - "Utiliser un code PIN" + "Utiliser un code" "Utiliser un schéma" "Utiliser un mot de passe" "Code incorrect" @@ -440,7 +440,8 @@ "Activé" "Activé • %1$s" "Désactivé" - "Configurer" + + "Gérer dans les paramètres" "{count,plural, =0{Aucun mode actif}=1{{mode} est actif}one{# mode est actif}many{# de modes sont actifs}other{# modes sont actifs}}" "Vous ne serez pas dérangé par des sons ou des vibrations, hormis ceux des alarmes, des rappels, des événements et des appelants de votre choix. Vous entendrez encore les sons que vous choisirez de jouer, notamment la musique, les vidéos et les jeux." @@ -573,8 +574,7 @@ "Conversations" "Effacer toutes les notifications silencieuses" "Notifications suspendues par le mode Ne pas déranger" - - + "{count,plural,offset:1 =0{Aucune notification}=1{Notifications suspendues par le mode {mode}}=2{Notifications suspendues par le mode {mode} et un autre mode}one{Notifications suspendues par le mode {mode} et # autre mode}many{Notifications suspendues par le mode {mode} et # d\'autres modes}other{Notifications suspendues par le mode {mode} et # autres modes}}" "Commencer" "Aucune notification" "Aucune nouvelle notification" @@ -706,6 +706,7 @@ "Afficher le mode de démonstration" "Ethernet" "Alarme" + "Mode %1$s activé" "Wallet" "Configurez un mode de paiement pour régler vos achats de façon sûre et rapide via votre téléphone" "Tout afficher" @@ -1405,26 +1406,38 @@ "Découvrir les gestes au pavé tactile" "Naviguer à l\'aide de votre clavier et de votre pavé tactile" "Découvrir les gestes au pavé tactile, les raccourcis clavier et plus encore" - "Geste Retour" - "Geste Accueil" + + + + "Afficher les applis récentes" "OK" "Retour" - "Pour revenir en arrière, balayez vers la gauche ou vers la droite avec trois doigts n\'importe où sur le pavé tactile.\n\nVous pouvez aussi utiliser le raccourci clavier Action+Échap pour cela." - "Bravo !" + + + + "Vous avez appris le geste pour revenir en arrière." "Retour à l\'accueil" - "Pour accéder à l\'écran d\'accueil à tout moment, balayez l\'écran du bas vers le haut avec trois doigts." - "Bravo !" - "Vous avez appris le geste pour revenir à l\'écran d\'accueil." + + + + + + "Afficher les applis récentes" - "Avec trois doigts, balayez le pavé tactile vers le haut et maintenez la position." + + "Bravo !" "Vous avez appris le geste pour afficher les applis récentes" - "Touche d\'action" - "Pour accéder à vos applis, appuyez sur la touche d\'action de votre clavier." - "Félicitations !" - "Vous avez appris le geste permettant d\'utiliser la touche d\'action.\n\nAction+/ affiche tous les raccourcis disponibles." + + + + + + + + "Rétroéclairage du clavier" "Niveau %1$d sur %2$d" "Contrôle de la maison" @@ -1436,6 +1449,7 @@ "Pour afficher toutes vos applis, appuyez sur la touche d\'action de votre clavier" "Masqué" "Déverrouiller pour afficher" + "Éducation contextuelle" "Utilisez votre pavé tactile pour revenir en arrière" "Balayez vers la gauche ou la droite en utilisant trois doigts. Appuyez pour apprendre d\'autres gestes." "Utilisez votre pavé tactile pour revenir à l\'accueil" diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index b9d0891b99fa..dc0f216ef4db 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -440,7 +440,8 @@ "Activado" "Activo • %1$s" "Desactivado" - "Configurar" + + "Xestionar na configuración" "{count,plural, =0{Non hai ningún modo activo}=1{{mode} está activo}other{Hai # modos activos}}" "Non te molestará ningún son nin vibración, agás os procedentes de alarmas, recordatorios, eventos e os emisores de chamada especificados. Seguirás escoitando todo aquilo que decidas reproducir, mesmo a música, os vídeos e os xogos." @@ -573,8 +574,7 @@ "Conversas" "Borrar todas as notificacións silenciadas" "O modo Non molestar puxo en pausa as notificacións" - - + "{count,plural,offset:1 =0{Non hai ningunha notificación}=1{Notificacións postas en pausa polo modo {mode}}=2{Notificacións postas en pausa polo modo {mode} e un máis}other{Notificacións postas en pausa polo modo {mode} e # máis}}" "Iniciar agora" "Non hai notificacións" "Non hai notificacións novas" @@ -706,6 +706,7 @@ "Mostrar modo de demostración" "Ethernet" "Alarma" + "%1$s activado" "Wallet" "Configura un método de pago para comprar de xeito máis rápido e seguro co teléfono" "Amosar todo" @@ -1405,26 +1406,38 @@ "Aprende a usar os xestos do panel táctil" "Navega co teclado e o panel táctil" "Aprende a usar os xestos do panel táctil, atallos de teclado e moito máis" - "Xesto para volver" - "Xesto para ir ao inicio" + + + + "Consultar aplicacións recentes" "Feito" "Volver" - "Para retroceder, pasa tres dedos cara á esquerda ou cara á dereita en calquera parte do panel táctil.\n\nTamén podes usar o atallo de teclado Acción + Escape." - "Moi ben!" + + + + "Completaches o xesto de retroceso." "Ir ao inicio" - "Para ir á pantalla de inicio, pasa tres dedos cara arriba desde a parte inferior da pantalla." - "Excelente!" - "Completaches o xesto de ir ao inicio." + + + + + + "Consultar aplicacións recentes" - "Pasa tres dedos cara arriba e mantenos premidos no panel táctil." + + "Moi ben!" "Completaches o titorial do xesto de consultar aplicacións recentes." - "Tecla de acción" - "Para acceder ás aplicacións, preme a tecla de acción do teclado." - "Parabéns!" - "Completaches o xesto da tecla de acción.\n\nAcción + / mostra todos os atallos que tes á túa disposición." + + + + + + + + "Retroiluminación do teclado" "Nivel %1$d de %2$d" "Controis domóticos" @@ -1436,6 +1449,7 @@ "Para ver todas as aplicacións, preme a tecla de acción do teclado" "Contido ocultado" "Desbloquea o dispositivo para ver o contido" + "Información contextual" "Usa o panel táctil para volver" "Pasa tres dedos cara á esquerda ou cara á dereita. Toca para obter máis información sobre os xestos." "Usa o panel táctil para volver ao inicio" diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index e9998e448595..866535e20489 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -440,7 +440,8 @@ "ચાલુ" "ચાલુ • %1$s" "બંધ" - "સેટઅપ કરો" + + "સેટિંગમાં જઈને મેનેજ કરો" "{count,plural, =0{કોઈ સક્રિય મોડ નથી}=1{{mode} સક્રિય છે}one{# મોડ સક્રિય છે}other{# મોડ સક્રિય છે}}" "અલાર્મ, રિમાઇન્ડર, ઇવેન્ટ અને તમે ઉલ્લેખ કરો તે કૉલર સિવાય તમને ધ્વનિ કે વાઇબ્રેશન દ્વારા ખલેલ પહોંચાડવામાં આવશે નહીં. સંગીત, વીડિઓ અને રમતો સહિત તમે જે કંઈપણ ચલાવવાનું પસંદ કરશો તે સંભળાતું રહેશે." @@ -573,8 +574,7 @@ "વાતચીત" "બધા સાઇલન્ટ નોટિફિકેશન સાફ કરો" "ખલેલ પાડશો નહીં દ્વારા થોભાવેલ નોટિફિકેશન" - - + "{count,plural,offset:1 =0{કોઈ નોટિફિકેશન નથી}=1{{mode} દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}=2{{mode} અને અન્ય એક મોડ દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}one{{mode} અને અન્ય # મોડ દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}other{{mode} અને અન્ય # મોડ દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}}" "હવે શરૂ કરો" "કોઈ નોટિફિકેશન નથી" "કોઈ નવું નોટિફિકેશન નથી" @@ -706,6 +706,7 @@ "ડેમો મોડ બતાવો" "ઇથરનેટ" "અલાર્મ" + "%1$s ચાલુ છે" "Wallet" "તમારા ફોન વડે વધુ ઝડપી તેમજ સુરક્ષિત ખરીદીઓ કરવાની રીત સેટઅપ કરી લો" "બધું બતાવો" @@ -1405,26 +1406,38 @@ "ટચપૅડના સંકેતો વિશે જાણો" "તમારા કીબોર્ડ અને ટચપૅડ વડે નૅવિગેટ કરો" "ટચપૅડના સંકેતો અને કીબોર્ડના શૉર્ટકટ જેવું બીજું ઘણું જાણો" - "પાછળ જવાનો સંકેત" - "હોમ સ્ક્રીન પર જવાનો સંકેત" + + + + "તાજેતરની ઍપ જુઓ" "થઈ ગયું" "પાછા જાઓ" - "પાછા જવા માટે, ટચપૅડ પર ગમે ત્યાં ત્રણ આંગળી વડે ડાબે અથવા જમણે સ્વાઇપ કરો.\n\nઆના માટે તમે કીબોર્ડ શૉર્ટકટ Action + ESCનો ઉપયોગ કરી શકો છો." - "ખૂબ સરસ કામ!" + + + + "તમે પાછા જવાનો સંકેત પૂર્ણ કર્યો છે." "હોમ પર જાઓ" - "કોઈપણ સમયે તમારી હોમ સ્ક્રીન પર જવા માટે, ત્રણ આંગળી વડે તમારી સ્ક્રીનની સૌથી નીચેની બાજુએથી ઉપરની તરફ સ્વાઇપ કરો." - "સરસ!" - "તમે હોમ સ્ક્રીન પર જવાનો સંકેત પૂર્ણ કર્યો છે." + + + + + + "તાજેતરની ઍપ જુઓ" - "તમારા ટચપૅડ પર ત્રણ આંગળીઓનો ઉપયોગ કરીને ઉપર સ્વાઇપ કરો અને દબાવી રાખો." + + "ખૂબ સરસ કામ!" "તમે \"તાજેતરની ઍપ જુઓ\" સંકેત પૂર્ણ કર્યો." - "ઍક્શન કી" - "તમારી ઍપ ઍક્સેસ કરવા માટે, તમારા કીબોર્ડ પરની ઍક્શન કી દબાવો." - "અભિનંદન!" - "તમે ઍક્શન કીનો સંકેત પૂર્ણ કર્યો છે.\n\nઍક્શન કી + /ને દબાવવાથી, તમારી પાસે ઉપલબ્ધ હોય તે બધા શૉર્ટકટ જોવા મળે છે." + + + + + + + + "કીબોર્ડની બૅકલાઇટ" "%2$dમાંથી %1$d લેવલ" "ઘરેલું સાધનોના નિયંત્રણો" @@ -1436,6 +1449,7 @@ "તમારી બધી ઍપ જોવા માટે, તમારા કીબોર્ડ પર ઍક્શન કી દબાવો" "બદલાવેલું" "જોવા માટે અનલૉક કરો" + "સંદર્ભાત્મક શિક્ષણ" "પાછા જવા માટે તમારા ટચપૅડનો ઉપયોગ કરો" "ત્રણ આંગળીનો ઉપયોગ કરીને ડાબે અથવા જમણે સ્વાઇપ કરો. સંકેતો વિશે વધુ જાણવા માટે ટૅપ કરો." "હોમ સ્ક્રીન પર જવા માટે તમારા ટચપૅડનો ઉપયોગ કરો" @@ -1444,7 +1458,7 @@ "ત્રણ આંગળીઓનો ઉપયોગ કરીને ઉપર સ્વાઇપ કરો અને દબાવી રાખો. સંકેતો વિશે વધુ જાણવા માટે ટૅપ કરો." "બધી ઍપ જોવા માટે તમારા કીબોર્ડનો ઉપયોગ કરો" "કોઈપણ સમયે ઍક્શન કી દબાવો. સંકેતો વિશે વધુ જાણવા માટે ટૅપ કરો." - "બ્રાઇટનેસ સ્લાઇડર હવે એક્સ્ટ્રા ડિમનો ભાગ છે" + "એક્સ્ટ્રા ડિમ હવે બ્રાઇટનેસ સ્લાઇડરનો ભાગ છે" "તમે હવે બ્રાઇટનેસ લેવલને હજી પણ ઘટાડીને સ્ક્રીનને એક્સ્ટ્રા ડિમ બનાવી શકો છો.\n\nઆ સુવિધા હવે બ્રાઇટનેસ સ્લાઇડરનો ભાગ હોવાથી એક્સ્ટ્રા ડિમ શૉર્ટકટને કાઢી નાખવામાં આવી રહ્યાં છે." "એક્સ્ટ્રા ડિમ શૉર્ટકટ કાઢી નાખો" "એક્સ્ટ્રા ડિમ શૉર્ટકટ કાઢી નાખ્યા" diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 534da68f0286..7a1bf83a101e 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -440,7 +440,8 @@ "चालू है" "%1$s • पर" "बंद है" - "सेट अप करें" + + "सेटिंग में जाकर मैनेज करें" "{count,plural, =0{कोई मोड चालू नहीं है}=1{{mode} चालू है}one{# मोड चालू है}other{# मोड चालू हैं}}" "आपको अलार्म, रिमाइंडर, इवेंट और चुनिंदा कॉल करने वालों के अलावा किसी और तरह से (आवाज़ करके और थरथरा कर ) परेशान नहीं किया जाएगा. आप फिर भी संगीत, वीडियो और गेम सहित अपना चुना हुआ सब कुछ सुन सकते हैं." @@ -573,8 +574,7 @@ "बातचीत" "बिना आवाज़ की सभी सूचनाएं हटाएं" "\'परेशान न करें\' सुविधा के ज़रिए कुछ समय के लिए सूचनाएं दिखाना रोक दिया गया है" - - + "{count,plural,offset:1 =0{कोई सूचना नहीं है}=1{{mode} की वजह से सूचना नहीं दिख रही है}=2{{mode} और एक अन्य मोड की वजह से सूचना नहीं दिख रही है}one{{mode} और # अन्य मोड की वजह से सूचना नहीं दिख रही है}other{{mode} और # अन्य मोड के की वजह से सूचनाएं नहीं दिख रही है}}" "अभी शुरू करें" "कोई सूचना नहीं है" "कोई नई सूचना नहीं है" @@ -706,6 +706,7 @@ "डेमो मोड दिखाएं" "ईथरनेट" "अलार्म" + "%1$s चालू है" "Wallet" "फ़ोन के ज़रिए तेज़ी से और सुरक्षित तरीके से खरीदारी करने के लिए सेट अप करें" "सभी दिखाएं" @@ -1405,26 +1406,38 @@ "टचपैड पर हाथ के जेस्चर के बारे में जानें" "कीबोर्ड और टचपैड का इस्तेमाल करके नेविगेट करें" "टचपैड पर हाथ के जेस्चर, कीबोर्ड शॉर्टकट वगैरह के बारे में जानें" - "पीछे जाने का जेस्चर" - "होम स्क्रीन पर जाने का जेस्चर" + + + + "हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखें" "हो गया" "वापस जाएं" - "वापस जाने के लिए, टचपैड पर कहीं भी तीन उंगलियों से दाईं या बाईं ओर स्वाइप करें.\n\nइसके अलावा, ऐसा करने के लिए Action + ESC बटन का भी इस्तेमाल किया जा सकता है." - "बहुत बढ़िया!" + + + + "अब आपने जान लिया है कि हाथ का जेस्चर इस्तेमाल करके, पिछली स्क्रीन पर वापस कैसे जाएं." "होम स्क्रीन पर जाएं" - "किसी भी समय फ़ोन की होम स्क्रीन पर जाने के लिए, तीन उंगलियों से फ़ोन पर सबसे नीचे से ऊपर की ओर स्वाइप करें." - "बढ़िया!" - "आपने जान लिया कि हाथ का जेस्चर इस्तेमाल करके, होम स्क्रीन पर कैसे जाएं." + + + + + + "हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखें" - "अपने टचपैड पर तीन उंगलियों से ऊपर की ओर स्वाइप करें और फिर होल्ड करें." + + "बहुत बढ़िया!" "आपने हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखने के लिए, हाथ के जेस्चर के बारे में जान लिया है." - "ऐक्शन बटन" - "अपने ऐप्लिकेशन ऐक्सेस करने के लिए, कीबोर्ड पर ऐक्शन बटन दबाएं." - "बधाई हो!" - "आपने ऐक्शन बटन का जेस्चर इस्तेमाल करने की प्रोसेस पूरी कर ली है.\n\nऐक्शन बटन और / को साथ में दबाने पर, आपके पास उपलब्ध सभी शॉर्टकट दिखते हैं." + + + + + + + + "कीबोर्ड की बैकलाइट" "%2$d में से %1$d लेवल" "होम कंट्रोल" @@ -1436,6 +1449,7 @@ "सभी ऐप्लिकेशन देखने के लिए, कीबोर्ड पर ऐक्शन बटन दबाएं" "जानकारी छिपाने के लिए सूचना में बदलाव किया गया" "देखने के लिए डिवाइस अनलॉक करें" + "कॉन्टेक्स्ट के हिसाब से जानकारी" "वापस जाने के लिए, अपने डिवाइस के टचपैड का इस्तेमाल करें" "तीन उंगलियों से बाईं या दाईं ओर स्वाइप करें. जेस्चर के बारे में ज़्यादा जानने के लिए टैप करें." "होम पर जाने के लिए, अपने डिवाइस के टचपैड का इस्तेमाल करें" diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 0d226b1db920..96071202926e 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -440,7 +440,8 @@ "Uključeno" "Uklj. • %1$s" "Isključeno" - "Postavi" + + "Upravljajte u postavkama" "{count,plural, =0{Nema aktivnih načina}=1{Aktivno: {mode}}one{# način je aktivan}few{# načina su aktivna}other{# načina je aktivno}}" "Neće vas ometati zvukovi i vibracije, osim alarma, podsjetnika, događaja i pozivatelja koje navedete. I dalje ćete čuti sve što želite reproducirati, uključujući glazbu, videozapise i igre." @@ -573,8 +574,7 @@ "Razgovori" "Izbriši sve bešumne obavijesti" "Značajka Ne uznemiravaj pauzirala je Obavijesti" - - + "{count,plural,offset:1 =0{Nema obavijesti}=1{Obavijesti je pauzirao način {mode}}=2{Obavijesti su pauzirali način {mode} i još jedan način}one{Obavijesti su pauzirali način {mode} i još # način rada}few{Obavijesti su pauzirali način {mode} i još # načina rada}other{Obavijesti su pauzirali način {mode} i još # načina rada}}" "Pokreni" "Nema obavijesti" "Nema novih obavijesti" @@ -706,6 +706,7 @@ "Prikaži demo način" "Ethernet" "Alarm" + "Uključen je način %1$s" "Wallet" "Postavite aplikaciju za bržu i sigurniju kupnju telefonom" "Prikaži sve" @@ -1405,26 +1406,38 @@ "Saznajte više o pokretima za dodirnu podlogu" "Krećite se pomoću tipkovnice i dodirne podloge" "Saznajte više o pokretima za dodirnu podlogu, tipkovnim prečacima i ostalom" - "Pokret za povratak" - "Pokret za otvaranje početnog zaslona" + + + + "Pregled nedavnih aplikacija" "Gotovo" "Natrag" - "Da biste se vratili natrag, s tri prsta prijeđite ulijevo ili udesno bilo gdje na dodirnoj podlozi.\n\nZa to možete upotrijebiti i tipku za radnju tipkovnog prečaca + ESC." - "Sjajno!" + + + + "Izvršili ste pokret za povratak." "Na početnu stranicu" - "Da biste u bilo kojem trenutku otvorili početni zaslon, trima prstima prijeđite prema gore od dna zaslona." - "Odlično!" - "Izvršili ste pokret za otvaranje početnog zaslona." + + + + + + "Pregled nedavnih aplikacija" - "Prijeđite prema gore trima prstima na dodirnoj podlozi i zadržite pritisak." + + "Sjajno!" "Izvršili ste pokret za prikaz nedavno korištenih aplikacija." - "Tipka za radnju" - "Da biste pristupili svojim aplikacijama, pritisnite tipku za radnje na tipkovnici." - "Čestitamo!" - "Izvršili ste pokret tipke za radnju.\n\nRadnja + / prikazuje sve prečace koji su vam dostupni." + + + + + + + + "Pozadinsko osvjetljenje tipkovnice" "Razina %1$d od %2$d" "Upravljanje uređajima" @@ -1436,6 +1449,7 @@ "Za prikaz svojih svih aplikacija pritisnite tipku za radnju na tipkovnici" "Redaktirano" "Otključajte za prikaz" + "Kontekstualno obrazovanje" "Upotrijebite dodirnu podlogu za povratak" "Prijeđite ulijevo ili udesno trima prstima. Dodirnite da biste naučili više pokreta." "Uz pomoć dodirne podloge vratite se na početni zaslon" diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 6c26cd5f817e..3a9735bbf7fd 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -440,7 +440,8 @@ "Be" "Be • %1$s" "Ki" - "Beállítás" + + "A Beállítások között kezelheti" "{count,plural, =0{Nincs aktív mód}=1{A(z) {mode} aktív}other{# mód aktív}}" "Az Ön által meghatározott ébresztéseken, emlékeztetőkön, eseményeken és hívókon kívül nem fogja Önt más hang vagy rezgés megzavarni. Továbbra is lesz hangjuk azoknak a tartalmaknak, amelyeket Ön elindít, például zenék, videók és játékok." @@ -573,8 +574,7 @@ "Beszélgetések" "Az összes néma értesítés törlése" "Ne zavarjanak funkcióval szüneteltetett értesítések" - - + "{count,plural,offset:1 =0{Nincs értesítés}=1{A(z) {mode} szüneteltette az értesítéseket}=2{A(z) {mode} és egy másik mód szüneteltette az értesítéseket}other{A(z) {mode} és # másik mód szüneteltette az értesítéseket}}" "Indítás most" "Nincs értesítés" "Nincsenek új értesítések" @@ -706,6 +706,7 @@ "Demó mód megjelenítése" "Ethernet" "Ébresztés" + "A(z) %1$s aktív" "Wallet" "Végezze el a beállítást a telefonjával való gyorsabb és biztonságosabb vásárláshoz" "Összes mutatása" @@ -1405,26 +1406,38 @@ "Érintőpad-kézmozdulatok megismerése" "Navigálás a billentyűzet és az érintőpad használatával" "Érintőpad-kézmozdulatok, billentyűparancsok és egyebek megismerése" - "Vissza kézmozdulat" - "Kezdőképernyő kézmozdulat" + + + + "Legutóbbi alkalmazások megtekintése" "Kész" "Vissza" - "A visszalépéshez csúsztasson három ujjal balra vagy a jobbra az érintőpadon.\n\nEnnek végrehajtásához használhatja az Action + Esc billentyűparancsot is." - "Kiváló!" + + + + "Teljesítette a visszalépési kézmozdulatot." "Ugrás a főoldalra" - "Ha bármikor vissza szeretne térni a kezdőképernyőre, csúsztassa gyorsan felfelé három ujját a képernyő aljáról." - "Remek!" - "Teljesítette a kezdőképernyőre lépés kézmozdulatát." + + + + + + "Legutóbbi alkalmazások megtekintése" - "Csúsztasson felfelé három ujjal az érintőpadon, és tartsa lenyomva az ujjait." + + "Kiváló!" "Teljesítette a legutóbbi alkalmazások megtekintésének kézmozdulatát." - "Műveletbillentyű" - "Az alkalmazásokhoz való hozzáféréshez nyomja meg a billentyűzet műveletbillentyűjét." - "Gratulálunk!" - "Teljesítette a műveletbillentyű kézmozdulatát.\n\nA Művelet + / billentyűkombinációval megjelenítheti az összes használható billentyűparancsot." + + + + + + + + "A billentyűzet háttérvilágítása" "Fényerő: %2$d/%1$d" "Otthon vezérlése" @@ -1436,6 +1449,7 @@ "Az összes alkalmazás megtekintéséhez nyomja meg a billentyűzet műveletbillentyűjét." "Törölve" "Oldja fel a megtekintéshez" + "Kontextusfüggő tájékoztató párbeszédpanel" "A visszalépéshez használja az érintőpadot" "Csúsztatasson gyorsan három ujjal balra vagy jobbra. Koppintson a további kézmozdulatokért." "A kezdőképernyő megnyitásához használja az érintőpadot" diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index c0e7c309fef2..804550cb6319 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -440,7 +440,8 @@ "Միացված է" "Միաց․ • %1$s" "Անջատված է" - "Կարգավորել" + + "Կառավարել կարգավորումներում" "{count,plural, =0{Ակտիվ ռեժիմներ չկան}=1{{mode} ռեժիմ ակտիվ է}one{# ռեժիմ ակտիվ է}other{# ռեժիմ ակտիվ է}}" "Ձայները և թրթռոցները չեն անհանգստացնի ձեզ, բացի ձեր կողմից նշված զարթուցիչները, հիշեցումները, միջոցառումների ծանուցումները և զանգերը։ Դուք կլսեք ձեր ընտրածի նվագարկումը, այդ թվում՝ երաժշտություն, տեսանյութեր և խաղեր:" @@ -573,8 +574,7 @@ "Զրույցներ" "Ջնջել բոլոր անձայն ծանուցումները" "Ծանուցումները չեն ցուցադրվի «Չանհանգստացնել» ռեժիմում" - - + "{count,plural,offset:1 =0{Ծանուցումներ չկան}=1{Ծանուցումները դադարեցվել են «{mode}» ռեժիմի կողմից}=2{Ծանուցումները դադարեցվել են «{mode}» ու ևս մի ռեժիմի կողմից}one{Ծանուցումները դադարեցվել են «{mode}» ու ևս # ռեժիմի կողմից}other{Ծանուցումները դադարեցվել են «{mode}» ու ևս # ռեժիմի կողմից}}" "Սկսել հիմա" "Ծանուցումներ չկան" "Նոր ծանուցումներ չկան" @@ -706,6 +706,7 @@ "Ցուցադրական ռեժիմի ցուցադրում" "Ethernet" "Զարթուցիչ" + %1$s» ռեժիմը միացված է" "Wallet" "Վճարեք հեռախոսով՝ ավելի արագ և ապահով" "Ցույց տալ բոլորը" @@ -1405,26 +1406,38 @@ "Սովորեք օգտագործել հպահարթակի ժեստերը" "Կողմնորոշվեք ստեղնաշարի և հպահարթակի օգնությամբ" "Սովորեք օգտագործել հպահարթակի ժեստերը, ստեղնային դյուրանցումները և ավելին" - "«Հետ» ժեստ" - "Հիմնական էկրան անցնելու ժեստ" + + + + "Դիտել վերջին հավելվածները" "Պատրաստ է" "Հետ գնալ" - "Հետ գնալու համար հպահարթակի վրա երեք մատով սահեցրեք ձախ կամ աջ։\n\nԻնչպես նաև կարող եք օգտագործել ստեղնային դյուրանցման գործողությունը + Esc։" - "Կեցցե՛ք" + + + + "Դուք սովորեցիք հետ գնալու ժեստը։" "Անցում հիմնական էկրան" - "Հիմնական էկրան վերադառնալու համար երեք մատը էկրանի ներքևից սահեցրեք վերև։" - "Գերազանց է" - "Դուք սովորեցիք հիմնական էկրան անցնելու ժեստը։" + + + + + + "Դիտել վերջին հավելվածները" - "Երեք մատը սահեցրեք վերև և սեղմած պահեք հպահարթակին։" + + "Կեցցե՛ք։" "Դուք կատարեցիք վերջին օգտագործված հավելվածների դիտման ժեստը։" - "Գործողության ստեղն" - "Բոլոր հավելվածներն օգտագործելու համար սեղմեք գործողության ստեղնը ստեղնաշարի վրա" - "Շնորհավո՛ր" - "Դուք սովորեցիք գործողության ստեղնի ժեստը։\n\nԳործողություն + / ժեստը ցույց է տալիս ձեզ հասանելի բոլոր դյուրանցումները։" + + + + + + + + "Հետին լուսավորությամբ ստեղնաշար" "%1$d՝ %2$d-ից" "Տան կառավարման տարրեր" @@ -1436,6 +1449,7 @@ "Բոլոր հավելվածները դիտելու համար սեղմեք գործողության ստեղնը ստեղնաշարի վրա" "Կոդավորված" "Ապակողպել դիտելու համար" + "Համատեքստային ուսուցում" "Օգտագործեք ձեր հպահարթակը՝ վերադառնալու համար" "Երեք մատը սահեցրեք ձախ կամ աջ։ Հպեք՝ ավելի շատ ժեստերի ծանոթանալու համար։" "Օգտագործեք ձեր հպահարթակը՝ հիմնական էկրան անցնելու համար" diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 906fde458d82..98bbf4f8ca5d 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -440,7 +440,8 @@ "Aktif" "Aktif • %1$s" "Nonaktif" - "Siapkan" + + "Kelola di setelan" "{count,plural, =0{Tidak ada mode yang aktif}=1{{mode} aktif}other{# mode aktif}}" "Anda tidak akan terganggu oleh suara dan getaran, kecuali dari alarm, pengingat, acara, dan penelepon yang Anda tentukan. Anda akan tetap mendengar apa pun yang telah dipilih untuk diputar, termasuk musik, video, dan game." @@ -573,8 +574,7 @@ "Percakapan" "Hapus semua notifikasi senyap" "Notifikasi dijeda oleh mode Jangan Ganggu" - - + "{count,plural,offset:1 =0{Tidak ada notifikasi}=1{Notifikasi dijeda oleh {mode}}=2{Notifikasi dijeda oleh {mode} dan satu mode lainnya}other{Notifikasi dijeda oleh {mode} dan # mode lainnya}}" "Mulai sekarang" "Tidak ada notifikasi" "Tidak ada notifikasi baru" @@ -706,6 +706,7 @@ "Tampilkan mode demo" "Ethernet" "Alarm" + "%1$s aktif" "Wallet" "Siapkan metode pembayaran untuk melakukan pembelian dengan lebih cepat dan aman menggunakan ponsel Anda" "Tampilkan semua" @@ -1405,26 +1406,38 @@ "Pelajari gestur touchpad" "Menavigasi menggunakan keyboard dan touchpad" "Pelajari gestur touchpad, pintasan keyboard, dan lainnya" - "Gestur kembali" - "Gestur layar utama" + + + + "Lihat aplikasi terbaru" "Selesai" "Kembali" - "Untuk kembali, geser ke kiri atau kanan menggunakan tiga jari di touchpad.\n\nAnda juga dapat menggunakan pintasan keyboard Action + ECS untuk melakukannya." - "Bagus!" + + + + "Anda telah menyelesaikan gestur kembali." "Buka layar utama" - "Untuk membuka layar utama kapan saja, geser ke atas menggunakan tiga jari dari bawah layar Anda." - "Bagus!" - "Anda telah menyelesaikan gestur buka layar utama." + + + + + + "Lihat aplikasi terbaru" - "Geser ke atas dan tahan menggunakan tiga jari di touchpad." + + "Bagus!" "Anda telah menyelesaikan gestur untuk melihat aplikasi terbaru." - "Tombol tindakan" - "Untuk mengakses aplikasi, tekan tombol tindakan di keyboard." - "Selamat!" - "Anda telah menyelesaikan gestur tombol tindakan.\n\nTindakan + / akan menampilkan semua pintasan yang Anda miliki." + + + + + + + + "Lampu latar keyboard" "Tingkat %1$d dari %2$d" "Kontrol Rumah" @@ -1436,6 +1449,7 @@ "Untuk melihat semua aplikasi, tekan tombol tindakan di keyboard" "Disamarkan" "Buka kunci untuk melihat" + "Pendidikan kontekstual" "Gunakan touchpad untuk kembali" "Geser ke kiri atau kanan menggunakan tiga jari. Ketuk untuk mempelajari gestur lainnya." "Gunakan touchpad untuk membuka layar utama" diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 68f2c23e4a19..b12a475b9efd 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -440,7 +440,8 @@ "Kveikt" "Kveikt • %1$s" "Slökkt" - "Setja upp" + + "Stjórna í stillingum" "{count,plural, =0{Engar virkar stillingar}=1{{mode} er virk}one{# stilling er virk}other{# stillingar eru virkar}}" "Þú verður ekki fyrir truflunum frá hljóðmerkjum og titringi, fyrir utan vekjara, áminningar, viðburði og símtöl frá þeim sem þú leyfir fyrirfram. Þú heyrir áfram í öllu sem þú velur að spila, svo sem tónlist, myndskeiðum og leikjum." @@ -573,8 +574,7 @@ "Samtöl" "Hreinsa allar þöglar tilkynningar" "Hlé gert á tilkynningum þar sem stillt er á „Ónáðið ekki“" - - + "{count,plural,offset:1 =0{Engar tilkynningar}=1{Hlé gert á tilkynningum þar sem stillt er á {mode}}=2{Hlé gert á tilkynningum þar sem stillt er á {mode} og eina aðra stillingu}one{Hlé gert á tilkynningum þar sem stillt er á {mode} og # aðra stillingu}other{Hlé gert á tilkynningum þar sem stillt er á {mode} og # aðrar stillingar}}" "Byrja núna" "Engar tilkynningar" "Engar nýjar tilkynningar" @@ -706,6 +706,7 @@ "Sýna prufustillingu" "Ethernet" "Vekjari" + "Kveikt er á „%1$s“" "Veski" "Stilltu hlutina þannig að þú getir verslað með símanum á hraðari og öruggari hátt" "Sýna allt" @@ -1405,26 +1406,38 @@ "Nánar um bendingar á snertifleti" "Flettu með því að nota lyklaborðið og snertiflötinn" "Kynntu þér bendingar á snertifleti, flýtilykla og fleira" - "Bending til að fara til baka" - "Bending til að fara á upphafsskjá" + + + + "Sjá nýleg forrit" "Lokið" "Til baka" - "Strjúktu til vinstri eða hægri með þremur fingrum hvar sem er á snertifletinum til að fara til baka.\n\nÞú getur einnig notað flýtileiðaraðgerðina + ESC til að gera þetta." - "Vel gert!" + + + + "Þú laukst við að kynna þér bendinguna „til baka“." "Heim" - "Strjúktu upp frá neðri brún skjásins með þremur fingrum til að opna heimaskjáinn." - "Flott!" - "Þú laukst við að kynna þér bendinguna „heim“." + + + + + + "Sjá nýleg forrit" - "Strjúktu upp og haltu þremur fingrum inni á snertifletinum." + + "Vel gert!" "Þú framkvæmdir bendinguna til að sjá nýleg forrit." - "Aðgerðalykill" - "Ýttu á aðgerðalykilinn á lyklaborðinu til að opna forritin þín." - "Til hamingju!" - "Þú laukst við að kynna þér bendinguna „aðgerðalykill“.\n\nAðgerðalykill + / sýnir þér alla flýtilykla sem eru í boði." + + + + + + + + "Baklýsing lyklaborðs" "Stig %1$d af %2$d" "Heimastýringar" @@ -1436,6 +1449,7 @@ "Ýttu á aðgerðalykilinn á lyklaborðinu til að sjá öll forritin þín" "Ritskoðað" "Taktu úr lás til að skoða" + "Samhengismiðuð menntun" "Notaðu snertiflötinn til að fara til baka" "Strjúktu til vinstri eða hægri með þremur fingrum. Ýttu til að læra fleiri bendingar." "Notaðu snertiflötinn til að fara á heimaskjá" diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 4f8015ce31a2..4fdf01d7622f 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -440,7 +440,8 @@ "On" "On • %1$s" "Off" - "Configura" + + "Gestisci nelle impostazioni" "{count,plural, =0{Nessuna modalità attiva}=1{{mode} è attiva}many{# di modalità sono attive}other{# modalità sono attive}}" "Suoni e vibrazioni non ti disturberanno, ad eccezione di sveglie, promemoria, eventi, chiamate da contatti da te specificati ed elementi che hai scelto di continuare a riprodurre, inclusi video, musica e giochi." @@ -573,8 +574,7 @@ "Conversazioni" "Cancella tutte le notifiche silenziose" "Notifiche messe in pausa in base alla modalità Non disturbare" - - + "{count,plural,offset:1 =0{Nessuna notifica}=1{Notifica messa in pausa da {mode}}=2{Notifiche messe in pausa da {mode} e un\'altra modalità}many{Notifiche messe in pausa da {mode} e # di modalità}other{Notifiche messe in pausa da {mode} e altre # modalità}}" "Avvia adesso" "Nessuna notifica" "Nessuna nuova notifica" @@ -706,6 +706,7 @@ "Mostra modalità demo" "Ethernet" "Sveglia" + "Programmazione %1$s attiva" "Wallet" "Imposta un metodo di pagamento per effettuare acquisti in modo più rapido e sicuro con il telefono" "Mostra tutto" @@ -1405,26 +1406,38 @@ "Impara i gesti con il touchpad" "Naviga usando la tastiera e il touchpad" "Scopri gesti con il touchpad, scorciatoie da tastiera e altro ancora" - "Gesto Indietro" - "Gesto Home" + + + + "Visualizza app recenti" "Fine" "Indietro" - "Per tornare indietro, scorri verso sinistra o verso destra utilizzando tre dita in un punto qualsiasi del touchpad.\n\nPuoi usare anche la scorciatoia da tastiera Action + Esc per farlo." - "Ottimo lavoro." + + + + "Hai completato il gesto Indietro." "Vai alla schermata Home" - "Per andare alla schermata Home, scorri verso l\'alto con tre dita dalla parte inferiore dello schermo." - "Bene!" - "Hai completato il gesto Vai alla schermata Home." + + + + + + "Visualizza app recenti" - "Scorri verso l\'alto e tieni premuto con tre dita sul touchpad." + + "Ottimo lavoro." "Hai completato il gesto Visualizza app recenti." - "Tasto azione" - "Per accedere alle tue app, premi il tasto azione sulla tastiera." - "Complimenti!" - "Hai completato il gesto del tasto azione.\n\nAzione + / mostra tutte le scorciatoie disponibili." + + + + + + + + "Retroilluminazione della tastiera" "Livello %1$d di %2$d" "Controlli della casa" @@ -1436,6 +1449,7 @@ "Per visualizzare tutte le tue app, premi il tasto azione sulla tastiera" "Oscurata" "Sblocca per visualizzare" + "Istruzione contestuale" "Usa il touchpad per tornare indietro" "Scorri verso sinistra o destra con tre dita. Tocca per scoprire altri gesti." "Usa il touchpad per andare alla schermata Home" @@ -1445,7 +1459,7 @@ "Usa la tastiera per visualizzare tutte le app" "Premi il tasto azione in qualsiasi momento. Tocca per scoprire altri gesti." "Ora l\'attenuazione extra è nel cursore della luminosità" - "Ora puoi usare l\'attenuazione extra per lo schermo abbassando il livello di luminosità ancora di più.\n\nDato che questa funzionalità ora fa parte del cursore della luminosità, le scorciatoie per l\'attenuazione extra vengono rimosse." + "Ora puoi usare l\'attenuazione extra per lo schermo abbassando ulteriormente il livello di luminosità.\n\nDato che questa funzionalità è ora integrata nel cursore della luminosità, le scorciatoie per l\'attenuazione extra vengono rimosse." "Rimuovi scorciatoie attenuazione extra" "Scorciatoie attenuazione extra rimosse" "Connettività" diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 3d7a25c0e3ea..78d60e575499 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -440,7 +440,8 @@ "מצב מופעל" "פועל • %1$s" "מצב מושבת" - "להגדרה" + + "שינוי ב\'הגדרות\'" "{count,plural, =0{אין מצבים פעילים}=1{מצב פעיל אחד ({mode})}one{‫# מצבים פעילים}two{‫# מצבים פעילים}other{‫# מצבים פעילים}}" "כדי לא להפריע לך, המכשיר לא ירטוט ולא ישמיע שום צליל, חוץ מהתראות, תזכורות, אירועים ושיחות ממתקשרים מסוימים לבחירתך. המצב הזה לא ישפיע על צלילים שהם חלק מתוכן שבחרת להפעיל, כמו מוזיקה, סרטונים ומשחקים." @@ -573,8 +574,7 @@ "שיחות" "ניקוי כל ההתראות השקטות" "התראות הושהו על ידי מצב \'נא לא להפריע\'" - - + "{count,plural,offset:1 =0{אין התראות}=1{ההתראות הושהו על ידי {mode}}=2{ההתראות הושהו על ידי {mode} ועל ידי מצב אחד נוסף}one{ההתראות הושהו על ידי {mode} ועל ידי # מצבים נוספים}other{ההתראות הושהו על ידי {mode} ועל ידי # מצבים נוספים}}" "כן, אפשר להתחיל" "אין התראות" "אין התראות חדשות" @@ -706,6 +706,7 @@ "הצגת מצב הדגמה" "אתרנט" "התראה" + "מצב %1$s פועל" "Wallet" "מגדירים אמצעי תשלום ונהנים מביצוע מהיר ומאובטח יותר של רכישות באמצעות הטלפון" "הצגת הכול" @@ -1405,26 +1406,38 @@ "מידע על התנועות בלוח המגע" "ניווט באמצעות המקלדת ולוח המגע" "מידע על התנועות בלוח המגע, מקשי קיצור ועוד" - "תנועת חזרה" - "תנועת חזרה למסך הבית" + + + + "הצגת האפליקציות האחרונות" "סיום" "חזרה" - "‏כדי לחזור אחורה, מחליקים שמאלה או ימינה עם שלוש אצבעות בכל מקום על לוח המגע.\n\nאפשר לבצע את הפעולה הזו גם באמצעות קיצור הדרך לפעולה + מקש ESC." - "מעולה!" + + + + "השלמת את התנועה \'הקודם\'." "מעבר לדף הבית" - "כדי לעבור למסך הבית בכל שלב, צריך להחליק למעלה עם שלוש אצבעות מהחלק התחתון של המסך." - "איזה יופי!" - "השלמת את תנועת המעבר למסך הבית." + + + + + + "הצגת האפליקציות האחרונות" - "מחליקים למעלה ולוחצים לחיצה ארוכה עם שלוש אצבעות על לוח המגע." + + "מעולה!" "השלמת את התנועה להצגת האפליקציות האחרונות." - "מקש הפעולה" - "כדי לגשת לאפליקציות, מקישים על מקש הפעולה במקלדת." - "כל הכבוד!" - "השלמת את התנועה של מקש הפעולה.\n\nלחיצה על מקש הפעולה + מקש / מציגה את כל מקשי הקיצור הזמינים." + + + + + + + + "התאורה האחורית במקלדת" "‏רמה %1$d מתוך %2$d" "שליטה במכשירים" @@ -1436,6 +1449,7 @@ "כדי לראות את כל האפליקציות, מקישים על מקש הפעולה במקלדת" "מצונזר" "צריך לבטל את הנעילה כדי לראות" + "חינוך בהתאם להקשר" "איך להשתמש בלוח המגע כדי לחזור אחורה" "מחליקים ימינה או שמאלה עם שלוש אצבעות. ניתן להקיש כדי לקבל מידע נוסף על התנועות." "איך להשתמש בלוח המגע כדי לעבור למסך הבית" diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 3e29ed62fa7c..2a35e17cd259 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -440,7 +440,7 @@ "ON" "ON • %1$s" "OFF" - "設定" + "未設定" "設定で管理" "{count,plural, =0{アクティブなモードはありません}=1{{mode} がアクティブです}other{# 個のモードがアクティブです}}" "アラーム、リマインダー、予定、指定した人からの着信以外の音やバイブレーションに煩わされることはありません。音楽、動画、ゲームなど再生対象として選択したコンテンツは引き続き再生されます。" @@ -573,8 +573,7 @@ "会話" "サイレント通知がすべて消去されます" "サイレント モードにより通知は一時停止中です" - - + "{count,plural,offset:1 =0{通知なし}=1{{mode} により通知は一時停止中です}=2{{mode} と他 1 個のモードにより通知は一時停止中です}other{{mode} と他 # 個のモードにより通知は一時停止中です}}" "今すぐ開始" "通知はありません" "新しい通知はありません" @@ -706,6 +705,7 @@ "デモモードを表示" "イーサネット" "アラーム" + "%1$s: ON" "ウォレット" "スマートフォンを使ってよりすばやく安全に購入できるように設定しましょう" "すべて表示" @@ -1405,26 +1405,26 @@ "タッチパッド操作の詳細" "キーボードとタッチパッドを使用して移動する" "タッチパッド操作やキーボード ショートカットなどの詳細" - "「戻る」ジェスチャー" - "「ホーム」ジェスチャー" + "戻る" + "ホームに移動" "最近使ったアプリを表示する" "完了" "戻る" - "戻るには、3 本の指でタッチパッドを左右にスワイプします。\n\nキーボード ショートカットのアクション + ESC キーを使用して、この操作を行うこともできます。" - "お疲れさまでした。" + "タッチパッドを 3 本の指で左右にスワイプします" + "その調子です!" "「戻る」操作を学習しました。" "ホームに移動" - "3 本の指で画面を下から上にスワイプすると、ホーム画面にいつでも移動できます。" - "お疲れさまでした。" - "「ホームに移動」操作を学習しました。" + "タッチパッドを 3 本の指で上にスワイプします" + "よくできました!" + "「ホームに移動」操作を学習しました" "最近使ったアプリを表示する" - "タッチパッドを 3 本の指で上にスワイプして長押しします。" + "タッチパッドを 3 本の指で上にスワイプして長押しします" "よくできました" "「最近使ったアプリを表示する」操作を学習しました。" - "アクションキー" - "アプリにアクセスするには、キーボードのアクションキーを押します。" - "お疲れさまでした。" - "アクションキー操作を学習しました。\n\nアクションキーと + キーを同時に押すと、利用可能なショートカットがすべて表示されます。" + "すべてのアプリを表示" + "キーボードのアクションキーを押します" + "完了です!" + "「すべてのアプリを表示する」操作を学習しました" "キーボード バックライト" "レベル %1$d/%2$d" "ホーム コントロール" @@ -1436,6 +1436,7 @@ "すべてのアプリを表示するには、キーボードのアクションキーを押してください" "削除済み" "表示するにはロックを解除してください" + "コンテキスト メニューに関する説明" "タッチパッドを使用して、前の画面に戻る" "3 本の指で左または右にスワイプします。ジェスチャーの詳細を確認するにはタップしてください。" "タッチパッドを使用して、ホームに移動する" diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 539c186011e3..05a7e42a5937 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -440,7 +440,7 @@ "ჩართული" "ჩართულია • %1$s" "გამორთული" - "დაყენება" + "არ არის დაყენებული" "პარამეტრებში მართვა" "{count,plural, =0{აქტიური რეჟიმები არ მოიძებნა}=1{{mode} აქტიურია}other{აქტიურია # რეჟიმი}}" "თქვენ მიერ მითითებული მაღვიძარების, შეხსენებების, მოვლენებისა და ზარების გარდა, არავითარი ხმა და ვიბრაცია არ შეგაწუხებთ. თქვენ მაინც შეძლებთ სასურველი კონტენტის, მაგალითად, მუსიკის, ვიდეოებისა და თამაშების აუდიოს მოსმენა." @@ -573,8 +573,7 @@ "საუბრები" "ყველა ჩუმი შეტყობინების გასუფთავება" "შეტყობინებები დაპაუზდა „არ შემაწუხოთ“ რეჟიმის მეშვეობით" - - + "{count,plural,offset:1 =0{შეტყობინებები არ არის}=1{შეტყობინებები შეჩერებულია {mode}-ის გამო}=2{შეტყობინებები შეჩერებულია {mode}-ის და ერთი სხვა რეჟიმის გამო}other{შეტყობინებები შეჩერებულია {mode}-ის და # სხვა რეჟიმის გამო}}" "დაწყება ახლავე" "შეტყობინებები არ არის." "ახალი შეტყობინებები არ არის" @@ -706,6 +705,7 @@ "დემო-რეჟიმის ჩვენება" "ეთერნეტი" "მაღვიძარა" + "%1$s ჩართულია" "საფულე" "დააყენეთ შესყიდვების თქვენი ტელეფონით უფრო სწრაფად და უსაფრთხოდ შესასრულებლად" "ყველას ჩვენება" @@ -1405,26 +1405,26 @@ "სენსორული პანელის ჟესტების სწავლა" "ნავიგაცია კლავიატურის და სენსორული პანელის გამოყენებით" "სენსორული პანელის ჟესტების, კლავიატურის მალსახმობების და სხვა ფუნქციების სწავლა" - "უკან დაბრუნების ჟესტი" - "მთავარ ეკრანზე გადასვლის ჟესტი" + "უკან დაბრუნება" + "მთავარ ეკრანზე გადასვლა" "ბოლო აპების ნახვა" "მზადაა" "უკან დაბრუნება" - "უკან დასაბრუნებლად სენსორულ პანელზე გადაფურცლეთ მარცხნივ ან მარჯვნივ სამი თითის გამოყენებით ნებისმიერ ადგილას.\n\nამისთვის თქვენ ასევე შეგიძლიათ გამოიყენოთ კლავიატურის მალსახმობის მოქმედება + ESC." - "შესანიშნავია!" + "თქვენს სენსორულ პანელზე სამი თითით გადაფურცლეთ მარცხნივ ან მარჯვნივ" + "მშვენიერია!" "თქვენ შეასრულეთ უკან დაბრუნების ჟესტი." "მთავარზე გადასვლა" - "თქვენს მთავარ ეკრანზე ნებისმიერ დროს გადასასვლელად გადაფურცლეთ ეკრანის ქვემოდან ზემოთ სამი თითით." - "მშვენიერია!" - "თქვენ შეასრულეთ მთავარ ეკრანზე დაბრუნების ჟესტი." + "თქვენს სენსორულ პანელზე სამი თითით გადაფურცლეთ ზევით" + "შესანიშნავია!" + "თქვენ შეასრულეთ მთავარ ეკრანზე გადასვლის ჟესტი" "ბოლო აპების ნახვა" - "თქვენს სენსორულ პანელზე სამი თითით გადაფურცლეთ ზემოთ და მოიცადეთ." + "თქვენს სენსორულ პანელზე სამი თითით გადაფურცლეთ ზევით და ხანგრძლივად დააჭირეთ" "შესანიშნავია!" "თქვენ დაასრულეთ ბოლო აპების ხედის ჟესტი." - "მოქმედების კლავიში" - "აპებზე წვდომისთვის დააჭირეთ მოქმედების კლავიშს თქვენს კლავიატურაზე." - "გილოცავთ!" - "თქვენ შეასრულეთ მოქმედების კლავიშის ჟესტი.\n\nქმედება + / აჩვენებს თქვენთვის ხელმისაწვდომ ყველა მალსახმობს." + "ყველა აპის ნახვა" + "დააჭირეთ მოქმედების კლავიშს თქვენს კლავიატურაზე" + "ყოჩაღ!" + "თქვენ დაასრულეთ ყველა აპის ნახვის ჟესტი" "კლავიატურის შენათება" "დონე: %1$d %2$d-დან" "სახლის კონტროლი" @@ -1436,6 +1436,7 @@ "ყველა აპის სანახავად დააჭირეთ მოქმედების კლავიშს თქვენს კლავიატურაზე" "ტექსტს ადევს ცენზურა" "განბლოკვა სანახავად" + "კონტექსტური განათლება" "უკან დასაბრუნებლად გამოიყენეთ სენსორული პანელი" "გადაფურცლეთ მარცხნივ ან მარჯვნივ სამი თითით. შეეხეთ მეტი ჟესტის შესასწავლად." "მთავარ გვერდზე გადასასვლელად გამოიყენეთ სენსორული პანელი" diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 7343fa1440d6..328c82fba67f 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -440,7 +440,8 @@ "Қосулы" "Қосулы • %1$s" "Өшірулі" - "Реттеу" + + "\"Параметрлер\" бөлімінде реттеу" "{count,plural, =0{Қосулы режим жоқ}=1{{mode} қосулы}other{# режим қосулы}}" "Оятқыш, еске салғыш, іс-шара мен өзіңіз көрсеткен контактілердің қоңырауларынан басқа дыбыстар мен дірілдер мазаламайтын болады. Музыка, бейне және ойын сияқты медиафайлдарды қоссаңыз, оларды естисіз." @@ -573,8 +574,7 @@ "Әңгімелер" "Барлық үнсіз хабарландыруларды өшіру" "Хабарландырулар Мазаламау режимінде кідіртілді" - - + "{count,plural,offset:1 =0{Хабарландырулар жоқ.}=1{Хабарландыруларды {mode} режимі кідіртті.}=2{Хабарландыруларды {mode} және тағы бір режим кідіртті.}other{Хабарландыруларды {mode} және тағы # режим кідіртті.}}" "Қазір бастау" "Хабарландырулар жоқ" "Жаңа хабарландырулар жоқ" @@ -706,6 +706,7 @@ "Демо режимін көрсету" "Ethernet" "Оятқыш" + "%1$s қосулы." "Wallet" "Телефоныңызбен бұрынғыдан да жылдам әрі қауіпсіз сатып алу үшін параметрлерді орнатыңыз." "Барлығын көрсету" @@ -1405,26 +1406,38 @@ "Сенсорлық тақта қимылдарын үйреніңіз." "Пернетақтамен және сенсорлық тақтамен жұмыс істеңіз" "Сенсорлық тақта қимылдарын, перне тіркесімдерін және т.б. үйреніңіз." - "Артқа қайтару қимылы" - "Негізгі бетке қайтару қимылы" + + + + "Соңғы қолданбаларды көру" "Дайын" "Артқа" - "Артқа қайту үшін сенсорлық тақтаның кез келген жерін үш саусақпен солға не оңға сырғытыңыз.\n\nСондай-ақ Action + ESC перне тіркесімін пайдалануға болады." - "Жарайсыз!" + + + + "Артқа қайту қимылын аяқтадыңыз." "Негізгі экранға өту" - "Негізгі экранға кез келген уақытта өту үшін экранның төменгі жағынан жоғары қарай үш саусағыңызбен сырғытыңыз." - "Жақсы нәтиже!" - "Негізгі экранға қайту қимылын аяқтадыңыз." + + + + + + "Соңғы қолданбаларды көру" - "Сенсорлық тақтада үш саусақпен жоғары сырғытып, басып тұрыңыз." + + "Жарайсыз!" "Соңғы қолданбаларды көру қимылын орындадыңыз." - "Әрекет пернесі" - "Қолданбаларыңызға кіру үшін пернетақтадағы әрекет пернесін басыңыз." - "Құттықтаймыз!" - "Әрекет пернесі қимылын аяқтадыңыз.\n\n\"+ /\" әрекеті сіз үшін қолжетімді барлық таңбашаны көрсетеді." + + + + + + + + "Пернетақта жарығы" "Деңгей: %1$d/%2$d" "Үй басқару элементтері" @@ -1436,6 +1449,7 @@ "Пернетақтада әрекет пернесін басып, барлық қолданбаны көре аласыз." "Жасырылған" "Көру үшін құлыпты ашыңыз." + "Контекстік білім" "Артқа қайту үшін сенсорлық тақтаны қолданыңыз" "Үш саусақпен солға не оңға сырғытыңыз. Басқа қимылдарды үйрену үшін түртіңіз." "Негізгі бетке өту үшін сенсорлық тақтаны қолданыңыз" diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 117463564fd3..dce1adc32540 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -440,7 +440,8 @@ "បើក" "បើក • %1$s" "បិទ" - "រៀបចំ" + + "គ្រប់គ្រង​នៅ​ក្នុង​ការកំណត់" "{count,plural, =0{គ្មានមុខងារ​ដែលកំពុងដំណើរការទេ}=1{{mode} កំពុង​ដំណើរការ}other{មុខងារ # កំពុងដំណើរការ}}" "សំឡេង និងរំញ័រនឹងមិន​រំខានដល់អ្នកឡើយ លើកលែងតែម៉ោងរោទ៍ ការរំលឹក ព្រឹត្តិការណ៍ និងអ្នកហៅទូរសព្ទដែលអ្នកបញ្ជាក់ប៉ុណ្ណោះ។ អ្នកនឹងនៅតែឮសំឡេងសកម្មភាពគ្រប់យ៉ាងដែលអ្នកលេងដដែល រួមទាំងតន្រ្តី វីដេអូ និងហ្គេម។" @@ -573,8 +574,7 @@ "ការសន្ទនា" "សម្អាត​ការជូនដំណឹង​ស្ងាត់ទាំងអស់" "ការជូនដំណឹង​បានផ្អាក​ដោយ​មុខងារកុំរំខាន" - - + "{count,plural,offset:1 =0{គ្មាន​ការជូន​ដំណឹង}=1{ការជូនដំណឹង​ត្រូវបាន​ផ្អាកដោយ {mode}}=2{ការជូនដំណឹង​ត្រូវបាន​ផ្អាកដោយ {mode} និង​មុខងារមួយ​ផ្សេងទៀត}other{ការជូនដំណឹង​ត្រូវបាន​ផ្អាកដោយ {mode} និង​មុខងារ # ផ្សេងទៀត}}" "ចាប់ផ្ដើម​ឥឡូវ" "គ្មាន​ការ​ជូនដំណឹង" "គ្មាន​ការ​ជូន​ដំណឹង​​ថ្មីៗទេ" @@ -706,6 +706,7 @@ "បង្ហាញរបៀបសាកល្បង" "អ៊ីសឺរណិត" "ម៉ោងរោទ៍" + "%1$s ត្រូវបាន​បើក" "Wallet" "ធ្វើការ​រៀបចំ ដើម្បី​ធ្វើការទិញ​កាន់តែលឿន​ជាងមុន សុវត្ថិភាព​ជាងមុន ដោយ​ប្រើ​ទូរសព្ទ​របស់អ្នក" "បង្ហាញ​ទាំងអស់" @@ -1405,26 +1406,38 @@ "ស្វែងយល់អំពីចលនាផ្ទាំងប៉ះ" "រុករកដោយប្រើក្ដារចុច និងផ្ទាំងប៉ះរបស់អ្នក" "ស្វែងយល់អំពីចលនាផ្ទាំងប៉ះ ផ្លូវកាត់​ក្ដារ​ចុច និងអ្វីៗជាច្រើនទៀត" - "ចលនាថយក្រោយ" - "ចលនាទៅទំព័រដើម" + + + + "មើលកម្មវិធីថ្មីៗ" "រួចរាល់" "ថយ​ក្រោយ" - "ដើម្បីថយក្រោយ សូមអូសទៅឆ្វេង ឬស្ដាំដោយប្រើ​​ម្រាមដៃបីនៅត្រង់ណាក៏បានលើផ្ទាំងប៉ះ។\n\nអ្នកក៏អាចប្រើសកម្មភាពផ្លូវកាត់ក្ដារចុច + ESC សម្រាប់ការធ្វើបែបនេះ។" - "ធ្វើបានល្អ!" + + + + "អ្នក​បានបញ្ចប់​ចលនា​ថយក្រោយ​ហើយ។" "ទៅទំព័រដើម" - "ដើម្បីចូលទៅអេក្រង់ដើមរបស់អ្នកនៅពេលណាក៏បាន សូមអូសឡើងលើដោយប្រើម្រាមដៃបីពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នក។" - "ល្អ!" - "អ្នក​បានបញ្ចប់​ចលនា​ចូលទៅកាន់​ទំព័រដើម​ហើយ។" + + + + + + "មើលកម្មវិធីថ្មីៗ" - "អូសឡើងលើ ហើយសង្កត់ឱ្យជាប់ដោយប្រើម្រាមដៃបីលើផ្ទាំងប៉ះរបស់អ្នក។" + + "ធ្វើបានល្អ!" "អ្នកបានបញ្ចប់ការមើលចលនាកម្មវិធីថ្មីៗ។" - "គ្រាប់ចុចសកម្មភាព" - "ដើម្បីចូលប្រើប្រាស់កម្មវិធីរបស់អ្នក សូមចុចគ្រាប់ចុចសកម្មភាពនៅលើក្ដារចុចរបស់អ្នក។" - "សូមអបអរសាទរ!" - "អ្នកបានបញ្ចប់មេរៀនអំពីចលនាសម្រាប់គ្រាប់ចុចសកម្មភាព។\n\nគ្រាប់ចុចសកម្មភាព + / បង្ហាញផ្លូវកាត់ទាំងអស់ដែលអ្នកអាចប្រើបាន។" + + + + + + + + "ពន្លឺក្រោយក្ដារចុច" "កម្រិតទី %1$d នៃ %2$d" "ការគ្រប់គ្រង​ផ្ទះ" @@ -1436,6 +1449,7 @@ "ដើម្បីមើលកម្មវិធីទាំងអស់របស់អ្នក សូមចុចគ្រាប់ចុចសកម្មភាពនៅលើក្ដារចុចរបស់អ្នក" "បាន​កែ​លម្អ​ពាក្យពេចន៍" "ដោះសោដើម្បីមើល" + "ការអប់រំ​តាមបរិបទ" "ប្រើផ្ទាំងប៉ះរបស់អ្នក ដើម្បីថយក្រោយ" "អូសទៅឆ្វេង ឬស្ដាំដោយប្រើ​ម្រាមដៃបី។ ចុច ដើម្បីស្វែងយល់បន្ថែមអំពីចលនា។" "ប្រើផ្ទាំងប៉ះរបស់អ្នក ដើម្បីចូលទៅទំព័រដើម" diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 52daecb89c63..5ac910256f04 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -440,7 +440,8 @@ "ಆನ್ ಆಗಿದೆ" "%1$s • ನಲ್ಲಿ" "ಆಫ್ ಆಗಿದೆ" - "ಸೆಟಪ್ ಮಾಡಿ" + + "ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ನಿರ್ವಹಿಸಿ" "{count,plural, =0{ಯಾವುದೇ ಸಕ್ರಿಯ ಮೋಡ್‌ಗಳಿಲ್ಲ}=1{{mode} ಸಕ್ರಿಯವಾಗಿದೆ}one{# ಮೋಡ್‌ಗಳು ಸಕ್ರಿಯವಾಗಿವೆ}other{# ಮೋಡ್‌ಗಳು ಸಕ್ರಿಯವಾಗಿವೆ}}" "ಅಲಾರಾಂಗಳು, ಜ್ಞಾಪನೆಗಳು, ಈವೆಂಟ್‌ಗಳು ಹಾಗೂ ನೀವು ಸೂಚಿಸಿರುವ ಕರೆದಾರರನ್ನು ಹೊರತುಪಡಿಸಿ ಬೇರಾವುದೇ ಸದ್ದುಗಳು ಅಥವಾ ವೈಬ್ರೇಶನ್‌ಗಳು ನಿಮಗೆ ತೊಂದರೆ ನೀಡುವುದಿಲ್ಲ. ಹಾಗಿದ್ದರೂ, ನೀವು ಪ್ಲೇ ಮಾಡುವ ಸಂಗೀತ, ವೀಡಿಯೊಗಳು ಮತ್ತು ಆಟಗಳ ಆಡಿಯೊವನ್ನು ನೀವು ಕೇಳಿಸಿಕೊಳ್ಳುತ್ತೀರಿ." @@ -573,8 +574,7 @@ "ಸಂಭಾಷಣೆಗಳು" "ಎಲ್ಲಾ ನಿಶ್ಶಬ್ಧ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸಿ" "ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಎನ್ನುವ ಮೂಲಕ ಅಧಿಸೂಚನೆಗಳನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ" - - + "{count,plural,offset:1 =0{ಯಾವುದೇ ನೋಟಿಫಿಕೇಶನ್‌ಗಳು ಇಲ್ಲ}=1{ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು {mode} ವಿರಾಮಗೊಳಿಸಿದೆ}=2{ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು {mode} ಹಾಗೂ ಇತರ ಒಂದು ಮೋಡ್ ವಿರಾಮಗೊಳಿಸಿವೆ}one{ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು {mode} ಹಾಗೂ ಇತರ # ಮೋಡ್‌ಗಳು ವಿರಾಮಗೊಳಿಸಿವೆ}other{ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು {mode} ಹಾಗೂ ಇತರ # ಮೋಡ್‌ಗಳು ವಿರಾಮಗೊಳಿಸಿವೆ}}" "ಈಗ ಪ್ರಾರಂಭಿಸಿ" "ಯಾವುದೇ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ" "ಯಾವುದೇ ಹೊಸ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ" @@ -706,6 +706,7 @@ "ಡೆಮೊ ಮೋಡ್ ತೋರಿಸು" "ಇಥರ್ನೆಟ್" "ಅಲಾರಮ್" + "%1$s ಆನ್ ಆಗಿದೆ" "ವಾಲೆಟ್" "ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ವೇಗವಾದ, ಹೆಚ್ಚು ಸುರಕ್ಷಿತ ಖರೀದಿಗಳನ್ನು ಮಾಡಲು ಸೆಟಪ್ ಮಾಡಿಕೊಳ್ಳಿ" "ಎಲ್ಲವನ್ನೂ ತೋರಿಸಿ" @@ -1405,26 +1406,38 @@ "ಟಚ್‌ಪ್ಯಾಡ್ ಗೆಸ್ಚರ್‌ಗಳನ್ನು ಕಲಿಯಿರಿ" "ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ ಮತ್ತು ಟಚ್‌ಪ್ಯಾಡ್ ಬಳಸಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ" "ಟಚ್‌ಪ್ಯಾಡ್ ಗೆಸ್ಚರ್‌ಗಳು, ಕೀಬೋರ್ಡ್‌ಗಳ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು ಮತ್ತು ಹೆಚ್ಚಿನದನ್ನು ತಿಳಿಯಿರಿ" - "ಹಿಂಬದಿ ಗೆಸ್ಚರ್" - "ಹೋಮ್ ಗೆಸ್ಚರ್" + + + + "ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ" "ಮುಗಿದಿದೆ" "ಹಿಂತಿರುಗಿ" - "ಹಿಂತಿರುಗಲು, ಟಚ್‌ಪ್ಯಾಡ್‌ನಲ್ಲಿ ಎಲ್ಲಿಯಾದರೂ ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಎಡ ಅಥವಾ ಬಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ.\n\nಇದಕ್ಕಾಗಿ ನೀವು ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್ Action + ESC ಅನ್ನು ಸಹ ಬಳಸಬಹುದು." - "ಭೇಷ್!" + + + + "ನೀವು ಗೋ ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ." "ಮುಖಪುಟಕ್ಕೆ ಹೋಗಿ" - "ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಹೋಗಲು, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಕೆಳಗಿನಿಂದ ಮೂರು ಬೆರಳುಗಳಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ." - "ಭೇಷ್!" - "ನೀವು ಗೋ ಹೋಮ್ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ." + + + + + + "ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ" - "ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್‌ನಲ್ಲಿ ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ." + + "ಭೇಷ್‌!" "ನೀವು ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳ ಗೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ." - "ಆ್ಯಕ್ಷನ್‌ ಕೀ" - "ನಿಮ್ಮ ಆ್ಯಪ್‌ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು, ನಿಮ್ಮ ಕೀಬೋರ್ಡ್‌ನಲ್ಲಿರುವ ಆ್ಯಕ್ಷನ್‌ ಕೀಯನ್ನು ಒತ್ತಿರಿ." - "ಅಭಿನಂದನೆಗಳು!" - "ನೀವು ಆ್ಯಕ್ಷನ್‌ ಕೀ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ.\n\nನಿಮಗೆ ಲಭ್ಯವಿರುವ ಎಲ್ಲಾ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಆ್ಯಕ್ಷನ್‌ + / ತೋರಿಸುತ್ತದೆ." + + + + + + + + "ಕೀಬೋರ್ಡ್ ಬ್ಯಾಕ್‌ಲೈಟ್" "%2$d ರಲ್ಲಿ %1$d ಮಟ್ಟ" "ಮನೆ ನಿಯಂತ್ರಣಗಳು" @@ -1436,6 +1449,7 @@ "ನಿಮ್ಮ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಲು, ನಿಮ್ಮ ಕೀಬೋರ್ಡ್‌ನಲ್ಲಿರುವ ಆ್ಯಕ್ಷನ್‌ ಕೀಯನ್ನು ಒತ್ತಿರಿ" "ಅರ್ಥಬದ್ಧವಾಗಿಸಲಾಗಿದೆ" "ನೋಡಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ" + "ಸಂದರ್ಭೋಚಿತ ಶಿಕ್ಷಣ" "ಹಿಂತಿರುಗಲು ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್ ಅನ್ನು ಬಳಸಿ" "ಮೂರು ಬೆರಳುಗಳಿಂದ ಎಡಕ್ಕೆ ಅಥವಾ ಬಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ. ಇನ್ನಷ್ಟು ಗೆಸ್ಚರ್‌ಗಳನ್ನು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ." "ಹೋಮ್‌ಗೆ ಹೋಗಲು ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್ ಅನ್ನು ಬಳಸಿ" diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 9a9f3ebe71a8..b7d81b41ac87 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -440,7 +440,8 @@ "사용" "켜짐 • %1$s" "사용 안함" - "설정" + + "설정에서 관리" "{count,plural, =0{활성화된 모드 없음}=1{{mode} 모드가 활성화됨}other{모드 #개가 활성화됨}}" "알람, 알림, 일정 및 지정한 발신자로부터 받은 전화를 제외한 소리와 진동을 끕니다. 음악, 동영상, 게임 등 재생하도록 선택한 소리는 정상적으로 들립니다." @@ -573,8 +574,7 @@ "대화" "무음 알림 모두 삭제" "방해 금지 모드로 알림이 일시중지됨" - - + "{count,plural,offset:1 =0{알림 없음}=1{{mode} 모드로 인해 알림이 일시중지되었습니다.}=2{{mode} 및 다른 모드로 인해 알림이 일시중지되었습니다.}other{{mode} 및 다른 모드 #개로 인해 알림이 일시중지되었습니다.}}" "시작하기" "알림 없음" "새로운 알림 없음" @@ -706,6 +706,7 @@ "데모 모드 표시" "이더넷" "알람" + "%1$s 사용 중" "월렛" "설정하여 휴대전화로 더욱 빠르고 안전하게 구매하세요." "모두 표시" @@ -1405,26 +1406,38 @@ "터치패드 동작 알아보기" "키보드와 터치패드를 사용하여 이동" "터치패드 동작, 단축키 등 알아보기" - "뒤로 동작" - "홈 동작" + + + + "최근 앱 보기" "완료" "뒤로" - "돌아가려면 세 손가락을 사용해 터치패드의 아무 곳이나 왼쪽 또는 오른쪽으로 스와이프합니다.\n\n키보드 단축키 Action + ESC를 사용할 수도 있습니다." - "아주 좋습니다" + + + + "돌아가기 동작을 완료했습니다." "홈으로 이동" - "언제든지 홈 화면으로 이동하려면 세 손가락으로 화면 하단에서 위로 스와이프하세요." - "좋습니다" - "홈으로 이동 동작을 완료했습니다." + + + + + + "최근 앱 보기" - "터치패드에서 세 손가락을 사용해 위로 스와이프한 후 잠시 기다리세요." + + "아주 좋습니다" "최근 앱 보기 동작을 완료했습니다." - "작업 키" - "앱에 액세스하려면 키보드의 작업 키를 누르세요." - "축하합니다" - "작업 키 동작을 완료했습니다.\n\n작업 키 + /를 누르면 사용 가능한 모든 단축키가 표시됩니다." + + + + + + + + "키보드 백라이트" "%2$d단계 중 %1$d단계" "홈 컨트롤" @@ -1436,6 +1449,7 @@ "모든 앱을 보려면 키보드의 작업 키를 누르세요" "수정됨" "잠금 해제하여 보기" + "컨텍스트 교육" "터치패드를 사용하여 돌아가기" "세 손가락을 사용해 왼쪽 또는 오른쪽으로 스와이프하세요. 더 많은 동작을 알아보려면 탭하세요." "터치패드를 사용하여 홈으로 이동" @@ -1444,8 +1458,8 @@ "세 손가락을 사용해 위로 스와이프한 다음 잠시 기다리세요. 더 많은 동작을 알아보려면 탭하세요." "키보드를 사용하여 모든 앱 보기" "언제든지 작업 키를 누릅니다. 더 많은 동작을 알아보려면 탭하세요." - "이제 \'더 어둡게\' 기능이 밝기 슬라이더에 추가되었습니다" - "이제 밝기 수준을 더 낮춰 화면을 더 어둡게 만들 수 있습니다.\n\n이 기능은 이제 밝기 슬라이더에 포함되므로 \'더 어둡게\' 단축키가 삭제됩니다." + "\'더 어둡게\' 기능이 밝기 슬라이더에 추가되었습니다" + "이제 밝기 수준을 더 낮춰 화면을 더 어둡게 만들 수 있습니다.\n\n밝기 슬라이더에서 이 기능을 이용할 수 있으므로 \'더 어둡게\' 단축키가 삭제됩니다." "\'더 어둡게\' 단축키 삭제" "\'더 어둡게\' 단축키가 삭제되었습니다." "연결" diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 33ebf6df3c11..da4d4c38a57a 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -440,7 +440,8 @@ "Күйүк" "Күйүк • %1$s" "Өчүк" - "Тууралоо" + + "Параметрлерден тескөө" "{count,plural, =0{Жигердүү режимдер жок}=1{{mode} иштеп жатат}other{# режим иштеп жатат}}" "Ойготкучтардан, эскертүүлөрдөн, жылнаамадагы иш-чараларды эстеткичтерден жана белгиленген байланыштардын чалууларынан тышкары башка үндөр жана дирилдөөлөр тынчыңызды албайт. Бирок ойнотулуп жаткан музыканы, видеолорду жана оюндарды мурдагыдай эле уга бересиз." @@ -573,8 +574,7 @@ "Сүйлөшүүлөр" "Бардык үнсүз билдирмелерди өчүрүү" "\"Тынчымды алба\" режиминде билдирмелер тындырылды" - - + "{count,plural,offset:1 =0{Билдирмелер жок}=1{{mode} режими билдирмелерди тындырды}=2{{mode} жана дагы бир режим билдирмелерди тындырды}other{{mode} жана дагы # режим билдирмелерди тындырды}}" "Азыр баштоо" "Билдирме жок" "Жаңы билдирмелер жок" @@ -706,6 +706,7 @@ "Демо режимин көрсөтүү" "Ethernet" "Ойготкуч" + "%1$s күйүк" "Капчык" "Телефонуңуз менен тез жана коопсуз сатып алуу үчүн жөндөңүз" "Баарын көрсөтүү" @@ -1405,26 +1406,38 @@ "Сенсордук тактадагы жаңсоолорду үйрөнүп алыңыз" "Нерселерге баскычтоп жана сенсордук такта аркылуу өтүңүз" "Сенсордук тактадагы жаңсоолор, ыкчам баскычтар жана башкалар жөнүндө билип алыңыз" - "Артка кайтуу жаңсоосу" - "Башкы бетке өтүү жаңсоосу" + + + + "Акыркы колдонмолорду көрүү" "Бүттү" "Артка кайтуу" - "Кайтуу үчүн сенсордук тактанын каалаган жерин үч манжаңыз менен солго же оңго сүрүңүз.\n\nОшондой эле Action + ESC баскычтарынын айкалышын колдоно аласыз." - "Азаматсыз!" + + + + "\"Артка\" жаңсоосу боюнча үйрөткүчтү бүтүрдүңүз." "Башкы бетке өтүү" - "Каалаган убакта башкы экранга өтүү үчүн экранды үч манжаңыз менен ылдыйдан жогору карай сүрүңүз." - "Сонун!" - "\"Башкы бетке өтүү\" жаңсоосун үйрөндүңүз." + + + + + + "Акыркы колдонмолорду көрүү" - "Сенсордук тактаны үч манжаңыз менен өйдө сүрүп, кармап туруңуз." + + "Азаматсыз!" "Акыркы колдонмолорду көрүү жаңсоосун аткардыңыз." - "Аракет баскычы" - "Бардык колдонмолоруңузду көрүү үчүн баскычтобуңуздагы аракет баскычын басыңыз" - "Куттуктайбыз!" - "Аракет баскычынын жаңсоосун аткардыңыз.\n\n+ / аракети бардык жеткиликтүү ыкчам баскычтарды көрсөтөт." + + + + + + + + "Баскычтоптун жарыгы" "%2$d ичинен %1$d-деңгээл" "Үйдөгү түзмөктөрдү тескөө" @@ -1436,6 +1449,7 @@ "Бардык колдонмолоруңузду көрүү үчүн баскычтобуңуздагы аракет баскычын басыңыз" "Жашырылды" "Көрүү үчүн кулпусун ачыңыз" + "Контексттик билим берүү" "Артка кайтуу үчүн сенсордук тактаны колдонуңуз" "Үч манжаңыз менен солго же оңго сүрүңүз. Башка жаңсоолорду үйрөнүү үчүн таптаңыз." "Башкы бетке өтүү үчүн сенсордук тактаны колдонуңуз" @@ -1445,7 +1459,7 @@ "Бардык колдонмолорду көрүү үчүн баскычтобуңузду колдонуңуз" "Каалаганда аракет баскычын басыңыз. Башка жаңсоолорду үйрөнүү үчүн таптаңыз." "Кошумча караңгылатуу эми жарыктык сыдырмасында жайгашкан" - "Эми экрандын жарыктыктыгынын деңгээлин азайтып, экранды кошумча караңгылата аласыз.\n\nБул функция эми жарыктык сыдырмасынын бир бөлүгү болуп калгандыктан, кошумча караңгылатуунун ыкчам баскычтары өтүрүлөт." + "Эми экрандын жарыктыктыгынын деңгээлин азайтып, аны кошумча караңгылата аласыз.\n\nБул функция эми жарыктык сыдырмасынын бир бөлүгү болуп калгандыктан, кошумча караңгылатуунун ыкчам баскычтары өчүрүлөт." "Кошумча караңгылатуу ыкчам баскычтарын өчүрүү" "Кошумча караңгылатуу ыкчам баскычтары өчүрүлдү" "Байланыш" diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 410f7d5a506f..92b39745ab73 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -440,7 +440,7 @@ "ເປີດ" "ເປີດ • %1$s" "ປິດ" - "ຕັ້ງຄ່າ" + "ຍັງບໍ່ໄດ້ຕັ້ງ" "ຈັດການໃນການຕັ້ງຄ່າ" "{count,plural, =0{ບໍ່ມີໂໝດທີ່ເຮັດວຽກຢູ່}=1{{mode} ເຮັດວຽກຢູ່}other{# ໂໝດເຮັດວຽກຢູ່}}" "ທ່ານຈະບໍ່ໄດ້ຮັບການລົບກວນຈາກສຽງ ແລະ ການສັ່ນເຕືອນ, ຍົກເວັ້ນໃນເວລາໂມງປຸກດັງ, ມີການແຈ້ງເຕືອນ ຫຼື ມີສາຍໂທເຂົ້າຈາກຜູ້ໂທທີ່ທ່ານລະບຸໄວ້. ທ່ານອາດຍັງຄົງໄດ້ຍິນຫາກທ່ານເລືອກຫຼິ້ນເພງ, ວິດີໂອ ແລະ ເກມ." @@ -573,8 +573,7 @@ "ການສົນທະນາ" "ລຶບລ້າງການແຈ້ງເຕືອນແບບງຽບທັງໝົດ" "ຢຸດການແຈ້ງເຕືອນໂດຍໂໝດຫ້າມລົບກວນແລ້ວ" - - + "{count,plural,offset:1 =0{ບໍ່ມີການແຈ້ງເຕືອນ}=1{{mode} ຢຸດການແຈ້ງເຕືອນໄວ້ຊົ່ວຄາວ}=2{{mode} ແລະ ອີກ 1 ໂໝດຢຸດການແຈ້ງເຕືອນໄວ້ຊົ່ວຄາວ}other{{mode} ແລະ ອີກ # ໂໝດຢຸດການແຈ້ງເຕືອນໄວ້ຊົ່ວຄາວ}}" "ເລີ່ມດຽວນີ້" "ບໍ່ມີການແຈ້ງເຕືອນ" "ບໍ່ມີການແຈ້ງເຕືອນໃໝ່" @@ -706,6 +705,7 @@ "ສະ​ແດງ​ໂຫມດ​ສາ​ທິດ" "ອີ​ເທ​ເນັດ" "ໂມງປຸກ" + "%1$s ເປີດຢູ່" "Wallet" "ຕັ້ງຄ່າເພື່ອຊື້ດ້ວຍໂທລະສັບຂອງທ່ານໄດ້ໄວຂຶ້ນ ແລະ ປອດໄພຂຶ້ນ" "ສະແດງທັງໝົດ" @@ -1405,26 +1405,26 @@ "ສຶກສາທ່າທາງຂອງແຜ່ນສຳຜັດ" "ນຳທາງໂດຍໃຊ້ແປ້ນພິມ ແລະ ແຜ່ນສຳຜັດຂອງທ່ານ" "ສຶກສາທ່າທາງຂອງແຜ່ນສຳຜັດ, ຄີລັດ ແລະ ອື່ນໆ" - "ທ່າທາງສຳລັບກັບຄືນ" - "ທ່າທາງສຳລັບໜ້າຫຼັກ" + "ກັບຄືນ" + "ໄປຫາໜ້າຫຼັກ" "ເບິ່ງແອັບຫຼ້າສຸດ" "ແລ້ວໆ" "ກັບຄືນ" - "ເພື່ອກັບຄືນ, ໃຫ້ໃຊ້ 3 ນິ້ວປັດຊ້າຍ ຫຼື ຂວາບ່ອນໃດກໍໄດ້ເທິງແຜ່ນສຳຜັດ.\n\nທ່ານຍັງສາມາດໃຊ້ຄຳສັ່ງຄີລັດ + ESC ສຳລັບການດຳເນີນການນີ້ໄດ້ນຳ." - "ເກັ່ງຫຼາຍ!" + "ປັດຊ້າຍ ຫຼື ຂວາໂດຍໃຊ້ມືສາມນິ້ວຢູ່ແຜ່ນສໍາຜັດຂອງທ່ານ" + "ດີ!" "ທ່ານໃຊ້ທ່າທາງກັບຄືນສຳເລັດແລ້ວ." "ໄປຫາໜ້າຫຼັກ" - "ເພື່ອໄປຫາໜ້າຫຼັກຂອງທ່ານຕອນໃດກໍໄດ້, ໃຫ້ປັດຂຶ້ນດ້ວຍສາມນິ້ວຈາກລຸ່ມສຸດຂອງໜ້າຈໍຂອງທ່ານ." - "ດີຫຼາຍ!" - "ທ່ານໃຊ້ທ່າທາງໄປໜ້າຫຼັກສຳເລັດແລ້ວ." + "ປັດຂຶ້ນໂດຍໃຊ້ມືສາມນິ້ວຢູ່ແຜ່ນສໍາຜັດຂອງທ່ານ" + "ດີຫຼາຍ!" + "ທ່ານໃຊ້ທ່າທາງໄປໜ້າຫຼັກສຳເລັດແລ້ວ" "ເບິ່ງແອັບຫຼ້າສຸດ" - "ໃຊ້ 3 ນິ້ວປັດຂຶ້ນແລ້ວຄ້າງໄວ້ຢູ່ແຜ່ນສໍາຜັດຂອງທ່ານ." + "ປັດຂຶ້ນໂດຍໃຊ້ມືສາມນິ້ວແລ້ວຄ້າງໄວ້ຢູ່ແຜ່ນສໍາຜັດຂອງທ່ານ" "ດີຫຼາຍ!" "ທ່ານເບິ່ງທ່າທາງຂອງແອັບຫຼ້າສຸດສຳເລັດແລ້ວ." - "ປຸ່ມຄຳສັ່ງ" - "ເພື່ອເຂົ້າເຖິງແອັບ, ໃຫ້ກົດປຸ່ມຄຳສັ່ງຢູ່ແປ້ນພິມຂອງທ່ານ." - "ຂໍສະແດງຄວາມຍິນດີ!" - "ທ່ານໃຊ້ທ່າທາງປຸ່ມຄຳສັ່ງສໍາເລັດແລ້ວ.\n\nຄໍາສັ່ງ + / ຈະສະແດງທາງລັດທັງໝົດທີ່ທ່ານມີ." + "ເບິ່ງແອັບທັງໝົດ" + "ກົດປຸ່ມຄຳສັ່ງຢູ່ແປ້ນພິມຂອງທ່ານ" + "ດີຫຼາຍ!" + "ທ່ານເບິ່ງທ່າທາງຂອງແອັບທັງໝົດສຳເລັດແລ້ວ" "ໄຟປຸ່ມແປ້ນພິມ" "ລະດັບທີ %1$d ຈາກ %2$d" "ການຄວບຄຸມເຮືອນ" @@ -1436,6 +1436,7 @@ "ເພື່ອເບິ່ງແອັບທັງໝົດຂອງທ່ານ, ໃຫ້ກົດປຸ່ມຄຳສັ່ງຢູ່ແປ້ນພິມຂອງທ່ານ" "ປົກປິດໄວ້ແລ້ວ" "ປົດລັອກເພື່ອເບິ່ງ" + "ການສຶກສາຕາມບໍລິບົດ" "ໃຊ້ແຜ່ນສໍາຜັດຂອງທ່ານເພື່ອກັບຄືນ" "ໃຊ້ 3 ນິ້ວປັດຊ້າຍ ຫຼື ຂວາ. ແຕະເພື່ອສຶກສາທ່າທາງເພີ່ມເຕີມ." "ໃຊ້ແຜ່ນສໍາຜັດຂອງທ່ານເພື່ອໄປຫາໜ້າຫຼັກ" diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 67ead2399a38..a5e325e28fad 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -440,7 +440,8 @@ "Įjungta" "Įjungta • %1$s" "Išjungta" - "Nustatyti" + + "Tvarkyti skiltyje „Nustatymai“" "{count,plural, =0{Nėra aktyvių režimų}=1{Aktyvus režimas „{mode}“}one{# aktyvus režimas}few{# aktyvūs režimai}many{# aktyvaus režimo}other{# aktyvių režimų}}" "Jūsų netrikdys garsai ir vibravimas, išskyrus nurodytų signalų, priminimų, įvykių ir skambintojų garsus. Vis tiek girdėsite viską, ką pasirinksite leisti, įskaitant muziką, vaizdo įrašus ir žaidimus." @@ -573,8 +574,7 @@ "Pokalbiai" "Išvalyti visus tylius pranešimus" "Pranešimai pristabdyti naudojant netrukdymo režimą" - - + "{count,plural,offset:1 =0{Nėra pranešimų}=1{Pranešimai pristabdyti naudojant režimą „{mode}“}=2{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar vieną režimą}one{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimą}few{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimus}many{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimo}other{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimų}}" "Pradėti dabar" "Nėra įspėjimų" "Naujų pranešimų nėra" @@ -706,6 +706,7 @@ "Rodyti demonstraciniu režimu" "Eternetas" "Signalas" + "Tvarkaraštis „%1$s“ įjungtas" "Wallet" "Nustatykite, kad galėtumėte greičiau ir saugiau pirkti telefonu" "Rodyti viską" @@ -1405,26 +1406,38 @@ "Sužinokite jutiklinės dalies gestus" "Naršykite naudodamiesi klaviatūra ir jutikline dalimi" "Sužinokite jutiklinės dalies gestus, sparčiuosius klavišus ir kt." - "Grįžimo atgal gestas" - "Pagrindinio ekrano gestas" + + + + "Peržiūrėti naujausias programas" "Atlikta" "Grįžti" - "Jei norite grįžti, perbraukite kairėn arba dešinėn trimis pirštais bet kurioje jutiklinės dalies vietoje.\n\nTaip pat galite naudoti šį spartųjį klavišą: veiksmų klavišas + klavišas „Esc“." - "Puiku!" + + + + "Atlikote grįžimo atgal gestą." "Eikite į pagrindinį ekraną" - "Jei norite bet kada pasiekti pagrindinį ekraną, perbraukite aukštyn trim pirštais iš ekrano apačios." - "Šaunu!" - "Atlikote perėjimo į pagrindinį ekraną gestą." + + + + + + "Peržiūrėti naujausias programas" - "Jutiklinėje dalyje perbraukite aukštyn trimis pirštais ir palaikykite." + + "Puiku!" "Atlikote naujausių programų peržiūros gestą." - "Veiksmų klavišas" - "Jei norite pasiekti programas, paspauskite klaviatūros veiksmų klavišą." - "Sveikiname!" - "Atlikote veiksmų klavišo gestą.\n\nVeiksmas + / rodo visus pasiekiamus sparčiuosius klavišus." + + + + + + + + "Klaviatūros foninis apšvietimas" "%1$d lygis iš %2$d" "Namų sistemos valdymas" @@ -1436,6 +1449,7 @@ "Jei norite peržiūrėti visas programas, paspauskite klaviatūros veiksmų klavišą" "Paslėpta" "Atrakinkite, kad peržiūrėtumėte" + "Kontekstinis švietimas" "Naudokite klaviatūrą, kad grįžtumėte atgal" "Perbraukite į kairę ar dešinę trimis pirštais. Palieskite, kad sužinotumėte daugiau gestų." "Naudokite jutiklinę dalį, jei norite eiti į pagrindinį ekraną" diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 53e0baabcd28..b570ad6f700f 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -440,7 +440,8 @@ "Ieslēgts" "Ieslēgts • %1$s" "Izslēgts" - "Iestatīt" + + "Pārvaldīt iestatījumos" "{count,plural, =0{Nav aktīvu režīmu}=1{Režīms “{mode}” ir aktīvs}zero{# režīmi ir aktīvi}one{# režīms ir aktīvs}other{# režīmi ir aktīvi}}" "Jūs netraucēs skaņas un vibrācija, izņemot signālus, atgādinājumus, pasākumus un zvanītājus, ko būsiet norādījis. Jūs joprojām dzirdēsiet atskaņošanai izvēlētos vienumus, tostarp mūziku, videoklipus un spēles." @@ -573,8 +574,7 @@ "Sarunas" "Notīrīt visus klusos paziņojumus" "Paziņojumi pārtraukti, izmantojot iestatījumu “Netraucēt”" - - + "{count,plural,offset:1 =0{Nav paziņojumu}=1{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” dēļ}=2{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl viena režīma dēļ}zero{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl # režīmu dēļ}one{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl # režīma dēļ}other{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl # režīmu dēļ}}" "Sākt tūlīt" "Nav paziņojumu" "Nav jaunu paziņojumu" @@ -706,6 +706,8 @@ "Rādīt demonstrācijas režīmu" "Tīkls Ethernet" "Signāls" + + "Maks" "Iestatiet, lai ātrāk un drošāk veiktu pirkumus, izmantojot tālruni" "Rādīt visu" @@ -1405,26 +1407,38 @@ "Apgūstiet skārienpaliktņa žestus." "Pārvietošanās, izmantojot tastatūru un skārienpaliktni" "Uzziniet par skārienpaliktņa žestiem, īsinājumtaustiņiem un citām iespējām." - "Žests pāriešanai atpakaļ" - "Žests pāriešanai uz sākumu" + + + + "Skatīt nesen izmantotās lietotnes" "Gatavs" "Atpakaļ" - "Lai atgrieztos, ar trīs pirkstiem velciet pa kreisi vai pa labi jebkurā vietā uz skārienpaliktņa.\n\nVarat arī izmantot šim nolūkam īsinājumtaustiņus: darbību taustiņu + Esc." - "Lieliski!" + + + + "Jūs sekmīgi veicāt atgriešanās žestu." "Pāreja uz sākuma ekrānu" - "Lai jebkurā brīdī pārietu uz sākuma ekrānu, ar trim pirkstiem velciet augšup no ekrāna apakšdaļas." - "Lieliski!" - "Jūs sekmīgi veicāt sākuma ekrāna atvēršanas žestu." + + + + + + "Nesen izmantoto lietotņu skatīšana" - "Skārienpaliktnī ar trīs pirkstiem velciet augšup un turiet." + + "Lieliski!" "Jūs sekmīgi veicāt nesen izmantoto lietotņu skatīšanas žestu." - "Darbību taustiņš" - "Lai piekļūtu savām lietotnēm, tastatūrā nospiediet darbību taustiņu." - "Apsveicam!" - "Jūs pabeidzāt darbību taustiņa žesta apmācību.\n\nNospiežot darbību taustiņu un taustiņu “/”, tiks parādīti visi pieejamie īsinājumtaustiņi." + + + + + + + + "Tastatūras fona apgaismojums" "Līmenis numur %1$d, kopā ir %2$d" "Mājas kontrolierīces" @@ -1436,6 +1450,7 @@ "Lai skatītu visas savas lietotnes, tastatūrā nospiediet darbību taustiņu." "Rediģēts" "Lai skatītu, atbloķējiet" + "Kontekstuāla pamācība" "Atgriešanās, izmantojot skārienpaliktni" "Ar trīs pirkstiem velciet pa kreisi vai pa labi. Lai apgūtu citus žestus, pieskarieties šeit." "Pāriešana uz sākuma ekrānu, izmantojot skārienpaliktni" diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 86c93acada52..708135dbc006 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -440,7 +440,8 @@ "Вклучено" "Вклучено: %1$s" "Исклучено" - "Поставете" + + "Управувајте во поставките" "{count,plural, =0{Нема активни режими}=1{Активен е {mode}}one{Активни се # режим}other{Активни се # режими}}" "Нема да ве вознемируваат звуци и вибрации, освен од аларми, потсетници, настани и повикувачи што ќе ги наведете. Сѐ уште ќе слушате сѐ што ќе изберете да пуштите, како музика, видеа и игри." @@ -573,8 +574,7 @@ "Разговори" "Избриши ги сите бесчујни известувања" "Известувањата се паузирани од „Не вознемирувај“" - - + "{count,plural,offset:1 =0{Нема известувања}=1{Известувањата ги паузираше {mode}}=2{Известувањата ги паузираа {mode} и уште еден режим}one{Известувањата ги паузираа {mode} и уште # режим}other{Известувањата ги паузираа {mode} и уште # режими}}" "Започни сега" "Нема известувања" "Нема нови известувања" @@ -706,6 +706,8 @@ "Прикажи демо-режим" "Етернет" "Аларм" + + "Wallet" "Поставете за да купувате побрзо и побезбедно преку вашиот телефон" "Прикажи ги сите" @@ -1405,26 +1407,38 @@ "Научете движења за допирната подлога" "Движете се со користење на тастатурата и допирната подлога" "Научете движења за допирната подлога, кратенки од тастатурата и друго" - "Движење за назад" - "Движење за почетен екран" + + + + "Прегледајте ги неодамнешните апликации" "Готово" "Назад" - "За да се вратите назад, повлечете налево или надесно со три прста каде било на допирната подлога.\n\nЗа ова може да ја користите и кратенката од тастатурата Action + ESC." - "Одлично сторено!" + + + + "Го научивте движењето за враќање назад." "Одете на почетниот екран" - "За да одите на вашиот почетен екран кога сакате, повлечете нагоре со три прсти од дното на екранот." - "Одлично!" - "Го научивте движењето за враќање на почетниот екран." + + + + + + "Прегледајте ги неодамнешните апликации" - "Повлечете нагоре и задржете со три прста на допирната подлога." + + "Одлично!" "Го завршивте движењето за прегледување на неодамнешните апликации." - "Копче за дејство" - "За да пристапите до апликациите, притиснете го копчето за дејство на тастатурата." - "Честитки!" - "Го научивте движењето со копчето за дејство.\n\nДејство + / ги прикажува сите кратенки што ги имате на располагање." + + + + + + + + "Осветлување на тастатура" "Ниво %1$d од %2$d" "Контроли за домот" @@ -1436,6 +1450,7 @@ "Притиснете го копчето за дејство на тастатурата за да ги видите сите апликации" "Редактирано" "Отклучете за приказ" + "Контекстуално образование" "Користете ја допирната подлога за да се вратите назад" "Повлечете налево или надесно со три прста. Допрете за да научите повеќе движења." "Користете ја допирната подлога за да одите на почетниот екран" diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 6958679712e6..28fd77d5ac0b 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -440,7 +440,8 @@ "ഓണാണ്" "ഓണാണ് • %1$s" "ഓഫാണ്" - "സജ്ജീകരിക്കുക" + + "ക്രമീകരണത്തിൽ മാനേജ് ചെയ്യുക" "{count,plural, =0{സജീവ മോഡുകൾ ഒന്നുമില്ല}=1{{mode} സജീവമാണ്}other{# മോഡുകൾ സജീവമാണ്}}" "നിങ്ങൾ സജ്ജീകരിച്ച അലാറങ്ങൾ, റിമൈൻഡറുകൾ, ഇവന്റുകൾ, കോളർമാർ എന്നിവയിൽ നിന്നുള്ള ശബ്‌ദങ്ങളും വൈബ്രേഷനുകളുമൊഴികെ മറ്റൊന്നും നിങ്ങളെ ശല്യപ്പെടുത്തുകയില്ല. സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയുൾപ്പെടെ പ്ലേ ചെയ്യുന്നതെന്തും നിങ്ങൾക്ക് ‌തുടർന്നും കേൾക്കാൻ കഴിയും." @@ -573,8 +574,7 @@ "സംഭാഷണങ്ങൾ" "എല്ലാ നിശബ്‌ദ അറിയിപ്പുകളും മായ്ക്കുക" "\'ശല്യപ്പെടുത്തരുത്\' വഴി അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തി" - - + "{count,plural,offset:1 =0{അറിയിപ്പുകൾ ഒന്നുമില്ല}=1{{mode}, അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തിയിരിക്കുന്നു}=2{{mode} എന്നതും മറ്റൊരു മോഡും, അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തിയിരിക്കുന്നു}other{{mode} എന്നതും മറ്റ് # മോഡുകളും, അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തിയിരിക്കുന്നു}}" "ഇപ്പോൾ ആരംഭിക്കുക" "അറിയിപ്പുകൾ ഒന്നുമില്ല" "പുതിയ അറിയിപ്പുകളൊന്നുമില്ല" @@ -706,6 +706,7 @@ "ഡെമോ മോഡ് കാണിക്കുക" "ഇതർനെറ്റ്" "അലാറം" + "%1$s ഓണാണ്" "Wallet" "നിങ്ങളുടെ ഫോൺ ഉപയോഗിച്ച് വാങ്ങലുകൾ വേഗത്തിലും സുരക്ഷിതമായും നടത്താനുള്ള സജ്ജീകരണം നടത്തുക" "എല്ലാം കാണിക്കുക" @@ -1405,26 +1406,38 @@ "ടച്ച്പാഡ് ജെസ്ച്ചറുകൾ മനസ്സിലാക്കുക" "നിങ്ങളുടെ കീപാഡ്, ടച്ച്‌പാഡ് എന്നിവ ഉപയോഗിച്ച് നാവിഗേറ്റ് ചെയ്യുക" "ടച്ച്‌പാഡ് ജെസ്ച്ചറുകൾ, കീബോർഡ് കുറുക്കുവഴികൾ എന്നിവയും മറ്റും മനസ്സിലാക്കുക" - "\'മടങ്ങുക\' ജെസ്ച്ചർ" - "ഹോം ജെസ്‌ച്ചർ" + + + + "അടുത്തിടെയുള്ള ആപ്പുകൾ കാണുക" "പൂർത്തിയായി" "മടങ്ങുക" - "തിരികെ പോകാൻ, ടച്ച്പാഡിൽ എവിടെയെങ്കിലും മൂന്ന് വിരലുകൾ ഉപയോഗിച്ച് ഇടത്തേക്കോ വലത്തേക്കോ സ്വൈപ്പ് ചെയ്യുക.\n\nഇതിന് Action + ESC കീബോഡ് കുറുക്കുവഴികളും നിങ്ങൾക്ക് ഉപയോഗിക്കാം." - "കൊള്ളാം!" + + + + "മടങ്ങുക ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി." "ഹോമിലേക്ക് പോകൂ" - "ഏതുസമയത്തും ഹോം സ്ക്രീനിലേക്ക് പോകാൻ, മൂന്ന് വിരലുകൾ ഉപയോഗിച്ച് സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യൂ." - "കൊള്ളാം!" - "ഹോമിലേക്ക് പോകുക ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി." + + + + + + "അടുത്തിടെയുള്ള ആപ്പുകൾ കാണുക" - "നിങ്ങളുടെ ടച്ച്പാഡിൽ മൂന്ന് വിരലുകൾ കൊണ്ട് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്‌ത് പിടിക്കുക." + + "കൊള്ളാം!" "അടുത്തിടെയുള്ള ആപ്പുകൾ കാണുക എന്ന ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി." - "Action കീ" - "നിങ്ങളുടെ ആപ്പുകൾ ആക്‌സസ് ചെയ്യാൻ, നിങ്ങളുടെ കീബോർഡിലെ Action കീ അമർത്തുക." - "അഭിനന്ദനങ്ങൾ!" - "നിങ്ങൾ Action കീ ജെസ്ച്ചർ പൂർത്തിയാക്കി.\n\nനിങ്ങൾക്ക് ലഭ്യമാകുന്ന എല്ലാ കുറുക്കുവഴികളും Action + / കാണിക്കുന്നു." + + + + + + + + "കീബോഡ് ബാക്ക്‌ലൈറ്റ്" "%2$d-ൽ %1$d-ാമത്തെ ലെവൽ" "ഹോം കൺട്രോളുകൾ" @@ -1436,6 +1449,7 @@ "എല്ലാ ആപ്പുകളും കാണാൻ, നിങ്ങളുടെ കീബോർഡിലെ ആക്‌ഷൻ കീ അമർത്തുക" "മറച്ചത്" "കാണാൻ, അൺലോക്ക് ചെയ്യുക" + "സന്ദർഭോചിത വിദ്യാഭ്യാസം" "തിരികെ പോകാൻ നിങ്ങളുടെ ടച്ച്‌പാഡ് ഉപയോഗിക്കുക" "മൂന്ന് വിരലുകൾ കൊണ്ട് ഇടത്തേക്കോ വലത്തേക്കോ സ്വൈപ്പ് ചെയ്യൂ. കൂടുതൽ ജെസ്ച്ചറുകളറിയാൻ ടാപ്പ് ചെയ്യൂ." "ഹോമിലേക്ക് പോകാൻ നിങ്ങളുടെ ടച്ച്‌പാഡ് ഉപയോഗിക്കുക" diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 95ff970ed0f4..dfd239838f54 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -440,7 +440,8 @@ "Асаалттай" "Асаасан • %1$s" "Унтраалттай" - "Тохируулах" + + "Тохиргоонд удирдах" "{count,plural, =0{Ямар ч идэвхтэй горим байхгүй}=1{{mode} идэвхтэй байна}other{# горим идэвхтэй байна}}" "Танд сэрүүлэг, сануулга, арга хэмжээ, таны сонгосон дуудлага илгээгчээс бусад дуу, чичиргээ саад болохгүй. Та хөгжим, видео, тоглоом зэрэг тоглуулахыг хүссэн бүх зүйлээ сонсох боломжтой хэвээр байна." @@ -573,8 +574,7 @@ "Харилцан яриа" "Бүх чимээгүй мэдэгдлийг арилгах" "Бүү саад бол горимын түр зогсоосон мэдэгдэл" - - + "{count,plural,offset:1 =0{Мэдэгдэл байхгүй}=1{Мэдэгдлийг {mode} түр зогсоосон}=2{Мэдэгдлийг {mode} болон өөр нэг горим түр зогсоосон}other{Мэдэгдлийг {mode} болон өөр # горим түр зогсоосон}}" "Одоо эхлүүлэх" "Мэдэгдэл байхгүй" "Шинэ мэдэгдэл алга" @@ -706,6 +706,7 @@ "Демо горимыг харуулах" "Этернет" "Сэрүүлэг" + "%1$s асаалттай байна" "Wallet" "Утсаараа илүү хурдан, аюулгүй худалдан авалт хийхийн тулд тохируулгыг авна уу" "Бүгдийг харуулах" @@ -1405,26 +1406,38 @@ "Мэдрэгч самбарын зангааг мэдэж аваарай" "Гар эсвэл мэдрэгч самбараа ашиглан шилжээрэй" "Мэдрэгч самбарын зангаа, товчлуурын шууд холбоос болон бусад зүйлийг мэдэж аваарай" - "Буцах зангаа" - "Үндсэн нүүрний зангаа" + + + + "Саяхны аппуудыг харах" "Болсон" "Буцах" - "Буцахын тулд мэдрэгч самбар дээр гурван хуруугаар хүссэн газраа зүүн эсвэл баруун тийш шударна уу.\n\nТа мөн үүнийг хийхэд Action + ESC товчлуурын шууд холбоосыг ашиглах боломжтой." - "Үнэхээр сайн ажиллалаа!" + + + + "Та буцах зангааг гүйцэтгэлээ." "Үндсэн нүүр лүү очих" - "Үндсэн нүүр лүүгээ хүссэн үедээ очихын тулд дэлгэцийнхээ доод талаас гурван хуруугаараа дээш шударна уу." - "Янзтай!" - "Та үндсэн нүүр лүү очих зангааг гүйцэтгэлээ." + + + + + + "Саяхны аппуудыг харах" - "Мэдрэгч самбар дээрээ гурван хуруугаа ашиглан дээш шудраад, удаан дарна уу." + + "Сайн байна!" "Та саяхны аппуудыг харах зангааг гүйцэтгэсэн." - "Тусгай товчлуур" - "Аппууддаа хандахын тулд гар дээр тань байх тусгай товчлуурыг дарна уу." - "Баяр хүргэе!" - "Та тусгай товчлуурын зангааг гүйцэтгэлээ.\n\nТусгай товчлуур болох + / нь танд боломжтой бүх товчлолыг харуулна." + + + + + + + + "Гарын арын гэрэл" "%2$d-с %1$d-р түвшин" "Гэрийн удирдлага" @@ -1436,6 +1449,7 @@ "Бүх аппаа харахын тулд гар дээр тань байх тусгай товчлуурыг дарна уу" "Хассан" "Харахын тулд түгжээг тайлна уу" + "Хам сэдэвт боловсрол" "Буцахын тулд мэдрэгч самбараа ашиглах" "Гурван хуруугаараа зүүн эсвэл баруун тийш шударна уу. Илүү олон зангаа сурахын тулд товшино уу." "Нүүр хуудас руу очихын тулд мэдрэгч самбараа ашиглах" diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 14739299f2ff..db2ed93da0a9 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -440,7 +440,8 @@ "सुरू आहे" "सुरू • %1$s" "बंद आहे" - "सेट करा" + + "सेटिंग्जमध्ये व्यवस्थापित करा" "{count,plural, =0{कोणतेही अ‍ॅक्टिव्ह मोड नाहीत}=1{{mode} अ‍ॅक्टिव्ह आहे}other{# मोड अ‍ॅक्टिव्ह आहेत}}" "अलार्म, रिमाइंडर, इव्‍हेंट आणि तुम्ही निश्चित केलेल्या कॉलर व्यतिरिक्त तुम्हाला कोणत्याही आवाज आणि कंपनांचा व्यत्त्यय आणला जाणार नाही. तरीही तुम्ही प्ले करायचे ठरवलेले कोणतेही संगीत, व्हिडिओ आणि गेमचे आवाज ऐकू शकतात." @@ -573,8 +574,7 @@ "संभाषणे" "सर्व सायलंट सूचना साफ करा" "व्यत्यय आणून नकाद्वारे सूचना थांबवल्या" - - + "{count,plural,offset:1 =0{कोणतेही नोटिफिकेशन नाही}=1{{mode} द्वारे नोटिफिकेशन थांबवली आहेत}=2{{mode} द्वारे आणि आणखी एका मोडद्वारे नोटिफिकेशन थांबवली आहेत}other{{mode} द्वारे आणि आणखी # मोडद्वारे नोटिफिकेशन थांबवली आहेत}}" "आता सुरू करा" "सूचना नाहीत" "नवीन सूचना नाहीत" @@ -706,6 +706,7 @@ "डेमो मोड दर्शवा" "इथरनेट" "अलार्म" + "%1$s हे सुरू आहे" "Wallet" "तुमचा फोन वापरून जलदरीत्या, अधिक सुरक्षित खरेदी करण्यासाठी सेट करा" "सर्व दाखवा" @@ -1405,26 +1406,38 @@ "टचपॅड जेश्चर जाणून घ्या" "तुमचा कीबोर्ड आणि टचपॅड वापरून नेव्हिगेट करा" "टचपॅड जेश्चर, कीबोर्ड शॉर्टकट आणि आणखी बरेच काही जाणून घ्या" - "मागे जा जेश्चर" - "होम जेश्चर" + + + + "अलीकडील अ‍ॅप्स पहा" "पूर्ण झाले" "मागे जा" - "मागे जाण्यासाठी, तीन बोटांनी टचपॅडवर कुठेही डावीकडे किंवा उजवीकडे स्वाइप करा.\n\nतुम्ही यासाठी Action + ESC हा कीबोर्ड शॉर्टकटदेखील वापरू शकता." - "उत्तम कामगिरी!" + + + + "तुम्ही गो बॅक जेश्चर पूर्ण केले." "होमवर जा" - "कधीही तुमच्या होम स्क्रीनवर जाण्यासाठी, तीन बोटांनी तुमच्या स्क्रीनच्या तळापासून स्वाइप करा." - "छान!" - "तुम्ही गो होम जेश्चर पूर्ण केले आहे." + + + + + + "अलीकडील अ‍ॅप्स पहा" - "तुमच्या टचपॅडवर तीन बोटांनी वरती आणि खाली स्वाइप करा." + + "उत्तम कामगिरी!" "तुम्ही अलीकडील ॲप्स पाहण्याचे जेश्चर पूर्ण केले आहे." - "अ‍ॅक्शन की" - "तुमची ॲप्स अ‍ॅक्सेस करण्यासाठी, तुमच्या कीबोर्डवरील अ‍ॅक्शन की प्रेस करा." - "अभिनंदन!" - "तुम्ही अ‍ॅक्शन की जेश्चर पूर्ण केले आहे.\n\nकृती + / हे तुमच्याकडे उपलब्ध असलेले सर्व शॉर्टकट दाखवते." + + + + + + + + "कीबोर्ड बॅकलाइट" "%2$d पैकी %1$d पातळी" "होम कंट्रोल" @@ -1436,6 +1449,7 @@ "तुमची सर्व ॲप्स पाहण्यासाठी, तुमच्या कीबोर्डवरील अ‍ॅक्शन की प्रेस करा" "रिडॅक्ट केलेले" "पाहण्यासाठी अनलॉक करा" + "संदर्भीय शिक्षण" "मागे जाण्यासाठी तुमचा टचपॅड वापरा" "तीन बोटांनी डावीकडे किंवा उजवीकडे स्वाइप करा. आणखी जेश्चर जाणून घेण्यासाठी टॅप करा." "होमवर जाण्यासाठी तुमचा टचपॅड वापरा" diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index ed3a0bc3d737..abdb32fceebc 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -440,7 +440,7 @@ "Hidup" "Pada • %1$s" "Mati" - "Sediakan" + "Tidak ditetapkan" "Urus dalam tetapan" "{count,plural, =0{Tiada mod yang aktif}=1{{mode} aktif}other{# mod aktif}}" "Anda tidak akan diganggu oleh bunyi dan getaran, kecuali daripada penggera, peringatan, acara dan pemanggil yang anda tetapkan. Anda masih mendengar item lain yang anda pilih untuk dimainkan termasuk muzik, video dan permainan." @@ -573,8 +573,7 @@ "Perbualan" "Kosongkan semua pemberitahuan senyap" "Pemberitahuan dijeda oleh Jangan Ganggu" - - + "{count,plural,offset:1 =0{Tiada pemberitahuan}=1{Pemberitahuan dijeda oleh {mode}}=2{Pemberitahuan dijeda oleh {mode} dan satu lagi mod yang lain}other{Pemberitahuan dijeda oleh {mode} dan # mod yang lain}}" "Mulakan sekarang" "Tiada pemberitahuan" "Tiada pemberitahuan baharu" @@ -706,6 +705,7 @@ "Tunjukkan mod tunjuk cara" "Ethernet" "Penggera" + "%1$s dihidupkan" "Wallet" "Buat persediaan untuk membuat pembelian yang lebih pantas dan selamat dengan telefon anda" "Tunjukkan semua" @@ -1405,26 +1405,26 @@ "Ketahui gerak isyarat pad sentuh" "Navigasi menggunakan papan kekunci dan pad sentuh anda" "Ketahui gerak isyarat pad sentuh, pintasan papan kekunci dan pelbagai lagi" - "Gerak isyarat kembali" - "Gerak isyarat pergi ke laman utama" + "Kembali" + "Akses laman utama" "Lihat apl terbaharu" "Selesai" "Kembali" - "Untuk kembali, leret ke kiri atau ke kanan menggunakan tiga jari di mana-mana sahaja pada pad sentuh.\n\nAnda juga boleh menggunakan pintasan papan kekunci Action + ESC untuk kembali." - "Syabas!" + "Leret ke kiri atau kanan menggunakan tiga jari pada pad sentuh anda" + "Bagus!" "Anda telah melengkapkan gerak isyarat undur." "Akses laman utama" - "Untuk mengakses skrin utama anda pada bila-bila masa, leret ke atas menggunakan tiga jari daripada bahagian bawah skrin anda." - "Bagus!" - "Anda telah melengkapkan gerak isyarat akses laman utama." + "Leret ke atas dengan tiga jari pada pad sentuh anda" + "Bagus!" + "Anda telah melengkapkan gerak isyarat akses laman utama" "Lihat apl terbaharu" - "Leret ke atas dan tahan menggunakan tiga jari pada pad sentuh anda." + "Leret ke atas dan tahan menggunakan tiga jari pada pad sentuh anda" "Syabas!" "Anda melengkapkan gerak isyarat lihat apl terbaharu." - "Kekunci tindakan" - "Untuk mengakses semua apl anda, tekan kekunci tindakan pada papan kekunci anda." - "Tahniah!" - "Anda telah melengkapkan gerak isyarat kekunci tindakan.\n\nTindakan + / menunjukkan semua pintasan anda yang tersedia." + "Lihat semua apl" + "Tekan kekunci tindakan pada papan kekunci anda" + "Syabas!" + "Anda telah melengkapkan gerak isyarat lihat semua apl" "Cahaya latar papan kekunci" "Tahap %1$d daripada %2$d" "Kawalan Rumah" @@ -1436,6 +1436,7 @@ "Untuk melihat semua apl anda, tekan kekunci tindakan pada papan kekunci anda" "Disunting" "Buka kunci untuk melihat" + "Pendidikan kontekstual" "Gunakan pad sentuh anda untuk kembali" "Leret ke kiri atau ke kanan dengan tiga jari. Ketik dan ketahui lebih lanjut tentang gerak isyarat." "Gunakan pad sentuh untuk mengakses laman utama" @@ -1444,8 +1445,8 @@ "Leret ke atas, tahan dengan tiga jari. Ketik untuk mengetahui lebih lanjut tentang gerak isyarat." "Gunakan papan kekunci anda untuk melihat semua apl" "Tekan kekunci tindakan pada bila-bila masa. Ketik dan ketahui lebih lanjut tentang gerak isyarat." - "Kini ciri amat malap merupakan sebahagian daripada peluncur kecerahan" - "Kini anda boleh menjadikan skrin amat malap dengan merendahkan lebih lagi tahap kecerahan.\n\nMemandangkan ciri ini kini merupakan sebahagian daripada peluncur kecerahan, pintasan amat malap dialih keluar." + "Ciri amat malap kini bergabung dengan peluncur kecerahan" + "Skrin boleh dijadikan amat malap dengan menurunkan lagi tahap kecerahannya.\n\nOleh sebab ciri ini telah bergabung dengan peluncur kecerahan, pintasan amat malap dialih keluar." "Alih keluar pintasan amat malap" "Pintasan amat malap dialih keluar" "Kesambungan" diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index ea10ec267512..f4f337b05dee 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -440,7 +440,8 @@ "ဖွင့်" "ဖွင့် • %1$s" "ပိတ်" - "စနစ်ထည့်သွင်းရန်" + + "ဆက်တင်များတွင် စီမံရန်" "{count,plural, =0{သုံးနေသော မုဒ်မရှိပါ}=1{{mode} ကို သုံးနေသည်}other{မုဒ် # ခု သုံးနေသည်}}" "နှိုးစက်သံ၊ သတိပေးချက်အသံများ၊ ပွဲစဉ်သတိပေးသံများနှင့် သင်ခွင့်ပြုထားသူများထံမှ ဖုန်းခေါ်မှုများမှလွဲ၍ အခြားအသံများနှင့် တုန်ခါမှုများက သင့်ကို အနှောင့်အယှက်ပြုမည် မဟုတ်ပါ။ သို့သော်လည်း သီချင်း၊ ဗီဒီယိုနှင့် ဂိမ်းများအပါအဝင် သင်ကရွေးချယ်ဖွင့်ထားသည့် အရာတိုင်း၏ အသံကိုမူ ကြားနေရဆဲဖြစ်ပါလိမ့်မည်။" @@ -573,8 +574,7 @@ "စကားဝိုင်းများ" "အသံတိတ် အကြောင်းကြားချက်များအားလုံးကို ရှင်းလင်းရန်" "အကြောင်းကြားချက်များကို \'မနှောင့်ယှက်ရ\' က ခေတ္တရပ်ထားသည်" - - + "{count,plural,offset:1 =0{အကြောင်းကြားချက် မရှိပါ}=1{{mode} က ခဏရပ်ထားသော အကြောင်းကြားချက်များ}=2{{mode} နှင့် အခြားမုဒ်တစ်ခုက ခဏရပ်ထားသော အကြောင်းကြားချက်များ}other{{mode} နှင့် အခြားမုဒ် # ခုက ခဏရပ်ထားသော အကြောင်းကြားချက်များ}}" "ယခု စတင်ပါ" "အကြောင်းကြားချက် မရှိပါ" "အကြောင်းကြားချက်သစ် မရှိပါ" @@ -706,6 +706,7 @@ "သရုပ်ပြမုဒ် ပြရန်" "အီသာနက်" "နှိုးစက်" + "%1$s ဖွင့်ထားသည်" "Wallet" "သင့်ဖုန်းဖြင့် ပိုမိုမြန်ဆန်၊ ပိုမိုစိတ်ချရသော ဝယ်ယူမှုများ ပြုလုပ်ရန် စတင်သတ်မှတ်ပါ" "အားလုံးပြရန်" @@ -1405,26 +1406,38 @@ "တာ့ချ်ပက်လက်ဟန်များကို လေ့လာပါ" "သင်၏ ကီးဘုတ်နှင့် တာ့ချ်ပက်တို့ကိုသုံး၍ လမ်းညွှန်ခြင်း" "တာ့ချ်ပက်လက်ဟန်များ၊ လက်ကွက်ဖြတ်လမ်းများ စသည်တို့ကို လေ့လာပါ" - "နောက်သို့ လက်ဟန်" - "ပင်မစာမျက်နှာ လက်ဟန်" + + + + "မကြာသေးမီကအက်ပ်များကို ကြည့်ရန်" "ပြီးပြီ" "ပြန်သွားရန်" - "နောက်ပြန်သွားရန် တာ့ချ်ပက်ပေါ်ရှိ မည်သည့်နေရာ၌မဆို လက်သုံးချောင်းဖြင့် ဘယ် (သို့) ညာသို့ ပွတ်ဆွဲပါ။\n\n၎င်းအတွက် လက်ကွက်ဖြတ်လမ်း Action + ESC ကိုလည်း သုံးနိုင်သည်။" - "တော်ပါပေသည်။" + + + + "နောက်သို့လက်ဟန် အပြီးသတ်လိုက်ပါပြီ" "ပင်မစာမျက်နှာသို့ သွားရန်" - "ပင်မစာမျက်နှာသို့ အချိန်မရွေးသွားရန် စခရင်အောက်ခြေမှ အပေါ်သို့ လက်သုံးချောင်းဖြင့် ပွတ်ဆွဲပါ။" - "ကောင်းသည်။" - "ပင်မစာမျက်နှာသို့သွားသည့် လက်ဟန် အပြီးသတ်လိုက်ပါပြီ။" + + + + + + "မကြာသေးမီကအက်ပ်များကို ကြည့်ခြင်း" - "သင့်တာ့ချ်ပက်တွင် လက်သုံးချောင်းဖြင့် အပေါ်သို့ပွတ်ဆွဲပြီး ဖိထားပါ။" + + "တော်ပါပေသည်။" "မကြာသေးမီကအက်ပ်များကို ကြည့်ခြင်းလက်ဟန် သင်ခန်းစာပြီးပါပြီ။" - "လုပ်ဆောင်ချက်ကီး" - "သင့်အက်ပ်များသုံးရန် ကီးဘုတ်ပေါ်ရှိ လုပ်ဆောင်ချက်ကီးကို နှိပ်ပါ။" - "ဂုဏ်ယူပါသည်။" - "လုပ်ဆောင်ချက်ကီး လက်ဟန် အပြီးသတ်လိုက်ပါပြီ။\n\nလုပ်ဆောင်ချက် + / သည် ရရှိနိုင်သော ဖြတ်လမ်းအားလုံးကို ပြသည်။" + + + + + + + + "ကီးဘုတ်နောက်မီး" "အဆင့် %2$d အနက် %1$d" "အိမ်ထိန်းချုပ်မှုများ" @@ -1436,6 +1449,7 @@ "သင့်အက်ပ်အားလုံးကြည့်ရန် ကီးဘုတ်ပေါ်ရှိ လုပ်ဆောင်ချက်ကီးကို နှိပ်ပါ" "အစားထိုးထားသည်" "ကြည့်ရန် ဖွင့်ပါ" + "အကြောင်းအရာအလိုက် ပညာရေး" "နောက်ပြန်သွားရန် သင့်တာ့ချ်ပက်ကို သုံးပါ" "လက်သုံးချောင်းဖြင့် ဘယ် (သို့) ညာသို့ ပွတ်ဆွဲပါ။ လက်ဟန်များ ပိုမိုလေ့လာရန် တို့ပါ။" "ပင်မစာမျက်နှာသို့ သွားရန် သင့်တာ့ချ်ပက်ကို သုံးပါ" diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 6ce048e4b673..f98799aade14 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -440,7 +440,8 @@ "På" "På • %1$s" "Av" - "Konfigurer" + + "Administrer i innstillingene" "{count,plural, =0{Ingen aktive moduser}=1{{mode} er aktiv}other{# moduser er aktive}}" "Du blir ikke forstyrret av lyder og vibrasjoner, med unntak av alarmer, påminnelser, aktiviteter og oppringere du angir. Du kan fremdeles høre alt du velger å spille av, for eksempel musikk, videoer og spill." @@ -573,8 +574,7 @@ "Samtaler" "Fjern alle lydløse varsler" "Varsler er satt på pause av «Ikke forstyrr»" - - + "{count,plural,offset:1 =0{Ingen varsler}=1{Varsler er satt på pause av {mode}}=2{Varsler er satt på pause av {mode} og én modus til}other{Varsler er satt på pause av {mode} og # moduser til}}" "Start nå" "Ingen varsler" "Ingen nye varsler" @@ -706,6 +706,8 @@ "Vis demo-modus" "Ethernet" "Alarm" + + "Wallet" "Legg til en betalingsmåte for å gjennomføre kjøp raskere og sikrere med telefonen" "Vis alle" @@ -1405,26 +1407,38 @@ "Lær deg styreflatebevegelser" "Naviger med tastaturet og styreflaten" "Lær deg styreflatebevegelser, hurtigtaster med mer" - "Tilbakebevegelse" - "Startskjermbevegelse" + + + + "Se nylige apper" "Ferdig" "Gå tilbake" - "For å gå tilbake, sveip mot høyre eller venstre med tre fingre hvor som helst på styreflaten.\n\nDu kan også gjøre dette med hurtigtasten Action + Esc." - "Bra jobbet!" + + + + "Du har fullført bevegelsen for å gå tilbake." "Gå til startsiden" - "For å gå til startskjermen, sveip opp med tre fingre fra bunnen av skjermen når som helst." - "Bra!" - "Du har fullført bevegelsen for å gå til startskjermen." + + + + + + "Se nylige apper" - "Sveip opp og hold med tre fingre på styreflaten." + + "Bra jobbet!" "Du har fullført bevegelsen for å se nylige apper." - "Handlingstast" - "For å åpne appene dine, trykk på handlingstasten på tastaturet." - "Gratulerer!" - "Du har fullført bevegelsen for handlingstasten.\n\nHandling + / viser alle tilgjengelige snarveier." + + + + + + + + "Bakgrunnslys for tastatur" "Nivå %1$d av %2$d" "Hjemkontroller" @@ -1436,6 +1450,7 @@ "For å se alle appene dine, trykk på handlingstasten på tastaturet" "Fjernet" "Lås opp for å se" + "Kontekstuell opplæring" "Bruk styreflaten for å gå tilbake" "Sveip til venstre eller høyre med tre fingre. Trykk for å lære flere bevegelser." "Bruk styreflaten for å gå til startsiden" diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 01419b45a82e..2c8778f8cec6 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -440,7 +440,8 @@ "अन छ" "अन छ • %1$s" "अफ छ" - "सेटअप गर्नुहोस्" + + "सेटिङमा गई व्यवस्थापन गर्नुहोस्" "{count,plural, =0{कुनै पनि सक्रिय छैन}=1{{mode} सक्रिय छ}other{# मोड सक्रिय छन्}}" "तपाईंलाई अलार्म, रिमाइन्डर, कार्यक्रम र तपाईंले निर्दिष्ट गर्नुभएका कलरहरू बाहेकका ध्वनि र कम्पनहरूले बाधा पुऱ्याउने छैनन्। तपाईंले अझै सङ्गीत, भिडियो र खेलहरू लगायत आफूले प्ले गर्न छनौट गरेका जुनसुकै कुरा सुन्न सक्नुहुनेछ।" @@ -573,8 +574,7 @@ "वार्तालापहरू" "सबै मौन सूचनाहरू हटाउनुहोस्" "बाधा नपुऱ्याउनुहोस् नामक मोडमार्फत पज पारिएका सूचनाहरू" - - + "{count,plural,offset:1 =0{कुनै पनि नोटिफिकेसन छैन}=1{{mode} ले गर्दा नोटिफिकेसनहरू पज गरिएका छन्}=2{{mode} र अन्य एक मोडले गर्दा नोटिफिकेसनहरू पज गरिएका छन्}other{{mode} र अन्य # वटा मोडले गर्दा नोटिफिकेसनहरू पज गरिएका छन्}}" "अहिले न" "कुनै सूचनाहरू छैनन्" "कुनै पनि नयाँ सूचना छैन" @@ -706,6 +706,7 @@ "डेमो मोड देखाउनुहोस्" "इथरनेट" "अलार्म" + "%1$s अन छ" "Wallet" "फोनमार्फत अझ छिटो र थप सुरक्षित तरिकाले खरिद गर्न भुक्तानी विधि सेटअप गर्नुहोस्" "सबै देखाउनुहोस्" @@ -1405,26 +1406,38 @@ "टचप्याड जेस्चर प्रयोग गर्न सिक्नुहोस्" "किबोर्ड र टचप्याड प्रयोग गरी नेभिगेट गर्नुहोस्" "टचप्याड जेस्चर, किबोर्डका सर्टकट र अन्य कुरा प्रयोग गर्न सिक्नुहोस्" - "ब्याक जेस्चर" - "होम जेस्चर" + + + + "हालसालै चलाइएका एपहरू हेर्नुहोस्" "सम्पन्न भयो" "पछाडि जानुहोस्" - "पछाडि जान तीन वटा औँलाले टचप्याडमा कतै छोएर बायाँ वा दायाँतिर स्वाइप गर्नुहोस्।\n\nतपाईं यसका लागि किबोर्डको सर्टकट \"Action + ESC\" पनि प्रयोग गर्न सक्नुहुन्छ।" - "अद्भुत!" + + + + "तपाईंले \'पछाडि जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो।" "होमपेजमा जानुहोस्" - "जुनसुकै बेला आफ्नो होम स्क्रिनमा जान स्क्रिनको फेदबाट तीन वटा औँलाले माथितिर स्वाइप गर्नुहोस्।" - "राम्रो!" - "तपाईंले \"होम स्क्रिनमा जानुहोस्\" नामक जेस्चर प्रयोग गर्ने तरिका सिक्नुभयो।" + + + + + + "हालसालै चलाइएका एपहरू हेर्नुहोस्" - "तीन वटा औँला प्रयोग गरी टचप्याडमा माथितिर स्वाइप गर्नुहोस् र होल्ड गर्नुहोस्।" + + "अद्भुत!" "तपाईंले हालसालै चलाइएका एपहरू हेर्ने जेस्चर पूरा गर्नुभएको छ।" - "एक्सन की" - "आफ्ना एपहरू एक्सेस गर्न आफ्नो किबोर्डमा भएको एक्सन की थिच्नुहोस्।" - "बधाई छ!" - "तपाईंले एक्सन की थिचेर गरिने जेस्चर प्रयोग गर्ने तरिका सिक्नुभयो।\n\nएक्सन + / थिच्नुभयो भने उपलब्ध सबै सर्टकटहरू देखिन्छन्।" + + + + + + + + "किबोर्ड ब्याकलाइट" "%2$d मध्ये %1$d औँ स्तर" "होम कन्ट्रोलहरू" @@ -1436,6 +1449,7 @@ "आफ्ना सबै एपहरू हेर्न आफ्नो किबोर्डमा भएको एक्सन की थिच्नुहोस्" "जानकारी लुकाउन सम्पादन गरिएको" "हेर्नका लागि अनलक गर्नुहोस्" + "सान्दर्भिक शिक्षा" "पछाडि जान आफ्नो टचप्याड प्रयोग गर्नुहोस्" "तिन वटा औँला प्रयोग गरी बायाँ वा दायाँतिर स्वाइप गर्नुहोस्। थप जेस्चर प्रयोग गर्ने तरिका सिक्न ट्याप गर्नुहोस्।" "होममा जान आफ्नो टचप्याड प्रयोग गर्नुहोस्" diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 325e361686c5..cd20a29329d7 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -440,7 +440,8 @@ "Aan" "Aan • %1$s" "Uit" - "Instellen" + + "Beheren via instellingen" "{count,plural, =0{Geen actieve modi}=1{{mode} is actief}other{# modi zijn actief}}" "Je wordt niet gestoord door geluiden en trillingen, behalve bij wekkers, herinneringen, afspraken en specifieke bellers die je selecteert. Je kunt nog steeds alles horen wat je wilt afspelen, waaronder muziek, video\'s en games." @@ -573,8 +574,7 @@ "Gesprekken" "Alle stille meldingen wissen" "Meldingen onderbroken door \'Niet storen\'" - - + "{count,plural,offset:1 =0{Geen meldingen}=1{Meldingen onderbroken door {mode}}=2{Meldingen onderbroken door {mode} en 1 andere modus}other{Meldingen onderbroken door {mode} en # andere modi}}" "Nu starten" "Geen meldingen" "Geen nieuwe meldingen" @@ -706,6 +706,7 @@ "Demomodus tonen" "Ethernet" "Wekker" + "%1$s staat aan" "Portemonnee" "Zorg dat je sneller en beter beveiligd aankopen kunt doen met je telefoon" "Alles tonen" @@ -1405,26 +1406,38 @@ "Leer touchpadgebaren die je kunt gebruiken" "Navigeren met je toetsenbord en touchpad" "Leer meer over onder andere touchpadgebaren en sneltoetsen" - "Gebaar voor terug" - "Gebaar voor startscherm" + + + + "Recente apps bekijken" "Klaar" "Terug" - "Als je wilt teruggaan, swipe je met 3 vingers naar links of rechts op de touchpad.\n\nJe kunt hiervoor ook de sneltoets Actie + ESC gebruiken." - "Goed bezig!" + + + + "Je weet nu hoe je het gebaar voor terug maakt." "Naar startscherm" - "Swipe met 3 vingers omhoog vanaf de onderkant van het scherm om naar het startscherm te gaan." - "Mooi zo!" - "Je weet nu hoe je het gebaar Naar startscherm maakt." + + + + + + "Recente apps bekijken" - "Swipe met 3 vingers omhoog en houd vast op je touchpad." + + "Goed werk!" "Je weet nu hoe je het gebaar Recente apps bekijken maakt." - "Actietoets" - "Als je toegang tot je apps wilt krijgen, druk je op de actietoets op je toetsenbord." - "Gefeliciteerd!" - "Je hebt het gebaar voor de actietoets uitgevoerd.\n\nActie + / toont alle beschikbare sneltoetsen." + + + + + + + + "Achtergrondverlichting van toetsenbord" "Niveau %1$d van %2$d" "Bediening voor in huis" @@ -1436,6 +1449,7 @@ "Als je alle apps wilt bekijken, druk je op de actietoets op je toetsenbord" "Verborgen" "Ontgrendelen om te bekijken" + "Contextuele educatie" "Je touchpad gebruiken om terug te gaan" "Swipe met 3 vingers naar links of rechts. Tik voor meer gebaren." "Je touchpad gebruiken om naar het startscherm te gaan" diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index e0349999acde..59e64621cbae 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -440,7 +440,8 @@ "ଚାଲୁ ଅଛି" "ଚାଲୁ ଅଛି • %1$s" "ବନ୍ଦ ଅଛି" - "ସେଟ ଅପ କରନ୍ତୁ" + + "ସେଟିଂସରେ ପରିଚାଳନା କରନ୍ତୁ" "{count,plural, =0{କୌଣସି ସକ୍ରିୟ ମୋଡ ନାହିଁ}=1{{mode} ସକ୍ରିୟ ଅଛି}other{# ମୋଡ ସକ୍ରିୟ ଅଛି}}" "ଆଲାର୍ମ, ରିମାଇଣ୍ଡର୍‌, ଇଭେଣ୍ଟ ଏବଂ ଆପଣ ନିର୍ଦ୍ଦିଷ୍ଟ କରିଥିବା କଲର୍‌ଙ୍କ ବ୍ୟତୀତ ଆପଣଙ୍କ ଧ୍ୟାନ ଅନ୍ୟ କୌଣସି ଧ୍ୱନୀ ଏବଂ ଭାଇବ୍ରେଶନ୍‌ରେ ଆକର୍ଷଣ କରାଯିବନାହିଁ। ମ୍ୟୁଜିକ୍‍, ଭିଡିଓ ଏବଂ ଗେମ୍‌ ସମେତ ନିଜେ ଚଲାଇବାକୁ ବାଛିଥିବା ଅନ୍ୟ ସବୁକିଛି ଆପଣ ଶୁଣିପାରିବେ।" @@ -573,8 +574,7 @@ "ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ" "ସମସ୍ତ ନୀରବ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଖାଲି କରନ୍ତୁ" "\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ବିକଳ୍ପ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତି ପଜ୍‍ ହୋଇଛି" - - + "{count,plural,offset:1 =0{କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ}=1{{mode} ଦ୍ୱାରା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବିରତ କରାଯାଇଛି}=2{{mode} ଏବଂ ଅନ୍ୟ ଏକ ମୋଡ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବିରତ କରାଯାଇଛି}other{{mode} ଏବଂ ଅନ୍ୟ # ମୋଡ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବିରତ କରାଯାଇଛି}}" "ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ" "କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ" "କୌଣସି ନୂଆ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ନାହିଁ" @@ -706,6 +706,8 @@ "ଡେମୋ ମୋଡ୍‍ ଦେଖାନ୍ତୁ" "ଇଥରନେଟ୍‌" "ଆଲାରାମ" + + "ୱାଲେଟ୍" "ଆପଣଙ୍କ ଫୋନ୍ ମାଧ୍ୟମରେ ଆହୁରି ଶୀଘ୍ର, ଅଧିକ ସୁରକ୍ଷିତ କ୍ରୟ କରିବା ପାଇଁ ସେଟ୍ ଅପ୍ କରନ୍ତୁ" "ସବୁ ଦେଖାନ୍ତୁ" @@ -1405,26 +1407,38 @@ "ଟଚପେଡର ଜେଶ୍ଚରଗୁଡ଼ିକ ବିଷୟରେ ଜାଣନ୍ତୁ" "ଆପଣଙ୍କ କୀବୋର୍ଡ ଏବଂ ଟଚପେଡ ବ୍ୟବହାର କରି ନାଭିଗେଟ କରନ୍ତୁ" "ଟଚପେଡ ଜେଶ୍ଚର, କୀବୋର୍ଡ ସର୍ଟକଟ ଏବଂ ଆହୁରି ଅନେକ କିଛି ବିଷୟରେ ଜାଣନ୍ତୁ" - "ବେକ ଜେଶ୍ଚର" - "ହୋମ ଜେଶ୍ଚର" + + + + "ବର୍ତ୍ତମାନର ଆପ୍ସ ଭ୍ୟୁ କରନ୍ତୁ" "ହୋଇଗଲା" "ପଛକୁ ଫେରନ୍ତୁ" - "ପଛକୁ ଫେରିବା ପାଇଁ ଯେ କୌଣସି ସ୍ଥାନରେ ତିନି ଆଙ୍ଗୁଠି ବ୍ୟବହାର କରି ବାମ କିମ୍ବା ଡାହାଣକୁ ସ୍ୱାଇପ କରନ୍ତୁ।\n\nଏଥିପାଇଁ ଆପଣ କୀବୋର୍ଡ ସର୍ଟକଟ ଆକ୍ସନ + ESC ମଧ୍ୟ ବ୍ୟବହାର କରିପାରିବେ।" - "ବଢ଼ିଆ କାମ!" + + + + "ଆପଣ \'ପଛକୁ ଫେରନ୍ତୁ\' ଜେଶ୍ଚର ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।" "ହୋମକୁ ଯାଆନ୍ତୁ" - "ଯେ କୌଣସି ସମୟରେ ଆପଣଙ୍କ ହୋମ ସ୍କ୍ରିନକୁ ଯିବା ପାଇଁ ଆପଣଙ୍କ ସ୍କିନର ତଳୁ ତିନୋଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ।" - "ବଢ଼ିଆ!" - "ଆପଣ \'ହୋମକୁ ଯାଆନ୍ତୁ\' ଜେଶ୍ଚର ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।" + + + + + + "ବର୍ତ୍ତମାନର ଆପ୍ସ ଭ୍ୟୁ କରନ୍ତୁ" - "ଆପଣଙ୍କ ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠିକୁ ବ୍ୟବହାର କରି ଉପରକୁ ସ୍ୱାଇପ କରି ଧରି ରଖନ୍ତୁ।" + + "ବଢ଼ିଆ କାମ!" "ଆପଣ ବର୍ତ୍ତମାନର ଆପ୍ସ ଜେଶ୍ଚରକୁ ଭ୍ୟୁ କରିବା ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।" - "ଆକ୍ସନ କୀ" - "ଆପଣଙ୍କ ଆପ୍ସ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପଣଙ୍କର କୀବୋର୍ଡରେ ଆକ୍ସନ କୀ\'କୁ ଦବାନ୍ତୁ।" - "ଅଭିନନ୍ଦନ!" - "ଆପଣ ଆକ୍ସନ କୀ ଜେଶ୍ଚରକୁ ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।\n\nଆକ୍ସନ + / ଆପଣଙ୍କ ପାଖରେ ଉପଲବ୍ଧ ଥିବା ସମସ୍ତ ସଟକର୍ଟକୁ ଦେଖାଇଥାଏ।" + + + + + + + + "କୀବୋର୍ଡ ବେକଲାଇଟ" "%2$dରୁ %1$d ନମ୍ବର ଲେଭେଲ" "ହୋମ କଣ୍ଟ୍ରୋଲ୍ସ" @@ -1436,6 +1450,7 @@ "ଆପଣଙ୍କ ସମସ୍ତ ଆପ୍ସ ଭ୍ୟୁ କରିବା ପାଇଁ ଆପଣଙ୍କ କୀବୋର୍ଡରେ ଆକ୍ସନ କୀ\'କୁ ଦବାନ୍ତୁ" "ଲୁଚା ଯାଇଥିବା" "ଭ୍ୟୁ କରିବାକୁ ଅନଲକ କରନ୍ତୁ" + "ପ୍ରାସଙ୍ଗିକ ଶିକ୍ଷା" "ପଛକୁ ଫେରିବା ପାଇଁ ଆପଣଙ୍କ ଟଚପେଡକୁ ବ୍ୟବହାର କରନ୍ତୁ" "ତିନୋଟି ଆଙ୍ଗୁଠିରେ ବାମ ବା ଡାହାଣକୁ ସ୍ୱାଇପ କରନ୍ତୁ। ଜେଶ୍ଚରଗୁଡ଼ିକ ବିଷୟରେ ଅଧିକ ଜାଣିବାକୁ ଟାପ କରନ୍ତୁ।" "ହୋମକୁ ଯିବା ପାଇଁ ଆପଣଙ୍କ ଟଚପେଡ ବ୍ୟବହାର କରନ୍ତୁ" diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 9659930f23c9..4c6697d39f81 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -440,7 +440,8 @@ "ਚਾਲੂ" "%1$s • \'ਤੇ" "ਬੰਦ" - "ਸੈੱਟਅੱਪ ਕਰੋ" + + "ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਪ੍ਰਬੰਧਨ ਕਰੋ" "{count,plural, =0{ਕੋਈ ਕਿਰਿਆਸ਼ੀਲ ਮੋਡ ਨਹੀਂ ਹੈ}=1{{mode} ਕਿਰਿਆਸ਼ੀਲ ਹੈ}other{# ਮੋਡ ਕਿਰਿਆਸ਼ੀਲ ਹਨ}}" "ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟਾਂ ਤੁਹਾਨੂੰ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕਰਨਗੀਆਂ, ਸਿਵਾਏ ਅਲਾਰਮਾਂ, ਯਾਦ-ਦਹਾਨੀਆਂ, ਵਰਤਾਰਿਆਂ, ਅਤੇ ਤੁਹਾਡੇ ਵੱਲੋਂ ਨਿਰਧਾਰਤ ਕੀਤੇ ਕਾਲਰਾਂ ਦੀ ਸੂਰਤ ਵਿੱਚ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਸੰਗੀਤ, ਵੀਡੀਓ ਅਤੇ ਗੇਮਾਂ ਸਮੇਤ ਆਪਣੀ ਚੋਣ ਅਨੁਸਾਰ ਕੁਝ ਵੀ ਸੁਣ ਸਕਦੇ ਹੋ।" @@ -573,8 +574,7 @@ "ਗੱਲਾਂਬਾਤਾਂ" "ਸਾਰੀਆਂ ਸ਼ਾਂਤ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ" "\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ" - - + "{count,plural,offset:1 =0{ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ ਹੈ}=1{{mode} ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ}=2{{mode} ਅਤੇ ਇੱਕ ਹੋਰ ਮੋਡ ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ}other{{mode} ਅਤੇ # ਹੋਰ ਮੋਡਾਂ ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ}}" "ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ" "ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ" "ਕੋਈ ਨਵੀਂ ਸੂਚਨਾ ਨਹੀਂ ਹੈ" @@ -706,6 +706,7 @@ "ਡੈਮੋ ਮੋਡ ਦੇਖੋ" "ਈਥਰਨੈਟ" "ਅਲਾਰਮ" + "%1$s ਚਾਲੂ ਹੈ" "Wallet" "ਆਪਣੇ ਫ਼ੋਨ ਨਾਲ ਜ਼ਿਆਦਾ ਤੇਜ਼ ਅਤੇ ਜ਼ਿਆਦਾ ਸੁਰੱਖਿਅਤ ਖਰੀਦਾਂ ਕਰਨ ਲਈ ਸੈੱਟਅੱਪ ਕਰੋ" "ਸਭ ਦਿਖਾਓ" @@ -1405,26 +1406,38 @@ "ਟੱਚਪੈਡ ਇਸ਼ਾਰਿਆਂ ਬਾਰੇ ਜਾਣੋ" "ਆਪਣੇ ਕੀ-ਬੋਰਡ ਅਤੇ ਟੱਚਪੈਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ" "ਟੱਚਪੈਡ ਇਸ਼ਾਰੇ, ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ ਬਾਰੇ ਜਾਣੋ" - "ਪਿੱਛੇ ਜਾਣ ਦਾ ਇਸ਼ਾਰਾ" - "ਹੋਮ \'ਤੇ ਜਾਣ ਦਾ ਇਸ਼ਾਰਾ" + + + + "ਹਾਲੀਆ ਐਪਾਂ ਦੇਖੋ" "ਹੋ ਗਿਆ" "ਵਾਪਸ ਜਾਓ" - "ਵਾਪਸ ਜਾਣ ਲਈ, ਟੱਚਪੈਡ \'ਤੇ ਕਿਤੇ ਵੀ ਤਿੰਨ ਉਂਗਲਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਖੱਬੇ ਜਾਂ ਸੱਜੇ ਪਾਸੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ।\n\nਤੁਸੀਂ ਇਸ ਲਈ ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ Action + ESC ਦੀ ਵਰਤੋਂ ਵੀ ਕਰ ਸਕਦੇ ਹੋ।" - "ਬਹੁਤ ਵਧੀਆ!" + + + + "ਤੁਸੀਂ \'ਵਾਪਸ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ।" "ਹੋਮ \'ਤੇ ਜਾਓ" - "ਕਿਸੇ ਵੀ ਸਮੇਂ ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਜਾਣ ਲਈ, ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ।" - "ਵਧੀਆ!" - "ਤੁਸੀਂ \'ਹੋਮ \'ਤੇ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ।" + + + + + + "ਹਾਲੀਆ ਐਪਾਂ ਦੇਖੋ" - "ਆਪਣੇ ਟੱਚਪੈਡ \'ਤੇ ਤਿੰਨ ਉਂਗਲਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰ ਕੇ ਦਬਾਈ ਰੱਖੋ।" + + "ਬਹੁਤ ਵਧੀਆ!" "ਤੁਸੀਂ \'ਹਾਲੀਆ ਐਪਾਂ ਦੇਖੋ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ ਹੈ।" - "ਕਾਰਵਾਈ ਕੁੰਜੀ" - "ਆਪਣੀਆਂ ਐਪਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਲਈ, ਆਪਣੇ ਕੀ-ਬੋਰਡ \'ਤੇ ਕਾਰਵਾਈ ਕੁੰਜੀ ਨੂੰ ਦਬਾਓ।" - "ਵਧਾਈਆਂ!" - "ਤੁਸੀਂ \'ਕਾਰਵਾਈ ਕੁੰਜੀ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ।\n\nਕਾਰਵਾਈ ਬਟਨ ਅਤੇ / ਨੂੰ ਇਕੱਠੇ ਦਬਾਉਣ \'ਤੇ, ਤੁਹਾਡੇ ਕੋਲ ਉਪਲਬਧ ਸਾਰੇ ਸ਼ਾਰਟਕੱਟ ਦਿਖਦੇ ਹਨ।" + + + + + + + + "ਕੀ-ਬੋਰਡ ਬੈਕਲਾਈਟ" "%2$d ਵਿੱਚੋਂ %1$d ਪੱਧਰ" "ਹੋਮ ਕੰਟਰੋਲ" @@ -1436,6 +1449,7 @@ "ਆਪਣੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਨੂੰ ਦੇਖਣ ਲਈ, ਆਪਣੇ ਕੀ-ਬੋਰਡ \'ਤੇ ਕਾਰਵਾਈ ਕੁੰਜੀ ਨੂੰ ਦਬਾਓ" "ਅਸਪਸ਼ਟ ਬਣਾਇਆ ਗਿਆ" "ਦੇਖਣ ਲਈ ਅਣਲਾਕ ਕਰੋ" + "ਸੰਦਰਭੀ ਸਿੱਖਿਆ" "ਪਿੱਛੇ ਜਾਣ ਲਈ ਆਪਣੇ ਟੱਚਪੈਡ ਦੀ ਵਰਤੋਂ ਕਰੋ" "ਤਿੰਨ ਉਂਗਲਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਖੱਬੇ ਜਾਂ ਸੱਜੇ ਪਾਸੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ। ਹੋਰ ਇਸ਼ਾਰਿਆਂ ਨੂੰ ਜਾਣਨ ਲਈ ਟੈਪ ਕਰੋ।" "ਹੋਮ \'ਤੇ ਜਾਣ ਲਈ ਆਪਣੇ ਟੱਚਪੈਡ ਦੀ ਵਰਤੋਂ ਕਰੋ" diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 9c97423fccc7..f4efe0b5a985 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -440,7 +440,8 @@ "Wł." "Włączone • %1$s" "Wył." - "Skonfiguruj" + + "Zarządzaj w ustawieniach" "{count,plural, =0{Brak aktywnych trybów}=1{Tryb {mode} jest aktywny}few{# tryby są aktywne}many{# trybów jest aktywnych}other{# trybu jest aktywne}}" "Nie będą Cię niepokoić żadne dźwięki ani wibracje z wyjątkiem alarmów, przypomnień, wydarzeń i połączeń od wybranych osób. Będziesz słyszeć wszystkie odtwarzane treści, takie jak muzyka, filmy czy gry." @@ -573,8 +574,7 @@ "Rozmowy" "Usuń wszystkie ciche powiadomienia" "Powiadomienia wstrzymane przez tryb Nie przeszkadzać" - - + "{count,plural,offset:1 =0{Brak powiadomień}=1{Powiadomienia są wstrzymane przez tryb {mode}}=2{Powiadomienia są wstrzymane przez tryb {mode} i 1 inny tryb}few{Powiadomienia są wstrzymane przez tryb {mode} i # inne tryby}many{Powiadomienia są wstrzymane przez tryb {mode} i # innych trybów}other{Powiadomienia są wstrzymane przez tryb {mode} i # innego trybu}}" "Rozpocznij teraz" "Brak powiadomień" "Brak nowych powiadomień" @@ -706,6 +706,7 @@ "Pokaż tryb demonstracyjny" "Ethernet" "Alarm" + "Aplikacja %1$s jest włączona" "Portfel" "Skonfiguruj formę płatności, aby szybciej i bezpieczniej płacić telefonem za zakupy" "Pokaż wszystko" @@ -1405,26 +1406,38 @@ "Poznaj gesty na touchpada" "Nawiguj za pomocą klawiatury i touchpada" "Poznaj gesty na touchpada, skróty klawiszowe i inne funkcje" - "Gest przejścia wstecz" - "Gest przejścia na ekran główny" + + + + "Wyświetlanie ostatnich aplikacji" "Gotowe" "Wróć" - "Aby przejść wstecz, przesuń 3 palcami w lewo lub w prawo w dowolnym miejscu touchpada.\n\nMożesz też użyć do tego skrótu klawiszowego Action + ESC." - "Brawo!" + + + + "Gest przejścia wstecz został opanowany." "Otwórz stronę główną" - "Aby w dowolnym momencie wyświetlić ekran główny, przesuń od dołu ekranu w górę 3 palcami." - "Super!" - "Gest przechodzenia na ekran główny został opanowany." + + + + + + "Wyświetlanie ostatnich aplikacji" - "Przesuń w górę za pomocą 3 palców na touchpadzie i przytrzymaj." + + "Brawo!" "Znasz już gest wyświetlania ostatnio używanych aplikacji." - "Klawisz działania" - "Aby uzyskać dostęp do aplikacji, naciśnij klawisz działania na klawiaturze." - "Gratulacje!" - "Gest klawisza działania został opanowany.\n\nKlawisz działania + / pokazuje wszystkie dostępne skróty." + + + + + + + + "Podświetlenie klawiatury" "Poziom %1$d z %2$d" "Sterowanie domem" @@ -1436,6 +1449,7 @@ "Aby wyświetlić wszystkie swoje aplikacje, naciśnij klawisz działania na klawiaturze" "Usunięto" "Odblokuj, aby zobaczyć" + "Edukacja kontekstowa" "Przechodzenie wstecz za pomocą touchpada" "Przesuń w prawo lub lewo za pomocą 3 palców. Kliknij, aby poznać więcej gestów." "Przechodzenie do ekranu głównego za pomocą touchpada" diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 399523e1aba2..b27242248da2 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -440,7 +440,8 @@ "Ativado" "Ativado • %1$s" "Desativado" - "Configurar" + + "Gerenciar nas configurações" "{count,plural, =0{Nenhum modo ativo}=1{{mode} está ativo}one{# modo está ativo}many{# de modos estão ativos}other{# modos estão ativos}}" "Você não será perturbado por sons e vibrações, exceto alarmes, lembretes, eventos e chamadas de pessoas especificadas. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos." @@ -573,8 +574,7 @@ "Conversas" "Apagar todas as notificações silenciosas" "Notificações pausadas pelo modo \"Não perturbe\"" - - + "{count,plural,offset:1 =0{Sem notificações}=1{Notificações pausadas pelo modo {mode}}=2{Notificações pausadas por {mode} e mais um modo}one{Notificações pausadas por {mode} e mais # modo}many{Notificações pausadas por {mode} e mais # de modos}other{Notificações pausadas por {mode} e mais # modos}}" "Iniciar agora" "Sem notificações" "Nenhuma notificação nova" @@ -706,6 +706,8 @@ "Mostrar modo de demonstração" "Ethernet" "Alarme" + + "Carteira" "Prepare tudo para fazer compras mais rápidas e seguras com seu smartphone" "Mostrar tudo" @@ -1405,26 +1407,38 @@ "Aprenda gestos do touchpad" "Navegue usando o teclado e o touchpad" "Aprenda gestos do touchpad, atalhos do teclado e muito mais" - "Gesto de volta" - "Gesto de início" + + + + "Ver os apps recentes" "Concluído" "Voltar" - "Para voltar, deslize para a esquerda ou direita usando 3 dedos em qualquer lugar do touchpad.\n\nVocê também pode usar o atalho de teclado Ação + ESC." - "Muito bem!" + + + + "Você concluiu o gesto para voltar." "Ir para a página inicial" - "Para acessar sua tela inicial a qualquer momento, deslize de baixo para cima na tela com três dedos." - "Legal!" - "Você concluiu o gesto para acessar a tela inicial." + + + + + + "Ver os apps recentes" - "Deslize para cima e pressione com 3 dedos no touchpad." + + "Muito bem!" "Você concluiu o gesto para ver os apps recentes." - "Tecla de ação" - "Para acessar os apps, pressione a tecla de ação no teclado." - "Parabéns!" - "Você concluiu o gesto da tecla de ação.\n\nA tecla de ação + / mostra todos os atalhos disponíveis." + + + + + + + + "Luz de fundo do teclado" "Nível %1$d de %2$d" "Automação residencial" @@ -1436,8 +1450,7 @@ "Para ver todos os apps, pressione a tecla de ação no teclado" "Encoberto" "Desbloquear para visualizar" - - + "Educação contextual" "Use o touchpad para voltar" "Deslize para a esquerda ou direita usando três dedos. Toque para aprender outros gestos." "Use o touchpad para acessar a tela inicial" diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index e87564d915fc..cca6d7234a21 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -440,7 +440,8 @@ "Ativado" "Ativado • %1$s" "Desativado" - "Configurar" + + "Gerir nas definições" "{count,plural, =0{Nenhum modo ativo}=1{{mode} está ativo}many{# modos estão ativos}other{# modos estão ativos}}" "Não é incomodado por sons e vibrações, exceto de alarmes, lembretes, eventos e autores de chamadas que especificar. Continua a ouvir tudo o que optar por reproduzir, incluindo música, vídeos e jogos." @@ -573,8 +574,7 @@ "Conversas" "Limpar todas as notificações silenciosas" "Notificações colocadas em pausa pelo modo Não incomodar." - - + "{count,plural,offset:1 =0{Sem notificações}=1{Notificações pausadas pelo modo {mode}}=2{Notificações pausadas pelo modo {mode} e mais um modo}many{Notificações pausadas pelo modo {mode} e mais # modos}other{Notificações pausadas pelo modo {mode} e mais # modos}}" "Começar agora" "Sem notificações" "Não existem novas notificações" @@ -706,6 +706,7 @@ "Mostrar modo de demonstração" "Ethernet" "Alarme" + "O modo %1$s está ativado" "Carteira" "Configure para efetuar pagamentos mais rápidos e seguros com o seu telemóvel" "Mostrar tudo" @@ -1405,26 +1406,38 @@ "Aprenda gestos do touchpad" "Navegue com o teclado e o touchpad" "Aprenda gestos do touchpad, atalhos de teclado e muito mais" - "Gesto para retroceder" - "Gesto para aceder ao ecrã principal" + + + + "Ver apps recentes" "Concluir" "Voltar" - "Para retroceder, deslize rapidamente para a esquerda ou direita com 3 dedos em qualquer parte do touchpad.\n\nPara o fazer, também pode usar o atalho de teclado Ação + ESC." - "Muito bem!" + + + + "Concluiu o gesto para retroceder." "Aceder ao ecrã principal" - "Para aceder ao ecrã principal em qualquer altura, deslize rapidamente com 3 dedos de baixo para cima no ecrã." - "Boa!" - "Concluiu o gesto para aceder ao ecrã principal." + + + + + + "Ver apps recentes" - "Deslize rapidamente para cima e mantenha premido com 3 dedos no touchpad." + + "Muito bem!" "Concluiu o gesto para ver as apps recentes." - "Tecla de ação" - "Para aceder às suas apps, prima a tecla de ação no teclado." - "Parabéns!" - "Concluiu o gesto da tecla de ação.\n\nA ação + / mostra todos os atalhos que tem disponíveis." + + + + + + + + "Luz do teclado" "Nível %1$d de %2$d" "Controlos domésticos" @@ -1436,6 +1449,7 @@ "Para ver todas as suas apps, prima a tecla de ação no teclado" "Revisto" "Desbloqueie para ver" + "Educação contextual" "Use o touchpad para retroceder" "Deslize rapidamente para a esquerda ou direita com 3 dedos. Toque para aprender mais gestos." "Use o touchpad para aceder ao ecrã principal" diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 5c9679d73d41..b27242248da2 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -440,7 +440,8 @@ "Ativado" "Ativado • %1$s" "Desativado" - "Configurar" + + "Gerenciar nas configurações" "{count,plural, =0{Nenhum modo ativo}=1{{mode} está ativo}one{# modo está ativo}many{# de modos estão ativos}other{# modos estão ativos}}" "Você não será perturbado por sons e vibrações, exceto alarmes, lembretes, eventos e chamadas de pessoas especificadas. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos." @@ -573,8 +574,7 @@ "Conversas" "Apagar todas as notificações silenciosas" "Notificações pausadas pelo modo \"Não perturbe\"" - - + "{count,plural,offset:1 =0{Sem notificações}=1{Notificações pausadas pelo modo {mode}}=2{Notificações pausadas por {mode} e mais um modo}one{Notificações pausadas por {mode} e mais # modo}many{Notificações pausadas por {mode} e mais # de modos}other{Notificações pausadas por {mode} e mais # modos}}" "Iniciar agora" "Sem notificações" "Nenhuma notificação nova" @@ -706,6 +706,8 @@ "Mostrar modo de demonstração" "Ethernet" "Alarme" + + "Carteira" "Prepare tudo para fazer compras mais rápidas e seguras com seu smartphone" "Mostrar tudo" @@ -1405,26 +1407,38 @@ "Aprenda gestos do touchpad" "Navegue usando o teclado e o touchpad" "Aprenda gestos do touchpad, atalhos do teclado e muito mais" - "Gesto de volta" - "Gesto de início" + + + + "Ver os apps recentes" "Concluído" "Voltar" - "Para voltar, deslize para a esquerda ou direita usando 3 dedos em qualquer lugar do touchpad.\n\nVocê também pode usar o atalho de teclado Ação + ESC." - "Muito bem!" + + + + "Você concluiu o gesto para voltar." "Ir para a página inicial" - "Para acessar sua tela inicial a qualquer momento, deslize de baixo para cima na tela com três dedos." - "Legal!" - "Você concluiu o gesto para acessar a tela inicial." + + + + + + "Ver os apps recentes" - "Deslize para cima e pressione com 3 dedos no touchpad." + + "Muito bem!" "Você concluiu o gesto para ver os apps recentes." - "Tecla de ação" - "Para acessar os apps, pressione a tecla de ação no teclado." - "Parabéns!" - "Você concluiu o gesto da tecla de ação.\n\nA tecla de ação + / mostra todos os atalhos disponíveis." + + + + + + + + "Luz de fundo do teclado" "Nível %1$d de %2$d" "Automação residencial" @@ -1436,6 +1450,7 @@ "Para ver todos os apps, pressione a tecla de ação no teclado" "Encoberto" "Desbloquear para visualizar" + "Educação contextual" "Use o touchpad para voltar" "Deslize para a esquerda ou direita usando três dedos. Toque para aprender outros gestos." "Use o touchpad para acessar a tela inicial" diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 8c764910f638..4222b3d9542a 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -440,7 +440,8 @@ "Activat" "Activat • %1$s" "Dezactivat" - "Configurează" + + "Gestionează în setări" "{count,plural, =0{Niciun mod activ}=1{{mode} este activ}few{# moduri sunt active}other{# de moduri sunt active}}" "Se vor anunța prin sunete și vibrații numai alarmele, mementourile, evenimentele și apelanții specificați de tine. Totuși, vei auzi tot ce alegi să redai, inclusiv muzică, videoclipuri și jocuri." @@ -573,8 +574,7 @@ "Conversații" "Șterge toate notificările silențioase" "Notificări întrerupte prin „Nu deranja”" - - + "{count,plural,offset:1 =0{Nicio notificare}=1{Notificările au fost întrerupte de {mode}}=2{Notificările au fost întrerupte de {mode} și de un alt mod}few{Notificările au fost întrerupte de {mode} și de alte # moduri}other{Notificările au fost întrerupte de {mode} și de alte # de moduri}}" "Începe acum" "Nicio notificare" "Nicio notificare nouă" @@ -706,6 +706,7 @@ "Afișează modul demonstrativ" "Ethernet" "Alarmă" + "%1$s este activ" "Portofel" "Configurează pentru a face achiziții mai rapide și mai sigure cu telefonul" "Afișează-le pe toate" @@ -1405,26 +1406,38 @@ "Învață gesturi pentru touchpad" "Navighează folosind tastatura și touchpadul" "Învață gesturi pentru touchpad, comenzi rapide de la tastatură și altele" - "Gestul Înapoi" - "Gestul Ecran de pornire" + + + + "Vezi aplicațiile recente" "Gata" "Înapoi" - "Pentru a reveni, glisează spre stânga sau spre dreapta cu trei degete oriunde pe touchpad.\n\nPoți folosi și comanda rapidă de la tastatură Action + ESC pentru aceasta." - "Excelent!" + + + + "Ai finalizat gestul Înapoi." "Înapoi la pagina de pornire" - "Pentru a accesa oricând ecranul de pornire, glisează în sus cu trei degete din partea de jos a ecranului" - "Bravo!" - "Ai finalizat gestul „accesează ecranul de pornire”." + + + + + + "Vezi aplicațiile recente" - "Glisează în sus și ține apăsat cu trei degete pe touchpad." + + "Excelent!" "Ai finalizat gestul pentru afișarea aplicațiilor recente." - "Tasta de acțiuni" - "Pentru a accesa aplicațiile, apasă tasta de acțiuni de pe tastatură." - "Felicitări!" - "Ai finalizat gestul cu tasta de acțiuni.\n\nAcțiune + / afișează toate comenzile rapide disponibile." + + + + + + + + "Iluminarea din spate a tastaturii" "Nivelul %1$d din %2$d" "Comenzi pentru locuință" @@ -1436,6 +1449,7 @@ "Ca să vezi toate aplicațiile, apasă tasta de acțiuni de pe tastatură" "Ascunsă" "Deblochează pentru a afișa" + "Educație contextuală" "Folosește-ți touchpadul ca să revii" "Glisează la stânga sau la dreapta cu trei degete. Atinge ca să înveți mai multe gesturi." "Folosește-ți touchpadul ca să accesezi pagina de pornire" diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index c5b6479a9b15..0340a1e563f9 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -440,7 +440,8 @@ "Включено" "Вкл. • %1$s" "Отключено" - "Настроить" + + "Открыть настройки" "{count,plural, =0{Включено 0 режимов}=1{Включен режим \"{mode}\"}one{Включен # режим}few{Включено # режима}many{Включено # режимов}other{Включено # режима}}" "Вас не будут отвлекать звуки и вибрация, за исключением сигналов будильника, напоминаний, уведомлений о мероприятиях и звонков от помеченных контактов. Вы по-прежнему будете слышать включенную вами музыку, видео, игры и т. д." @@ -573,8 +574,7 @@ "Разговоры" "Отклонить все беззвучные уведомления" "В режиме \"Не беспокоить\" уведомления заблокированы" - - + "{count,plural,offset:1 =0{Уведомлений нет}=1{Режим \"{mode}\" приостанавливает уведомления}=2{Режим \"{mode}\" и ещё один режим приостанавливают уведомления}one{Режим \"{mode}\" и ещё # режим приостанавливают уведомления}few{Режим \"{mode}\" и ещё # режима приостанавливают уведомления}many{Режим \"{mode}\" и ещё # режимов приостанавливают уведомления}other{Режим \"{mode}\" и ещё # режима приостанавливают уведомления}}" "Начать" "Нет уведомлений." "Новых уведомлений нет" @@ -706,6 +706,7 @@ "Перейти в демонстрационный режим" "Ethernet" "Будильник" + "%1$s: включено" "Кошелек" "Расплачивайтесь через телефон быстро и безопасно." "Показать все" @@ -1405,26 +1406,38 @@ "Узнайте о жестах на сенсорной панели." "Навигация с помощью клавиатуры и сенсорной панели" "Узнайте о жестах на сенсорной панели, сочетаниях клавиш и многом другом." - "Жест \"назад\"" - "Жест \"на главный экран\"" + + + + "Жест \"Просмотр недавних приложений\"" "Готово" "Назад" - "Чтобы вернуться назад, проведите по сенсорной панели тремя пальцами влево или вправо.\n\nВы также можете нажать клавишу действия + Esc." - "Отлично!" + + + + "Вы выполнили жест для перехода назад." "На главный экран" - "Чтобы перейти на главный экран, проведите снизу вверх тремя пальцами." - "Неплохо!" - "Вы выполнили жест для перехода на главный экран." + + + + + + "Просмотр недавних приложений" - "Проведите вверх по сенсорной панели тремя пальцами и удерживайте." + + "Отлично!" "Вы выполнили жест для просмотра недавних приложений." - "Клавиша действия" - "Чтобы перейти к приложениям, нажмите клавишу действия на клавиатуре." - "Готово!" - "Вы выполнили жест с клавишей действия.\n\nЧтобы посмотреть доступные сочетания, нажмите клавишу действия и \"/\"." + + + + + + + + "Подсветка клавиатуры" "Уровень %1$d из %2$d" "Управление домом" @@ -1436,6 +1449,7 @@ "Чтобы открыть список всех своих приложений, нажмите клавишу действия." "Скрыто" "Разблокируйте экран, чтобы посмотреть." + "Контекстные подсказки" "Используйте сенсорную панель, чтобы возвращаться назад" "Для этого проведите тремя пальцами влево или вправо. Нажмите, чтобы посмотреть другие жесты." "Используйте сенсорную панель, чтобы переходить на главный экран" diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index ff0c28dbbf26..93f72584eb2e 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -440,7 +440,8 @@ "ක්‍රියාත්මකයි" "ක්‍රියාත්මකයි • %1$s" "ක්‍රියාවිරහිතයි" - "පිහිටුවන්න" + + "සැකසීම් තුළ කළමනාකරණය කරන්න" "{count,plural, =0{සක්‍රිය ප්‍රකාර නොමැත}=1{{mode} සක්‍රියයි}one{ප්‍රකාර #ක් සක්‍රියයි}other{ප්‍රකාර #ක් සක්‍රියයි}}" "එලාම සිහිකැඳවීම්, සිදුවීම්, සහ ඔබ සඳහන් කළ අමතන්නන් හැර, ශබ්ද සහ කම්පනවලින් ඔබට බාධා නොවනු ඇත. සංගීතය, වීඩියෝ, සහ ක්‍රීඩා ඇතුළු ඔබ වාදනය කිරීමට තෝරන ලද සියලු දේ ඔබට තවම ඇසෙනු ඇත." @@ -573,8 +574,7 @@ "සංවාද" "සියලු නිහඬ දැනුම්දීම් හිස් කරන්න" "බාධා නොකරන්න මගින් විරාම කරන ලද දැනුම්දීම්" - - + "{count,plural,offset:1 =0{දැනුම්දීම් නැත}=1{{mode} මගින් දැනුම්දීම් විරාම කරන ලදි}=2{{mode} සහ තව එක ප්‍රකාරයක් මගින් දැනුම්දීම් විරාම කරන ලදි}one{{mode} සහ තව ප්‍රකාර #ක් මගින් දැනුම්දීම් විරාම කරන ලදි}other{{mode} සහ තව ප්‍රකාර #ක් මගින් දැනුම්දීම් විරාම කරන ලදි}}" "දැන් අරඹන්න" "දැනුම්දීම් නැත" "නව දැනුම්දීම් නැත" @@ -706,6 +706,8 @@ "ආදර්ශන ප්‍රකාරය පෙන්වන්න" "Ethernet" "එලාමය" + + "Wallet" "ඔබගේ දුරකථනය සමඟ වඩා වේගවත්, වඩා සුරක්ෂිත මිලදී ගැනීම් සිදු කිරීමට සූදානම් වන්න" "සියල්ල පෙන්වන්න" @@ -1405,26 +1407,38 @@ "ස්පර්ශක පුවරු අභිනයන් ඉගෙන ගන්න" "ඔබේ යතුරු පුවරුව සහ ස්පර්ශ පෑඩ් භාවිතයෙන් සංචාලනය කරන්න" "ස්පර්ශ පෑඩ් අභිනයන්, යතුරුපුවරු කෙටිමං සහ තවත් දේ ඉගෙන ගන්න" - "ආපසු අභිනය" - "නිවෙස් අභිනය" + + + + "මෑත යෙදුම් බලන්න" "නිමයි" "ආපස්සට යන්න" - "ආපසු යාමට, ස්පර්ශ පුවරුවවේ ඕනෑම තැනක ඇඟිලි තුනක් භාවිතයෙන් වමට හෝ දකුණට ස්වයිප් කරන්න.\n\nඔබට මේ සඳහා යතුරු පුවරු කෙටිමං ක්‍රියාව + ESC ද භාවිත කළ හැක." - "අනර්ඝ වැඩක්!" + + + + "ඔබ ආපසු යාමේ ඉංගිතය සම්පූර්ණ කරන ලදි." "මුල් පිටුවට යන්න" - "ඕනෑම වේලාවක ඔබේ මුල් තිරයට යාමට, ඔබේ තිරයේ පහළ සිට ඇඟිලි තුනකින් ඉහළට ස්වයිප් කරන්න." - "කදිමයි!" - "ඔබ මුල් පිටුවට යාමේ ඉංගිතය සම්පූර්ණ කළා." + + + + + + "මෑත යෙදුම් බලන්න" - "ඉහළට ස්වයිප් කර ඔබේ ස්පර්ශ පුවරුව මත ඇඟිලි තුනක් භාවිතා කර සිටින්න." + + "අනර්ඝ වැඩක්!" "ඔබ මෑත යෙදුම් ඉංගිත බැලීම සම්පූර්ණ කර ඇත." - "ක්‍රියා යතුර" - "ඔබේ යෙදුම් වෙත ප්‍රවේශ වීමට, ඔබේ යතුරු පුවරුවෙහි ක්‍රියා යතුර ඔබන්න." - "සුබ පැතුම්!" - "ඔබ ක්‍රියා යතුරු අභිනය සම්පූර්ණ කළා.\n\nක්‍රියාව + / ඔබට ලබා ගත හැකි සියලු කෙටිමං පෙන්වයි." + + + + + + + + "යතුරු පුවරු පසු ආලෝකය" "%2$dන් %1$d වැනි මට්ටම" "නිවෙස් පාලන" @@ -1436,6 +1450,7 @@ "ඔබේ සියලුම යෙදුම් බැලීමට, ඔබේ යතුරුපුවරුවේ ක්‍රියාකාරී යතුර ඔබන්න" "නැවත සකස් කරන ලද" "බැලීමට අගුළු හරින්න" + "සන්දර්භීය අධ්‍යාපනය" "ආපසු යාමට ඔබේ ස්පර්ශ පුවරුව භාවිත කරන්න" "ඇඟිලි තුනක් භාවිතයෙන් වමට හෝ දකුණට ස්වයිප් කරන්න. තව ඉංගිත දැන ගැනීමට තට්ටු කරන්න." "මුල් පිටුවට යාමට ඔබේ ස්පර්ශ පුවරුව භාවිත කරන්න" diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 16af11a26b94..e7c92634670f 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -440,7 +440,8 @@ "Zapnuté" "Zapnuté • %1$s" "Vypnuté" - "Nastaviť" + + "Správa v nastaveniach" "{count,plural, =0{Žiadne aktívne režimy}=1{{mode} je aktívny}few{# režimy sú aktívne}many{# modes are active}other{# režimov je aktívnych}}" "Nebudú vás vyrušovať zvuky ani vibrácie, iba budíky, pripomenutia, udalosti a volajúci, ktorých určíte. Budete naďalej počuť všetko, čo sa rozhodnete prehrať, ako napríklad hudbu, videá a hry." @@ -573,8 +574,7 @@ "Konverzácie" "Vymazať všetky tiché upozornenia" "Upozornenia sú pozastavené režimom bez vyrušení" - - + "{count,plural,offset:1 =0{Žiadne upozornenia}=1{Upozornenia boli pozastavené režimom {mode}}=2{Upozornenia boli pozastavené režimom {mode} a jedným ďalším}few{Upozornenia boli pozastavené režimom {mode} a # ďalšími}many{Notifications paused by {mode} and # other modes}other{Upozornenia boli pozastavené režimom {mode} a # ďalšími}}" "Spustiť" "Žiadne upozornenia" "Žiadne nové upozornenia" @@ -706,6 +706,7 @@ "Zobraziť režim ukážky" "Ethernet" "Budík" + "Režim %1$s je zapnutý" "Peňaženka" "Nastavte si všetko potrebné na rýchlejšie a bezpečnejšie nákupy telefónom" "Zobraziť všetko" @@ -1405,26 +1406,38 @@ "Naučte sa gestá touchpadu" "Prechádzajte pomocou klávesnice a touchpadu" "Naučte sa gestá touchpadu, klávesové skratky a ďalšie funkcie" - "Gesto prechodu späť" - "Gesto prechodu domov" + + + + "Zobrazenie nedávnych aplikácií" "Hotovo" "Prejsť späť" - "Ak chcete prejsť späť, potiahnite kdekoľvek na touchpade troma prstami doľava alebo doprava.\n\nMôžete použiť aj klávesovú skratku, teda akčný kláves + ESC." - "Skvelé!" + + + + "Dokončili ste gesto na prechod späť." "Prechod na plochu" - "Na plochu môžete kedykoľvek prejsť potiahnutím troma prstami zdola obrazovky." - "Výborne!" - "Dokončili ste gesto na prechod na plochu." + + + + + + "Zobrazenie nedávnych aplikácií" - "Potiahnite troma prstami na touchpade nahor a pridržte ich." + + "Skvelé!" "Dokončili ste gesto na zobrazenie nedávnych aplikácií." - "Akčný kláves" - "Ak chcete získať prístup k aplikáciám, stlačte na klávesnici akčný kláves." - "Blahoželáme!" - "Dokončili ste gesto akčného klávesa.\n\nStlačením kombinácie akčný kláves + / zobrazíte všetky skratky, ktoré máte k dispozícii" + + + + + + + + "Podsvietenie klávesnice" "%1$d. úroveň z %2$d" "Ovládanie domácnosti" @@ -1436,6 +1449,7 @@ "Ak si chcete zobraziť všetky aplikácie, stlačte na klávesnici akčný kláves" "Zamaskované" "Zobrazíte odomknutím" + "Kontextová náuka" "Prechádzajte späť pomocou touchpadu" "Potiahnite troma prstami doľava alebo doprava. Viac o gestách sa dozviete klepnutím." "Vráťte sa na plochu pomocou touchpadu" diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index e664810b82c0..701cdd1f1bfe 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -440,7 +440,7 @@ "Vklopljeno" "Vklopljeno • %1$s" "Izklopljeno" - "Nastavitev" + "Ni nastavljeno" "Upravljanje v nastavitvah" "{count,plural, =0{Ni aktivnih načinov}=1{Način {mode} je aktiven}one{# način je aktiven}two{# načina sta aktivna}few{# načini so aktivni}other{# načinov je aktivnih}}" "Ne bodo vas motili zvoki ali vibriranje, razen v primeru alarmov, opomnikov, dogodkov in klicateljev, ki jih določite. Še vedno pa boste slišali vse, kar se boste odločili predvajati, vključno z glasbo, videoposnetki in igrami." @@ -573,8 +573,7 @@ "Pogovori" "Brisanje vseh tihih obvestil" "Prikazovanje obvestil je začasno zaustavljeno z načinom »ne moti«" - - + "{count,plural,offset:1 =0{Ni obvestil}=1{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode}}=2{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še enim drugim načinom}one{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugim načinom}two{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugima načinoma}few{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugimi načini}other{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugimi načini}}" "Začni zdaj" "Ni obvestil" "Ni novih obvestil" @@ -706,6 +705,7 @@ "Prikaz predstavitvenega načina" "Ethernet" "Alarm" + "%1$s: Vklopljeno" "Denarnica" "Nastavite možnost hitrejšega in varnejšega plačevanja s telefonom." "Prikaži vse" @@ -1405,26 +1405,26 @@ "Učenje potez na sledilni ploščici" "Krmarjenje s tipkovnico in sledilno ploščico" "Učenje potez na sledilni ploščici, bližnjičnih tipk in drugega" - "Poteza za pomik nazaj" - "Poteza za začetni zaslon" + "Nazaj" + "Pojdi na začetni zaslon" "Ogled nedavnih aplikacij" "Končano" "Nazaj" - "Za pomik nazaj povlecite levo ali desno s tremi prsti kjer koli na sledilni ploščici.\n\nUporabite lahko tudi bližnjični tipki Action + ESC." - "Odlično!" + "Na sledilni ploščici s tremi prsti povlecite levo ali desno" + "Odlično!" "Izvedli ste potezo za pomik nazaj." "Pomik na začetni zaslon" - "Za pomik na začetni zaslon lahko kadar koli s tremi prsti povlečete navzgor z dna zaslona." - "Odlično!" - "Izvedli ste potezo za pomik na začetni zaslon." + "Na sledilni ploščici s tremi prsti povlecite navzgor" + "Odlično!" + "Izvedli ste potezo za pomik na začetni zaslon" "Ogled nedavnih aplikacij" - "Na sledilni ploščici s tremi prsti povlecite navzgor in pridržite." + "Na sledilni ploščici s tremi prsti povlecite navzgor in pridržite" "Odlično!" "Izvedli ste potezo za ogled nedavnih aplikacij." - "Tipka za dejanja" - "Za dostop do aplikacij pritisnite tipko za dejanja na tipkovnici." - "Čestitamo!" - "Izvedli ste potezo za tipko za dejanja.\n\nČe hkrati pritisnete tipko za dejanja in poševnico naprej »/«, bodo prikazane vse razpoložljive bližnjice." + "Ogled vseh aplikacij" + "Pritisnite tipko za dejanja na tipkovnici" + "Odlično!" + "Izvedli ste potezo za ogled vseh aplikacij" "Osvetlitev tipkovnice" "Stopnja %1$d od %2$d" "Kontrolniki za dom" @@ -1436,6 +1436,7 @@ "Za ogled vseh aplikacij pritisnite tipko za dejanja na tipkovnici" "Zakrito" "Odklenite za ogled" + "Kontekstualno izobraževanje" "Uporaba sledilne ploščice za pomik nazaj" "S tremi prsti povlecite levo ali desno. Dotaknite se, če želite spoznati več potez." "Uporaba sledilne ploščice za pomik na začetni zaslon" diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index e70629f20cc9..20f7e822a139 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -440,7 +440,8 @@ "Aktiv" "Aktiv • %1$s" "Joaktiv" - "Konfiguro" + + "Menaxho te cilësimet" "{count,plural, =0{Nuk ka modalitete aktive}=1{\"{mode}\" është aktiv}other{# modalitete janë aktive}}" "Nuk do të shqetësohesh nga tingujt dhe dridhjet, përveç alarmeve, alarmeve rikujtuese, ngjarjeve dhe telefonuesve që specifikon. Do të vazhdosh të dëgjosh çdo gjë që zgjedh të luash duke përfshirë muzikën, videot dhe lojërat." @@ -573,8 +574,7 @@ "Bisedat" "Pastro të gjitha njoftimet në heshtje" "Njoftimet janë vendosur në pauzë nga modaliteti \"Mos shqetëso\"" - - + "{count,plural,offset:1 =0{Asnjë njoftim}=1{Njoftimet u vendosën në pauzë nga {mode}}=2{Njoftimet u vendosën në pauzë nga {mode} dhe një modalitet tjetër}other{Njoftimet u vendosën në pauzë nga {mode} dhe # modalitete të tjera}}" "Fillo tani" "Asnjë njoftim" "Nuk ka njoftime të reja" @@ -706,6 +706,8 @@ "Shfaq modalitetin e demonstrimit" "Eternet" "Alarmi" + + "Portofoli" "Konfiguro për të kryer pagesa më të shpejta dhe më të sigurta përmes telefonit" "Shfaqi të gjitha" @@ -1405,26 +1407,38 @@ "Mëso gjestet e bllokut me prekje" "Navigo duke përdorur tastierën dhe bllokun me prekje" "Mëso gjestet e bllokut me prekje, shkurtoret e tastierës etj." - "Gjesti i kthimit prapa" - "Gjesti për të shkuar tek ekrani bazë" + + + + "Shiko aplikacionet e fundit" "U krye" "Kthehu prapa" - "Për t\'u kthyer, rrëshqit shpejt majtas ose djathtas duke përdorur tri gishta kudo në bllokun me prekje.\n\nPër ta bërë këtë, mund të përdorësh gjithashtu shkurtoren e tastierës \"Action + ESC\"." - "Punë e shkëlqyer!" + + + + "E ke përfunduar gjestin e kthimit prapa." "Shko tek ekrani bazë" - "Për të shkuar tek ekrani bazë në çdo kohë, rrëshqit shpejt lart me tre gishta nga fundi i ekranit." - "Bukur!" - "E ke përfunduar gjestin e kalimit tek ekrani bazë." + + + + + + "Shiko aplikacionet e fundit" - "Rrëshqit shpejt lart dhe mbaj shtypur me tre gishta në bllokun me prekje." + + "Punë e shkëlqyer!" "Përfundove gjestin për shikimin e aplikacioneve të fundit." - "Tasti i veprimit" - "Për t\'u qasur në aplikacionet e tua, shtyp tastin e veprimit në tastierë." - "Urime!" - "Ke përfunduar gjestin e tastit të veprimit.\n\nVeprimi + / shfaq të gjitha shkurtoret që janë të disponueshme për ty." + + + + + + + + "Drita e sfondit e tastierës" "Niveli: %1$d nga %2$d" "Kontrollet e shtëpisë" @@ -1436,6 +1450,7 @@ "Për të shikuar të gjitha aplikacionet, shtyp tastin e veprimit në tastierë" "Redaktuar" "Shkyçe për ta parë" + "Edukimi kontekstual" "Përdor bllokun me prekje për t\'u kthyer prapa" "Rrëshqit shpejt majtas ose djathtas duke përdorur tre gishta. Trokit për të mësuar më shumë gjeste." "Përdor bllokun me prekje për të shkuar tek ekrani bazë" diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 164b4aa246a9..f757cdcf1a6d 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -440,7 +440,8 @@ "Укључено" "Укљ. • %1$s" "Искључено" - "Подеси" + + "Управљајте у подешавањима" "{count,plural, =0{Нема активних режима}=1{Активан је {mode} режим}one{Активан је # режим}few{Активна су # режима}other{Активно је # режима}}" "Неће вас узнемиравати звукови и вибрације осим за аларме, подсетнике, догађаје и позиваоце које наведете. И даље ћете чути све што одаберете да пустите, укључујући музику, видео снимке и игре." @@ -573,8 +574,7 @@ "Конверзације" "Обришите сва нечујна обавештења" "Обавештења су паузирана режимом Не узнемиравај" - - + "{count,plural,offset:1 =0{Нема обавештења}=1{Обавештења је паузирао {mode}}=2{Обавештења су паузирали {mode} и још један режим}one{Обавештења су паузирали {mode} и још # режим}few{Обавештења су паузирали {mode} и још # режима}other{Обавештења су паузирали {mode} и још # режима}}" "Започни" "Нема обавештења" "Нема нових обавештења" @@ -706,6 +706,7 @@ "Прикажи режим демонстрације" "Етернет" "Аларм" + "%1$s: укључено" "Новчаник" "Обавите конфигурисање да бисте могли брже и сигурније да купујете помоћу телефона" "Прикажи све" @@ -1405,26 +1406,38 @@ "Научите покрете за тачпед" "Крећите се помоћу тастатуре и тачпeда" "Научите покрете за тачпед, тастерске пречице и друго" - "Покрет за враћање" - "Покрет за почетну страницу" + + + + "Прикажи недавно коришћене апликације" "Готово" "Назад" - "Да бисте се вратили, превуците улево са три прста било где на тачпеду.\n\nМожете да користите и тастерску пречицу Alt + ESC за ово." - "Одлично!" + + + + "Довршили сте покрет за повратак." "Иди на почетни екран" - "Да бисте отишли на почетни екран у било ком тренутку, превуците нагоре од дна екрана помоћу три прста." - "Свака част!" - "Довршили сте покрет за повратак на почетну страницу." + + + + + + "Прикажи недавно коришћене апликације" - "Превуците нагоре и задржите помоћу три прста на тачпеду." + + "Одлично!" "Довршили сте покрет за приказивање недавно коришћених апликација." - "Тастер радњи" - "Да бисте приступили апликацијама, притисните тастер радњи на тастатури." - "Честитамо!" - "Довршили сте покрет помоћу тастера радњи.\n\nРадња + / приказује све пречице које су вам доступне." + + + + + + + + "Позадинско осветљење тастатуре" "%1$d. ниво од %2$d" "Контроле за дом" @@ -1436,6 +1449,7 @@ "Да бисте погледали све апликације, притисните тастер радњи на тастатури" "Редиговано" "Откључајте за приказ" + "Контекстуално образовање" "Користите тачпед да бисте се вратили" "Превуците улево или удесно са три прста. Додирните да бисте видели више покрета." "Користите тачпед да бисте отишли на почетни екран" diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 3016e83464fd..c8ece1313c49 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -440,7 +440,7 @@ "På" "På • %1$s" "Av" - "Ställ in" + "Inte angivet" "Hantera i inställningarna" "{count,plural, =0{Inga aktiva lägen}=1{{mode} är aktivt}other{# lägen är aktiva}}" "Du blir inte störd av ljud och vibrationer, förutom från alarm, påminnelser, händelser och specifika samtal. Ljudet är fortfarande på för sådant du väljer att spela upp, till exempel musik, videor och spel." @@ -573,8 +573,7 @@ "Konversationer" "Rensa alla ljudlösa aviseringar" "Aviseringar har pausats via Stör ej" - - + "{count,plural,offset:1 =0{Inga aviseringar}=1{Aviseringar har pausats av {mode}}=2{Aviseringar har pausats av {mode} och ett annat läge}other{Aviseringar har pausats av {mode} och # andra lägen}}" "Starta nu" "Inga aviseringar" "Det finns inga nya aviseringar" @@ -706,6 +705,7 @@ "Visa demoläge" "Ethernet" "Alarm" + "%1$s är på" "Wallet" "Lägg till en betalningsmetod för att betala snabbare och säkrare med telefonen" "Visa alla" @@ -1405,26 +1405,26 @@ "Lär dig rörelser för styrplattan" "Navigera med tangentbordet och styrplattan" "Lär dig rörelser för styrplattan, kortkommandon med mera" - "Tillbaka-rörelse" - "Rörelse för att öppna startskärmen" + "Tillbaka" + "Återvänd till startsidan" "Se de senaste apparna" "Klar" "Tillbaka" - "Gå tillbaka genom att svepa åt vänster eller höger med tre fingrar var som helst på styrplattan.\n\nDu kan även använda kortkommandot Åtgärd + Esc." - "Bra jobbat!" + "Svep åt vänster eller höger med tre fingrar på styrplattan" + "Bra!" "Du är klar med rörelsen för att gå tillbaka." "Återvänd till startskärmen" - "Öppna startskärmen när som helst genom att svepa uppåt med tre fingrar från skärmens nederkant." - "Bra!" - "Du är klar med rörelsen för att öppna startskärmen." + "Svep uppåt med tre fingrar på styrplattan" + "Bra jobbat!" + "Du är klar med rörelsen för att öppna startskärmen" "Se de senaste apparna" - "Svep uppåt med tre fingrar på styrplattan och håll kvar." + "Svep uppåt med tre fingrar på styrplattan och håll kvar" "Bra jobbat!" "Du är klar med rörelsen för att se de senaste apparna." - "Åtgärdstangent" - "Tryck på åtgärdstangenten på tangentbordet för att komma åt dina appar." - "Grattis!" - "Du är klar med rörelsen med åtgärdstangenten.\n\nÅtgärd + / visar alla tillgängliga genvägar." + "Visa alla appar" + "Tryck på åtgärdstangenten på tangentbordet" + "Bra gjort!" + "Du är klar med rörelsen för att se alla apparna." "Bakgrundsbelysning för tangentbord" "Nivå %1$d av %2$d" "Hemstyrning" @@ -1436,6 +1436,7 @@ "Tryck på åtgärdstangenten på tangentbordet för att se alla appar" "Anonymiserad" "Lås upp för att visa" + "Kontextuell utbildning" "Använd styrplattan för att gå tillbaka" "Svep åt vänster eller höger med tre fingrar. Tryck för att lära dig fler rörelser." "Använd styrplattan för att gå till startskärmen" diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 45095dfcc0bc..17a88239b135 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -440,7 +440,8 @@ "Imewashwa" "Imewashwa • %1$s" "Imezimwa" - "Ratibu" + + "Dhibiti katika mipangilio" "{count,plural, =0{Hakuna hali zinazotumika}=1{Unatumia {mode}}other{Unatumia hali #}}" "Hutasumbuliwa na sauti na mitetemo, isipokuwa kengele, vikumbusho, matukio na simu zinazopigwa na watu uliobainisha. Bado utasikia chochote utakachochagua kucheza, ikiwa ni pamoja na muziki, video na michezo." @@ -573,8 +574,7 @@ "Mazungumzo" "Futa arifa zote zisizo na sauti" "Kipengele cha Usinisumbue kimesitisha arifa" - - + "{count,plural,offset:1 =0{Hakuna arifa}=1{Arifa zimesitishwa na {mode}}=2{Arifa zimesitishwa na {mode} na hali nyingine moja}other{Arifa zimesitishwa na {mode} na hali nyingine #}}" "Anza sasa" "Hakuna arifa" "Hakuna arifa mpya" @@ -706,6 +706,7 @@ "Onyesha hali ya onyesho" "Ethaneti" "Kengele" + "Umewasha %1$s" "Pochi" "Weka njia ya kulipa ili uweze kununua kwa njia salama na haraka zaidi ukitumia simu yako" "Onyesha zote" @@ -1405,26 +1406,38 @@ "Jifunze kuhusu miguso ya padi ya kugusa" "Kusogeza kwa kutumia kibodi na padi yako ya kugusa" "Jifunze kuhusu miguso ya padi ya kugusa, mikato ya kibodi na mengineyo" - "Ishara ya kurudi nyuma" - "Mguso wa kurudi kwenye skrini ya kwanza" + + + + "Angalia programu za hivi majuzi" "Nimemaliza" "Rudi nyuma" - "Telezesha vidole vitatu kushoto au kulia mahali popote kwenye padi ya kugusa ili urudi nyuma.\n\nUnaweza pia kutumia mikato ya kibodi ya Kitendo pamoja na ESC kutekeleza kitendo hiki." - "Kazi nzuri!" + + + + "Umekamilisha ishara ya kurudi nyuma." "Nenda kwenye skrini ya kwanza" - "Ili uende kwenye skrini ya kwanza wakati wowote, telezesha vidole vitatu juu kutoka sehemu ya chini ya skrini yako." - "Safi!" - "Umeweka ishara ya kwenda kwenye skrini ya kwanza." + + + + + + "Angalia programu za hivi majuzi" - "Telezesha vidole vitatu juu kisha ushikilie kwenye padi yako ya kugusa." + + "Kazi nzuri!" "Umekamilisha mafunzo ya mguso wa kuangalia programu za hivi majuzi." - "Kitufe cha vitendo" - "Bonyeza kitufe cha vitendo kwenye kibodi yako ili ufikie programu zako." - "Hongera!" - "Umekamilisha ishara ya kitufe cha vitendo.\n\nKitendo + / huonyesha njia zote za mkato zinazopatikana." + + + + + + + + "Mwanga chini ya kibodi" "Kiwango cha %1$d kati ya %2$d" "Dhibiti Vifaa Nyumbani" @@ -1436,6 +1449,7 @@ "Bonyeza kitufe cha vitendo kwenye kibodi yako ili uangalie programu zako zote" "Maandishi yameondolewa" "Fungua ili uone" + "Elimu inayolingana na muktadha" "Kutumia padi yako ya kugusa ili kurudi nyuma" "Telezesha vidole vitatu kulia au kushoto. Gusa ili upate maelezo kuhusu miguso zaidi." "Kutumia padi yako ya kugusa ili kurudi kwenye skrini ya kwanza" diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 3dd0c73170fd..2381e1b5cc0b 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -440,7 +440,8 @@ "இயக்கப்பட்டுள்ளது" "ஆன் • %1$s" "முடக்கப்பட்டுள்ளது" - "அமையுங்கள்" + + "அமைப்புகளில் நிர்வகியுங்கள்" "{count,plural, =0{செயலிலுள்ள பயன்முறைகள் எதுவுமில்லை}=1{{mode} செயலில் உள்ளது}other{# பயன்முறைகள் செயலில் உள்ளன}}" "அலாரங்கள், நினைவூட்டல்கள், நிகழ்வுகள் மற்றும் குறிப்பிட்ட அழைப்பாளர்களைத் தவிர்த்து, பிற ஒலிகள் மற்றும் அதிர்வுகளின் தொந்தரவு இருக்காது. எனினும், நீங்கள் எதையேனும் (இசை, வீடியோக்கள், கேம்ஸ் போன்றவை) ஒலிக்கும்படி தேர்ந்தெடுத்திருந்தால், அவை வழக்கம் போல் ஒலிக்கும்." @@ -573,8 +574,7 @@ "உரையாடல்கள்" "சைலன்ட் அறிவிப்புகள் அனைத்தையும் அழிக்கும்" "\'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தின் மூலம் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன" - - + "{count,plural,offset:1 =0{அறிவிப்புகள் இல்லை}=1{{mode} பயன்முறையால் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன}=2{{mode} மற்றும் வேறொரு பயன்முறையால் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன}other{{mode} மற்றும் வேறு # பயன்முறைகளால் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன}}" "இப்போது தொடங்கு" "அறிவிப்புகள் இல்லை" "புதிய அறிவிப்புகள் இல்லை" @@ -706,6 +706,7 @@ "டெமோ முறையைக் காட்டு" "ஈதர்நெட்" "அலாரம்" + "%1$s இயக்கப்பட்டுள்ளது" "Wallet" "மொபைல் மூலம் விரைவாகவும் பாதுகாப்பாகவும் பர்ச்சேஸ்கள் செய்ய பேமெண்ட் முறையை அமைக்கவும்" "அனைத்தையும் காட்டு" @@ -1405,26 +1406,38 @@ "டச்பேட் சைகைள் குறித்துத் தெரிந்துகொள்ளுங்கள்" "உங்கள் டச்பேட் மற்றும் கீபோர்டைப் பயன்படுத்திச் செல்லுதல்" "டச்பேட் சைகைகள், கீபோர்டு ஷார்ட்கட்கள் மற்றும் பலவற்றைத் தெரிந்துகொள்ளுங்கள்" - "பின்செல்வதற்கான சைகை" - "முகப்பிற்குச் செல்வதற்கான சைகை" + + + + "சமீபத்திய ஆப்ஸைக் காட்டுதல்" "முடிந்தது" "பின்செல்" - "பின்செல்ல, உங்கள் டச்பேடில் எங்கு வேண்டுமானாலும் இடது அல்லது வலதுபுறமாக மூன்று விரல்களால் ஸ்வைப் செய்யவும்.\n\nஇதற்கு நீங்கள் கீபோர்டு ஷார்ட்கட் செயல்பாடுகள் + Esc பட்டனையும் பயன்படுத்தலாம்." - "அருமை!" + + + + "பின்செல்வதற்கான சைகையை நிறைவுசெய்துவிட்டீர்கள்." "முகப்பிற்குச் செல்" - "எப்போது வேண்டுமானாலும் உங்கள் முகப்புத் திரைக்குச் செல்ல, மூன்று விரல்களால் திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்யவும்." - "அற்புதம்!" - "முகப்புக்குச் செல்வதற்கான சைகையை நிறைவுசெய்துவிட்டீர்கள்." + + + + + + "சமீபத்திய ஆப்ஸைக் காட்டுதல்" - "உங்கள் டச்பேடில் மூன்று விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடிக்கவும்." + + "அருமை!" "சமீபத்தில் பயன்படுத்திய ஆப்ஸுக்கான சைகை பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்." - "ஆக்‌ஷன் பட்டன்" - "ஆப்ஸை அணுக உங்கள் கீபோர்டில் உள்ள ஆக்‌ஷன் பட்டனை அழுத்துங்கள்." - "வாழ்த்துகள்!" - "ஆக்‌ஷன் பட்டன் சைகையை நிறைவுசெய்துவிட்டீர்கள்.\n\nAction + / உங்களுக்குக் கிடைக்கக்கூடிய எல்லா ஷார்ட்கட்களையும் காட்டும்." + + + + + + + + "கீபோர்டு பேக்லைட்" "நிலை, %2$d இல் %1$d" "ஹோம் கன்ட்ரோல்கள்" @@ -1436,6 +1449,7 @@ "அனைத்து ஆப்ஸையும் பார்க்க, உங்கள் கீபோர்டில் உள்ள ஆக்ஷன் பட்டனை அழுத்தவும்" "அர்த்தம் புரியாதபடி திருத்தப்பட்டது" "பார்ப்பதற்கு அன்லாக் செய்யவும்" + "சூழல் சார்ந்த கல்வி" "பின்செல்ல, உங்கள் டச்பேடைப் பயன்படுத்துங்கள்" "மூன்று விரல்களால் இடது அல்லது வலதுபுறம் ஸ்வைப் செய்யவும். சைகைகள் குறித்து மேலும் அறிய தட்டவும்." "முகப்புக்குச் செல்ல, உங்கள் டச்பேடைப் பயன்படுத்துங்கள்" diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 65de840488f6..fcc344bc84c6 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -21,7 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "సిస్టమ్ UI" "బ్యాటరీ సేవర్‌ను ఆన్ చేయాలా?" - "మీకు %s బ్యాటరీ మిగిలి ఉంది. బ్యాటరీ సేవర్ ముదురు రంగు రూపాన్ని ఆన్ చేస్తుంది, బ్యాక్‌గ్రౌండ్ యాక్టివిటీని పరిమితం చేస్తుంది, అలాగే నోటిఫికేషన్‌లను ఆలస్యంగా పంపిస్తుంది." + "బ్యాటరీ %s మిగిలి ఉంది. \"బ్యాటరీ సేవర్\" వల్ల డార్క్ థీమ్ ఆన్ అవుతుంది, బ్యాక్‌గ్రౌండ్ యాక్టివిటీ పరిమితం అవుతుంది, అలాగే నోటిఫికేషన్‌లు ఆలస్యంగా వస్తాయి." "బ్యాటరీ సేవర్ ముదురు రంగు రూపాన్ని ఆన్ చేస్తుంది, బ్యాక్‌గ్రౌండ్ యాక్టివిటీని పరిమితం చేస్తుంది, అలాగే నోటిఫికేషన్‌లను ఆలస్యంగా పంపిస్తుంది." "%s మిగిలి ఉంది" "USB ద్వారా ఛార్జ్ చేయలేరు" @@ -440,7 +440,8 @@ "ఆన్‌లో ఉంది" "ఆన్ • %1$s" "ఆఫ్‌లో ఉంది" - "సెటప్ చేయండి" + + "సెట్టింగ్‌లలో మేనేజ్ చేయండి" "{count,plural, =0{మోడ్స్ ఏవీ యాక్టివ్‌గా లేవు}=1{{mode} యాక్టివ్‌గా ఉంది}other{# మోడ్స్ యాక్టివ్‌గా ఉన్నాయి}}" "మీరు పేర్కొనే అలారాలు, రిమైండర్‌లు, ఈవెంట్‌లు మరియు కాలర్‌ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్‌లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు." @@ -573,8 +574,7 @@ "సంభాషణలు" "అన్ని నిశ్శబ్ద నోటిఫికేషన్‌లను క్లియర్ చేస్తుంది" "అంతరాయం కలిగించవద్దు ద్వారా నోటిఫికేషన్‌లు పాజ్ చేయబడ్డాయి" - - + "{count,plural,offset:1 =0{నోటిఫికేషన్‌లు ఏవీ లేవు}=1{{mode} ద్వారా నోటిఫికేషన్‌లు పాజ్ చేయబడ్డాయి}=2{నోటిఫికేషన్‌లు, {mode}, మరో ఒక మోడ్ ద్వారా పాజ్ చేయబడ్డాయి}other{నోటిఫికేషన్‌లు, {mode}, మరో # మోడ్‌ల ద్వారా పాజ్ చేయబడ్డాయి}}" "ఇప్పుడే ప్రారంభించండి" "నోటిఫికేషన్‌లు లేవు" "కొత్త నోటిఫికేషన్‌లు ఏవీ లేవు" @@ -706,6 +706,7 @@ "డెమో మోడ్ చూపు" "ఈథర్‌నెట్" "అలారం" + "%1$s ఆన్‌లో ఉంది" "Wallet" "మీ ఫోన్‌తో మరింత వేగంగా, సురక్షితంగా కొనుగోళ్లు చేయడానికి సెటప్ చేయండి" "అన్నింటినీ చూపు" @@ -1405,26 +1406,38 @@ "టచ్‌ప్యాడ్ సంజ్ఞ గురించి తెలుసుకోండి" "మీ కీబోర్డ్, టచ్‌ప్యాడ్‌ను ఉపయోగించి నావిగేట్ చేయండి" "టచ్‌ప్యాడ్ సంజ్ఞలు, కీబోర్డ్ షార్ట్‌కట్‌లు, అలాగే మరిన్నింటిని గురించి తెలుసుకోండి" - "వెనుకకు పంపే సంజ్ఞ" - "హోమ్‌కు పంపే సంజ్ఞ" + + + + "ఇటీవలి యాప్‌లను చూడండి" "పూర్తయింది" "వెనుకకు" - "వెనుకకు వెళ్లడానికి, టచ్‌ప్యాడ్‌లో ఎక్కడైనా మూడు వేళ్లను ఉపయోగించి ఎడమ లేదా కుడి వైపునకు స్వైప్ చేయండి.\n\nమీరు దీని కోసం + ESC కీబోర్డ్ షార్ట్‌కట్ యాక్షన్‌ను కూడా ఉపయోగించవచ్చు." - "చక్కగా పూర్తి చేశారు!" + + + + "తిరిగి వెనుకకు వెళ్ళడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు." "మొదటి ట్యాబ్‌కు వెళ్లండి" - "ఏ సమయంలోనైనా మీ మొదటి స్క్రీన్‌కు వెళ్లడానికి, మీ స్క్రీన్ కింది నుండి మూడు వేళ్లతో పైకి స్వైప్ చేయండి." - "సూపర్!" - "మొదటి స్క్రీన్‌కు వెళ్ళడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు." + + + + + + "ఇటీవలి యాప్‌లను చూడండి" - "మీ టచ్‌ప్యాడ్‌లో మూడు వేళ్లను ఉపయోగించి పైకి స్వైప్ చేసి, హోల్డ్ చేయండి." + + "పనితీరు అద్భుతంగా ఉంది!" "మీరు ఇటీవలి యాప్‌ల వీక్షణ సంజ్ఞను పూర్తి చేశారు." - "యాక్షన్ కీ" - "మీ యాప్‌లను యాక్సెస్ చేయడానికి, మీ కీబోర్డ్‌లో యాక్షన్ కీని నొక్కండి." - "అభినందనలు!" - "మీరు \'యాక్షన్ కీ\' సంజ్ఞను పూర్తి చేశారు.\n\nAction + / నొక్కితే, మీకు అందుబాటులో ఉండే షార్ట్‌కట్‌లన్నీ కనిపిస్తాయి." + + + + + + + + "కీబోర్డ్ బ్యాక్‌లైట్" "%2$dలో %1$dవ స్థాయి" "హోమ్ కంట్రోల్స్" @@ -1436,6 +1449,7 @@ "మీ యాప్‌లన్నింటినీ చూడటానికి, మీ కీబోర్డ్‌లో యాక్షన్ కీని నొక్కండి" "దాచిపెట్టినది" "చూడటానికి అన్‌లాక్ చేయండి" + "సందర్భోచిత విద్య" "వెనుకకు వెళ్లడానికి మీ టచ్‌ప్యాడ్‌ను ఉపయోగించండి" "మూడు వేళ్లతో ఎడమ / కుడి వైపునకు స్వైప్ చేయండి. మరిన్ని సంజ్ఞల గురించి తెలుసుకోవడానికి ట్యాప్ చేయండి." "హోమ్‌కు వెళ్లడానికి మీ టచ్‌ప్యాడ్‌ను ఉపయోగించండి" @@ -1445,7 +1459,7 @@ "యాప్‌లన్నింటినీ చూడటానికి మీ కీబోర్డ్‌ను ఉపయోగించండి" "ఏ సమయంలోనైనా యాక్షన్ కీని నొక్కండి. మరిన్ని సంజ్ఞల గురించి తెలుసుకోవడానికి ట్యాప్ చేయండి." "కాంతిని మరింత డిమ్ చేసే ఫీచర్ ఇప్పుడు బ్రైట్‌నెస్ స్లయిడర్‌లో ఒక భాగం" - "మీరు ఇప్పుడు బ్రైట్‌నెస్ స్థాయిని మరింత తగ్గించడం ద్వారా స్క్రీన్‌ను కాంతిని మరింత డిమ్ చేయవచ్చు.\n\nఈ ఫీచర్ ఇప్పుడు బ్రైట్‌నెస్ స్లయిడర్‌లో భాగం కాబట్టి, కాంతిని మరింత డిమ్ చేసే షార్ట్‌కట్‌లు తీసివేయబడుతున్నాయి." + "మీరు ఇప్పుడు బ్రైట్‌నెస్ స్థాయిని మరింత తగ్గించడం ద్వారా స్క్రీన్‌ కాంతిని మరింత డిమ్ చేయవచ్చు.\n\nఈ ఫీచర్ ఇప్పుడు బ్రైట్‌నెస్ స్లయిడర్‌లో భాగం కాబట్టి, కాంతిని మరింత డిమ్ చేసే షార్ట్‌కట్‌లు తీసివేయబడుతున్నాయి." "కాంతిని మరింత డిమ్ చేసే షార్ట్‌కట్‌లను తీసివేయండి" "కాంతిని మరింత డిమ్ చేసే షార్ట్‌కట్‌లు తీసివేయబడ్డాయి" "కనెక్టివిటీ" diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index b8a385a12fec..06c26619bb86 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -440,7 +440,8 @@ "เปิด" "เปิด • %1$s" "ปิด" - "ตั้งค่า" + + "จัดการในการตั้งค่า" "{count,plural, =0{ไม่มีโหมดที่ใช้งานอยู่}=1{ใช้งานอยู่ {mode} โหมด}other{ใช้งานอยู่ # โหมด}}" "คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นเสียงนาฬิกาปลุก การช่วยเตือน กิจกรรม และผู้โทรที่ระบุไว้ คุณจะยังคงได้ยินสิ่งที่คุณเลือกเล่น เช่น เพลง วิดีโอ และเกม" @@ -573,8 +574,7 @@ "การสนทนา" "ล้างการแจ้งเตือนแบบไม่มีเสียงทั้งหมด" "หยุดการแจ้งเตือนชั่วคราวโดย \"ห้ามรบกวน\"" - - + "{count,plural,offset:1 =0{ไม่มีการแจ้งเตือน}=1{หยุดการแจ้งเตือนชั่วคราวโดย {mode}}=2{หยุดการแจ้งเตือนชั่วคราวโดย {mode} และโหมดอื่นอีก 1 โหมด}other{หยุดการแจ้งเตือนชั่วคราวโดย {mode} และโหมดอื่นอีก # โหมด}}" "เริ่มเลย" "ไม่มีการแจ้งเตือน" "ไม่มีการแจ้งเตือนใหม่" @@ -706,6 +706,7 @@ "แสดงโหมดสาธิต" "อีเทอร์เน็ต" "การปลุก" + "%1$s เปิดอยู่" "Wallet" "ตั้งค่าเพื่อซื้อสินค้าและบริการด้วยโทรศัพท์ได้อย่างรวดเร็วและปลอดภัยยิ่งขึ้น" "แสดงทั้งหมด" @@ -1405,26 +1406,38 @@ "ดูข้อมูลเกี่ยวกับท่าทางสัมผัสของทัชแพด" "ไปยังส่วนต่างๆ โดยใช้แป้นพิมพ์และทัชแพด" "ดูข้อมูลเกี่ยวกับท่าทางสัมผัสของทัชแพด แป้นพิมพ์ลัด และอื่นๆ" - "ท่าทางสัมผัสสำหรับย้อนกลับ" - "ท่าทางสัมผัสสำหรับหน้าแรก" + + + + "ดูแอปล่าสุด" "เสร็จสิ้น" "ย้อนกลับ" - "หากต้องการย้อนกลับ ให้ใช้ 3 นิ้วปัดไปทางซ้ายหรือขวาที่ใดก็ได้บนทัชแพด\n\nหรือใช้การดำเนินการแป้นพิมพ์ลัด + ESC ได้เช่นเดียวกัน" - "เก่งมาก" + + + + "คุณทำท่าทางสัมผัสเพื่อย้อนกลับเสร็จแล้ว" "ไปที่หน้าแรก" - "ใช้ 3 นิ้วปัดขึ้นจากด้านล่างของหน้าจอเพื่อไปที่หน้าจอหลักได้ทุกเมื่อ" - "ดีมาก" - "คุณทำท่าทางสัมผัสเพื่อไปที่หน้าแรกเสร็จแล้ว" + + + + + + "ดูแอปล่าสุด" - "ใช้ 3 นิ้วปัดขึ้นแล้วค้างไว้บนทัชแพด" + + "เยี่ยมมาก" "คุณทำท่าทางสัมผัสเพื่อดูแอปล่าสุดสำเร็จแล้ว" - "ปุ่มดำเนินการ" - "หากต้องการเข้าถึงแอป ให้กดปุ่มดำเนินการบนแป้นพิมพ์" - "ยินดีด้วย" - "คุณทำท่าทางสัมผัสสำหรับปุ่มดำเนินการเสร็จแล้ว\n\nการดำเนินการ + / จะแสดงแป้นพิมพ์ลัดทั้งหมดที่คุณมี" + + + + + + + + "ไฟแบ็กไลต์ของแป้นพิมพ์" "ระดับที่ %1$d จาก %2$d" "ระบบควบคุมอุปกรณ์สมาร์ทโฮม" @@ -1436,6 +1449,7 @@ "หากต้องการดูแอปทั้งหมด ให้กดปุ่มดำเนินการบนแป้นพิมพ์" "ปกปิดไว้" "ปลดล็อกเพื่อดู" + "การศึกษาตามบริบท" "ใช้ทัชแพดเพื่อย้อนกลับ" "ใช้ 3 นิ้วปัดไปทางซ้ายหรือขวา แตะเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับท่าทางสัมผัสต่างๆ" "ใช้ทัชแพดเพื่อไปยังหน้าแรก" diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index f2cecf97b7b1..8241b723ae3c 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -440,7 +440,8 @@ "Naka-on" "Naka-on • %1$s" "Naka-off" - "I-set up" + + "Pamahalaan sa mga setting" "{count,plural, =0{Walang aktibong mode}=1{Aktibo ang {mode}}one{# mode ang aktibo}other{# na mode ang aktibo}}" "Hindi ka maiistorbo ng mga tunog at pag-vibrate, maliban mula sa mga alarm, paalala, event, at tumatawag na tutukuyin mo. Maririnig mo pa rin ang kahit na anong piliin mong i-play kabilang ang mga musika, video, at laro." @@ -573,8 +574,7 @@ "Mga Pag-uusap" "I-clear ang lahat ng silent na notification" "Mga notification na na-pause ng Huwag Istorbohin" - - + "{count,plural,offset:1 =0{Walang notification}=1{Na-pause ng {mode} ang mga notification}=2{Na-pause ng {mode} at isa pang mode ang mga notification}one{Na-pause ng {mode} at # pang mode ang mga notification}other{Na-pause ng {mode} at # pang mode ang mga notification}}" "Magsimula ngayon" "Walang mga notification" "Walang bagong notification" @@ -706,6 +706,7 @@ "Ipakita ang demo mode" "Ethernet" "Alarm" + "Naka-on ang %1$s" "Wallet" "I-set up para makapagsagawa ng mas mabibilis, mas secure na pagbili gamit ang telepono mo" "Ipakita lahat" @@ -1405,26 +1406,38 @@ "Matuto ng mga galaw sa touchpad" "Mag-navigate gamit ang iyong keyboard at touchpad" "Matuto ng mga galaw sa touchpad, keyboard shortcut, at higit pa" - "Galaw para bumalik" - "Galaw para sa Home" + + + + "Tingnan ang mga kamakailang app" "Tapos na" "Bumalik" - "Para bumalik, mag-swipe pakaliwa o pakanan gamit ang tatlong daliri saanman sa touchpad.\n\nPuwede mo ring gamitin ang keyboard shortcut na Action + ESC para dito." - "Magaling!" + + + + "Nakumpleto mo na ang galaw para bumalik." "Pumunta sa home" - "Para pumunta sa iyong home screen anumang oras, mag-swipe pataas gamit ang tatlong daliri mula sa ibaba ng screen. mo." - "Magaling!" - "Nakumpleto mo na ang galaw para pumunta sa home." + + + + + + "Tingnan ang mga kamakailang app" - "Mag-swipe pataas at i-hold gamit ang tatlong daliri sa iyong touchpad." + + "Magaling!" "Nakumpleto mo ang galaw sa pag-view ng mga kamakailang app." - "Action key" - "Para ma-access ang iyong mga app, pindutin ang action key sa keyboard mo." - "Binabati kita!" - "Nakumpleto mo na ang galaw ng action key.\n\nIpinapakita ng Action + / ang lahat ng shortcut na available sa iyo." + + + + + + + + "Backlight ng keyboard" "Level %1$d sa %2$d" "Mga Home Control" @@ -1436,6 +1449,7 @@ "Para tingnan ang lahat ng iyong app, pindutin ang action key sa keyboard mo" "Na-redact" "I-unlock para tingnan" + "Edukasyon ayon sa konteksto" "Gamitin ang iyong touchpad para bumalik" "Mag-swipe pakaliwa o pakanan gamit ang tatlong daliri. I-tap para matuto pa tungkol sa mga galaw." "Gamitin ang touchpad mo para pumunta sa home" @@ -1445,7 +1459,7 @@ "Gamitin ang iyong keyboard para tingnan ang lahat ng app" "Pindutin ang action key kahit kailan. I-tap para matuto pa tungkol sa mga galaw." "Bahagi na ng slider ng liwanag ang extra dim" - "Puwede mo nang gawing extra dim ang screen sa pamamagitan ng pagbababa pa sa antas ng liwanag .\n\nDahil bahagi na ang feature na ito ng slider ng liwanag, aalisin na ang mga shortcut sa extra dim." + "Puwede mo nang gawing extra dim ang screen sa pamamagitan ng pagbababa pa ng antas ng liwanag .\n\nDahil bahagi na ang feature na ito ng slider ng liwanag, aalisin na ang mga shortcut sa extra dim." "Alisin ang mga shortcut sa extra dim" "Inalis ang mga shortcut sa extra dim" "Pagkakonekta" diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 570657d4494a..966c6efd942e 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -440,7 +440,8 @@ "Açık" "Açık • %1$s" "Kapalı" - "Ayarla" + + "Ayarlarda yönet" "{count,plural, =0{Etkin mod yok}=1{{mode} etkin}other{# mod etkin}}" "Alarmlar, hatırlatıcılar, etkinlikler ve sizin seçtiğiniz kişilerden gelen çağrılar dışında hiçbir ses ve titreşimle rahatsız edilmeyeceksiniz. O sırada çaldığınız müzik, seyrettiğiniz video ya da oynadığınız oyunların sesini duymaya devam edeceksiniz." @@ -573,8 +574,7 @@ "Görüşmeler" "Sessiz bildirimlerin tümünü temizle" "Bildirimler, Rahatsız Etmeyin özelliği tarafından duraklatıldı" - - + "{count,plural,offset:1 =0{Bildirim yok}=1{Bildirimler {mode} tarafından duraklatıldı}=2{Bildirimler, {mode} ve bir diğer mod tarafından duraklatıldı}other{Bildirimler, {mode} ve # diğer mod tarafından duraklatıldı}}" "Şimdi başlat" "Bildirim yok" "Yeni bildirim yok" @@ -706,6 +706,8 @@ "Demo modunu göster" "Ethernet" "Alarm" + + "Cüzdan" "Telefonunuzla daha hızlı ve güvenli satın alma işlemleri gerçekleştirmek için gerekli ayarları yapın" "Tümünü göster" @@ -1405,26 +1407,38 @@ "Dokunmatik alan hareketlerini öğrenin" "Klavyenizi ve dokunmatik alanınızı kullanarak gezinin" "Dokunmatik alan hareketlerini, klavye kısayollarını ve daha fazlasını öğrenin" - "Geri hareketi" - "Ana sayfa hareketi" + + + + "Son uygulamaları görüntüle" "Bitti" "Geri dön" - "Geri dönmek için dokunmatik alanın herhangi bir yerinde üç parmağınızla sola veya sağa kaydırın.\n\nDilerseniz işlem düğmesi + Esc klavye kısayolunu kullanarak da geri dönebilirsiniz." - "Tebrikler!" + + + + "Geri dön hareketini tamamladınız." "Ana sayfaya gidin" - "İstediğiniz zaman ana ekrana gitmek için üç parmağınızla ekranınızın altından yukarı doğru kaydırın." - "Güzel!" - "Ana ekrana git hareketini tamamladınız." + + + + + + "Son uygulamaları görüntüle" - "Dokunmatik alanda üç parmağınızla yukarı doğru kaydırıp basılı tutun." + + "Tebrikler!" "Son uygulamaları görüntüleme hareketini tamamladınız." - "Eylem tuşu" - "Uygulamalarınıza erişmek için klavyenizdeki eylem tuşuna basın." - "Tebrikler!" - "Eylem tuşu hareketini tamamladınız.\n\nKullanabileceğiniz tüm kısayolları görmek için eylem + / tuşuna basın." + + + + + + + + "Klavye aydınlatması" "Seviye %1$d / %2$d" "Ev Kontrolleri" @@ -1436,6 +1450,7 @@ "Tüm uygulamalarınızı görüntülemek için klavyenizdeki eylem tuşuna basın" "Çıkartıldı" "Görüntülemek için kilidi açın" + "Bağlama dayalı eğitim" "Geri dönmek için dokunmatik alanınızı kullanın" "Üç parmağınızla sola veya sağa kaydırın. Daha fazla hareket öğrenmek için dokunun." "Ana sayfaya gitmek için dokunmatik alanınızı kullanın" diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 65b1b39cccd2..c146021968ae 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -440,7 +440,8 @@ "Увімкнено" "Увімк. • %1$s" "Вимкнено" - "Налаштувати" + + "Керувати в налаштуваннях" "{count,plural, =0{Немає активних режимів}=1{Активовано режим \"{mode}\"}one{Активовано # режим}few{Активовано # режими}many{Активовано # режимів}other{Активовано # режиму}}" "Ви отримуватиме звукові та вібросигнали лише для вибраних будильників, нагадувань, подій і абонентів. Однак ви чутимете все, що захочете відтворити, зокрема музику, відео й ігри." @@ -573,8 +574,7 @@ "Розмови" "Очистити всі беззвучні сповіщення" "Режим \"Не турбувати\" призупинив сповіщення" - - + "{count,plural,offset:1 =0{Немає сповіщень}=1{Режим \"{mode}\" призупинив надсилання сповіщень}=2{\"{mode}\" і ще один режим призупинили надсилання сповіщень}one{\"{mode}\" і ще # режим призупинили надсилання сповіщень}few{\"{mode}\" і ще # режими призупинили надсилання сповіщень}many{\"{mode}\" і ще # режимів призупинили надсилання сповіщень}other{\"{mode}\" і ще # режиму призупинили надсилання сповіщень}}" "Почати зараз" "Сповіщень немає" "Немає нових сповіщень" @@ -706,6 +706,8 @@ "Показати демонстраційний режим" "Ethernet" "Будильник" + + "Гаманець" "Швидше й безпечніше сплачуйте за покупки за допомогою телефона" "Показати все" @@ -1405,26 +1407,38 @@ "Жести для сенсорної панелі: докладніше" "Навігація за допомогою клавіатури й сенсорної панелі" "Жести для сенсорної панелі, комбінації клавіш тощо: докладніше" - "Жест \"Назад\"" - "Жест переходу на головний екран" + + + + "Переглянути нещодавні додатки" "Готово" "Назад" - "Щоб перейти назад, проведіть трьома пальцями вліво або вправо по сенсорній панелі.\n\nТакож можна скористатися комбінацією \"клавіша дії\" + ESC." - "Чудово!" + + + + "Ви виконали жест \"Назад\"." "Перейти на головний екран" - "Щоб будь-коли перейти на головний екран, проведіть трьома пальцями вгору від нижнього краю екрана." - "Чудово!" - "Ви виконали жест переходу на головний екран." + + + + + + "Переглянути нещодавні додатки" - "Проведіть трьома пальцями вгору й утримуйте їх на сенсорній панелі." + + "Чудово!" "Ви виконали жест для перегляду нещодавно відкритих додатків." - "Клавіша дії" - "Щоб переглянути додатки, натисніть клавішу дії на клавіатурі." - "Вітаємо!" - "Ви виконали жест клавіші дії.\n\nНатисніть клавішу дії + /, щоб переглянути всі доступні комбінації клавіш." + + + + + + + + "Підсвічування клавіатури" "Рівень %1$d з %2$d" "Автоматизація дому" @@ -1436,6 +1450,7 @@ "Щоб переглянути всі додатки, натисніть клавішу дії на клавіатурі" "Замасковано" "Розблокуйте, щоб переглянути" + "Контекстне навчання" "Щоб повернутися, використовуйте сенсорну панель" "Проведіть трьома пальцями вліво чи вправо. Натисніть, щоб дізнатися про інші жести." "Щоб перейти на головний екран, використовуйте сенсорну панель" diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index e65fd98e7dbf..a0e934749b3a 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -440,7 +440,8 @@ "آن ہے" "آن ہے • %1$s" "آف ہے" - "سیٹ اپ کریں" + + "ترتیبات میں نظم کریں" "{count,plural, =0{کوئی فعال موڈ نہیں ہے}=1{{mode} فعال ہے}other{# موڈز فعال ہیں}}" "الارمز، یاددہانیوں، ایونٹس اور آپ کے متعین کردہ کالرز کے علاوہ، آپ آوازوں اور وائبریشنز سے ڈسٹرب نہیں ہوں گے۔ موسیقی، ویڈیوز اور گیمز سمیت آپ ابھی بھی ہر وہ چیز سنیں گے جسے چلانے کا آپ انتخاب کرتے ہیں۔" @@ -573,8 +574,7 @@ "گفتگوئیں" "سبھی خاموش اطلاعات کو صاف کریں" "\'ڈسٹرب نہ کریں\' کے ذریعے اطلاعات کو موقوف کیا گیا" - - + "{count,plural,offset:1 =0{کوئی اطلاع نہیں ہے}=1{{mode} کی طرف سے اطلاعات کو روک دیا گیا ہے}=2{{mode} اور ایک دوسرے موڈ کے ذریعہ اطلاعات کو روک دیا گیا ہے}other{{mode} اور # دیگر طریقوں کے ذریعے اطلاعات کو روک دیا گیا ہے}}" "ابھی شروع کریں" "کوئی اطلاعات نہیں ہیں" "کوئی نئی اطلاعات نہیں" @@ -706,6 +706,7 @@ "ڈیمو موڈ دکھائیں" "ایتھرنیٹ" "الارم" + "%1$s آن ہے" "والٹ" "اپنے فون سے تیز تر مزید محفوظ خریداریاں کرنے کے لیے، سیٹ اپ مکمل کریں" "سبھی دکھائیں" @@ -1405,26 +1406,38 @@ "ٹچ پیڈ کے اشارے کو جانیں" "اپنے کی بورڈ اور ٹچ پیڈ کا استعمال کر کے نیویگیٹ کریں" "ٹچ پیڈ کے اشارے، کی بورڈ شارٹ کٹس اور مزید جانیں" - "پیچھے جانے کا اشارہ" - "ہوم کا اشارہ" + + + + "حالیہ ایپس دیکھیں" "ہو گیا" "واپس جائیں" - "‏واپس جانے کے لیے، ٹچ پیڈ پر کہیں بھی تین انگلیوں کی مدد سے دائیں یا بائیں سوائپ کریں۔\n\nآپ اس کیلئے کی بورڈ شارٹ کٹ ایکشن + Esc کا بھی استعمال کر سکتے ہیں۔" - "بہترین!" + + + + "آپ نے واپس جائیں اشارے کو مکمل کر لیا۔" "ہوم پر جائیں" - "کسی بھی وقت اپنی ہوم اسکرین پر جانے کے لیے، تین انگلیوں کی مدد سے اپنی اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں۔" - "عمدہ!" - "آپ نے ہوم پر جانے کا اشارہ مکمل کر لیا۔" + + + + + + "حالیہ ایپس دیکھیں" - "اپنے ٹچ پیڈ پر تین انگلیوں کا استعمال کرتے ہوئے اوپر کی طرف سوائپ کریں اور دبائے رکھیں۔" + + "بہترین!" "آپ نے حالیہ ایپس کا اشارہ مکمل کر لیا ہے۔" - "ایکشن کلید" - "اپنی ایپس تک رسائی حاصل کرنے کے لیے، اپنے کی بورڈ پر ایکشن کلید کو دبائیں۔" - "مبارکباد!" - "آپ نے ایکشن کلید کا اشارہ مکمل کر لیا۔\n\nایکشن + / دبانے سے آپ کے دستیاب تمام شارٹ کٹس دکھائی دیں گے۔" + + + + + + + + "کی بورڈ بیک لائٹ" "‏%2$d میں سے ‎%1$d کا لیول" "ہوم کنٹرولز" @@ -1436,6 +1449,7 @@ "اپنی سبھی ایپس دیکھنے کے لیے، اپنے کی بورڈ پر ایکشن کلید دبائیں" "چھپانے کیلئے تبدیل کردہ" "دیکھنے کے لیے غیر مقفل کریں" + "سیاق و سباق کی تعلیم" "واپس جانے کے لیے اپنے ٹچ پیڈ کا استعمال کریں" "تین انگلیوں سے دائیں یا بائیں طرف سوائپ کریں۔ مزید اشارے جاننے کے لیے تھپتھپائیں۔" "ہوم پر جانے کے لیے اپنے ٹچ پیڈ کا استعمال کریں" @@ -1447,7 +1461,7 @@ "اضافی دھندلا اب چمک سلائیڈر کا حصہ ہے" "آپ چمکیلے پن لیول کو مزید کم کر کے اپنی اسکرین کو اضافی دھندلی بنا سکتے ہیں۔\n\nچونکہ یہ خصوصیت اب چمکیلے پن کے سلائیڈر کا حصہ ہے، اس لیے اضافی دھندلا شارٹ کٹس کو ہٹایا جا رہا ہے۔" "اضافی دھندلا شارٹ کٹس کو ہٹائیں" - "اضافی دھندلا شارٹ کٹس ہٹا دیے گئے" + "اضافی دھندلے شارٹ کٹس ہٹا دیے گئے" "کنیکٹویٹی" "ایکسیسبیلٹی" "یوٹیلیٹیز" diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 0f2db3799438..05943136ee3a 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -440,7 +440,8 @@ "Yoniq" "Yoniq • %1$s" "Yoqilmagan" - "Sozlash" + + "Sozlamalarda boshqarish" "{count,plural, =0{0 ta rejim faol}=1{{mode} faol}other{# ta rejim faol}}" "Turli ovoz va tebranishlar endi sizni bezovta qilmaydi. Biroq, signallar, eslatmalar, tadbirlar haqidagi bildirishnomalar va siz tanlagan abonentlardan kelgan chaqiruvlar bundan mustasno. Lekin, ijro etiladigan barcha narsalar, jumladan, musiqa, video va o‘yinlar ovozi eshitiladi." @@ -573,8 +574,7 @@ "Suhbatlar" "Barcha sokin bildirishnomalarni tozalash" "Bezovta qilinmasin rejimida bildirishnomalar pauza qilinadi" - - + "{count,plural,offset:1 =0{Bildirishnomalar yoʻq}=1{{mode} rejimi bildirishnomalarni pauza qilgan}=2{{mode} va yana bitta boshqa rejim bildirishnomalarni pauza qilgan}other{{mode} va # ta boshqa rejim bildirishnomalarni pauza qilgan}}" "Boshlash" "Bildirishnomalar yo‘q" "Yangi bildirishoma yoʻq" @@ -706,6 +706,7 @@ "Demo rejimni ko‘rsatish" "Ethernet" "Signal" + "%1$s yoniq" "Wallet" "Telefonda tezroq va xavfsizroq xarid qilish uchun sozlang" "Hammasi" @@ -1405,26 +1406,38 @@ "Sensorli panel ishoralari haqida" "Klaviatura va sensorli panel yordamida kezing" "Sensorli panel ishoralari, tezkor tugmalar va boshqalar haqida" - "Orqaga qaytish ishorasi" - "Asosiy ekran ishorasi" + + + + "Oxirgi ilovalarni koʻrish" "Tayyor" "Orqaga qaytish" - "Ortga qaytish uchun sensorli panelda uchta barmoqni chapga yoki oʻngga suring.\n\nBuning uchun Action + ESC tezkor tugmalaridan ham foydalanishingiz mumkin." - "Barakalla!" + + + + "Ortga qaytish ishorasi darsini tamomladingiz." "Boshiga" - "Istalgan vaqtda bosh ekranga oʻtish uchun ekranning pastidan uchta barmoq bilan tepaga suring." - "Yaxshi!" - "Bosh ekranni ochish ishorasi darsini tamomladingiz." + + + + + + "Oxirgi ilovalarni koʻrish" - "Sensorli panelda uchta barmoq bilan tepaga surib, bosib turing." + + "Barakalla!" "Oxirgi ilovalarni koʻrish ishorasini tugalladingiz." - "Amal tugmasi" - "Ilovalarga kirish uchun klaviaturadagi amal tugmasini bosing" - "Tabriklaymiz!" - "Amal tugmasi ishorasi darsini tamomladingiz.\n\nAmal + / bosilsa, mavjud buyruqlar koʻrsatiladi." + + + + + + + + "Klaviatura orqa yoritkichi" "Daraja: %1$d / %2$d" "Uy boshqaruvi" @@ -1436,6 +1449,7 @@ "Barcha ishoralarni koʻrish uchun klaviaturadagi amal tugmasini bosing" "Chiqarildi" "Koʻrish uchun qulfdan chiqaring" + "Kontekstual taʼlim" "Sensorli panel orqali orqaga qaytish" "Uchta barmoq bilan chapga yoki oʻngga suring. Boshqa ishoralar bilan tanishish uchun bosing." "Sensorli panel orqali bosh ekranga qaytish" @@ -1446,8 +1460,8 @@ "Amal tugmasini istalganda bosing. Boshqa ishoralar bilan tanishish uchun bosing." "Juda xira endi yorqinlik slayderida joylashgan" "Endi yorqinlik darajasini yanada pasaytirish orqali ekranni yanada xiralashtirishingiz mumkin.\n\nBu funksiya yorqinlik slayderiga kiritilgani uchun \"juda xira\" buyruqlari olib tashlanmoqda." - "Juda xira buyruqlarini olib tashlash" - "Juda xira buyruqlari olib tashlandi" + "“Juda xira” buyruqlarini olib tashlash" + "“Juda xira” buyruqlari olib tashlandi" "Aloqa" "Qulayliklar" "Vositalar" diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index a37a7cd31343..c38f99fcb984 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -440,7 +440,8 @@ "Đang bật" "Bật • %1$s" "Đang tắt" - "Thiết lập" + + "Quản lý trong phần cài đặt" "{count,plural, =0{Không có chế độ nào đang hoạt động}=1{{mode} đang hoạt động}other{# chế độ đang hoạt động}}" "Bạn sẽ không bị làm phiền bởi âm thanh và tiếng rung, ngoại trừ báo thức, lời nhắc, sự kiện và người gọi mà bạn chỉ định. Bạn sẽ vẫn nghe thấy mọi thứ bạn chọn phát, bao gồm nhạc, video và trò chơi." @@ -573,8 +574,7 @@ "Cuộc trò chuyện" "Xóa tất cả thông báo im lặng" "Chế độ Không làm phiền đã tạm dừng thông báo" - - + "{count,plural,offset:1 =0{Không có thông báo}=1{{mode} đã tạm dừng thông báo}=2{{mode} và một chế độ khác đã tạm dừng thông báo}other{{mode} và # chế độ khác đã tạm dừng thông báo}}" "Bắt đầu ngay" "Không có thông báo nào" "Không có thông báo mới" @@ -706,6 +706,7 @@ "Hiển thị chế độ trình diễn" "Ethernet" "Chuông báo" + "%1$s đang bật" "Ví" "Thiết lập để mua hàng nhanh hơn và an toàn hơn bằng điện thoại" "Hiện tất cả" @@ -1405,26 +1406,38 @@ "Tìm hiểu về cử chỉ trên bàn di chuột" "Di chuyển bằng bàn phím và bàn di chuột" "Tìm hiểu về cử chỉ trên bàn di chuột, phím tắt và nhiều mục khác" - "Cử chỉ quay lại" - "Cử chỉ chuyển đến màn hình chính" + + + + "Xem các ứng dụng gần đây" "Xong" "Quay lại" - "Để quay lại, hãy dùng 3 ngón tay vuốt sang trái hoặc sang phải ở vị trí bất kỳ trên bàn di chuột.\n\nBạn cũng có thể dùng phím tắt Hành động + ESC cho thao tác này." - "Tuyệt vời!" + + + + "Bạn đã thực hiện xong cử chỉ quay lại." "Chuyển đến màn hình chính" - "Để chuyển đến màn hình chính bất cứ lúc nào, hãy dùng 3 ngón tay vuốt lên từ cuối màn hình lên." - "Tốt lắm!" - "Bạn đã thực hiện xong cử chỉ chuyển đến màn hình chính." + + + + + + "Xem các ứng dụng gần đây" - "Dùng 3 ngón tay vuốt lên và giữ trên bàn di chuột." + + "Tuyệt vời!" "Bạn đã hoàn tất cử chỉ xem ứng dụng gần đây." - "Phím hành động" - "Để truy cập vào các ứng dụng của bạn, hãy nhấn phím hành động trên bàn phím." - "Xin chúc mừng!" - "Bạn đã thực hiện xong cử chỉ nhấn phím hành động.\n\nThao tác + / sẽ hiển thị tất cả phím tắt bạn hiện có." + + + + + + + + "Đèn nền bàn phím" "Độ sáng %1$d/%2$d" "Điều khiển nhà" @@ -1436,6 +1449,7 @@ "Để xem tất cả ứng dụng của bạn, hãy nhấn phím hành động trên bàn phím" "Bị loại bỏ" "Mở khoá để xem" + "Hướng dẫn theo bối cảnh" "Dùng bàn di chuột để quay lại" "Dùng 3 ngón tay vuốt sang trái hoặc sang phải. Hãy nhấn để tìm hiểu các cử chỉ khác." "Dùng bàn di chuột để chuyển đến màn hình chính" diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 0d270beb0bf9..60e6c4fcb054 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -440,7 +440,8 @@ "已开启" "已开启 • %1$s" "已关闭" - "设置" + + "在设置中管理" "{count,plural, =0{未启用任何模式}=1{已启用“{mode}”模式}other{已启用 # 个模式}}" "您将不会受到声音和振动的打扰(闹钟、提醒、活动和所指定来电者的相关提示音除外)。您依然可以听到您选择播放的任何内容(包括音乐、视频和游戏)的相关音效。" @@ -573,8 +574,7 @@ "对话" "清除所有静音通知" "勿扰模式暂停的通知" - - + "{count,plural,offset:1 =0{无通知}=1{{mode}暂停了通知}=2{{mode}和另外 1 种模式暂停了通知}other{{mode}和另外 # 种模式暂停了通知}}" "立即开始" "没有通知" "没有新通知" @@ -706,6 +706,7 @@ "显示演示模式" "以太网" "闹钟" + "“%1$s”处于启用状态" "钱包" "开始设置,享受更加快捷安全的手机购物体验" "全部显示" @@ -1405,26 +1406,38 @@ "了解触控板手势" "使用键盘和触控板进行导航" "了解触控板手势、键盘快捷键等" - "返回手势" - "主屏幕手势" + + + + "查看最近用过的应用" "完成" "返回" - "如要返回,请使用三根手指在触控板上的任意位置左滑或右滑。\n\n您也可以使用键盘快捷操作键 + ESC 键进行返回。" - "太棒了!" + + + + "您完成了“返回”手势教程。" "前往主屏幕" - "若要随时进入主屏幕,请用三根手指从屏幕的底部向上滑动。" - "很好!" - "您完成了“前往主屏幕”手势教程。" + + + + + + "查看最近用过的应用" - "在触控板上用三根手指向上滑动并按住。" + + "太棒了!" "您已完成“查看最近用过的应用”的手势教程。" - "快捷操作按键" - "如要访问您的应用,请按下键盘上的快捷操作按键。" - "恭喜!" - "您完成了“快捷操作按键”手势教程。\n\n按下快捷操作按键 + / 可显示所有可用快捷键。" + + + + + + + + "键盘背光" "第 %1$d 级,共 %2$d 级" "家居控制" @@ -1436,6 +1449,7 @@ "如要查看所有应用,请按下键盘上的快捷操作按键" "已隐去" "解锁即可查看" + "内容相关指导" "使用触控板返回" "用三根手指向左或向右滑动。点按即可了解更多手势。" "使用触控板前往主屏幕" diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index d9a0877ec4aa..a838da4c02e4 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -440,7 +440,8 @@ "開啟" "開 • %1$s" "關閉" - "設定" + + "在「設定」中管理" "{count,plural, =0{沒有啟用模式}=1{已啟用{mode}}other{已啟用 # 個模式}}" "你不會受到聲音和震動騷擾 (鬧鐘、提醒、活動和你指定的來電者鈴聲除外)。當你選擇播放音樂、影片和遊戲等,仍可以聽到該內容的聲音。" @@ -573,8 +574,7 @@ "對話" "清除所有靜音通知" "「請勿騷擾」模式已將通知暫停" - - + "{count,plural,offset:1 =0{沒有通知}=1{{mode}已暫停通知}=2{{mode}和另外一個模式已暫停通知}other{{mode}和另外 # 個模式已暫停通知}}" "立即開始" "沒有通知" "沒有新通知" @@ -706,6 +706,7 @@ "顯示示範模式" "以太網" "鬧鐘" + "%1$s開咗" "錢包" "完成設定後即可透過手機更快速安全地購物" "顯示全部" @@ -1405,26 +1406,38 @@ "瞭解觸控板手勢" "使用鍵盤和觸控板導覽" "瞭解觸控板手勢、鍵盤快速鍵等等" - "返去手勢" - "主畫面手勢" + + + + "查看最近使用的應用程式" "完成" "返回" - "用三隻手指在觸控板上任何一處向左或向右滑動即可返回。\n\n你也可使用鍵盤快速鍵 Action 鍵 + Esc 鍵執行此操作。" - "太好了!" + + + + "你已完成「返回」手勢的教學課程。" "返回主畫面" - "只要用三隻手指從螢幕底部向上滑動,隨時可以返回主畫面。" - "做得好!" - "你已完成「返回主畫面」手勢的教學課程。" + + + + + + "查看最近使用的應用程式" - "用三隻手指在觸控板向上滑動並按住。" + + "做得好!" "你已完成「查看最近使用的應用程式」手勢的教學課程。" - "快捷操作鍵" - "如要存取應用程式,請在鍵盤上按下快捷操作鍵。" - "恭喜!" - "你已完成「快捷操作鍵」手勢的教學課程。\n\n按下動作 + / 鍵即可顯示所有可使用的快速鍵。" + + + + + + + + "鍵盤背光" "第 %1$d 級,共 %2$d 級" "智能家居" @@ -1436,6 +1449,7 @@ "如要查看所有應用程式,請在鍵盤上按下快捷操作鍵" "已剔除" "解鎖即可查看" + "內容教學" "使用觸控板返回" "用三隻手指向左或向右滑動。輕按即可瞭解更多手勢。" "使用觸控板返回主畫面" @@ -1445,7 +1459,7 @@ "使用鍵盤查看所有應用程式" "隨時按下快捷操作鍵。輕按即可瞭解更多手勢。" "亮度滑桿現已加入超暗功能" - "而家只要將亮度校得越低,螢幕就會更加暗。\n\n由於亮度滑桿而家加入咗呢個功能,所以系統將會移除超暗功能捷徑。" + "現在,只要調校亮度就能將螢幕變得超暗。\n\n由於超暗功能已加到亮度滑桿,其功能捷徑將被移除。" "移除超暗功能捷徑" "超暗功能捷徑已移除" "裝置連接" diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 83b456bab0b4..158b68a7d9b7 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -440,7 +440,8 @@ "開啟" "已開啟 • %1$s" "關閉" - "設定" + + "在「設定」中管理" "{count,plural, =0{未啟用任何模式}=1{已啟用 {mode} 個模式}other{已啟用 # 個模式}}" "裝置不會發出音效或震動造成干擾,但是會保留與鬧鐘、提醒、活動和指定來電者有關的設定。如果你選擇播放音樂、影片和遊戲等內容,還是可以聽見相關音訊。" @@ -573,8 +574,7 @@ "對話" "清除所有靜音通知" "「零打擾」模式已將通知設為暫停" - - + "{count,plural,offset:1 =0{沒有通知}=1{「{mode}」模式已將通知設為暫停}=2{「{mode}」和另一個模式已將通知設為暫停}other{「{mode}」和另外 # 個模式已將通知設為暫停}}" "立即開始" "沒有通知" "沒有新通知" @@ -706,6 +706,7 @@ "顯示展示模式" "乙太網路" "鬧鐘" + "%1$s已開啟" "錢包" "完成相關設定之後,就能以更快速安全的方式透過手機消費" "顯示全部" @@ -1405,26 +1406,38 @@ "學習觸控板手勢" "使用鍵盤和觸控板操作" "學習觸控板手勢、鍵盤快速鍵等" - "返回手勢" - "主畫面手勢" + + + + "查看最近使用的應用程式" "完成" "返回" - "如要返回,請在觸控板的任何位置上用三指向左或向右滑動。\n\n使用快捷操作鍵 + ESC 鍵 (鍵盤快速鍵) 也可以返回。" - "太棒了!" + + + + "你已完成「返回」手勢的教學課程。" "返回主畫面" - "用 3 指從螢幕底部向上滑動,就能隨時返回主畫面。" - "太棒了!" - "你已完成「返回主畫面」手勢的教學課程。" + + + + + + "查看最近使用的應用程式" - "在觸控板上用三指向上滑動並按住。" + + "太棒了!" "你已完成「查看最近使用的應用程式」手勢教學課程。" - "快捷操作鍵" - "如要存取應用程式,請按下鍵盤上的快捷操作鍵。" - "恭喜!" - "你已完成「快捷操作鍵」手勢的教學課程。\n\n按下快捷操作鍵 + / 鍵,就能顯示所有可用的快速鍵。" + + + + + + + + "鍵盤背光" "第 %1$d 級,共 %2$d 級" "居家控制" @@ -1436,6 +1449,7 @@ "如要查看所有應用程式,請按下鍵盤上的快捷操作鍵" "已遮蓋" "解鎖即可查看" + "內容教學" "使用觸控板返回" "用三指向左或向右滑動。輕觸即可進一步瞭解手勢。" "使用觸控板前往主畫面" diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 34f368388d0e..a351b1b91f64 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -440,7 +440,8 @@ "Vuliwe" "Vuliwe • %1$s" "Valiwe" - "Setha" + + "Phatha kumasethingi" "{count,plural, =0{Awekho amamodi asebenzayo}=1{I-{mode} iyasebenza}one{Amamodi angu-# ayasebenza}other{Amamodi angu-# ayasebenza}}" "Ngeke uphazanyiswe imisindo nokudlidliza, ngaphandle kusukela kuma-alamu, izikhumbuzi, imicimbi, nabafonayo obacacisayo. Usazozwa noma yini okhetha ukuyidlala okufaka umculo, amavidiyo, namageyimu." @@ -573,8 +574,7 @@ "Izingxoxo" "Sula zonke izaziso ezithulile" "Izaziso zimiswe okwesikhashana ukungaphazamisi" - - + "{count,plural,offset:1 =0{Azikho izaziso}=1{Izaziso zimiswe okwesikhashana yi-{mode}}=2{Izaziso zimiswe okwesikhashana yi-{mode} nelinye imodi elilodwa}one{Izaziso zimiswe okwesikhashana yi-{mode} kanye namanye amamodi angu-#}other{Izaziso zimiswe okwesikhashana yi-{mode} kanye namanye amamodi angu-#}}" "Qala manje" "Azikho izaziso" "Azikho izaziso ezintsha" @@ -706,6 +706,8 @@ "Bonisa imodi yedemo" "I-Ethernet" "I-alamu" + + "I-wallet" "Lungela ukuthenga ngokushesha, ngokuphepha ngefoni yakho" "Bonisa konke" @@ -1405,26 +1407,38 @@ "Funda ukunyakaza kwephedi lokuthinta" "Funa usebenzisa ikhibhodi yakho nephedi yokuthinta" "Funda ukunyakaza kwephedi yokuthinta, izinqamuleli zamakhibhodi, nokuningi" - "Ukunyakazisa umzimba kwangemuva" - "Ukunyakazisa umzimba kwasekhaya" + + + + "Buka ama-app akamuva" "Kwenziwe" "Buyela emuva" - "Ukuze ubuyele emuva, swayiphela kwesokunxele noma kwesokudla usebenzisa iminwe emithathu noma yikuphi ephedini yokuthinta.\n\nUngasebenzisa nesinqamuleli sekhibhodi Isenzo + ESC kulokhu." - "Umsebenzi omuhle!" + + + + "Ukuqedile ukuthinta kokubuyela emuva." "Iya ekhasini lokuqala" - "Ukuze uye esikrinini sakho sasekhaya nganoma isiphi isikhathi, swayipha uye phezulu ngeminwe emithathu usuka phansi esikrinini sakho." - "Kuhle!" - "Ukuqedile ukuthinta kokuya ekhaya." + + + + + + "Buka ama-app akamuva" - "Swayiphela phezulu bese ubamba usebenzisa iminwe emithathu kuphedi yokuthinta." + + "Umsebenzi omuhle!" "Uqedele ukubuka ukuthinta kwama-app akamuva." - "Inkinobho yokufinyelela" - "Ukuze ufinyelele ama-app wakho, cindezela inkinobho yokufinyelela kukhibhodi yakho." - "Halala!" - "Uqedele ukuthinta inkinobho yokufinyelela.\n\nIsenzo +/ sibonisa zonke izinqamuleli onazo." + + + + + + + + "Ilambu lekhibhodi" "Ileveli %1$d ka-%2$d" "Izilawuli Zasekhaya" @@ -1436,6 +1450,7 @@ "Ukuze ubuke wonke ama-app wakho, cindezela inkinobho yokufinyelela kukhibhodi yakho" "Kwenziwe iredact" "Vula ukuze ubuke" + "Imfundo yokuqukethwe" "Sebenzisa iphedi yokuthinta ukuze ubuyele emuva" "Swayiphela kwesokunxele noma kwesokudla usebenzisa iminwe emithathu. Thepha ukuze ufunde kabanzi ngokunyakazisa umzimba." "Sebenzisa iphedi yokuthinta ukuya ekhaya" -- GitLab From 3267e5259c7a15394a351b58880e06b08f340415 Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Fri, 4 Oct 2024 12:50:09 -0400 Subject: [PATCH 148/447] Update app widget size when resized Instead of relying on the passed-in size, we calculate the size of the view after layout and update the widget with that size. This ensures the widget is always up-to-date with the right size. Bug: 368056517 Test: manually by expanding and shrinking widgets Flag: com.android.systemui.communal_widget_resizing Change-Id: Ief764b582df5e5784d63444d33a2171f6dd5e4be --- .../binder/CommunalAppWidgetHostViewBinder.kt | 41 ++++++++++++++++++- .../sections/CommunalAppWidgetSection.kt | 12 +++++- .../communal/util/WidgetViewFactory.kt | 20 +++++---- 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt index 5f421fd19550..ba96f4e56421 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt @@ -17,19 +17,30 @@ package com.android.systemui.communal.ui.binder import android.content.Context +import android.os.Bundle import android.util.SizeF import android.view.View import android.view.ViewGroup import android.widget.FrameLayout +import androidx.compose.ui.unit.IntSize import androidx.core.view.doOnLayout +import com.android.app.tracing.coroutines.flow.flowOn import com.android.app.tracing.coroutines.launch +import com.android.systemui.Flags.communalWidgetResizing +import com.android.systemui.common.ui.view.onLayoutChanged import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.util.WidgetViewFactory import com.android.systemui.util.kotlin.DisposableHandles +import com.android.systemui.util.kotlin.toDp +import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow +import kotlin.coroutines.CoroutineContext import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DisposableHandle +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged object CommunalAppWidgetHostViewBinder { private const val TAG = "CommunalAppWidgetHostViewBinder" @@ -37,9 +48,11 @@ object CommunalAppWidgetHostViewBinder { fun bind( context: Context, applicationScope: CoroutineScope, + mainContext: CoroutineContext, + backgroundContext: CoroutineContext, container: FrameLayout, model: CommunalContentModel.WidgetContent.Widget, - size: SizeF, + size: SizeF?, factory: WidgetViewFactory, ): DisposableHandle { val disposables = DisposableHandles() @@ -49,6 +62,22 @@ object CommunalAppWidgetHostViewBinder { val widget = factory.createWidget(context, model, size) waitForLayout(container) container.post { container.setView(widget) } + if (communalWidgetResizing()) { + // Update the app widget size in the background. + launch("$TAG#updateSize", backgroundContext) { + container.sizeFlow().flowOn(mainContext).distinctUntilChanged().collect { + (width, height) -> + widget.updateAppWidgetSize( + /* newOptions = */ Bundle(), + /* minWidth = */ width, + /* minHeight = */ height, + /* maxWidth = */ width, + /* maxHeight = */ height, + /* ignorePadding = */ true, + ) + } + } + } } disposables += DisposableHandle { loadingJob.cancel() } @@ -69,3 +98,13 @@ private fun ViewGroup.setView(view: View) { (view.parent as? ViewGroup)?.removeView(view) addView(view) } + +private fun View.sizeAsDp(): IntSize = IntSize(width.toDp(context), height.toDp(context)) + +private fun View.sizeFlow(): Flow = conflatedCallbackFlow { + if (isLaidOut && !isLayoutRequested) { + trySend(sizeAsDp()) + } + val disposable = onLayoutChanged { trySend(sizeAsDp()) } + awaitClose { disposable.dispose() } +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/CommunalAppWidgetSection.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/CommunalAppWidgetSection.kt index 56b769e7bc13..2e12bad744f0 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/CommunalAppWidgetSection.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/CommunalAppWidgetSection.kt @@ -25,13 +25,17 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.android.systemui.Flags.communalWidgetResizing import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.ui.binder.CommunalAppWidgetHostViewBinder import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.communal.util.WidgetViewFactory import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.dagger.qualifiers.UiBackground import com.android.systemui.res.R import javax.inject.Inject +import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DisposableHandle @@ -39,6 +43,8 @@ class CommunalAppWidgetSection @Inject constructor( @Application private val applicationScope: CoroutineScope, + @Main private val mainContext: CoroutineContext, + @UiBackground private val backgroundContext: CoroutineContext, private val factory: WidgetViewFactory, ) { @@ -76,10 +82,12 @@ constructor( context = context, container = this, model = model, - size = size, + size = if (!communalWidgetResizing()) size else null, factory = factory, applicationScope = applicationScope, - ) + mainContext = mainContext, + backgroundContext = backgroundContext, + ), ) accessibilityDelegate = viewModel.widgetAccessibilityDelegate diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt b/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt index cafa74faf1a1..07a7c7cba2fd 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt @@ -43,7 +43,7 @@ constructor( suspend fun createWidget( context: Context, model: CommunalContentModel.WidgetContent.Widget, - size: SizeF, + size: SizeF?, ): CommunalAppWidgetHostView = withContext("$TAG#createWidget", uiBgContext) { val view = @@ -54,14 +54,16 @@ constructor( // Instead of setting the view as the listener directly, we wrap the view in a delegate // which ensures the callbacks always get called on the main thread. appWidgetHost.setListener(model.appWidgetId, listenerFactory.create(view)) - view.updateAppWidgetSize( - /* newOptions = */ Bundle(), - /* minWidth = */ size.width.toInt(), - /* minHeight = */ size.height.toInt(), - /* maxWidth = */ size.width.toInt(), - /* maxHeight = */ size.height.toInt(), - /* ignorePadding = */ true, - ) + if (size != null) { + view.updateAppWidgetSize( + /* newOptions = */ Bundle(), + /* minWidth = */ size.width.toInt(), + /* minHeight = */ size.height.toInt(), + /* maxWidth = */ size.width.toInt(), + /* maxHeight = */ size.height.toInt(), + /* ignorePadding = */ true, + ) + } view } -- GitLab From b4419eed70f15e16fc6da23c02b2460bbb4673ab Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 7 Oct 2024 12:04:42 -0700 Subject: [PATCH 149/447] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I2c070c48f21695ce7349d507c295fd6455060a38 --- packages/SystemUI/res-keyguard/values-ur/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml index fcb3a3ec8edc..042067b12e8a 100644 --- a/packages/SystemUI/res-keyguard/values-ur/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml @@ -20,7 +20,7 @@ - "‏اپنا PIN درج کریں" + "‏‫اپنا PIN درج کریں" "‏PIN درج کریں" "اپنا پیٹرن درج کریں" "پیٹرن ڈرا کریں" -- GitLab From 2ded7dd462151d667648aba107cbae3d2b46acaa Mon Sep 17 00:00:00 2001 From: Scarlett Song Date: Fri, 6 Sep 2024 01:39:06 +0000 Subject: [PATCH 150/447] Health Permissions: Add OP_READ_HEART_RATE Add OP_READ_HEART_RATE app op for runtime health permission READ_HEART_RATE. Flag: android.permission.flags.replace_body_sensor_permission_enabled Bug: 364638912 Bug: 364643245 Bug: 360781841 Test: atest AppOpDefinitionTest Change-Id: I3355e93051f6068ee88eb93bb95e0b91afcb49dd --- core/api/system-current.txt | 1 + core/java/android/app/AppOpsManager.java | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 879c7a271e79..91c16c2dffde 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -694,6 +694,7 @@ package android.app { field public static final String OPSTR_PROJECT_MEDIA = "android:project_media"; field @FlaggedApi("android.view.contentprotection.flags.rapid_clear_notifications_by_listener_app_op_enabled") public static final String OPSTR_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER = "android:rapid_clear_notifications_by_listener"; field public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard"; + field @FlaggedApi("android.permission.flags.replace_body_sensor_permission_enabled") public static final String OPSTR_READ_HEART_RATE = "android:read_heart_rate"; field public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms"; field public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio"; field public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images"; diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 5907af0904ad..0472ff8c9f50 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -54,6 +54,7 @@ import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.database.DatabaseUtils; import android.health.connect.HealthConnectManager; +import android.health.connect.HealthPermissions; import android.media.AudioAttributes.AttributeUsage; import android.media.MediaRouter2; import android.os.Binder; @@ -1607,9 +1608,12 @@ public class AppOpsManager { public static final int OP_RECEIVE_SENSITIVE_NOTIFICATIONS = AppProtoEnums.APP_OP_RECEIVE_SENSITIVE_NOTIFICATIONS; + /** @hide Access to read heart rate sensor. */ + public static final int OP_READ_HEART_RATE = AppProtoEnums.APP_OP_READ_HEART_RATE; + /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final int _NUM_OP = 149; + public static final int _NUM_OP = 150; /** * All app ops represented as strings. @@ -1762,6 +1766,7 @@ public class AppOpsManager { OPSTR_UNARCHIVAL_CONFIRMATION, OPSTR_EMERGENCY_LOCATION, OPSTR_RECEIVE_SENSITIVE_NOTIFICATIONS, + OPSTR_READ_HEART_RATE, }) public @interface AppOpString {} @@ -2499,6 +2504,11 @@ public class AppOpsManager { public static final String OPSTR_RECEIVE_SENSITIVE_NOTIFICATIONS = "android:receive_sensitive_notifications"; + /** @hide Access to read heart rate sensor. */ + @SystemApi + @FlaggedApi(Flags.FLAG_REPLACE_BODY_SENSOR_PERMISSION_ENABLED) + public static final String OPSTR_READ_HEART_RATE = "android:read_heart_rate"; + /** {@link #sAppOpsToNote} not initialized yet for this op */ private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0; /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */ @@ -2572,6 +2582,8 @@ public class AppOpsManager { OP_NEARBY_WIFI_DEVICES, // Notifications OP_POST_NOTIFICATION, + // Health + Flags.replaceBodySensorPermissionEnabled() ? OP_READ_HEART_RATE : OP_NONE, }; /** @@ -2612,6 +2624,7 @@ public class AppOpsManager { OP_READ_SYSTEM_GRAMMATICAL_GENDER, }; + @SuppressWarnings("FlaggedApi") static final AppOpInfo[] sAppOpInfos = new AppOpInfo[]{ new AppOpInfo.Builder(OP_COARSE_LOCATION, OPSTR_COARSE_LOCATION, "COARSE_LOCATION") .setPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) @@ -3079,6 +3092,10 @@ public class AppOpsManager { new AppOpInfo.Builder(OP_RECEIVE_SENSITIVE_NOTIFICATIONS, OPSTR_RECEIVE_SENSITIVE_NOTIFICATIONS, "RECEIVE_SENSITIVE_NOTIFICATIONS") .setDefaultMode(MODE_IGNORED).build(), + new AppOpInfo.Builder(OP_READ_HEART_RATE, OPSTR_READ_HEART_RATE, "READ_HEART_RATE") + .setPermission(Flags.replaceBodySensorPermissionEnabled() ? + HealthPermissions.READ_HEART_RATE : null) + .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(), }; // The number of longs needed to form a full bitmask of app ops @@ -3132,6 +3149,10 @@ public class AppOpsManager { } } for (int op : RUNTIME_PERMISSION_OPS) { + if (op == OP_NONE) { + // Skip ops with a disabled feature flag. + continue; + } if (sAppOpInfos[op].permission != null) { sPermToOp.put(sAppOpInfos[op].permission, op); } -- GitLab From 5c3a99a08181ad7d58b636d69a470ad7d8127b0f Mon Sep 17 00:00:00 2001 From: Paul Colta Date: Tue, 17 Sep 2024 18:42:28 +0000 Subject: [PATCH 151/447] HDMI: Disable CEC on standby when Low Power Standby is enabled Add the option for OEMs to set a custom property (`persist.sys.hdmi.property_disable_cec_on_standby_in_low_energy_mode`) to allow CEC to be disabled when TV is in turned off when low energy mode is used. Test: atest com.android.server.hdmi Bug: 371617005 Flag: EXEMPT urgent feature Change-Id: I65bb94bc2ddedd0863d6e5cc868a60f6ae0634fb --- .../com/android/server/hdmi/Constants.java | 20 +++ .../server/hdmi/HdmiControlService.java | 69 ++++++++- .../server/hdmi/PowerManagerWrapper.java | 8 + .../server/hdmi/FakePowerManagerWrapper.java | 10 ++ .../server/hdmi/HdmiCecLocalDeviceTvTest.java | 143 ++++++++++++++++++ 5 files changed, 248 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index b78f8a7d8ee7..0e7d2b631833 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -509,6 +509,21 @@ final class Constants { static final String PROPERTY_STRIP_AUDIO_TV_NO_SYSTEM_AUDIO = "persist.sys.hdmi.property_strip_audio_tv_no_system_audio"; + /** + * Property that decides whether CEC should be disabled on standby when the low energy mode + * option is used. + */ + static final String PROPERTY_WAS_CEC_DISABLED_ON_STANDBY_BY_LOW_ENERGY_MODE = + "persist.sys.hdmi.property_was_cec_disabled_on_standby_by_low_energy_mode"; + + /** + * Property that checks if CEC was disabled on standby by low energy mode. With the help of this + * property we avoid re-enabling CEC if the user explicitly disabled it, unrelated to the + * selected energy mode. + */ + static final String PROPERTY_DISABLE_CEC_ON_STANDBY_IN_LOW_ENERGY_MODE = + "persist.sys.hdmi.property_disable_cec_on_standby_in_low_energy_mode"; + static final int RECORDING_TYPE_DIGITAL_RF = 1; static final int RECORDING_TYPE_ANALOGUE_RF = 2; static final int RECORDING_TYPE_EXTERNAL_PHYSICAL_ADDRESS = 3; @@ -644,6 +659,11 @@ final class Constants { }) @interface FeatureFlag {} + /** + * Identifier key for Low energy mode. + */ + static final String KEY_LOW_ENERGY_USE = "low_energy_use"; + private Constants() { /* cannot be instantiated */ } diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 8e41d18f0953..81be0baefd7a 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -22,6 +22,7 @@ import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE; import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE; import static android.hardware.hdmi.HdmiControlManager.EARC_FEATURE_DISABLED; import static android.hardware.hdmi.HdmiControlManager.EARC_FEATURE_ENABLED; +import static android.hardware.hdmi.HdmiControlManager.HDMI_CEC_CONTROL_DISABLED; import static android.hardware.hdmi.HdmiControlManager.HDMI_CEC_CONTROL_ENABLED; import static android.hardware.hdmi.HdmiControlManager.POWER_CONTROL_MODE_NONE; import static android.hardware.hdmi.HdmiControlManager.SOUNDBAR_MODE_DISABLED; @@ -478,7 +479,8 @@ public class HdmiControlService extends SystemService { @Nullable private HdmiCecController mCecController; - private HdmiCecPowerStatusController mPowerStatusController; + @VisibleForTesting + protected HdmiCecPowerStatusController mPowerStatusController; @Nullable private HdmiEarcController mEarcController; @@ -3814,7 +3816,32 @@ public class HdmiControlService extends SystemService { mPowerStatusController.setPowerStatus(HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON, false); if (mCecController != null) { - if (isCecControlEnabled()) { + if (isTvDevice() && getWasCecDisabledOnStandbyByLowEnergyMode()) { + Slog.w(TAG, "Re-enable CEC on wake-up since it was disabled due to low energy " + + " mode."); + getHdmiCecConfig().setIntValue(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED, + HDMI_CEC_CONTROL_ENABLED); + setWasCecDisabledOnStandbyByLowEnergyMode(false); + int controlStateChangedReason = -1; + switch (wakeUpAction) { + case WAKE_UP_SCREEN_ON: + controlStateChangedReason = + HdmiControlManager.CONTROL_STATE_CHANGED_REASON_WAKEUP; + break; + case WAKE_UP_BOOT_UP: + controlStateChangedReason = + HdmiControlManager.CONTROL_STATE_CHANGED_REASON_START; + break; + default: + Slog.e(TAG, "wakeUpAction " + wakeUpAction + " not defined."); + return; + + } + // Since CEC is going to be initialized by the setting value update, we must invoke + // the vendor command listeners here with the reason TV woke up. + invokeVendorCommandListenersOnControlStateChanged(true, + controlStateChangedReason); + } else if (isCecControlEnabled()) { int startReason = -1; switch (wakeUpAction) { case WAKE_UP_SCREEN_ON: @@ -3988,6 +4015,14 @@ public class HdmiControlService extends SystemService { if (isAudioSystemDevice() || !isPowerStandby()) { return; } + if (isTvDevice() && getDisableCecOnStandbyByLowEnergyMode() + && mPowerManager.isLowPowerStandbyEnabled()) { + Slog.w(TAG, "Disable CEC on standby due to low power energy mode."); + setWasCecDisabledOnStandbyByLowEnergyMode(true); + getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED, + HDMI_CEC_CONTROL_DISABLED); + } mCecController.enableSystemCecControl(false); mMhlController.setOption(OPTION_MHL_SERVICE_CONTROL, DISABLED); } @@ -5148,4 +5183,34 @@ public class HdmiControlService extends SystemService { protected boolean isHdmiControlEnhancedBehaviorFlagEnabled() { return hdmiControlEnhancedBehavior(); } + + /** + * Reads the property value that decides whether CEC should be disabled on standby when the low + * energy mode option is used. + */ + @VisibleForTesting + protected boolean getDisableCecOnStandbyByLowEnergyMode() { + return SystemProperties.getBoolean( + Constants.PROPERTY_DISABLE_CEC_ON_STANDBY_IN_LOW_ENERGY_MODE, false); + } + + /** + * Reads the property that checks if CEC was disabled on standby by low energy mode. + */ + @VisibleForTesting + protected boolean getWasCecDisabledOnStandbyByLowEnergyMode() { + return SystemProperties.getBoolean( + Constants.PROPERTY_WAS_CEC_DISABLED_ON_STANDBY_BY_LOW_ENERGY_MODE, false); + } + + /** + * Sets the truth value of the property that checks if CEC was disabled on standby by low energy + * mode. + */ + @VisibleForTesting + protected void setWasCecDisabledOnStandbyByLowEnergyMode(boolean value) { + writeStringSystemProperty( + Constants.PROPERTY_WAS_CEC_DISABLED_ON_STANDBY_BY_LOW_ENERGY_MODE, + String.valueOf(value)); + } } diff --git a/services/core/java/com/android/server/hdmi/PowerManagerWrapper.java b/services/core/java/com/android/server/hdmi/PowerManagerWrapper.java index 7530b3b239b4..5292cbbb9336 100644 --- a/services/core/java/com/android/server/hdmi/PowerManagerWrapper.java +++ b/services/core/java/com/android/server/hdmi/PowerManagerWrapper.java @@ -16,6 +16,8 @@ package com.android.server.hdmi; +import static com.android.server.hdmi.Constants.KEY_LOW_ENERGY_USE; + import android.content.Context; import android.os.PowerManager; @@ -47,6 +49,12 @@ public class PowerManagerWrapper { return new DefaultWakeLockWrapper(mPowerManager.newWakeLock(levelAndFlags, tag)); } + boolean isLowPowerStandbyEnabled() { + PowerManager.LowPowerStandbyPolicy lowPowerStandbyPolicy + = mPowerManager.getLowPowerStandbyPolicy(); + return lowPowerStandbyPolicy.getIdentifier().equals(KEY_LOW_ENERGY_USE); + } + /** * "Default" wrapper for {@link PowerManager.WakeLock}, as opposed to a "Fake" wrapper for * testing - see {@link FakePowerManagerWrapper.FakeWakeLockWrapper}. diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakePowerManagerWrapper.java b/services/tests/servicestests/src/com/android/server/hdmi/FakePowerManagerWrapper.java index 04f921f495a2..629f9683a547 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/FakePowerManagerWrapper.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/FakePowerManagerWrapper.java @@ -26,6 +26,7 @@ final class FakePowerManagerWrapper extends PowerManagerWrapper { private boolean mInteractive; private WakeLockWrapper mWakeLock; private boolean mWasWakeLockInstanceCreated = false; + private boolean mIsLowPowerStandbyEnabled = false; FakePowerManagerWrapper(@NonNull Context context) { @@ -59,6 +60,15 @@ final class FakePowerManagerWrapper extends PowerManagerWrapper { return; } + @Override + boolean isLowPowerStandbyEnabled() { + return mIsLowPowerStandbyEnabled; + } + + void setIsLowPowerStandbyEnabled(boolean isLowPowerStandbyEnabled) { + mIsLowPowerStandbyEnabled = isLowPowerStandbyEnabled; + } + @Override WakeLockWrapper newWakeLock(int levelAndFlags, String tag) { if (mWakeLock == null) { diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java index 2d957401e6bd..935c8b8720fb 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -70,6 +70,7 @@ import org.junit.runners.JUnit4; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.concurrent.TimeUnit; @SmallTest @@ -113,6 +114,10 @@ public class HdmiCecLocalDeviceTvTest { private boolean mWokenUp; private boolean mEarcBlocksArc; private List mDeviceEventListeners = new ArrayList<>(); + private List mVendorCommandListeners = new ArrayList<>(); + private boolean mDisableCecOnStandbyByLowEnergyMode; + private boolean mWasCecDisabledOnStandbyByLowEnergyMode; + private boolean mUseHdmiCecPowerStatusController; private class DeviceEventListener { private HdmiDeviceInfo mDevice; @@ -132,6 +137,30 @@ public class HdmiCecLocalDeviceTvTest { } } + private class VendorCommandListener { + private boolean mEnabled; + private int mReason; + + VendorCommandListener(boolean enabled, int reason) { + this.mEnabled = enabled; + this.mReason = reason; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof VendorCommandListener)) { + return false; + } + VendorCommandListener other = (VendorCommandListener) obj; + return other.mReason == mReason && other.mEnabled == mEnabled; + } + + @Override + public int hashCode() { + return Objects.hash(mEnabled, mReason); + } + } + private FakeAudioFramework mAudioFramework; private AudioManagerWrapper mAudioManager; @@ -169,6 +198,9 @@ public class HdmiCecLocalDeviceTvTest { @Override boolean isPowerStandby() { + if (mUseHdmiCecPowerStatusController) { + return mPowerStatusController.isPowerStatusStandby(); + } return false; } @@ -187,6 +219,13 @@ public class HdmiCecLocalDeviceTvTest { mDeviceEventListeners.add(new DeviceEventListener(device, status)); } + @Override + boolean invokeVendorCommandListenersOnControlStateChanged( + boolean enabled, int reason) { + mVendorCommandListeners.add(new VendorCommandListener(enabled, reason)); + return true; + } + @Override protected boolean earcBlocksArcConnection() { return mEarcBlocksArc; @@ -196,6 +235,21 @@ public class HdmiCecLocalDeviceTvTest { protected void sendBroadcastAsUser(@RequiresPermission Intent intent) { // do nothing } + + @Override + protected boolean getDisableCecOnStandbyByLowEnergyMode() { + return mDisableCecOnStandbyByLowEnergyMode; + } + + @Override + protected boolean getWasCecDisabledOnStandbyByLowEnergyMode() { + return mWasCecDisabledOnStandbyByLowEnergyMode; + } + + @Override + protected void setWasCecDisabledOnStandbyByLowEnergyMode(boolean value) { + mWasCecDisabledOnStandbyByLowEnergyMode = value; + } }; mHdmiControlService.setIoLooper(mMyLooper); @@ -241,6 +295,9 @@ public class HdmiCecLocalDeviceTvTest { mHdmiControlService.getHdmiCecConfig().setIntValue( sad, HdmiControlManager.QUERY_SAD_DISABLED); } + mWasCecDisabledOnStandbyByLowEnergyMode = false; + mDisableCecOnStandbyByLowEnergyMode = false; + mUseHdmiCecPowerStatusController = false; mNativeWrapper.clearResultMessages(); } @@ -2238,6 +2295,92 @@ public class HdmiCecLocalDeviceTvTest { assertThat(mHdmiCecLocalDeviceTv.getActions(SystemAudioActionFromTv.class)).hasSize(1); } + @Test + public void lowEnergyMode_disableCecOnStandby_reEnableOnWakeup() { + mDisableCecOnStandbyByLowEnergyMode = true; + mUseHdmiCecPowerStatusController = true; + mPowerManager.setIsLowPowerStandbyEnabled(true); + + assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED), + HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlService.onStandby(STANDBY_SCREEN_OFF); + mTestLooper.dispatchAll(); + + assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED), + HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + assertTrue(mWasCecDisabledOnStandbyByLowEnergyMode); + mHdmiControlService.onWakeUp(WAKE_UP_SCREEN_ON); + mTestLooper.dispatchAll(); + + assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED), + HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + assertFalse(mWasCecDisabledOnStandbyByLowEnergyMode); + } + + @Test + public void lowEnergyMode_disableCecBeforeStandby_cecStaysDisabledOnWakeup() { + mDisableCecOnStandbyByLowEnergyMode = true; + mUseHdmiCecPowerStatusController = true; + mPowerManager.setIsLowPowerStandbyEnabled(true); + + assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED), + HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED, + HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + mTestLooper.dispatchAll(); + + mHdmiControlService.onStandby(STANDBY_SCREEN_OFF); + mTestLooper.dispatchAll(); + + assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED), + HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + assertFalse(mWasCecDisabledOnStandbyByLowEnergyMode); + mHdmiControlService.onWakeUp(WAKE_UP_SCREEN_ON); + mTestLooper.dispatchAll(); + + assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED), + HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + } + + @Test + public void lowEnergyMode_onWakeUp_reEnableCec_invokeVendorCommandListeners() { + mDisableCecOnStandbyByLowEnergyMode = true; + mUseHdmiCecPowerStatusController = true; + mPowerManager.setIsLowPowerStandbyEnabled(true); + VendorCommandListener vendorCommandListenerInvocationWakeup = new VendorCommandListener( + true, HdmiControlManager.CONTROL_STATE_CHANGED_REASON_WAKEUP); + VendorCommandListener vendorCommandListenerInvocationSettingChange = + new VendorCommandListener(true, + HdmiControlManager.CONTROL_STATE_CHANGED_REASON_WAKEUP); + + assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED), + HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiControlService.onStandby(STANDBY_SCREEN_OFF); + mTestLooper.dispatchAll(); + + assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED), + HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + assertTrue(mWasCecDisabledOnStandbyByLowEnergyMode); + mVendorCommandListeners.clear(); + mTestLooper.dispatchAll(); + + mHdmiControlService.onWakeUp(WAKE_UP_SCREEN_ON); + mTestLooper.dispatchAll(); + + assertThat(mVendorCommandListeners.size()).isEqualTo(2); + assertTrue(mVendorCommandListeners.contains(vendorCommandListenerInvocationWakeup)); + assertTrue(mVendorCommandListeners.contains(vendorCommandListenerInvocationSettingChange)); + } + protected static class MockTvDevice extends HdmiCecLocalDeviceTv { MockTvDevice(HdmiControlService service) { super(service); -- GitLab From 7a23baeddf98074cd14eb69be23fd3163b4940cd Mon Sep 17 00:00:00 2001 From: Liefu Liu Date: Fri, 4 Oct 2024 15:52:05 -0700 Subject: [PATCH 152/447] Changes in ContactsContract to support SIM in getDefaultAccountForNewContacts and setDefaultAccountForNewContacts. Bug: 368127857 Test: cts test (atest CtsContactsProviderTestCases:ContactsContract_DefaultAccountTest) Flag:android.provider.new_default_account_api_enabled modified: core/java/android/provider/ContactsContract.java Change-Id: If90fb3cb03be3899489a71838952ca7444140db4 --- .../android/provider/ContactsContract.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index e65f0d2214b6..74533fca0b4c 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -3209,7 +3209,11 @@ public final class ContactsContract { return new DefaultAccountAndState(DEFAULT_ACCOUNT_STATE_NOT_SET, null); } - private static boolean isCloudOrSimAccount(@DefaultAccountState int state) { + /** + * + * @hide + */ + public static boolean isCloudOrSimAccount(@DefaultAccountState int state) { return state == DEFAULT_ACCOUNT_STATE_CLOUD || state == DEFAULT_ACCOUNT_STATE_SIM; } @@ -3287,23 +3291,20 @@ public final class ContactsContract { Bundle response = nullSafeCall(resolver, ContactsContract.AUTHORITY_URI, QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD, null, null); - int defaultContactsAccountState = response.getInt(KEY_DEFAULT_ACCOUNT_STATE, -1); - if (defaultContactsAccountState - == DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD) { + int defaultAccountState = response.getInt(KEY_DEFAULT_ACCOUNT_STATE, -1); + if (DefaultAccountAndState.isCloudOrSimAccount(defaultAccountState)) { String accountName = response.getString(Settings.ACCOUNT_NAME); String accountType = response.getString(Settings.ACCOUNT_TYPE); if (TextUtils.isEmpty(accountName) || TextUtils.isEmpty(accountType)) { throw new IllegalStateException( "account name and type cannot be null or empty"); } - return new DefaultAccountAndState( - DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD, + return new DefaultAccountAndState(defaultAccountState, new Account(accountName, accountType)); - } else if (defaultContactsAccountState - == DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_LOCAL - || defaultContactsAccountState + } else if (defaultAccountState == DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_LOCAL + || defaultAccountState == DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_NOT_SET) { - return new DefaultAccountAndState(defaultContactsAccountState, /*cloudAccount=*/ + return new DefaultAccountAndState(defaultAccountState, /*account=*/ null); } else { throw new IllegalStateException("Invalid default account state"); @@ -3348,12 +3349,11 @@ public final class ContactsContract { Bundle extras = new Bundle(); extras.putInt(KEY_DEFAULT_ACCOUNT_STATE, defaultAccountAndState.getState()); - if (defaultAccountAndState.getState() - == DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD) { - Account cloudAccount = defaultAccountAndState.getAccount(); - assert cloudAccount != null; - extras.putString(Settings.ACCOUNT_NAME, cloudAccount.name); - extras.putString(Settings.ACCOUNT_TYPE, cloudAccount.type); + if (DefaultAccountAndState.isCloudOrSimAccount(defaultAccountAndState.getState())) { + Account account = defaultAccountAndState.getAccount(); + assert account != null; + extras.putString(Settings.ACCOUNT_NAME, account.name); + extras.putString(Settings.ACCOUNT_TYPE, account.type); } nullSafeCall(resolver, ContactsContract.AUTHORITY_URI, SET_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD, null, extras); -- GitLab From 5a4166738028356c3ffb9cf99debcd12688b68dd Mon Sep 17 00:00:00 2001 From: Ben Lin Date: Thu, 12 Sep 2024 06:50:43 +0000 Subject: [PATCH 153/447] Have Keyguard drive Unlock/Lock transition directly to Shell. Currently we have the following back-and-forth for keyguard transitions: 1) Keyguard/SystemUI talks to Core via ATMS to show/hide keyguard, or tell that keyguard is about to go away 2) Core shows apps 3) Core sends a transition request to Shell 4) Shell chooses KeyguardTransitionHandler to handle it and sends off to RemoteAnimation to animate keyguard going away This new change changes it so that instead of SystemUI -> Core, it's now SystemUI -> Shell: 1) Keyguard/SystemUI starts a Transition immediately as it show/hide/"about to hide" keyguard (keyguardGoingAway) 2) Shell uses KeyguardTransitionHandler to start the transition with a WCT=DisplayOperation.setKeyguardShowing(true/false) 3) Core receives WCT and calls on KeyguardController#setKeyguardShown to show apps 4) Transition system comes back to KeyguardTransitionHandler#startAnimation and process the new Changes w.r.t. app showing This change mostly focuses only on the simple unlock/lock use case, where the user just swipes up and keyguard unlocks. Other use cases need more care and will be addressed on subsequent CLs. This new logic is also behind a flag. Bug: 364930619 Test: Manually swipe up to see that it animates properly with Flag on Flag: com.android.window.flags.ensure_keyguard_does_transition_starting Change-Id: I3d770b41249a54452b8b01d7a3159f59168811ee --- .../keyguard/KeyguardTransitionHandler.java | 16 ++++++ .../shell/keyguard/KeyguardTransitions.java | 7 +++ ...wManagerLockscreenVisibilityManagerTest.kt | 3 ++ .../keyguard/KeyguardViewMediator.java | 50 +++++++++++++------ ...indowManagerLockscreenVisibilityManager.kt | 19 ++++++- .../android/server/wm/KeyguardController.java | 23 ++++++++- .../server/wm/WindowOrganizerController.java | 2 +- 7 files changed, 101 insertions(+), 19 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java index abec3b9c0c3b..f8d2011d0934 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java @@ -28,6 +28,8 @@ import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_OCCLUDING; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_UNOCCLUDING; import static android.view.WindowManager.TRANSIT_SLEEP; +import static android.view.WindowManager.TRANSIT_TO_BACK; +import static android.view.WindowManager.TRANSIT_TO_FRONT; import static com.android.wm.shell.shared.TransitionUtil.isOpeningType; @@ -44,6 +46,7 @@ import android.view.SurfaceControl; import android.view.WindowManager; import android.window.IRemoteTransition; import android.window.IRemoteTransitionFinishedCallback; +import android.window.KeyguardState; import android.window.TransitionInfo; import android.window.TransitionRequestInfo; import android.window.WindowContainerToken; @@ -388,5 +391,18 @@ public class KeyguardTransitionHandler mMainExecutor.execute(() -> mIsLaunchingActivityOverLockscreen = isLaunchingActivityOverLockscreen); } + + @Override + public void startKeyguardTransition(boolean keyguardShowing, boolean aodShowing) { + final WindowContainerTransaction wct = new WindowContainerTransaction(); + final KeyguardState keyguardState = + new KeyguardState.Builder(android.view.Display.DEFAULT_DISPLAY) + .setKeyguardShowing(keyguardShowing).setAodShowing(aodShowing).build(); + wct.addKeyguardState(keyguardState); + mMainExecutor.execute(() -> { + mTransitions.startTransition(keyguardShowing ? TRANSIT_TO_FRONT : TRANSIT_TO_BACK, + wct, KeyguardTransitionHandler.this); + }); + } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitions.java index b7245b91f36c..1d349e6c96e0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitions.java @@ -44,4 +44,11 @@ public interface KeyguardTransitions { * Notify whether keyguard has created a remote animation runner for next app launch. */ default void setLaunchingActivityOverLockscreen(boolean isLaunchingActivityOverLockscreen) {} + + /** + * Notifies Shell to start a keyguard transition directly. + * @param keyguardShowing whether keyguard is showing or not. + * @param aodShowing whether aod is showing or not. + */ + default void startKeyguardTransition(boolean keyguardShowing, boolean aodShowing) {} } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt index 43c7ed6a769d..9c58e2b987a1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt @@ -25,6 +25,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardDismissTransition import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.time.FakeSystemClock +import com.android.wm.shell.keyguard.KeyguardTransitions import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -46,6 +47,7 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() { @Mock private lateinit var keyguardSurfaceBehindAnimator: KeyguardSurfaceBehindParamsApplier @Mock private lateinit var keyguardDismissTransitionInteractor: KeyguardDismissTransitionInteractor + @Mock private lateinit var keyguardTransitions: KeyguardTransitions @Before fun setUp() { @@ -59,6 +61,7 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() { keyguardStateController = keyguardStateController, keyguardSurfaceBehindAnimator = keyguardSurfaceBehindAnimator, keyguardDismissTransitionInteractor = keyguardDismissTransitionInteractor, + keyguardTransitions = keyguardTransitions, ) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 9c7cc81c34aa..2052459692b2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -178,6 +178,7 @@ import com.android.systemui.util.settings.SecureSettings; import com.android.systemui.util.settings.SystemSettings; import com.android.systemui.util.time.SystemClock; import com.android.systemui.wallpapers.data.repository.WallpaperRepository; +import com.android.window.flags.Flags; import com.android.wm.shell.keyguard.KeyguardTransitions; import dagger.Lazy; @@ -236,6 +237,9 @@ import java.util.function.Consumer; */ public class KeyguardViewMediator implements CoreStartable, Dumpable, StatusBarStateController.StateListener { + + private static final boolean ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS = + Flags.ensureKeyguardDoesTransitionStarting(); private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000; private static final long KEYGUARD_DONE_PENDING_TIMEOUT_MS = 3000; @@ -2865,9 +2869,14 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, return; } - try { - mActivityTaskManagerService.setLockScreenShown(showing, aodShowing); - } catch (RemoteException ignored) { + if (ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS) { + mKeyguardTransitions.startKeyguardTransition(showing, aodShowing); + } else { + try { + + mActivityTaskManagerService.setLockScreenShown(showing, aodShowing); + } catch (RemoteException ignored) { + } } }); } @@ -2998,18 +3007,23 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, // Handled in WmLockscreenVisibilityManager if flag is enabled. if (!KeyguardWmStateRefactor.isEnabled()) { - // Don't actually hide the Keyguard at the moment, wait for window manager - // until it tells us it's safe to do so with startKeyguardExitAnimation. - // Posting to mUiOffloadThread to ensure that calls to ActivityTaskManager - // will be in order. - final int keyguardFlag = flags; - mUiBgExecutor.execute(() -> { - try { - mActivityTaskManagerService.keyguardGoingAway(keyguardFlag); - } catch (RemoteException e) { - Log.e(TAG, "Error while calling WindowManager", e); - } - }); + // Don't actually hide the Keyguard at the moment, wait for window manager + // until it tells us it's safe to do so with startKeyguardExitAnimation. + // Posting to mUiOffloadThread to ensure that calls to ActivityTaskManager + // will be in order. + final int keyguardFlag = flags; + mUiBgExecutor.execute(() -> { + if (ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS) { + mKeyguardTransitions.startKeyguardTransition( + false /* keyguardShowing */, false /* aodShowing */); + return; + } + try { + mActivityTaskManagerService.keyguardGoingAway(keyguardFlag); + } catch (RemoteException e) { + Log.e(TAG, "Error while calling WindowManager", e); + } + }); } Trace.endSection(); @@ -3464,6 +3478,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, public void showSurfaceBehindKeyguard() { mSurfaceBehindRemoteAnimationRequested = true; + if (ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS) { + mKeyguardTransitions.startKeyguardTransition( + false /* keyguardShowing */, false /* aodShowing */); + return; + } + try { int flags = KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS | KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt index e89594e58aa0..032af94e62aa 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt @@ -26,6 +26,8 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.domain.interactor.KeyguardDismissTransitionInteractor import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindParamsApplier import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.window.flags.Flags +import com.android.wm.shell.keyguard.KeyguardTransitions import java.util.concurrent.Executor import javax.inject.Inject @@ -42,6 +44,7 @@ constructor( private val keyguardStateController: KeyguardStateController, private val keyguardSurfaceBehindAnimator: KeyguardSurfaceBehindParamsApplier, private val keyguardDismissTransitionInteractor: KeyguardDismissTransitionInteractor, + private val keyguardTransitions: KeyguardTransitions ) { /** @@ -97,6 +100,9 @@ constructor( /** Callback provided by WM to call once we're done with the going away animation. */ private var goingAwayRemoteAnimationFinishedCallback: IRemoteAnimationFinishedCallback? = null + private val enableNewKeyguardShellTransitions: Boolean = + Flags.ensureKeyguardDoesTransitionStarting() + /** * Set the visibility of the surface behind the keyguard, making the appropriate calls to Window * Manager to effect the change. @@ -114,7 +120,14 @@ constructor( return } + + if (visible) { + if (enableNewKeyguardShellTransitions) { + keyguardTransitions.startKeyguardTransition(false /* keyguardShowing */, false /* aodShowing */) + isKeyguardGoingAway = true + return + } // Make the surface visible behind the keyguard by calling keyguardGoingAway. The // lockscreen is still showing as well, allowing us to animate unlocked. Log.d(TAG, "ActivityTaskManagerService#keyguardGoingAway()") @@ -220,7 +233,11 @@ constructor( "isLockscreenShowing=$lockscreenShowing, " + "aodVisible=$aodVisible)." ) - activityTaskManagerService.setLockScreenShown(lockscreenShowing, aodVisible) + if (enableNewKeyguardShellTransitions) { + keyguardTransitions.startKeyguardTransition(lockscreenShowing, aodVisible) + } else { + activityTaskManagerService.setLockScreenShown(lockscreenShowing, aodVisible) + } this.isLockscreenShowing = lockscreenShowing this.isAodVisible = aodVisible } diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index 0c489d6207e9..2fde5aaef5d4 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -62,6 +62,7 @@ import android.view.WindowManager; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.policy.WindowManagerPolicy; +import com.android.window.flags.Flags; import java.io.PrintWriter; @@ -73,6 +74,9 @@ import java.io.PrintWriter; */ class KeyguardController { + private static final boolean ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS = + Flags.ensureKeyguardDoesTransitionStarting(); + private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardController" : TAG_ATM; static final String KEYGUARD_SLEEP_TOKEN_TAG = "keyguard"; @@ -201,6 +205,19 @@ class KeyguardController { setWakeTransitionReady(); return; } + + if (ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS) { + final TransitionController transitionController = + mWindowManager.mAtmService.getTransitionController(); + final Transition transition = transitionController.getCollectingTransition(); + if (transition != null && displayId == DEFAULT_DISPLAY) { + if (!keyguardShowing && state.mKeyguardShowing) { + transition.addFlag(TRANSIT_FLAG_KEYGUARD_GOING_AWAY); + } else if (keyguardShowing && !state.mKeyguardShowing) { + transition.addFlag(TRANSIT_FLAG_KEYGUARD_APPEARING); + } + } + } // Update the task snapshot if the screen will not be turned off. To make sure that the // unlocking animation can animate consistent content. The conditions are: // - Either AOD or keyguard changes to be showing. So if the states change individually, @@ -231,8 +248,10 @@ class KeyguardController { || (keyguardShowing && !Display.isOffState(dc.getDisplayInfo().state))) { // Keyguard decided to show or stopped going away. Send a transition to animate back // to the locked state before holding the sleep token again - dc.requestTransitionAndLegacyPrepare( - TRANSIT_TO_FRONT, TRANSIT_FLAG_KEYGUARD_APPEARING); + if (!ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS) { + dc.requestTransitionAndLegacyPrepare( + TRANSIT_TO_FRONT, TRANSIT_FLAG_KEYGUARD_APPEARING); + } dc.mWallpaperController.adjustWallpaperWindows(); dc.executeAppTransition(); } diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 8a7eefab6445..2229807f5db1 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -1802,8 +1802,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub int displayId = keyguardState.getDisplayId(); boolean keyguardShowing = keyguardState.getKeyguardShowing(); boolean aodShowing = keyguardState.getAodShowing(); + mService.mKeyguardController.setKeyguardShown(displayId, keyguardShowing, aodShowing); } - // TODO: At the moment, this does nothing. return effects; } -- GitLab From 0afaafeb602b5db7788d27b05f2f34b8f81ae262 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Mon, 7 Oct 2024 11:41:40 -0700 Subject: [PATCH 154/447] Fixes for errorprone update When updating errorprone from 2.23.0 -> 2.32.0, more issues are found. Bug: 253827323 Flag: EXEMPT refactor Test: m RUN_ERROR_PRONE=true javac-check Change-Id: I3f62c29d7c811421934e2386f2e9c8a76ef9da96 --- .../src/android/app/ActivityManagerTest.java | 1 - .../android/app/activity/ActivityManagerTest.java | 6 ------ .../android/settingslib/wifi/WifiUtilsTest.java | 14 -------------- .../stack/NotificationStackScrollLayoutTest.java | 4 ++-- .../server/display/PersistentDataStoreTest.java | 1 - ...splayRotationImmersiveAppCompatPolicyTests.java | 2 -- 6 files changed, 2 insertions(+), 26 deletions(-) diff --git a/core/tests/coretests/src/android/app/ActivityManagerTest.java b/core/tests/coretests/src/android/app/ActivityManagerTest.java index 3c042bac895d..536360f3ed3e 100644 --- a/core/tests/coretests/src/android/app/ActivityManagerTest.java +++ b/core/tests/coretests/src/android/app/ActivityManagerTest.java @@ -60,7 +60,6 @@ public class ActivityManagerTest { public void testProcState() throws Exception { // For the moment mostly want to confirm we don't crash assertNotNull(ActivityManager.procStateToString(PROCESS_STATE_SERVICE)); - assertNotNull(ActivityManager.processStateAmToProto(PROCESS_STATE_SERVICE)); assertTrue(ActivityManager.isProcStateBackground(PROCESS_STATE_SERVICE)); assertFalse(ActivityManager.isProcStateCached(PROCESS_STATE_SERVICE)); assertFalse(ActivityManager.isForegroundService(PROCESS_STATE_SERVICE)); diff --git a/core/tests/coretests/src/android/app/activity/ActivityManagerTest.java b/core/tests/coretests/src/android/app/activity/ActivityManagerTest.java index b972882e68e6..cd524214e6af 100644 --- a/core/tests/coretests/src/android/app/activity/ActivityManagerTest.java +++ b/core/tests/coretests/src/android/app/activity/ActivityManagerTest.java @@ -111,12 +111,6 @@ public class ActivityManagerTest extends AndroidTestCase { assertEquals(config.reqKeyboardType, vconfig.keyboard); assertEquals(config.reqTouchScreen, vconfig.touchscreen); assertEquals(config.reqNavigation, vconfig.navigation); - if (vconfig.navigation == Configuration.NAVIGATION_NONAV) { - assertNotNull(config.reqInputFeatures & ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV); - } - if (vconfig.keyboard != Configuration.KEYBOARD_UNDEFINED) { - assertNotNull(config.reqInputFeatures & ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD); - } } @SmallTest diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java index 529301138da3..d8b6707b9118 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java @@ -206,20 +206,6 @@ public class WifiUtilsTest { WifiUtils.getHotspotIconResource(NetworkProviderInfo.DEVICE_TYPE_UNKNOWN); } - @Test - public void getHotspotIconResource_deviceTypeExists_shouldNotNull() { - assertThat(WifiUtils.getHotspotIconResource(NetworkProviderInfo.DEVICE_TYPE_PHONE)) - .isNotNull(); - assertThat(WifiUtils.getHotspotIconResource(NetworkProviderInfo.DEVICE_TYPE_TABLET)) - .isNotNull(); - assertThat(WifiUtils.getHotspotIconResource(NetworkProviderInfo.DEVICE_TYPE_LAPTOP)) - .isNotNull(); - assertThat(WifiUtils.getHotspotIconResource(NetworkProviderInfo.DEVICE_TYPE_WATCH)) - .isNotNull(); - assertThat(WifiUtils.getHotspotIconResource(NetworkProviderInfo.DEVICE_TYPE_AUTO)) - .isNotNull(); - } - @Test public void testInternetIconInjector_getIcon_returnsCorrectValues() { WifiUtils.InternetIconInjector iconInjector = new WifiUtils.InternetIconInjector(mContext); 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 12f3ef3cf553..f80fdc8ca458 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 @@ -428,8 +428,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { ArgumentCaptor captor = ArgumentCaptor.forClass(FooterView.class); verify(mStackScroller).setFooterView(captor.capture()); - assertNotNull(captor.getValue().findViewById(R.id.manage_text).hasOnClickListeners()); - assertNotNull(captor.getValue().findViewById(R.id.dismiss_text).hasOnClickListeners()); + assertNotNull(captor.getValue().findViewById(R.id.manage_text)); + assertNotNull(captor.getValue().findViewById(R.id.dismiss_text)); } @Test diff --git a/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java b/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java index 5676a388acff..6d14065b6248 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java @@ -459,7 +459,6 @@ public class PersistentDataStoreTest { ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); newInjector.setReadStream(bais); newDataStore.loadIfNeeded(); - assertNotNull(newDataStore.getUserPreferredRefreshRate(testDisplayDevice)); assertEquals(85.3f, mDataStore.getUserPreferredRefreshRate(testDisplayDevice), 01.f); assertEquals(85.3f, newDataStore.getUserPreferredRefreshRate(testDisplayDevice), 0.1f); } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java index b1057032eb36..393181705f34 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java @@ -26,7 +26,6 @@ import static android.content.res.Configuration.ORIENTATION_UNDEFINED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static org.junit.Assert.assertFalse; @@ -73,7 +72,6 @@ public class DisplayRotationImmersiveAppCompatPolicyTests extends WindowTestsBas when(mMockWindowState.getRequestedVisibleTypes()).thenReturn(0); when(mMockActivityRecord.findMainWindow()).thenReturn(mMockWindowState); - spy(mDisplayContent); doReturn(mMockActivityRecord).when(mDisplayContent).topRunningActivity(); when(mDisplayContent.getIgnoreOrientationRequest()).thenReturn(true); -- GitLab From bdadc6d240239560a114d5ad4f51366393db502c Mon Sep 17 00:00:00 2001 From: John Reck Date: Fri, 4 Oct 2024 16:35:27 -0400 Subject: [PATCH 155/447] Fix backdrop effect for prerotation When doing prerotation the matrix math didn't work out due to makeImageSnapshot() being rotated already, but then drawn again into a rotating matrix. Fix this by having BackdropFilterDrawable do everything in post-rotation space. Bug: 353827335 Test: SilkFX view blur behind demo Flag: EXEMPT bugfix Change-Id: I7b41d95e7e5f15434f9c6481534c74ee998a83ef --- .../pipeline/skia/BackdropFilterDrawable.cpp | 12 +- .../tests/unit/RenderNodeDrawableTests.cpp | 2 +- .../SilkFX/res/layout/view_blur_behind.xml | 148 ++++++++++++++++++ .../src/com/android/test/silkfx/Main.kt | 3 +- .../silkfx/materials/BlurBehindContainer.kt | 30 ++++ 5 files changed, 191 insertions(+), 4 deletions(-) create mode 100644 tests/graphics/SilkFX/res/layout/view_blur_behind.xml create mode 100644 tests/graphics/SilkFX/src/com/android/test/silkfx/materials/BlurBehindContainer.kt diff --git a/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp b/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp index e81cbfb508ae..b6d30b06dc5b 100644 --- a/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp +++ b/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp @@ -86,9 +86,17 @@ void BackdropFilterDrawable::onDraw(SkCanvas* canvas) { backdropImage = SkImages::MakeWithFilter(backdropImage, backdropFilter, imageSubset, imageSubset, &mOutSubset, &mOutOffset); } - canvas->drawImageRect(backdropImage, SkRect::Make(mOutSubset), mDstBounds, + + // backdropImage & mOutSubset are in post-pre-rotation space, whereas mDstBounds is in + // prerotation space. So map dst bounds to post-pre-rotation space & draw there + SkRect dst; + canvas->getTotalMatrix().mapRect(&dst, mDstBounds); + canvas->save(); + canvas->resetMatrix(); + canvas->drawImageRect(backdropImage, SkRect::Make(mOutSubset), dst, SkSamplingOptions(SkFilterMode::kLinear), &mPaint, - SkCanvas::kStrict_SrcRectConstraint); + SkCanvas::kFast_SrcRectConstraint); + canvas->restore(); } } // namespace skiapipeline diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp index ca540874833c..4b29100c55a6 100644 --- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp +++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp @@ -1280,7 +1280,7 @@ RENDERTHREAD_TEST(BackdropFilterDrawable, drawing) { canvas->drawDrawable(&backdropDrawable); // the drawable is still visible, ok to draw. EXPECT_EQ(2, canvas->mDrawCounter); - EXPECT_EQ(SkRect::MakeLTRB(0, 0, CANVAS_WIDTH - 30, CANVAS_HEIGHT - 30), canvas->mDstBounds); + EXPECT_EQ(SkRect::MakeLTRB(30, 30, CANVAS_WIDTH, CANVAS_HEIGHT), canvas->mDstBounds); canvas->translate(CANVAS_WIDTH, CANVAS_HEIGHT); canvas->drawDrawable(&drawable); diff --git a/tests/graphics/SilkFX/res/layout/view_blur_behind.xml b/tests/graphics/SilkFX/res/layout/view_blur_behind.xml new file mode 100644 index 000000000000..83b1fa4b73cb --- /dev/null +++ b/tests/graphics/SilkFX/res/layout/view_blur_behind.xml @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/graphics/SilkFX/src/com/android/test/silkfx/Main.kt b/tests/graphics/SilkFX/src/com/android/test/silkfx/Main.kt index 59a6078376cf..6b6d3b8d3d12 100644 --- a/tests/graphics/SilkFX/src/com/android/test/silkfx/Main.kt +++ b/tests/graphics/SilkFX/src/com/android/test/silkfx/Main.kt @@ -61,7 +61,8 @@ private val AllDemos = listOf( )), DemoGroup("Materials", listOf( Demo("Glass", GlassActivity::class), - Demo("Background Blur", BackgroundBlurActivity::class) + Demo("Background Blur", BackgroundBlurActivity::class), + Demo("View blur behind", R.layout.view_blur_behind, commonControls = false) )) ) diff --git a/tests/graphics/SilkFX/src/com/android/test/silkfx/materials/BlurBehindContainer.kt b/tests/graphics/SilkFX/src/com/android/test/silkfx/materials/BlurBehindContainer.kt new file mode 100644 index 000000000000..ce6348e32969 --- /dev/null +++ b/tests/graphics/SilkFX/src/com/android/test/silkfx/materials/BlurBehindContainer.kt @@ -0,0 +1,30 @@ +/* + * 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.test.silkfx.materials + +import android.content.Context +import android.graphics.RenderEffect +import android.graphics.Shader +import android.util.AttributeSet +import android.widget.FrameLayout + +class BlurBehindContainer(context: Context, attributeSet: AttributeSet) : FrameLayout(context, attributeSet) { + override fun onFinishInflate() { + super.onFinishInflate() + setBackdropRenderEffect( + RenderEffect.createBlurEffect(16.0f, 16.0f, Shader.TileMode.CLAMP)) + } +} \ No newline at end of file -- GitLab From 25d6e3312d678766a25d584503253090e76043d5 Mon Sep 17 00:00:00 2001 From: John Reck Date: Fri, 4 Oct 2024 16:55:31 -0400 Subject: [PATCH 156/447] Simplify BackdropFilterDrawable Remove a bunch of state that didn't need to be state Only makeImageSnapshot of the bounds we need to sample Bug: 353827335 Test: SilkFX view blur behind demo Flag: EXEMPT bugfix Change-Id: I37d39d40eb48f2817dde286bcdf65d636bf28d2f --- .../pipeline/skia/BackdropFilterDrawable.cpp | 65 ++++++------------- .../pipeline/skia/BackdropFilterDrawable.h | 15 +---- 2 files changed, 22 insertions(+), 58 deletions(-) diff --git a/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp b/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp index b6d30b06dc5b..c0ef4b14d53f 100644 --- a/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp +++ b/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp @@ -29,37 +29,6 @@ namespace android { namespace uirenderer { namespace skiapipeline { -BackdropFilterDrawable::~BackdropFilterDrawable() {} - -bool BackdropFilterDrawable::prepareToDraw(SkCanvas* canvas, const RenderProperties& properties, - int backdropImageWidth, int backdropImageHeight) { - // the drawing bounds for blurred content. - mDstBounds.setWH(properties.getWidth(), properties.getHeight()); - - float alphaMultiplier = 1.0f; - RenderNodeDrawable::setViewProperties(properties, canvas, &alphaMultiplier, true); - - // get proper subset for previous content. - canvas->getTotalMatrix().mapRect(&mImageSubset, mDstBounds); - SkRect imageSubset(mImageSubset); - // ensure the subset is inside bounds of previous content. - if (!mImageSubset.intersect(SkRect::MakeWH(backdropImageWidth, backdropImageHeight))) { - return false; - } - - // correct the drawing bounds if subset was changed. - if (mImageSubset != imageSubset) { - SkMatrix inverse; - if (canvas->getTotalMatrix().invert(&inverse)) { - inverse.mapRect(&mDstBounds, mImageSubset); - } - } - - // follow the alpha from the target RenderNode. - mPaint.setAlpha(properties.layerProperties().alpha() * alphaMultiplier); - return true; -} - void BackdropFilterDrawable::onDraw(SkCanvas* canvas) { const RenderProperties& properties = mTargetRenderNode->properties(); auto* backdropFilter = properties.layerProperties().getBackdropImageFilter(); @@ -68,33 +37,41 @@ void BackdropFilterDrawable::onDraw(SkCanvas* canvas) { return; } - auto backdropImage = surface->makeImageSnapshot(); - // sync necessary properties from target RenderNode. - if (!prepareToDraw(canvas, properties, backdropImage->width(), backdropImage->height())) { + SkRect srcBounds = SkRect::MakeWH(properties.getWidth(), properties.getHeight()); + + float alphaMultiplier = 1.0f; + RenderNodeDrawable::setViewProperties(properties, canvas, &alphaMultiplier, true); + SkPaint paint; + paint.setAlpha(properties.layerProperties().alpha() * alphaMultiplier); + + SkRect surfaceSubset; + canvas->getTotalMatrix().mapRect(&surfaceSubset, srcBounds); + if (!surfaceSubset.intersect(SkRect::MakeWH(surface->width(), surface->height()))) { return; } - auto imageSubset = mImageSubset.roundOut(); + auto backdropImage = surface->makeImageSnapshot(surfaceSubset.roundOut()); + + SkIRect imageBounds = SkIRect::MakeWH(backdropImage->width(), backdropImage->height()); + SkIPoint offset; + SkIRect imageSubset; + #ifdef __ANDROID__ if (canvas->recordingContext()) { backdropImage = SkImages::MakeWithFilter(canvas->recordingContext(), backdropImage, backdropFilter, - imageSubset, imageSubset, &mOutSubset, &mOutOffset); + imageBounds, imageBounds, &imageSubset, &offset); } else #endif { - backdropImage = SkImages::MakeWithFilter(backdropImage, backdropFilter, imageSubset, - imageSubset, &mOutSubset, &mOutOffset); + backdropImage = SkImages::MakeWithFilter(backdropImage, backdropFilter, imageBounds, + imageBounds, &imageSubset, &offset); } - // backdropImage & mOutSubset are in post-pre-rotation space, whereas mDstBounds is in - // prerotation space. So map dst bounds to post-pre-rotation space & draw there - SkRect dst; - canvas->getTotalMatrix().mapRect(&dst, mDstBounds); canvas->save(); canvas->resetMatrix(); - canvas->drawImageRect(backdropImage, SkRect::Make(mOutSubset), dst, - SkSamplingOptions(SkFilterMode::kLinear), &mPaint, + canvas->drawImageRect(backdropImage, SkRect::Make(imageSubset), surfaceSubset, + SkSamplingOptions(SkFilterMode::kLinear), &paint, SkCanvas::kFast_SrcRectConstraint); canvas->restore(); } diff --git a/libs/hwui/pipeline/skia/BackdropFilterDrawable.h b/libs/hwui/pipeline/skia/BackdropFilterDrawable.h index 9e35837675ae..5e216a1fc3c3 100644 --- a/libs/hwui/pipeline/skia/BackdropFilterDrawable.h +++ b/libs/hwui/pipeline/skia/BackdropFilterDrawable.h @@ -37,23 +37,10 @@ public: BackdropFilterDrawable(RenderNode* renderNode, SkCanvas* canvas) : mTargetRenderNode(renderNode), mBounds(canvas->getLocalClipBounds()) {} - ~BackdropFilterDrawable(); + ~BackdropFilterDrawable() = default; private: RenderNode* mTargetRenderNode; - SkPaint mPaint; - - SkRect mDstBounds; - SkRect mImageSubset; - SkIRect mOutSubset; - SkIPoint mOutOffset; - - /** - * Check all necessary properties before actual drawing. - * Return true if ready to draw. - */ - bool prepareToDraw(SkCanvas* canvas, const RenderProperties& properties, int backdropImageWidth, - int backdropImageHeight); protected: void onDraw(SkCanvas* canvas) override; -- GitLab From 2a31d23688d0333449d872396e9caa4f151c5db0 Mon Sep 17 00:00:00 2001 From: John Reck Date: Fri, 4 Oct 2024 23:42:29 -0400 Subject: [PATCH 157/447] Add benchmark for backdrop blur Test: this Flag: EXEMPT test only Change-Id: If8778fcd2c82a14827447fd8dd2a1b7b5114e244 --- .../hwui/tests/common/scenes/BackdropBlur.cpp | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 libs/hwui/tests/common/scenes/BackdropBlur.cpp diff --git a/libs/hwui/tests/common/scenes/BackdropBlur.cpp b/libs/hwui/tests/common/scenes/BackdropBlur.cpp new file mode 100644 index 000000000000..a1133ffe96ef --- /dev/null +++ b/libs/hwui/tests/common/scenes/BackdropBlur.cpp @@ -0,0 +1,67 @@ +/* + * 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 + +#include "SkImageFilter.h" +#include "SkImageFilters.h" +#include "TestSceneBase.h" +#include "utils/Blur.h" + +class BackdropBlurAnimation : public TestScene { +private: + std::unique_ptr listView; + +public: + explicit BackdropBlurAnimation(const TestScene::Options& opts) { + listView.reset(TestScene::testMap()["listview"].createScene(opts)); + } + + void createContent(int width, int height, Canvas& canvas) override { + sp list = TestUtils::createNode( + 0, 0, width, height, + [this, width, height](RenderProperties& props, Canvas& canvas) { + props.setClipToBounds(false); + listView->createContent(width, height, canvas); + }); + + canvas.drawRenderNode(list.get()); + + int x = width / 8; + int y = height / 4; + sp blurNode = TestUtils::createNode( + x, y, width - x, height - y, [](RenderProperties& props, Canvas& canvas) { + props.mutableOutline().setRoundRect(0, 0, props.getWidth(), props.getHeight(), + dp(16), 1); + props.mutableOutline().setShouldClip(true); + sk_sp blurFilter = SkImageFilters::Blur( + Blur::convertRadiusToSigma(dp(8)), Blur::convertRadiusToSigma(dp(8)), + SkTileMode::kClamp, nullptr, nullptr); + props.mutateLayerProperties().setBackdropImageFilter(blurFilter.get()); + canvas.drawColor(0x33000000, SkBlendMode::kSrcOver); + }); + + canvas.drawRenderNode(blurNode.get()); + } + + void doFrame(int frameNr) override { listView->doFrame(frameNr); } +}; + +static TestScene::Registrar _BackdropBlur(TestScene::Info{ + "backdropblur", "A rounded rect that does a blur-behind of a sky animation.", + [](const TestScene::Options& opts) -> test::TestScene* { + return new BackdropBlurAnimation(opts); + }}); -- GitLab From f0a3a86ffffc6f30b6b48a907de3f6533121e65a Mon Sep 17 00:00:00 2001 From: Ibrahim Yilmaz Date: Mon, 7 Oct 2024 21:13:32 +0000 Subject: [PATCH 158/447] Fix LockscreenOtpRedaction flag usage in cancelContentViewFrees Flag: android.app.redact_sensitive_content_notifications_on_lockscreen Bug: 352020702 Change-Id: Ib07a75eb0bc87871413531184336d15fdfe8777c Test: atest NotificationRowContentBinderImplTest --- .../notification/row/NotificationContentInflater.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java index 36e3e92e4063..69f45db40c65 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java @@ -360,11 +360,11 @@ public class NotificationContentInflater implements NotificationRowContentBinder if ((contentViews & FLAG_CONTENT_VIEW_PUBLIC) != 0) { row.getPublicLayout().removeContentInactiveRunnable(VISIBLE_TYPE_CONTRACTED); } - if (AsyncHybridViewInflation.isEnabled() + if (LockscreenOtpRedaction.isEnabled() && (contentViews & FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE) != 0) { row.getPublicLayout().removeContentInactiveRunnable(VISIBLE_TYPE_SINGLELINE); } - if (LockscreenOtpRedaction.isEnabled() + if (AsyncHybridViewInflation.isEnabled() && (contentViews & FLAG_CONTENT_VIEW_SINGLE_LINE) != 0) { row.getPrivateLayout().removeContentInactiveRunnable(VISIBLE_TYPE_SINGLELINE); } -- GitLab From bdc9fd88318e1f5acc6531b27cc7aeeaf33ef7f6 Mon Sep 17 00:00:00 2001 From: "Priyanka Advani (xWF)" Date: Mon, 7 Oct 2024 21:22:13 +0000 Subject: [PATCH 159/447] Revert "Drop VDM permissions from Shell" Revert submission 29561525-no-vdm-shell Reason for revert: Droidmonitor created revert due to b/372058363. Will be verifying through ABTD before submission. Reverted changes: /q/submissionid:29561525-no-vdm-shell Change-Id: I2d8dddb4a761d5a27e3b86875b1a8f8ce09eda9c --- packages/Shell/AndroidManifest.xml | 6 ++ .../tests/servicestests/AndroidManifest.xml | 1 - .../server/appop/AppOpsActiveWatcherTest.java | 1 + .../appop/AppOpsDeviceAwareServiceTest.java | 1 + .../server/appop/AppOpsNotedWatcherTest.java | 25 ++++-- .../appop/AppOpsStartedWatcherTest.java | 26 ++++-- .../VirtualDeviceManagerServiceTest.java | 81 +++++++++++-------- .../MediaProjectionManagerServiceTest.java | 9 +-- 8 files changed, 97 insertions(+), 53 deletions(-) diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 408ed1e861c3..456fedf912ff 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -743,6 +743,12 @@ + + + + + + diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml index c645c0852f1b..2724149d859f 100644 --- a/services/tests/servicestests/AndroidManifest.xml +++ b/services/tests/servicestests/AndroidManifest.xml @@ -113,7 +113,6 @@ - diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java index 840e5c58078b..c970a3e34d12 100644 --- a/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java +++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsActiveWatcherTest.java @@ -65,6 +65,7 @@ public class AppOpsActiveWatcherTest { VirtualDeviceRule.withAdditionalPermissions( Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, + Manifest.permission.CREATE_VIRTUAL_DEVICE, Manifest.permission.GET_APP_OPS_STATS ); private static final long NOTIFICATION_TIMEOUT_MILLIS = 5000; diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsDeviceAwareServiceTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsDeviceAwareServiceTest.java index e3eca6d5fd83..7f2327aa4f24 100644 --- a/services/tests/servicestests/src/com/android/server/appop/AppOpsDeviceAwareServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsDeviceAwareServiceTest.java @@ -58,6 +58,7 @@ public class AppOpsDeviceAwareServiceTest { VirtualDeviceRule.withAdditionalPermissions( Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, + Manifest.permission.CREATE_VIRTUAL_DEVICE, Manifest.permission.GET_APP_OPS_STATS); private static final String ATTRIBUTION_TAG_1 = "attributionTag1"; diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java index b0846f62628c..1abd4eb6157f 100644 --- a/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java +++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java @@ -22,14 +22,16 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; import android.app.AppOpsManager; import android.app.AppOpsManager.OnOpNotedListener; import android.companion.virtual.VirtualDeviceManager; +import android.companion.virtual.VirtualDeviceParams; import android.content.AttributionSource; import android.content.Context; import android.os.Process; -import android.virtualdevice.cts.common.VirtualDeviceRule; +import android.virtualdevice.cts.common.FakeAssociationRule; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -40,6 +42,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; +import java.util.concurrent.atomic.AtomicInteger; + /** * Tests watching noted ops. */ @@ -47,7 +51,7 @@ import org.mockito.InOrder; @RunWith(AndroidJUnit4.class) public class AppOpsNotedWatcherTest { @Rule - public VirtualDeviceRule mVirtualDeviceRule = VirtualDeviceRule.createDefault(); + public FakeAssociationRule mFakeAssociationRule = new FakeAssociationRule(); private static final long NOTIFICATION_TIMEOUT_MILLIS = 5000; @Test @@ -115,12 +119,19 @@ public class AppOpsNotedWatcherTest { public void testWatchNotedOpsForExternalDevice() { final AppOpsManager.OnOpNotedListener listener = mock( AppOpsManager.OnOpNotedListener.class); - final VirtualDeviceManager.VirtualDevice virtualDevice = - mVirtualDeviceRule.createManagedVirtualDevice(); - final int virtualDeviceId = virtualDevice.getDeviceId(); + final VirtualDeviceManager virtualDeviceManager = getContext().getSystemService( + VirtualDeviceManager.class); + AtomicInteger virtualDeviceId = new AtomicInteger(); + runWithShellPermissionIdentity(() -> { + final VirtualDeviceManager.VirtualDevice virtualDevice = + virtualDeviceManager.createVirtualDevice( + mFakeAssociationRule.getAssociationInfo().getId(), + new VirtualDeviceParams.Builder().setName("virtual_device").build()); + virtualDeviceId.set(virtualDevice.getDeviceId()); + }); AttributionSource attributionSource = new AttributionSource(Process.myUid(), getContext().getOpPackageName(), getContext().getAttributionTag(), - virtualDeviceId); + virtualDeviceId.get()); final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); appOpsManager.startWatchingNoted(new int[]{AppOpsManager.OP_FINE_LOCATION, @@ -131,7 +142,7 @@ public class AppOpsNotedWatcherTest { verify(listener, timeout(NOTIFICATION_TIMEOUT_MILLIS) .times(1)).onOpNoted(eq(AppOpsManager.OPSTR_FINE_LOCATION), eq(Process.myUid()), eq(getContext().getOpPackageName()), - eq(getContext().getAttributionTag()), eq(virtualDeviceId), + eq(getContext().getAttributionTag()), eq(virtualDeviceId.get()), eq(AppOpsManager.OP_FLAG_SELF), eq(AppOpsManager.MODE_ALLOWED)); appOpsManager.finishOp(getContext().getAttributionSource().getToken(), diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsStartedWatcherTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsStartedWatcherTest.java index d46fb90f40d6..8a6ba4d484f7 100644 --- a/services/tests/servicestests/src/com/android/server/appop/AppOpsStartedWatcherTest.java +++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsStartedWatcherTest.java @@ -16,6 +16,8 @@ package com.android.server.appop; +import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; + import static org.mockito.Mockito.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; @@ -26,10 +28,11 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import android.app.AppOpsManager; import android.app.AppOpsManager.OnOpStartedListener; import android.companion.virtual.VirtualDeviceManager; +import android.companion.virtual.VirtualDeviceParams; import android.content.AttributionSource; import android.content.Context; import android.os.Process; -import android.virtualdevice.cts.common.VirtualDeviceRule; +import android.virtualdevice.cts.common.FakeAssociationRule; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -40,13 +43,15 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; +import java.util.concurrent.atomic.AtomicInteger; + /** Tests watching started ops. */ @SmallTest @RunWith(AndroidJUnit4.class) public class AppOpsStartedWatcherTest { @Rule - public VirtualDeviceRule mVirtualDeviceRule = VirtualDeviceRule.createDefault(); + public FakeAssociationRule mFakeAssociationRule = new FakeAssociationRule(); private static final long NOTIFICATION_TIMEOUT_MILLIS = 5000; @Test @@ -119,13 +124,20 @@ public class AppOpsStartedWatcherTest { @Test public void testWatchStartedOpsForExternalDevice() { - final VirtualDeviceManager.VirtualDevice virtualDevice = - mVirtualDeviceRule.createManagedVirtualDevice(); - final int virtualDeviceId = virtualDevice.getDeviceId(); + final VirtualDeviceManager virtualDeviceManager = getContext().getSystemService( + VirtualDeviceManager.class); + AtomicInteger virtualDeviceId = new AtomicInteger(); + runWithShellPermissionIdentity(() -> { + final VirtualDeviceManager.VirtualDevice virtualDevice = + virtualDeviceManager.createVirtualDevice( + mFakeAssociationRule.getAssociationInfo().getId(), + new VirtualDeviceParams.Builder().setName("virtual_device").build()); + virtualDeviceId.set(virtualDevice.getDeviceId()); + }); final OnOpStartedListener listener = mock(OnOpStartedListener.class); AttributionSource attributionSource = new AttributionSource(Process.myUid(), getContext().getOpPackageName(), getContext().getAttributionTag(), - virtualDeviceId); + virtualDeviceId.get()); final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); appOpsManager.startWatchingStarted(new int[]{AppOpsManager.OP_FINE_LOCATION, @@ -138,7 +150,7 @@ public class AppOpsStartedWatcherTest { verify(listener, timeout(NOTIFICATION_TIMEOUT_MILLIS) .times(1)).onOpStarted(eq(AppOpsManager.OP_FINE_LOCATION), eq(Process.myUid()), eq(getContext().getOpPackageName()), - eq(getContext().getAttributionTag()), eq(virtualDeviceId), + eq(getContext().getAttributionTag()), eq(virtualDeviceId.get()), eq(AppOpsManager.OP_FLAG_SELF), eq(AppOpsManager.MODE_ALLOWED), eq(OnOpStartedListener.START_TYPE_STARTED), eq(AppOpsManager.ATTRIBUTION_FLAGS_NONE), diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java index e16bc05d24f5..4d067f6bfc62 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java @@ -50,6 +50,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.testng.Assert.assertThrows; +import android.Manifest; import android.app.WindowConfiguration; import android.app.admin.DevicePolicyManager; import android.companion.AssociationInfo; @@ -112,11 +113,10 @@ import android.view.Display; import android.view.DisplayInfo; import android.view.KeyEvent; import android.view.WindowManager; -import android.virtualdevice.cts.common.VirtualDeviceRule; import androidx.test.platform.app.InstrumentationRegistry; -import com.android.compatibility.common.util.SystemUtil; +import com.android.compatibility.common.util.AdoptShellPermissionsRule; import com.android.internal.app.BlockedAppStreamingActivity; import com.android.internal.os.BackgroundThread; import com.android.server.LocalServices; @@ -223,7 +223,9 @@ public class VirtualDeviceManagerServiceTest { public SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Rule - public VirtualDeviceRule mVirtualDeviceRule = VirtualDeviceRule.createDefault(); + public AdoptShellPermissionsRule mAdoptShellPermissionsRule = new AdoptShellPermissionsRule( + InstrumentationRegistry.getInstrumentation().getUiAutomation(), + Manifest.permission.CREATE_VIRTUAL_DEVICE); private Context mContext; private InputManagerMockHelper mInputManagerMockHelper; @@ -1067,65 +1069,64 @@ public class VirtualDeviceManagerServiceTest { @Test public void createVirtualDpad_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. - SystemUtil.runWithShellPermissionIdentity(() -> - assertThrows(SecurityException.class, - () -> mDeviceImpl.createVirtualDpad(DPAD_CONFIG, BINDER))); + try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { + assertThrows(SecurityException.class, + () -> mDeviceImpl.createVirtualDpad(DPAD_CONFIG, BINDER)); + } } @Test public void createVirtualKeyboard_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. - SystemUtil.runWithShellPermissionIdentity(() -> - assertThrows(SecurityException.class, - () -> mDeviceImpl.createVirtualKeyboard(KEYBOARD_CONFIG, BINDER))); + try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { + assertThrows(SecurityException.class, + () -> mDeviceImpl.createVirtualKeyboard(KEYBOARD_CONFIG, BINDER)); + } } @Test public void createVirtualMouse_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. - SystemUtil.runWithShellPermissionIdentity(() -> - assertThrows(SecurityException.class, - () -> mDeviceImpl.createVirtualMouse(MOUSE_CONFIG, BINDER))); + try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { + assertThrows(SecurityException.class, + () -> mDeviceImpl.createVirtualMouse(MOUSE_CONFIG, BINDER)); + } } @Test public void createVirtualTouchscreen_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. - SystemUtil.runWithShellPermissionIdentity(() -> - assertThrows(SecurityException.class, - () -> mDeviceImpl.createVirtualTouchscreen(TOUCHSCREEN_CONFIG, BINDER))); + try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { + assertThrows(SecurityException.class, + () -> mDeviceImpl.createVirtualTouchscreen(TOUCHSCREEN_CONFIG, BINDER)); + } } @Test public void createVirtualNavigationTouchpad_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. - SystemUtil.runWithShellPermissionIdentity(() -> - assertThrows(SecurityException.class, - () -> mDeviceImpl.createVirtualNavigationTouchpad( - NAVIGATION_TOUCHPAD_CONFIG, - BINDER))); + try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { + assertThrows(SecurityException.class, + () -> mDeviceImpl.createVirtualNavigationTouchpad(NAVIGATION_TOUCHPAD_CONFIG, + BINDER)); + } } @Test public void onAudioSessionStarting_noPermission_failsSecurityException() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); - // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. - SystemUtil.runWithShellPermissionIdentity(() -> - assertThrows(SecurityException.class, - () -> mDeviceImpl.onAudioSessionStarting( - DISPLAY_ID_1, mRoutingCallback, mConfigChangedCallback))); + try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { + assertThrows(SecurityException.class, + () -> mDeviceImpl.onAudioSessionStarting( + DISPLAY_ID_1, mRoutingCallback, mConfigChangedCallback)); + } } @Test public void onAudioSessionEnded_noPermission_failsSecurityException() { - // Shell doesn't have CREATE_VIRTUAL_DEVICE permission. - SystemUtil.runWithShellPermissionIdentity(() -> - assertThrows(SecurityException.class, () -> mDeviceImpl.onAudioSessionEnded())); + try (DropShellPermissionsTemporarily drop = new DropShellPermissionsTemporarily()) { + assertThrows(SecurityException.class, () -> mDeviceImpl.onAudioSessionEnded()); + } } @Test @@ -2001,4 +2002,18 @@ public class VirtualDeviceManagerServiceTest { /* notifyOnDeviceNearby= */ false, /* revoked= */ false, /* pending= */ false, /* timeApprovedMs= */0, /* lastTimeConnectedMs= */0, /* systemDataSyncFlags= */ -1); } + + /** Helper class to drop permissions temporarily and restore them at the end of a test. */ + static final class DropShellPermissionsTemporarily implements AutoCloseable { + DropShellPermissionsTemporarily() { + InstrumentationRegistry.getInstrumentation().getUiAutomation() + .dropShellPermissionIdentity(); + } + + @Override + public void close() { + InstrumentationRegistry.getInstrumentation().getUiAutomation() + .adoptShellPermissionIdentity(); + } + } } diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java index 7e22d74c64e1..425bb158f997 100644 --- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java @@ -1256,8 +1256,7 @@ public class MediaProjectionManagerServiceTest { Manifest.permission.BYPASS_ROLE_QUALIFICATION); roleManager.setBypassingRoleQualification(true); - roleManager.addRoleHolderAsUser(role, packageName, - /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, + roleManager.addRoleHolderAsUser(role, packageName, /* flags = */ 0, user, mContext.getMainExecutor(), success -> { if (success) { latch.countDown(); @@ -1272,9 +1271,9 @@ public class MediaProjectionManagerServiceTest { } catch (InterruptedException e) { throw new RuntimeException(e); } finally { - roleManager.removeRoleHolderAsUser(role, packageName, - /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, - mContext.getMainExecutor(), (aBool) -> {}); + roleManager.removeRoleHolderAsUser(role, packageName, 0, user, + mContext.getMainExecutor(), (aBool) -> { + }); roleManager.setBypassingRoleQualification(false); instrumentation.getUiAutomation() .dropShellPermissionIdentity(); -- GitLab From 3044debe28854b621960e19c5a5a54c3fd35351f Mon Sep 17 00:00:00 2001 From: Vlad Popa Date: Mon, 7 Oct 2024 15:49:45 -0700 Subject: [PATCH 160/447] Synchronizing the loudness codec dispatcher Flag: EXEMPT bugfix Test: manual Bug: 371849072 Change-Id: I469069bc5fcdbe2957dce3bde9538c1ee55b40d9 --- .../server/audio/LoudnessCodecHelper.java | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java index 01f770b1e89f..9fa5da47aae7 100644 --- a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java +++ b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java @@ -133,6 +133,9 @@ public class LoudnessCodecHelper { private static final EventLogger sLogger = new EventLogger( AudioService.LOG_NB_EVENTS_LOUDNESS_CODEC, "Loudness updates"); + private final Object mDispatcherLock = new Object(); + + @GuardedBy("mDispatcherLock") private final LoudnessRemoteCallbackList mLoudnessUpdateDispatchers = new LoudnessRemoteCallbackList(this); @@ -339,12 +342,16 @@ public class LoudnessCodecHelper { } void registerLoudnessCodecUpdatesDispatcher(ILoudnessCodecUpdatesDispatcher dispatcher) { - mLoudnessUpdateDispatchers.register(dispatcher, Binder.getCallingPid()); + synchronized (mDispatcherLock) { + mLoudnessUpdateDispatchers.register(dispatcher, Binder.getCallingPid()); + } } void unregisterLoudnessCodecUpdatesDispatcher( ILoudnessCodecUpdatesDispatcher dispatcher) { - mLoudnessUpdateDispatchers.unregister(dispatcher); + synchronized (mDispatcherLock) { + mLoudnessUpdateDispatchers.unregister(dispatcher); + } } void startLoudnessCodecUpdates(int sessionId) { @@ -640,17 +647,20 @@ public class LoudnessCodecHelper { Log.d(TAG, "dispatchNewLoudnessParameters: sessionId " + sessionId + " bundle: " + bundle); } - final int nbDispatchers = mLoudnessUpdateDispatchers.beginBroadcast(); - for (int i = 0; i < nbDispatchers; ++i) { - try { - mLoudnessUpdateDispatchers.getBroadcastItem(i) - .dispatchLoudnessCodecParameterChange(sessionId, bundle); - } catch (RemoteException e) { - Log.e(TAG, "Error dispatching for sessionId " + sessionId + " bundle: " + bundle, - e); + synchronized (mDispatcherLock) { + final int nbDispatchers = mLoudnessUpdateDispatchers.beginBroadcast(); + for (int i = 0; i < nbDispatchers; ++i) { + try { + mLoudnessUpdateDispatchers.getBroadcastItem(i) + .dispatchLoudnessCodecParameterChange(sessionId, bundle); + } catch (RemoteException e) { + Log.e(TAG, + "Error dispatching for sessionId " + sessionId + " bundle: " + bundle, + e); + } } + mLoudnessUpdateDispatchers.finishBroadcast(); } - mLoudnessUpdateDispatchers.finishBroadcast(); } @GuardedBy("mLock") -- GitLab From 4fcd881df01d2833e95040242367a9a9cf96440e Mon Sep 17 00:00:00 2001 From: Atneya Nair Date: Mon, 7 Oct 2024 16:18:12 -0700 Subject: [PATCH 161/447] Log uncaught exceptions in AudioService Make sure this exceptions are loud for crash console. Test: compiles Bug: 150808347 Flag: EXEMPT safe: system_server wtf only logs, doesn't abort Change-Id: Ifc1f4462d0e6085be83d16af5fd21e068b1c821d --- .../core/java/com/android/server/audio/AudioService.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 561030e77e61..d2bc5329a456 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -2744,6 +2744,11 @@ public class AudioService extends IAudioService.Stub } } + @Override + protected void onUnhandledException(int code, int flags, Exception e) { + Slog.wtf(TAG, "Uncaught exception in AudioService: " + code + ", " + flags, e); + } + @Override // Binder call public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, -- GitLab From dceef49580a36eb6fe1b69d1e6f31a4353d96b63 Mon Sep 17 00:00:00 2001 From: Atneya Nair Date: Mon, 7 Oct 2024 16:18:47 -0700 Subject: [PATCH 162/447] Add unhandled exception listener to STService Bug: 150808347 Test: SoundTriggerManagerTest with injected exceptions Test: compiles Flag: EXEMPT safe, addtl logging, no abort in system_server Change-Id: I89b3e125dde679493082aee197363bea860453a1 --- .../com/android/server/soundtrigger/SoundTriggerService.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java index 2bb86bc305a7..34df49ea941c 100644 --- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java +++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java @@ -504,6 +504,11 @@ public class SoundTriggerService extends SystemService { pw.println("\n##Sound Model Stats dump:\n"); mSoundModelStatTracker.dump(pw); } + + @Override + protected void onUnhandledException(int code, int flags, Exception e) { + Slog.wtf(TAG, "Unhandled exception code: " + code, e); + } } class SoundTriggerSessionStub extends ISoundTriggerSession.Stub { -- GitLab From fbc4f88710beb1fd2d11c6532e0328d4f2386b68 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Mon, 7 Oct 2024 16:35:00 -0700 Subject: [PATCH 163/447] Remove dependencies on the 1-variant fallback Currently, adding depedencies will use the only variant of a module if only 1 variant exists. Otherwise, the variations of the two modules + the variations explicitly requested must match. The 1-variant fallback causes issues for incremental soong, so remove reliances on it. Bug: 372091092 Test: m nothing --no-skip-soong-tests Change-Id: I778d1d8d67e9d0ccc3432f12e50d15c174b5dbf5 --- api/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/api.go b/api/api.go index e9f1feebd899..1bbf3709480a 100644 --- a/api/api.go +++ b/api/api.go @@ -514,7 +514,7 @@ func (a *CombinedApis) createInternalModules(ctx android.LoadHookContext) { func combinedApisModuleFactory() android.Module { module := &CombinedApis{} module.AddProperties(&module.properties) - android.InitAndroidModule(module) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) android.AddLoadHook(module, func(ctx android.LoadHookContext) { module.createInternalModules(ctx) }) return module } -- GitLab From e585720c951e098ec8db1b0b00a6c6a4b98a1fd2 Mon Sep 17 00:00:00 2001 From: Song Chun Fan Date: Mon, 7 Oct 2024 16:36:00 -0700 Subject: [PATCH 164/447] [3/N] implement getDeclaredLibraries + Add declaredLibraries to ApkLite and PackageLite + Move parsing time to be slightly earlier in the verification stage. This change only impact mode_inherit installations, because for mode_full installs, parsing is already done at validation time. Test: atest CtsPackageManagerTestCases:VerifierServiceTest FLAG: android.content.pm.verification_service BUG: 360129103 BUG: 360129657 Change-Id: I68e8da44b90e3b22a2bc0ef34f6c31afe7294e45 --- .../android/content/pm/SharedLibraryInfo.java | 18 +++++++ .../android/content/pm/parsing/ApkLite.java | 16 ++++-- .../content/pm/parsing/ApkLiteParseUtils.java | 52 ++++++++++++++++++- .../content/pm/parsing/PackageLite.java | 13 ++++- .../server/pm/PackageInstallerSession.java | 46 +++++++++++----- 5 files changed, 127 insertions(+), 18 deletions(-) diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java index d77b2f53fc5b..f7191e605fb8 100644 --- a/core/java/android/content/pm/SharedLibraryInfo.java +++ b/core/java/android/content/pm/SharedLibraryInfo.java @@ -208,6 +208,24 @@ public final class SharedLibraryInfo implements Parcelable { VersionedPackage.class.getClassLoader(), VersionedPackage.class); } + /** + * @hide + * @param name + * @param versionMajor + */ + public SharedLibraryInfo(String name, long versionMajor, int type) { + mPath = null; + mPackageName = null; + mName = name; + mVersion = versionMajor; + mType = type; + mDeclaringPackage = null; + mDependentPackages = null; + mDependencies = null; + mIsNative = false; + mOptionalDependentPackages = null; + } + /** * Gets the type of this library. * diff --git a/core/java/android/content/pm/parsing/ApkLite.java b/core/java/android/content/pm/parsing/ApkLite.java index 74ce62c7abff..19a13db15b05 100644 --- a/core/java/android/content/pm/parsing/ApkLite.java +++ b/core/java/android/content/pm/parsing/ApkLite.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.content.pm.ArchivedPackageParcel; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.SharedLibraryInfo; import android.content.pm.SigningDetails; import android.content.pm.VerifierInfo; @@ -149,6 +150,8 @@ public class ApkLite { */ private final @Nullable String mEmergencyInstaller; + private final @NonNull List mDeclaredLibraries; + /** * Archival install info. */ @@ -165,7 +168,7 @@ public class ApkLite { int minSdkVersion, int targetSdkVersion, int rollbackDataPolicy, Set requiredSplitTypes, Set splitTypes, boolean hasDeviceAdminReceiver, boolean isSdkLibrary, boolean updatableSystem, - String emergencyInstaller) { + String emergencyInstaller, List declaredLibraries) { mPath = path; mPackageName = packageName; mSplitName = splitName; @@ -202,6 +205,7 @@ public class ApkLite { mUpdatableSystem = updatableSystem; mEmergencyInstaller = emergencyInstaller; mArchivedPackage = null; + mDeclaredLibraries = declaredLibraries; } public ApkLite(String path, ArchivedPackageParcel archivedPackage) { @@ -241,6 +245,7 @@ public class ApkLite { mUpdatableSystem = true; mEmergencyInstaller = null; mArchivedPackage = archivedPackage; + mDeclaredLibraries = null; } /** @@ -565,6 +570,11 @@ public class ApkLite { return mEmergencyInstaller; } + @DataClass.Generated.Member + public @NonNull List getDeclaredLibraries() { + return mDeclaredLibraries; + } + /** * Archival install info. */ @@ -574,10 +584,10 @@ public class ApkLite { } @DataClass.Generated( - time = 1706896661616L, + time = 1728333566322L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java", - inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final boolean mUpdatableSystem\nprivate final @android.annotation.Nullable java.lang.String mEmergencyInstaller\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") + inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final boolean mUpdatableSystem\nprivate final @android.annotation.Nullable java.lang.String mEmergencyInstaller\nprivate final @android.annotation.NonNull java.util.List mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") @Deprecated private void __metadata() {} diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java index ffb69c0a2821..1a7f628ae61c 100644 --- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java +++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java @@ -24,6 +24,7 @@ import android.annotation.NonNull; import android.app.admin.DeviceAdminReceiver; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.SharedLibraryInfo; import android.content.pm.SigningDetails; import android.content.pm.VerifierInfo; import android.content.pm.parsing.result.ParseInput; @@ -92,6 +93,8 @@ public class ApkLiteParseUtils { private static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES; private static final String TAG_PROCESSES = "processes"; private static final String TAG_PROCESS = "process"; + private static final String TAG_STATIC_LIBRARY = "static-library"; + private static final String TAG_LIBRARY = "library"; /** * Parse only lightweight details about the package at the given location. @@ -457,6 +460,7 @@ public class ApkLiteParseUtils { boolean hasDeviceAdminReceiver = false; boolean isSdkLibrary = false; + List declaredLibraries = new ArrayList<>(); // Only search the tree when the tag is the direct child of tag int type; @@ -521,6 +525,51 @@ public class ApkLiteParseUtils { break; case TAG_SDK_LIBRARY: isSdkLibrary = true; + // Mirrors ParsingPackageUtils#parseSdkLibrary until lite and full + // parsing are combined + String sdkLibName = parser.getAttributeValue( + ANDROID_RES_NAMESPACE, "name"); + int sdkLibVersionMajor = parser.getAttributeIntValue( + ANDROID_RES_NAMESPACE, "versionMajor", -1); + if (sdkLibName == null || sdkLibVersionMajor < 0) { + return input.error( + PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, + "Bad uses-sdk-library declaration name: " + sdkLibName + + " version: " + sdkLibVersionMajor); + } + declaredLibraries.add(new SharedLibraryInfo( + sdkLibName, sdkLibVersionMajor, + SharedLibraryInfo.TYPE_SDK_PACKAGE)); + break; + case TAG_STATIC_LIBRARY: + // Mirrors ParsingPackageUtils#parseStaticLibrary until lite and full + // parsing are combined + String staticLibName = parser.getAttributeValue( + ANDROID_RES_NAMESPACE, "name"); + int staticLibVersion = parser.getAttributeIntValue( + ANDROID_RES_NAMESPACE, "version", -1); + int staticLibVersionMajor = parser.getAttributeIntValue( + ANDROID_RES_NAMESPACE, "versionMajor", 0); + if (staticLibName == null || staticLibVersion < 0) { + return input.error("Bad static-library declaration name: " + + staticLibName + " version: " + staticLibVersion); + } + declaredLibraries.add(new SharedLibraryInfo(staticLibName, + PackageInfo.composeLongVersionCode(staticLibVersionMajor, + staticLibVersion), SharedLibraryInfo.TYPE_STATIC)); + break; + case TAG_LIBRARY: + // Mirrors ParsingPackageUtils#parseLibrary until lite and full parsing + // are combined + String libName = parser.getAttributeValue( + ANDROID_RES_NAMESPACE, "name"); + if (libName == null) { + return input.error("Bad library declaration name: null"); + } + libName = libName.intern(); + declaredLibraries.add(new SharedLibraryInfo(libName, + SharedLibraryInfo.VERSION_UNDEFINED, + SharedLibraryInfo.TYPE_DYNAMIC)); break; case TAG_PROCESSES: final int processesDepth = parser.getDepth(); @@ -645,7 +694,8 @@ public class ApkLiteParseUtils { overlayIsStatic, overlayPriority, requiredSystemPropertyName, requiredSystemPropertyValue, minSdkVersion, targetSdkVersion, rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second, - hasDeviceAdminReceiver, isSdkLibrary, updatableSystem, emergencyInstaller)); + hasDeviceAdminReceiver, isSdkLibrary, updatableSystem, emergencyInstaller, + declaredLibraries)); } private static boolean isDeviceAdminReceiver( diff --git a/core/java/android/content/pm/parsing/PackageLite.java b/core/java/android/content/pm/parsing/PackageLite.java index 116dd1fc9a42..9a2ee7fe4cc6 100644 --- a/core/java/android/content/pm/parsing/PackageLite.java +++ b/core/java/android/content/pm/parsing/PackageLite.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.pm.ArchivedPackageParcel; import android.content.pm.PackageInfo; +import android.content.pm.SharedLibraryInfo; import android.content.pm.SigningDetails; import android.content.pm.VerifierInfo; @@ -114,6 +115,8 @@ public class PackageLite { */ private final boolean mIsSdkLibrary; + private final @NonNull List mDeclaredLibraries; + /** * Archival install info. */ @@ -154,6 +157,7 @@ public class PackageLite { mSplitApkPaths = splitApkPaths; mSplitRevisionCodes = splitRevisionCodes; mTargetSdk = targetSdk; + mDeclaredLibraries = baseApk.getDeclaredLibraries(); mArchivedPackage = baseApk.getArchivedPackage(); } @@ -433,6 +437,11 @@ public class PackageLite { return mIsSdkLibrary; } + @DataClass.Generated.Member + public @NonNull List getDeclaredLibraries() { + return mDeclaredLibraries; + } + /** * Archival install info. */ @@ -442,10 +451,10 @@ public class PackageLite { } @DataClass.Generated( - time = 1694792176268L, + time = 1728333569917L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java", - inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic java.util.List getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") + inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\nprivate final @android.annotation.NonNull java.util.List mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic java.util.List getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") @Deprecated private void __metadata() {} diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index c581622914fa..9e0ba8492ab9 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -109,6 +109,7 @@ import android.content.pm.PackageInstaller.UserActionReason; import android.content.pm.PackageManager; import android.content.pm.PackageManager.PackageInfoFlags; import android.content.pm.PackageManagerInternal; +import android.content.pm.SharedLibraryInfo; import android.content.pm.SigningDetails; import android.content.pm.SigningInfo; import android.content.pm.dex.DexMetadataHelper; @@ -2840,19 +2841,38 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // since installation is in progress. activate(); } + try { + List children = getChildSessions(); + if (isMultiPackage()) { + for (PackageInstallerSession child : children) { + child.prepareInheritedFiles(); + child.parseApk(); + } + } else { + prepareInheritedFiles(); + parseApk(); + } + } catch (PackageManagerException e) { + final String completeMsg = ExceptionUtils.getCompleteMessage(e); + final String errorMsg = PackageManager.installStatusToString(e.error, completeMsg); + setSessionFailed(e.error, errorMsg); + onSessionVerificationFailure(e.error, errorMsg); + } if (Flags.verificationService()) { final Supplier snapshotSupplier = mPm::snapshotComputer; if (mVerifierController.isVerifierInstalled(snapshotSupplier, userId)) { - // TODO: extract shared library declarations final SigningInfo signingInfo; + final List declaredLibraries; synchronized (mLock) { signingInfo = new SigningInfo(mSigningDetails); + declaredLibraries = + mPackageLite == null ? null : mPackageLite.getDeclaredLibraries(); } // Send the request to the verifier and wait for its response before the rest of // the installation can proceed. if (!mVerifierController.startVerificationSession(snapshotSupplier, userId, - sessionId, params.appPackageName, Uri.fromFile(stageDir), signingInfo, - /* declaredLibraries= */null, /* extensionParams= */ null, + sessionId, getPackageName(), Uri.fromFile(stageDir), signingInfo, + declaredLibraries, /* extensionParams= */ null, new VerifierCallback(), /* retry= */ false)) { // A verifier is installed but cannot be connected. Installation disallowed. onSessionVerificationFailure(INSTALL_FAILED_INTERNAL_ERROR, @@ -2887,12 +2907,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { List children = getChildSessions(); if (isMultiPackage()) { for (PackageInstallerSession child : children) { - child.prepareInheritedFiles(); - child.parseApkAndExtractNativeLibraries(); + child.extractNativeLibraries(); } } else { - prepareInheritedFiles(); - parseApkAndExtractNativeLibraries(); + extractNativeLibraries(); } verifyNonStaged(); } catch (PackageManagerException e) { @@ -3069,7 +3087,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mStageDirInUse = true; } - private void parseApkAndExtractNativeLibraries() throws PackageManagerException { + private void parseApk() throws PackageManagerException { synchronized (mLock) { if (mStageDirInUse) { throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, @@ -3102,12 +3120,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // stage dir here. // Besides, PackageLite may be null for staged sessions that don't complete // pre-reboot verification. - result = getOrParsePackageLiteLocked(stageDir, /* flags */ 0); + mPackageLite = getOrParsePackageLiteLocked(stageDir, /* flags */ 0); } else { - result = getOrParsePackageLiteLocked(mResolvedBaseFile, /* flags */ 0); + mPackageLite = getOrParsePackageLiteLocked(mResolvedBaseFile, /* flags */ 0); } - if (result != null) { - mPackageLite = result; + } + } + + private void extractNativeLibraries() throws PackageManagerException { + synchronized (mLock) { + if (mPackageLite != null) { if (!isApexSession()) { synchronized (mProgressLock) { mInternalProgress = 0.5f; -- GitLab From 7c93465367edafc44c632e2024a8ebf872e77481 Mon Sep 17 00:00:00 2001 From: Liran Binyamin Date: Mon, 7 Oct 2024 16:59:02 -0400 Subject: [PATCH 165/447] Helper for loading flyout drawable Moves the code that loads the flyout icon as a drawable to a util class to share with launcher. Flag: com.android.wm.shell.enable_bubble_bar Bug: 277815200 Test: builds successfully -- no-op change Change-Id: Iddc4ca7d6fb0994a6c3d3fa184505b00e7395e7b --- .../shared/bubbles/FlyoutDrawableLoader.kt | 47 +++++++++++++++++++ .../wm/shell/bubbles/BubbleViewInfoTask.java | 24 +--------- .../bubbles/BubbleViewInfoTaskLegacy.java | 24 +--------- 3 files changed, 51 insertions(+), 44 deletions(-) create mode 100644 libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/FlyoutDrawableLoader.kt diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/FlyoutDrawableLoader.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/FlyoutDrawableLoader.kt new file mode 100644 index 000000000000..5a1733094019 --- /dev/null +++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/FlyoutDrawableLoader.kt @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.shared.bubbles + +import android.content.Context +import android.content.Intent +import android.graphics.drawable.Drawable +import android.graphics.drawable.Icon +import android.util.Log + +object FlyoutDrawableLoader { + + private const val TAG = "FlyoutDrawableLoader" + + /** Loads the flyout icon as a [Drawable]. */ + @JvmStatic + fun Icon?.loadFlyoutDrawable(context: Context): Drawable? { + if (this == null) return null + try { + if (this.type == Icon.TYPE_URI || this.type == Icon.TYPE_URI_ADAPTIVE_BITMAP) { + context.grantUriPermission( + context.packageName, + this.uri, + Intent.FLAG_GRANT_READ_URI_PERMISSION + ) + } + return loadDrawable(context) + } catch (e: Exception) { + Log.w(TAG, "loadFlyoutDrawable failed: ${e.message}") + return null + } + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java index c5e3afda34dd..39fb2f49c1ee 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java @@ -21,11 +21,10 @@ import static com.android.wm.shell.bubbles.BadgedImageView.WHITE_SCRIM_ALPHA; import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES; import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES; +import static com.android.wm.shell.shared.bubbles.FlyoutDrawableLoader.loadFlyoutDrawable; -import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; -import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; @@ -34,7 +33,6 @@ import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Path; import android.graphics.drawable.Drawable; -import android.graphics.drawable.Icon; import android.util.Log; import android.util.PathParser; import android.view.LayoutInflater; @@ -51,7 +49,6 @@ import com.android.wm.shell.bubbles.bar.BubbleBarLayerView; import com.android.wm.shell.shared.handles.RegionSamplingHelper; import java.lang.ref.WeakReference; -import java.util.Objects; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; @@ -340,7 +337,7 @@ public class BubbleViewInfoTask { info.flyoutMessage = b.getFlyoutMessage(); if (info.flyoutMessage != null) { info.flyoutMessage.senderAvatar = - loadSenderAvatar(c, info.flyoutMessage.senderIcon); + loadFlyoutDrawable(info.flyoutMessage.senderIcon, c); } return info; } @@ -422,21 +419,4 @@ public class BubbleViewInfoTask { Color.WHITE, WHITE_SCRIM_ALPHA); return true; } - - @Nullable - static Drawable loadSenderAvatar(@NonNull final Context context, @Nullable final Icon icon) { - Objects.requireNonNull(context); - if (icon == null) return null; - try { - if (icon.getType() == Icon.TYPE_URI - || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) { - context.grantUriPermission(context.getPackageName(), - icon.getUri(), Intent.FLAG_GRANT_READ_URI_PERMISSION); - } - return icon.loadDrawable(context); - } catch (Exception e) { - Log.w(TAG, "loadSenderAvatar failed: " + e.getMessage()); - return null; - } - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskLegacy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskLegacy.java index c12822a27662..e9a593392dc2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskLegacy.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskLegacy.java @@ -20,11 +20,10 @@ import static com.android.wm.shell.bubbles.BadgedImageView.DEFAULT_PATH_SIZE; import static com.android.wm.shell.bubbles.BadgedImageView.WHITE_SCRIM_ALPHA; import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES; import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.wm.shell.shared.bubbles.FlyoutDrawableLoader.loadFlyoutDrawable; -import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; -import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; @@ -33,7 +32,6 @@ import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Path; import android.graphics.drawable.Drawable; -import android.graphics.drawable.Icon; import android.os.AsyncTask; import android.util.Log; import android.util.PathParser; @@ -50,7 +48,6 @@ import com.android.wm.shell.bubbles.bar.BubbleBarLayerView; import com.android.wm.shell.shared.handles.RegionSamplingHelper; import java.lang.ref.WeakReference; -import java.util.Objects; import java.util.concurrent.Executor; /** @@ -264,7 +261,7 @@ public class BubbleViewInfoTaskLegacy extends info.flyoutMessage = b.getFlyoutMessage(); if (info.flyoutMessage != null) { info.flyoutMessage.senderAvatar = - loadSenderAvatar(c, info.flyoutMessage.senderIcon); + loadFlyoutDrawable(info.flyoutMessage.senderIcon, c); } return info; } @@ -346,21 +343,4 @@ public class BubbleViewInfoTaskLegacy extends Color.WHITE, WHITE_SCRIM_ALPHA); return true; } - - @Nullable - static Drawable loadSenderAvatar(@NonNull final Context context, @Nullable final Icon icon) { - Objects.requireNonNull(context); - if (icon == null) return null; - try { - if (icon.getType() == Icon.TYPE_URI - || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) { - context.grantUriPermission(context.getPackageName(), - icon.getUri(), Intent.FLAG_GRANT_READ_URI_PERMISSION); - } - return icon.loadDrawable(context); - } catch (Exception e) { - Log.w(TAG, "loadSenderAvatar failed: " + e.getMessage()); - return null; - } - } } -- GitLab From 9018d6c2d45949c72ffbbb0336d9f61d6206680e Mon Sep 17 00:00:00 2001 From: Kiran Ramachandra Date: Mon, 7 Oct 2024 19:54:11 +0000 Subject: [PATCH 166/447] IndexOutOfBoundsException fix by adding Synchronization Bug: 371847603 Test: post-submit Flag: EXEMPT bugfix Change-Id: I9bcd1ece2fffe64923b3d245e5571c38762fa5bf --- .../com/android/server/uri/UriPermission.java | 64 +++++++++++-------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/services/core/java/com/android/server/uri/UriPermission.java b/services/core/java/com/android/server/uri/UriPermission.java index 0d1f36794f49..0ff23eab472a 100644 --- a/services/core/java/com/android/server/uri/UriPermission.java +++ b/services/core/java/com/android/server/uri/UriPermission.java @@ -25,6 +25,8 @@ import android.util.ArraySet; import android.util.Log; import android.util.Slog; +import com.android.internal.annotations.GuardedBy; + import com.google.android.collect.Sets; import java.io.PrintWriter; @@ -82,7 +84,9 @@ final class UriPermission { static final long INVALID_TIME = Long.MIN_VALUE; + @GuardedBy("this") private ArraySet mReadOwners; + @GuardedBy("this") private ArraySet mWriteOwners; private String stringName; @@ -204,14 +208,16 @@ final class UriPermission { persistedModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; } globalModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; - if (mReadOwners != null && includingOwners) { - ownedModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; - for (UriPermissionOwner r : mReadOwners) { - if (r != null) { - r.removeReadPermission(this); + synchronized (this) { + if (mReadOwners != null && includingOwners) { + ownedModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; + for (UriPermissionOwner r : mReadOwners) { + if (r != null) { + r.removeReadPermission(this); + } } + mReadOwners = null; } - mReadOwners = null; } } if ((modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { @@ -220,14 +226,16 @@ final class UriPermission { persistedModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; } globalModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; - if (mWriteOwners != null && includingOwners) { - ownedModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; - for (UriPermissionOwner r : mWriteOwners) { - if (r != null) { - r.removeWritePermission(this); + synchronized (this) { + if (mWriteOwners != null && includingOwners) { + ownedModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; + for (UriPermissionOwner r : mWriteOwners) { + if (r != null) { + r.removeWritePermission(this); + } } + mWriteOwners = null; } - mWriteOwners = null; } } @@ -256,7 +264,7 @@ final class UriPermission { } } - private void addReadOwner(UriPermissionOwner owner) { + private synchronized void addReadOwner(UriPermissionOwner owner) { if (mReadOwners == null) { mReadOwners = Sets.newArraySet(); ownedModeFlags |= Intent.FLAG_GRANT_READ_URI_PERMISSION; @@ -270,7 +278,7 @@ final class UriPermission { /** * Remove given read owner, updating {@Link #modeFlags} as needed. */ - void removeReadOwner(UriPermissionOwner owner) { + synchronized void removeReadOwner(UriPermissionOwner owner) { if (mReadOwners == null || !mReadOwners.remove(owner)) { Slog.wtf(TAG, "Unknown read owner " + owner + " in " + this); return; @@ -282,7 +290,7 @@ final class UriPermission { } } - private void addWriteOwner(UriPermissionOwner owner) { + private synchronized void addWriteOwner(UriPermissionOwner owner) { if (mWriteOwners == null) { mWriteOwners = Sets.newArraySet(); ownedModeFlags |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION; @@ -296,7 +304,7 @@ final class UriPermission { /** * Remove given write owner, updating {@Link #modeFlags} as needed. */ - void removeWriteOwner(UriPermissionOwner owner) { + synchronized void removeWriteOwner(UriPermissionOwner owner) { if (mWriteOwners == null || !mWriteOwners.remove(owner)) { Slog.wtf(TAG, "Unknown write owner " + owner + " in " + this); return; @@ -339,20 +347,22 @@ final class UriPermission { } pw.println(); - if (mReadOwners != null) { - pw.print(prefix); - pw.println("readOwners:"); - for (UriPermissionOwner owner : mReadOwners) { + synchronized (this) { + if (mReadOwners != null) { pw.print(prefix); - pw.println(" * " + owner); + pw.println("readOwners:"); + for (UriPermissionOwner owner : mReadOwners) { + pw.print(prefix); + pw.println(" * " + owner); + } } - } - if (mWriteOwners != null) { - pw.print(prefix); - pw.println("writeOwners:"); - for (UriPermissionOwner owner : mWriteOwners) { + if (mWriteOwners != null) { pw.print(prefix); - pw.println(" * " + owner); + pw.println("writeOwners:"); + for (UriPermissionOwner owner : mWriteOwners) { + pw.print(prefix); + pw.println(" * " + owner); + } } } } -- GitLab From ea82a2680392581cb6a551c2cb090ca729c79133 Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Mon, 7 Oct 2024 23:51:58 +0000 Subject: [PATCH 167/447] Swap out owners for keystore frameworks bits Change-Id: I94b27b4d630ba05351c6570eb2283c97c4d636c7 --- keystore/OWNERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/keystore/OWNERS b/keystore/OWNERS index 689177715711..ea783e7f0c06 100644 --- a/keystore/OWNERS +++ b/keystore/OWNERS @@ -1,5 +1,6 @@ # Bug component: 189335 +ascull@google.com drysdale@google.com -eranm@google.com jbires@google.com +sethmo@google.com swillden@google.com -- GitLab From 2be0c97aef9dff83f8c813a001890cde06c3f703 Mon Sep 17 00:00:00 2001 From: Michael Mikhail Date: Mon, 7 Oct 2024 21:58:52 +0000 Subject: [PATCH 168/447] Add logs when media host visibility changes Flag: EXEMPT BUGFIX Bug: 371192645 Test: Build, new logs added according to UI changes. Change-Id: If1d856edcfe2cfbd752acde09d29dd74b6d02521 --- .../systemui/log/dagger/LogModule.java | 2 +- .../MediaCarouselControllerLogger.kt | 22 ++++++++++++---- .../media/controls/ui/view/MediaHost.kt | 3 +++ .../systemui/media/dagger/MediaModule.java | 26 ++++++++++++------- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index 4e975ff27361..4c21da52db3a 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -369,7 +369,7 @@ public class LogModule { @SysUISingleton @MediaCarouselControllerLog public static LogBuffer provideMediaCarouselControllerBuffer(LogBufferFactory factory) { - return factory.create("MediaCarouselCtlrLog", 20); + return factory.create("MediaCarouselCtlrLog", 100); } /** diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLogger.kt index 1be25a74dbea..9b443f56636a 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLogger.kt @@ -39,7 +39,7 @@ constructor(@MediaCarouselControllerLog private val buffer: LogBuffer) { { "Potential memory leak: " + "Removing control panel for $str1 from map without calling #onDestroy" - } + }, ) fun logMediaLoaded(key: String, active: Boolean) = @@ -50,7 +50,7 @@ constructor(@MediaCarouselControllerLog private val buffer: LogBuffer) { str1 = key bool1 = active }, - { "add player $str1, active: $bool1" } + { "add player $str1, active: $bool1" }, ) fun logMediaRemoved(key: String, userInitiated: Boolean) = @@ -61,7 +61,7 @@ constructor(@MediaCarouselControllerLog private val buffer: LogBuffer) { str1 = key bool1 = userInitiated }, - { "removing player $str1, by user $bool1" } + { "removing player $str1, by user $bool1" }, ) fun logRecommendationLoaded(key: String, isActive: Boolean) = @@ -72,7 +72,7 @@ constructor(@MediaCarouselControllerLog private val buffer: LogBuffer) { str1 = key bool1 = isActive }, - { "add recommendation $str1, active $bool1" } + { "add recommendation $str1, active $bool1" }, ) fun logRecommendationRemoved(key: String, immediately: Boolean) = @@ -83,12 +83,24 @@ constructor(@MediaCarouselControllerLog private val buffer: LogBuffer) { str1 = key bool1 = immediately }, - { "removing recommendation $str1, immediate=$bool1" } + { "removing recommendation $str1, immediate=$bool1" }, ) fun logCarouselHidden() = buffer.log(TAG, LogLevel.DEBUG, {}, { "hiding carousel" }) fun logCarouselVisible() = buffer.log(TAG, LogLevel.DEBUG, {}, { "showing carousel" }) + + fun logMediaHostVisibility(location: Int, visible: Boolean) { + buffer.log( + TAG, + LogLevel.DEBUG, + { + int1 = location + bool1 = visible + }, + { "media host visibility changed location=$location, visible:$visible" }, + ) + } } private const val TAG = "MediaCarouselCtlrLog" diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/MediaHost.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/MediaHost.kt index 5ddc3470da43..11251cdb6315 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/MediaHost.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/MediaHost.kt @@ -25,6 +25,7 @@ import com.android.systemui.media.controls.domain.pipeline.MediaDataManager import com.android.systemui.media.controls.shared.model.MediaData import com.android.systemui.media.controls.shared.model.SmartspaceMediaData import com.android.systemui.media.controls.ui.controller.MediaCarouselController +import com.android.systemui.media.controls.ui.controller.MediaCarouselControllerLogger import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager import com.android.systemui.media.controls.ui.controller.MediaHostStatesManager import com.android.systemui.media.controls.ui.controller.MediaLocation @@ -41,6 +42,7 @@ class MediaHost( private val mediaDataManager: MediaDataManager, private val mediaHostStatesManager: MediaHostStatesManager, private val mediaCarouselController: MediaCarouselController, + private val debugLogger: MediaCarouselControllerLogger, ) : MediaHostState by state { lateinit var hostView: UniqueObjectHostView var location: Int = -1 @@ -217,6 +219,7 @@ class MediaHost( val newVisibility = if (visible) View.VISIBLE else View.GONE if (newVisibility != hostView.visibility) { hostView.visibility = newVisibility + debugLogger.logMediaHostVisibility(location, visible) visibleChangedListeners.forEach { it.invoke(visible) } } } diff --git a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java index 59b98b2792be..36a9fb3eb753 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java +++ b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java @@ -22,6 +22,7 @@ import com.android.systemui.log.LogBufferFactory; import com.android.systemui.media.controls.domain.MediaDomainModule; import com.android.systemui.media.controls.domain.pipeline.MediaDataManager; import com.android.systemui.media.controls.ui.controller.MediaCarouselController; +import com.android.systemui.media.controls.ui.controller.MediaCarouselControllerLogger; import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager; import com.android.systemui.media.controls.ui.controller.MediaHostStatesManager; import com.android.systemui.media.controls.ui.view.MediaHost; @@ -60,9 +61,10 @@ public interface MediaModule { @Named(QS_PANEL) static MediaHost providesQSMediaHost(MediaHost.MediaHostStateHolder stateHolder, MediaHierarchyManager hierarchyManager, MediaDataManager dataManager, - MediaHostStatesManager statesManager, MediaCarouselController carouselController) { + MediaHostStatesManager statesManager, MediaCarouselController carouselController, + MediaCarouselControllerLogger logger) { return new MediaHost(stateHolder, hierarchyManager, dataManager, statesManager, - carouselController); + carouselController, logger); } /** */ @@ -71,9 +73,10 @@ public interface MediaModule { @Named(QUICK_QS_PANEL) static MediaHost providesQuickQSMediaHost(MediaHost.MediaHostStateHolder stateHolder, MediaHierarchyManager hierarchyManager, MediaDataManager dataManager, - MediaHostStatesManager statesManager, MediaCarouselController carouselController) { + MediaHostStatesManager statesManager, MediaCarouselController carouselController, + MediaCarouselControllerLogger logger) { return new MediaHost(stateHolder, hierarchyManager, dataManager, statesManager, - carouselController); + carouselController, logger); } /** */ @@ -82,9 +85,10 @@ public interface MediaModule { @Named(KEYGUARD) static MediaHost providesKeyguardMediaHost(MediaHost.MediaHostStateHolder stateHolder, MediaHierarchyManager hierarchyManager, MediaDataManager dataManager, - MediaHostStatesManager statesManager, MediaCarouselController carouselController) { + MediaHostStatesManager statesManager, MediaCarouselController carouselController, + MediaCarouselControllerLogger logger) { return new MediaHost(stateHolder, hierarchyManager, dataManager, statesManager, - carouselController); + carouselController, logger); } /** */ @@ -93,9 +97,10 @@ public interface MediaModule { @Named(DREAM) static MediaHost providesDreamMediaHost(MediaHost.MediaHostStateHolder stateHolder, MediaHierarchyManager hierarchyManager, MediaDataManager dataManager, - MediaHostStatesManager statesManager, MediaCarouselController carouselController) { + MediaHostStatesManager statesManager, MediaCarouselController carouselController, + MediaCarouselControllerLogger logger) { return new MediaHost(stateHolder, hierarchyManager, dataManager, statesManager, - carouselController); + carouselController, logger); } /** */ @@ -104,9 +109,10 @@ public interface MediaModule { @Named(COMMUNAL_HUB) static MediaHost providesCommunalMediaHost(MediaHost.MediaHostStateHolder stateHolder, MediaHierarchyManager hierarchyManager, MediaDataManager dataManager, - MediaHostStatesManager statesManager, MediaCarouselController carouselController) { + MediaHostStatesManager statesManager, MediaCarouselController carouselController, + MediaCarouselControllerLogger logger) { return new MediaHost(stateHolder, hierarchyManager, dataManager, statesManager, - carouselController); + carouselController, logger); } /** Provides a logging buffer related to the media tap-to-transfer chip on the sender device. */ -- GitLab From 01771fecf135d8db6742e76c117829b74a3c928a Mon Sep 17 00:00:00 2001 From: Sherry Zhou Date: Wed, 25 Sep 2024 03:31:17 +0000 Subject: [PATCH 169/447] Listen to change of notification stack bottom to pass correct bounds to magic portrait shape effects Bug: 364534860 Flag: com.android.systemui.magic_portrait_wallpapers Test: atest WallpaperRepositoryImplTest Change-Id: Ic3e59c8fb5916eacb3b3f030dc126abaf4b5b1a3 --- core/java/android/app/WallpaperManager.java | 8 ++ packages/SystemUI/aconfig/systemui.aconfig | 8 ++ .../repository/FakeWallpaperRepository.kt | 7 ++ .../repository/KeyguardClockRepository.kt | 19 +++- .../data/repository/KeyguardRepository.kt | 26 +++-- .../interactor/KeyguardClockInteractor.kt | 6 +- .../domain/interactor/KeyguardInteractor.kt | 4 + .../ui/view/layout/sections/ClockSection.kt | 26 ++++- .../sections/DefaultShortcutsSection.kt | 14 ++- .../stack/NotificationStackScrollLayout.java | 10 ++ ...tificationStackScrollLayoutController.java | 9 +- .../systemui/util/WallpaperController.kt | 11 +- .../repository/NoopWallpaperRepository.kt | 4 + .../data/repository/WallpaperRepository.kt | 107 +++++++++++++++++- .../domain/interactor/WallpaperInteractor.kt | 26 +++++ .../view/layout/sections/ClockSectionTest.kt | 4 +- ...cationStackScrollLayoutControllerTest.java | 7 +- .../NotificationStackScrollLayoutTest.java | 3 + .../repository/WallpaperRepositoryImplTest.kt | 73 +++++++++++- .../com/android/app/WallpaperManagerKosmos.kt | 27 +++++ .../repository/FakeKeyguardClockRepository.kt | 11 ++ .../data/repository/FakeKeyguardRepository.kt | 10 +- .../KeyguardBlueprintRepositoryKosmos.kt | 4 +- .../KeyguardClockInteractorKosmos.kt | 4 +- .../repository/WallpaperRepositoryKosmos.kt | 43 +++++++ .../interactor/WallpaperInteractorKosmos.kt | 23 ++++ 26 files changed, 460 insertions(+), 34 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/wallpapers/domain/interactor/WallpaperInteractor.kt create mode 100644 packages/SystemUI/tests/utils/src/com/android/app/WallpaperManagerKosmos.kt create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryKosmos.kt create mode 100644 packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/domain/interactor/WallpaperInteractorKosmos.kt diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index c1c96eaa098d..014e4660f944 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -284,6 +284,14 @@ public class WallpaperManager { */ public static final String COMMAND_UNFREEZE = "android.wallpaper.unfreeze"; + /** + * Command for {@link #sendWallpaperCommand}: in sendWallpaperCommand put extra to this command + * to give the bounds of space between the bottom of notifications and the top of shortcuts + * @hide + */ + public static final String COMMAND_LOCKSCREEN_LAYOUT_CHANGED = + "android.wallpaper.lockscreen_layout_changed"; + /** * Extra passed back from setWallpaper() giving the new wallpaper's assigned ID. * @hide diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index c6238e848070..1f5d0f512836 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -1483,3 +1483,11 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "magic_portrait_wallpapers" + namespace: "systemui" + description: "Magic Portrait related changes in systemui" + bug: "370863642" +} + diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperRepository.kt index fe5024fdc0a3..59676ce126da 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperRepository.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/FakeWallpaperRepository.kt @@ -17,10 +17,17 @@ package com.android.systemui.wallpapers.data.repository import android.app.WallpaperInfo +import android.view.View import kotlinx.coroutines.flow.MutableStateFlow /** Fake implementation of the wallpaper repository. */ class FakeWallpaperRepository : WallpaperRepository { override val wallpaperInfo = MutableStateFlow(null) override val wallpaperSupportsAmbientMode = MutableStateFlow(false) + override var rootView: View? = null + private val _notificationStackAbsoluteBottom = MutableStateFlow(0F) + + override fun setNotificationStackAbsoluteBottom(bottom: Float) { + _notificationStackAbsoluteBottom.value = bottom + } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt index ec52055020f2..95d1b5d7fcac 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt @@ -68,11 +68,16 @@ interface KeyguardClockRepository { val previewClock: Flow + /** top of notifications without bcsmartspace in small clock settings */ + val notificationDefaultTop: StateFlow + val clockEventController: ClockEventController val shouldForceSmallClock: Boolean fun setClockSize(size: ClockSize) + + fun setNotificationDefaultTop(top: Float) } @SysUISingleton @@ -108,7 +113,7 @@ constructor( .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), - initialValue = getClockSize() + initialValue = getClockSize(), ) override val currentClockId: Flow = @@ -138,7 +143,7 @@ constructor( .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), - initialValue = clockRegistry.createCurrentClock() + initialValue = clockRegistry.createCurrentClock(), ) override val previewClock: Flow = @@ -149,6 +154,14 @@ constructor( clockRegistry.createCurrentClock() } + private val _notificationDefaultTop: MutableStateFlow = MutableStateFlow(0F) + + override val notificationDefaultTop: StateFlow = _notificationDefaultTop.asStateFlow() + + override fun setNotificationDefaultTop(top: Float) { + _notificationDefaultTop.value = top + } + override val shouldForceSmallClock: Boolean get() = featureFlags.isEnabled(Flags.LOCKSCREEN_ENABLE_LANDSCAPE) && @@ -160,7 +173,7 @@ constructor( secureSettings.getIntForUser( Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, /* defaultValue= */ 1, - UserHandle.USER_CURRENT + UserHandle.USER_CURRENT, ) ) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt index 130242f55600..821017418277 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt @@ -269,6 +269,9 @@ interface KeyguardRepository { */ val isEncryptedOrLockdown: Flow + /** The top of shortcut in screen, used by wallpaper to find remaining space in lockscreen */ + val shortcutAbsoluteTop: StateFlow + /** * Returns `true` if the keyguard is showing; `false` otherwise. * @@ -339,6 +342,8 @@ interface KeyguardRepository { * otherwise. */ fun isShowKeyguardWhenReenabled(): Boolean + + fun setShortcutAbsoluteTop(top: Float) } /** Encapsulates application state for the keyguard. */ @@ -503,7 +508,7 @@ constructor( trySendWithFailureLogging( statusBarStateController.dozeAmount, TAG, - "initial dozeAmount" + "initial dozeAmount", ) awaitClose { statusBarStateController.removeCallback(callback) } @@ -521,7 +526,7 @@ constructor( object : DozeTransitionCallback { override fun onDozeTransition( oldState: DozeMachine.State, - newState: DozeMachine.State + newState: DozeMachine.State, ) { trySendWithFailureLogging( DozeTransitionModel( @@ -529,7 +534,7 @@ constructor( to = dozeMachineStateToModel(newState), ), TAG, - "doze transition model" + "doze transition model", ) } } @@ -541,7 +546,7 @@ constructor( to = dozeMachineStateToModel(dozeTransitionListener.newState), ), TAG, - "initial doze transition model" + "initial doze transition model", ) awaitClose { dozeTransitionListener.removeCallback(callback) } @@ -579,7 +584,7 @@ constructor( trySendWithFailureLogging( statusBarStateIntToObject(state), TAG, - "state" + "state", ) } } @@ -590,7 +595,7 @@ constructor( .stateIn( scope, SharingStarted.Eagerly, - statusBarStateIntToObject(statusBarStateController.state) + statusBarStateIntToObject(statusBarStateController.state), ) private val _biometricUnlockState: MutableStateFlow = @@ -610,7 +615,7 @@ constructor( trySendWithFailureLogging( authController.fingerprintSensorLocation, TAG, - "AuthController.Callback#onFingerprintLocationChanged" + "AuthController.Callback#onFingerprintLocationChanged", ) } @@ -635,6 +640,9 @@ constructor( private val _isActiveDreamLockscreenHosted = MutableStateFlow(false) override val isActiveDreamLockscreenHosted = _isActiveDreamLockscreenHosted.asStateFlow() + private val _shortcutAbsoluteTop = MutableStateFlow(0F) + override val shortcutAbsoluteTop = _shortcutAbsoluteTop.asStateFlow() + init { val callback = object : KeyguardStateController.Callback { @@ -721,6 +729,10 @@ constructor( } } + override fun setShortcutAbsoluteTop(top: Float) { + _shortcutAbsoluteTop.value = top + } + private fun dozeMachineStateToModel(state: DozeMachine.State): DozeStateModel { return when (state) { DozeMachine.State.UNINITIALIZED -> DozeStateModel.UNINITIALIZED diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt index c0049d4e2e6c..5b7eeddfb8e1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt @@ -94,7 +94,7 @@ constructor( .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), - initialValue = ClockSize.LARGE + initialValue = ClockSize.LARGE, ) } else { keyguardClockRepository.clockSize @@ -152,4 +152,8 @@ constructor( clock.largeClock.animations.fold(foldFraction) } } + + fun setNotificationStackDefaultTop(top: Float) { + keyguardClockRepository.setNotificationDefaultTop(top) + } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt index e6ee11215595..d7f96b55c4a3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt @@ -526,6 +526,10 @@ constructor( repository.showDismissibleKeyguard() } + fun setShortcutAbsoluteTop(top: Float) { + repository.setShortcutAbsoluteTop(top) + } + companion object { private const val TAG = "KeyguardInteractor" } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt index a1c963b3137a..0b10c8a14633 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt @@ -44,6 +44,7 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel import com.android.systemui.plugins.clocks.ClockController import com.android.systemui.plugins.clocks.ClockFaceLayout import com.android.systemui.res.R +import com.android.systemui.shade.LargeScreenHeaderHelper import com.android.systemui.shared.R as sharedR import com.android.systemui.util.ui.value import dagger.Lazy @@ -70,6 +71,7 @@ constructor( val blueprintInteractor: Lazy, private val rootViewModel: KeyguardRootViewModel, private val aodBurnInViewModel: AodBurnInViewModel, + private val largeScreenHeaderHelperLazy: Lazy, ) : KeyguardSection() { private var disposableHandle: DisposableHandle? = null @@ -172,7 +174,7 @@ constructor( } } - open fun applyDefaultConstraints(constraints: ConstraintSet) { + fun applyDefaultConstraints(constraints: ConstraintSet) { val guideline = if (keyguardClockViewModel.clockShouldBeCentered.value) PARENT_ID else R.id.split_shade_guideline @@ -211,6 +213,28 @@ constructor( // Explicitly clear pivot to force recalculate pivot instead of using legacy value setTransformPivot(R.id.lockscreen_clock_view_large, Float.NaN, Float.NaN) + + val smallClockBottom = + keyguardClockViewModel.getSmallClockTopMargin() + + context.resources.getDimensionPixelSize( + com.android.systemui.customization.R.dimen.small_clock_height + ) + val dateWeatherSmartspaceHeight = getDimen(context, DATE_WEATHER_VIEW_HEIGHT).toFloat() + val marginBetweenSmartspaceAndNotification = + context.resources.getDimensionPixelSize( + R.dimen.keyguard_status_view_bottom_margin + ) + + if (context.resources.getBoolean(R.bool.config_use_large_screen_shade_header)) { + largeScreenHeaderHelperLazy.get().getLargeScreenHeaderHeight() + } else { + 0 + } + + clockInteractor.setNotificationStackDefaultTop( + smallClockBottom + + dateWeatherSmartspaceHeight + + marginBetweenSmartspaceAndNotification + ) } constrainWeatherClockDateIconsBarrier(constraints) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt index 6c6e14cac84d..d3895def28e0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt @@ -30,6 +30,7 @@ import com.android.systemui.animation.view.LaunchableImageView import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.KeyguardBottomAreaRefactor import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor +import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordancesCombinedViewModel @@ -52,6 +53,7 @@ constructor( private val indicationController: KeyguardIndicationController, private val keyguardBlueprintInteractor: Lazy, private val keyguardQuickAffordanceViewBinder: KeyguardQuickAffordanceViewBinder, + private val keyguardInteractor: KeyguardInteractor, ) : BaseShortcutSection() { // Amount to increase the bottom margin by to avoid colliding with inset @@ -117,7 +119,7 @@ constructor( BOTTOM, PARENT_ID, BOTTOM, - verticalOffsetMargin + safeInsetBottom + verticalOffsetMargin + safeInsetBottom, ) constrainWidth(R.id.end_button, width) @@ -128,7 +130,7 @@ constructor( BOTTOM, PARENT_ID, BOTTOM, - verticalOffsetMargin + safeInsetBottom + verticalOffsetMargin + safeInsetBottom, ) // The constraint set visibility for start and end button are default visible, set to @@ -136,5 +138,13 @@ constructor( setVisibilityMode(R.id.start_button, VISIBILITY_MODE_IGNORE) setVisibilityMode(R.id.end_button, VISIBILITY_MODE_IGNORE) } + + val shortcutAbsoluteTopInScreen = + (resources.displayMetrics.heightPixels - + (verticalOffsetMargin + safeInsetBottom) - + height) + .toFloat() + + keyguardInteractor.setShortcutAbsoluteTop(shortcutAbsoluteTopInScreen) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index b466bf02387f..43989a85b045 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -129,6 +129,7 @@ import com.android.systemui.util.Assert; import com.android.systemui.util.ColorUtilKt; import com.android.systemui.util.DumpUtilsKt; import com.android.systemui.util.ListenerSet; +import com.android.systemui.wallpapers.domain.interactor.WallpaperInteractor; import com.google.errorprone.annotations.CompileTimeConstant; @@ -627,6 +628,9 @@ public class NotificationStackScrollLayout @Nullable private OnClickListener mManageButtonClickListener; + @Nullable + private WallpaperInteractor mWallpaperInteractor; + public NotificationStackScrollLayout(Context context, AttributeSet attrs) { super(context, attrs, 0, 0); Resources res = getResources(); @@ -1189,6 +1193,7 @@ public class NotificationStackScrollLayout if (!SceneContainerFlag.isEnabled()) { setMaxLayoutHeight(getHeight()); updateContentHeight(); + mWallpaperInteractor.setNotificationStackAbsoluteBottom(mContentHeight); } clampScrollPosition(); requestChildrenUpdate(); @@ -1248,6 +1253,7 @@ public class NotificationStackScrollLayout if (mAmbientState.getStackTop() != stackTop) { mAmbientState.setStackTop(stackTop); onTopPaddingChanged(/* animate = */ isAddOrRemoveAnimationPending()); + mWallpaperInteractor.setNotificationStackAbsoluteBottom((int) stackTop); } } @@ -5875,6 +5881,10 @@ public class NotificationStackScrollLayout mController.getNotificationRoundnessManager().setAnimatedChildren(mChildrenToAddAnimated); } + public void setWallpaperInteractor(WallpaperInteractor wallpaperInteractor) { + mWallpaperInteractor = wallpaperInteractor; + } + void addSwipedOutView(View v) { mSwipedOutViews.add(v); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 7b02d0cebfb3..00c5c40fc8ac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -145,6 +145,7 @@ import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.tuner.TunerService; import com.android.systemui.util.Compile; import com.android.systemui.util.settings.SecureSettings; +import com.android.systemui.wallpapers.domain.interactor.WallpaperInteractor; import java.io.PrintWriter; import java.util.ArrayList; @@ -226,6 +227,8 @@ public class NotificationStackScrollLayoutController implements Dumpable { private final SensitiveNotificationProtectionController mSensitiveNotificationProtectionController; + private final WallpaperInteractor mWallpaperInteractor; + private View mLongPressedView; private final NotificationListContainerImpl mNotificationListContainer = @@ -756,7 +759,8 @@ public class NotificationStackScrollLayoutController implements Dumpable { NotificationDismissibilityProvider dismissibilityProvider, ActivityStarter activityStarter, SplitShadeStateController splitShadeStateController, - SensitiveNotificationProtectionController sensitiveNotificationProtectionController) { + SensitiveNotificationProtectionController sensitiveNotificationProtectionController, + WallpaperInteractor wallpaperInteractor) { mView = view; mKeyguardTransitionRepo = keyguardTransitionRepo; mViewBinder = viewBinder; @@ -812,6 +816,7 @@ public class NotificationStackScrollLayoutController implements Dumpable { mDismissibilityProvider = dismissibilityProvider; mActivityStarter = activityStarter; mSensitiveNotificationProtectionController = sensitiveNotificationProtectionController; + mWallpaperInteractor = wallpaperInteractor; mView.passSplitShadeStateController(splitShadeStateController); if (SceneContainerFlag.isEnabled()) { mWakeUpCoordinator.setStackScroller(this); @@ -948,6 +953,8 @@ public class NotificationStackScrollLayoutController implements Dumpable { collectFlow(mView, mKeyguardTransitionRepo.getTransitions(), this::onKeyguardTransitionChanged); } + + mView.setWallpaperInteractor(mWallpaperInteractor); } private boolean isInVisibleLocation(NotificationEntry entry) { diff --git a/packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt b/packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt index 65a02184f96d..0744b5a0b18c 100644 --- a/packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt +++ b/packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt @@ -32,19 +32,24 @@ private const val TAG = "WallpaperController" * Note: New logic should be added to [WallpaperRepository], not this class. */ @SysUISingleton -class WallpaperController @Inject constructor( +class WallpaperController +@Inject +constructor( private val wallpaperManager: WallpaperManager, private val wallpaperRepository: WallpaperRepository, ) { var rootView: View? = null + set(value) { + field = value + wallpaperRepository.rootView = value + } private var notificationShadeZoomOut: Float = 0f private var unfoldTransitionZoomOut: Float = 0f private val shouldUseDefaultUnfoldTransition: Boolean - get() = wallpaperRepository.wallpaperInfo.value?.shouldUseDefaultUnfoldTransition() - ?: true + get() = wallpaperRepository.wallpaperInfo.value?.shouldUseDefaultUnfoldTransition() ?: true fun setNotificationShadeZoom(zoomOut: Float) { notificationShadeZoomOut = zoomOut diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/NoopWallpaperRepository.kt b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/NoopWallpaperRepository.kt index b45b8cd15bf5..54953c9c2574 100644 --- a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/NoopWallpaperRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/NoopWallpaperRepository.kt @@ -17,6 +17,7 @@ package com.android.systemui.wallpapers.data.repository import android.app.WallpaperInfo +import android.view.View import com.android.systemui.dagger.SysUISingleton import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow @@ -33,4 +34,7 @@ import kotlinx.coroutines.flow.asStateFlow class NoopWallpaperRepository @Inject constructor() : WallpaperRepository { override val wallpaperInfo: StateFlow = MutableStateFlow(null).asStateFlow() override val wallpaperSupportsAmbientMode = MutableStateFlow(false).asStateFlow() + override var rootView: View? = null + + override fun setNotificationStackAbsoluteBottom(bottom: Float) {} } diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt index 041b6f963e27..203e1da2afcf 100644 --- a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt @@ -21,10 +21,16 @@ import android.app.WallpaperManager import android.content.Context import android.content.Intent import android.content.IntentFilter +import android.os.Bundle import android.os.UserHandle +import android.view.View +import androidx.annotation.VisibleForTesting +import com.android.systemui.Flags import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.keyguard.data.repository.KeyguardClockRepository +import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.user.data.model.SelectedUserModel import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.UserRepository @@ -32,16 +38,19 @@ import com.android.systemui.utils.coroutines.flow.mapLatestConflated import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch import kotlinx.coroutines.withContext /** A repository storing information about the current wallpaper. */ @@ -51,6 +60,15 @@ interface WallpaperRepository { /** Emits true if the current user's current wallpaper supports ambient mode. */ val wallpaperSupportsAmbientMode: StateFlow + + /** Set rootView to get its windowToken afterwards */ + var rootView: View? + + /** + * Set bottom of notifications from notification stack, and Magic Portrait will layout base on + * this value + */ + fun setNotificationStackAbsoluteBottom(bottom: Float) } @SysUISingleton @@ -61,6 +79,8 @@ constructor( @Background private val bgDispatcher: CoroutineDispatcher, broadcastDispatcher: BroadcastDispatcher, userRepository: UserRepository, + keyguardRepository: KeyguardRepository, + keyguardClockRepository: KeyguardClockRepository, private val wallpaperManager: WallpaperManager, context: Context, ) : WallpaperRepository { @@ -69,10 +89,7 @@ constructor( private val wallpaperChanged: Flow = broadcastDispatcher - .broadcastFlow( - IntentFilter(Intent.ACTION_WALLPAPER_CHANGED), - user = UserHandle.ALL, - ) + .broadcastFlow(IntentFilter(Intent.ACTION_WALLPAPER_CHANGED), user = UserHandle.ALL) // The `combine` defining `wallpaperSupportsAmbientMode` will not run until both of the // input flows emit at least once. Since this flow is an input flow, it needs to emit // when it starts up to ensure that the `combine` will run if the user changes before we @@ -87,6 +104,27 @@ constructor( // Only update the wallpaper status once the user selection has finished. .filter { it.selectionStatus == SelectionStatus.SELECTION_COMPLETE } + /** The bottom of notification stack respect to the top of screen. */ + private val notificationStackAbsoluteBottom: MutableStateFlow = MutableStateFlow(0F) + + /** The top of shortcut respect to the top of screen. */ + private val shortcutAbsoluteTop: StateFlow = keyguardRepository.shortcutAbsoluteTop + + /** + * The top of notification stack to give a default state of lockscreen remaining space for + * states with notifications to compare with. It's the bottom of smartspace date and weather + * smartspace in small clock state, plus proper bottom margin. + */ + private val notificationStackDefaultTop = keyguardClockRepository.notificationDefaultTop + @VisibleForTesting var sendLockscreenLayoutJob: Job? = null + private val lockscreenRemainingSpaceWithNotification: Flow> = + combine( + notificationStackAbsoluteBottom, + notificationStackDefaultTop, + shortcutAbsoluteTop, + ::Triple, + ) + override val wallpaperInfo: StateFlow = if (!wallpaperManager.isWallpaperSupported || !deviceSupportsAodWallpaper) { MutableStateFlow(null).asStateFlow() @@ -116,9 +154,70 @@ constructor( initialValue = wallpaperInfo.value?.supportsAmbientMode() == true, ) + override var rootView: View? = null + + val shouldSendNotificationLayout = + wallpaperInfo + .map { + val shouldSendNotificationLayout = shouldSendNotificationLayout(it) + if (shouldSendNotificationLayout) { + sendLockscreenLayoutJob = + scope.launch { + lockscreenRemainingSpaceWithNotification.collect { + (notificationBottom, notificationDefaultTop, shortcutTop) -> + wallpaperManager.sendWallpaperCommand( + /* windowToken = */ rootView?.windowToken, + /* action = */ WallpaperManager + .COMMAND_LOCKSCREEN_LAYOUT_CHANGED, + /* x = */ 0, + /* y = */ 0, + /* z = */ 0, + /* extras = */ Bundle().apply { + putFloat("screenLeft", 0F) + putFloat("smartspaceBottom", notificationDefaultTop) + putFloat("notificationBottom", notificationBottom) + putFloat( + "screenRight", + context.resources.displayMetrics.widthPixels.toFloat(), + ) + putFloat("shortCutTop", shortcutTop) + }, + ) + } + } + } else { + sendLockscreenLayoutJob?.cancel() + } + shouldSendNotificationLayout + } + .stateIn( + scope, + // Always be listening for wallpaper changes. + if (Flags.magicPortraitWallpapers()) SharingStarted.Eagerly + else SharingStarted.Lazily, + initialValue = false, + ) + + override fun setNotificationStackAbsoluteBottom(bottom: Float) { + notificationStackAbsoluteBottom.value = bottom + } + private suspend fun getWallpaper(selectedUser: SelectedUserModel): WallpaperInfo? { return withContext(bgDispatcher) { wallpaperManager.getWallpaperInfoForUser(selectedUser.userInfo.id) } } + + private fun shouldSendNotificationLayout(wallpaperInfo: WallpaperInfo?): Boolean { + return if (wallpaperInfo != null && wallpaperInfo.component != null) { + wallpaperInfo.component!!.className == MAGIC_PORTRAIT_CLASSNAME + } else { + false + } + } + + companion object { + const val MAGIC_PORTRAIT_CLASSNAME = + "com.google.android.apps.magicportrait.service.MagicPortraitWallpaperService" + } } diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/domain/interactor/WallpaperInteractor.kt b/packages/SystemUI/src/com/android/systemui/wallpapers/domain/interactor/WallpaperInteractor.kt new file mode 100644 index 000000000000..79ebf0128d02 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/wallpapers/domain/interactor/WallpaperInteractor.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.wallpapers.domain.interactor + +import com.android.systemui.wallpapers.data.repository.WallpaperRepository +import javax.inject.Inject + +class WallpaperInteractor @Inject constructor(val wallpaperRepository: WallpaperRepository) { + fun setNotificationStackAbsoluteBottom(bottom: Float) { + wallpaperRepository.setNotificationStackAbsoluteBottom(bottom) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt index 0b944f04a6a2..96a0aadacbc3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt @@ -39,13 +39,13 @@ import com.android.systemui.keyguard.ui.viewmodel.keyguardSmartspaceViewModel import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.res.R +import com.android.systemui.shade.LargeScreenHeaderHelper import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationsKeyguardInteractor import com.android.systemui.statusbar.policy.fakeConfigurationController import com.android.systemui.statusbar.ui.fakeSystemBarUtilsProxy import com.android.systemui.testKosmos import com.android.systemui.util.mockito.eq -import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -57,6 +57,7 @@ import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyString import org.mockito.MockitoAnnotations +import org.mockito.kotlin.mock @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidJUnit4::class) @@ -122,6 +123,7 @@ class ClockSectionTest : SysuiTestCase() { { keyguardBlueprintInteractor }, keyguardRootViewModel, aodBurnInViewModel, + largeScreenHeaderHelperLazy = { mock() }, ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java index 7cd306ead027..6425da46fc67 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java @@ -83,6 +83,7 @@ import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.ColorUpdateLogger; import com.android.systemui.statusbar.notification.DynamicPrivacyController; +import com.android.systemui.statusbar.notification.HeadsUpTouchHelper; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifPipeline; @@ -103,7 +104,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.notification.stack.NotificationSwipeHelper.NotificationCallback; import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder; import com.android.systemui.statusbar.phone.HeadsUpAppearanceController; -import com.android.systemui.statusbar.notification.HeadsUpTouchHelper; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -113,6 +113,7 @@ import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionCont import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.tuner.TunerService; import com.android.systemui.util.settings.SecureSettings; +import com.android.systemui.wallpapers.domain.interactor.WallpaperInteractor; import org.junit.Before; import org.junit.Test; @@ -154,6 +155,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { @Mock private KeyguardBypassController mKeyguardBypassController; @Mock private PowerInteractor mPowerInteractor; @Mock private PrimaryBouncerInteractor mPrimaryBouncerInteractor; + @Mock private WallpaperInteractor mWallpaperInteractor; @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager; @Mock private MetricsLogger mMetricsLogger; @Mock private ColorUpdateLogger mColorUpdateLogger; @@ -1070,7 +1072,8 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { mock(NotificationDismissibilityProvider.class), mActivityStarter, new ResourcesSplitShadeStateController(), - mSensitiveNotificationProtectionController); + mSensitiveNotificationProtectionController, + mWallpaperInteractor); } static class LogMatcher implements ArgumentMatcher { 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 8a3e5510b561..59fc0d157d54 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 @@ -102,6 +102,7 @@ import com.android.systemui.statusbar.phone.ScreenOffAnimationController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.AvalancheController; import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController; +import com.android.systemui.wallpapers.domain.interactor.WallpaperInteractor; import kotlin.Unit; @@ -146,6 +147,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Mock private NotificationStackScrollLayoutController mStackScrollLayoutController; @Mock private ScreenOffAnimationController mScreenOffAnimationController; @Mock private NotificationShelf mNotificationShelf; + @Mock private WallpaperInteractor mWallpaperInteractor; @Mock private NotificationStackSizeCalculator mStackSizeCalculator; @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; @Mock private LargeScreenShadeInterpolator mLargeScreenShadeInterpolator; @@ -208,6 +210,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { .thenReturn(mNotificationRoundnessManager); mStackScroller.setController(mStackScrollLayoutController); mStackScroller.setShelf(mNotificationShelf); + mStackScroller.setWallpaperInteractor(mWallpaperInteractor); when(mStackScroller.getExpandHelper()).thenReturn(mExpandHelper); doNothing().when(mGroupExpansionManager).collapseGroups(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt index bdecf2bdb53d..b8dd334dcad9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt @@ -18,18 +18,21 @@ package com.android.systemui.wallpapers.data.repository import android.app.WallpaperInfo import android.app.WallpaperManager +import android.content.ComponentName import android.content.Intent import android.content.pm.UserInfo +import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.keyguard.data.repository.FakeKeyguardClockRepository +import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.user.data.model.SelectedUserModel import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.FakeUserRepository -import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.whenever +import com.android.systemui.wallpapers.data.repository.WallpaperRepositoryImpl.Companion.MAGIC_PORTRAIT_CLASSNAME import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.StandardTestDispatcher @@ -39,6 +42,9 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.kotlin.any +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever @SmallTest @OptIn(ExperimentalCoroutinesApi::class) @@ -48,6 +54,8 @@ class WallpaperRepositoryImplTest : SysuiTestCase() { private val testDispatcher = StandardTestDispatcher() private val testScope = TestScope(testDispatcher) private val userRepository = FakeUserRepository() + private val keyguardClockRepository = FakeKeyguardClockRepository() + private val keyguardRepository = FakeKeyguardRepository() private val wallpaperManager: WallpaperManager = mock() private val underTest: WallpaperRepositoryImpl by lazy { @@ -56,6 +64,8 @@ class WallpaperRepositoryImplTest : SysuiTestCase() { testDispatcher, fakeBroadcastDispatcher, userRepository, + keyguardRepository, + keyguardClockRepository, wallpaperManager, context, ) @@ -219,7 +229,7 @@ class WallpaperRepositoryImplTest : SysuiTestCase() { testScope.runTest { context.orCreateTestableResources.addOverride( com.android.internal.R.bool.config_dozeSupportsAodWallpaper, - false + false, ) val latest by collectLastValue(underTest.wallpaperInfo) @@ -407,7 +417,7 @@ class WallpaperRepositoryImplTest : SysuiTestCase() { testScope.runTest { context.orCreateTestableResources.addOverride( com.android.internal.R.bool.config_dozeSupportsAodWallpaper, - false + false, ) val latest by collectLastValue(underTest.wallpaperSupportsAmbientMode) @@ -425,6 +435,54 @@ class WallpaperRepositoryImplTest : SysuiTestCase() { assertThat(latest).isFalse() } + @Test + @EnableFlags(Flags.FLAG_MAGIC_PORTRAIT_WALLPAPERS) + fun shouldSendNotificationLayout_setMagicPortraitWallpaper_launchSendLayoutJob() = + testScope.runTest { + val latest by collectLastValue(underTest.shouldSendNotificationLayout) + val magicPortraitWallpaper = + mock().apply { + whenever(this.component) + .thenReturn(ComponentName(context, MAGIC_PORTRAIT_CLASSNAME)) + } + whenever(wallpaperManager.getWallpaperInfoForUser(any())) + .thenReturn(magicPortraitWallpaper) + fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( + context, + Intent(Intent.ACTION_WALLPAPER_CHANGED), + ) + assertThat(latest).isTrue() + assertThat(underTest.sendLockscreenLayoutJob).isNotNull() + assertThat(underTest.sendLockscreenLayoutJob!!.isActive).isEqualTo(true) + } + + @Test + @EnableFlags(Flags.FLAG_MAGIC_PORTRAIT_WALLPAPERS) + fun shouldSendNotificationLayout_setNotMagicPortraitWallpaper_cancelSendLayoutJob() = + testScope.runTest { + val latest by collectLastValue(underTest.shouldSendNotificationLayout) + val magicPortraitWallpaper = MAGIC_PORTRAIT_WP + whenever(wallpaperManager.getWallpaperInfoForUser(any())) + .thenReturn(magicPortraitWallpaper) + fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( + context, + Intent(Intent.ACTION_WALLPAPER_CHANGED), + ) + assertThat(latest).isTrue() + assertThat(underTest.sendLockscreenLayoutJob).isNotNull() + assertThat(underTest.sendLockscreenLayoutJob!!.isActive).isEqualTo(true) + + val nonMagicPortraitWallpaper = UNSUPPORTED_WP + whenever(wallpaperManager.getWallpaperInfoForUser(any())) + .thenReturn(nonMagicPortraitWallpaper) + fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( + context, + Intent(Intent.ACTION_WALLPAPER_CHANGED), + ) + assertThat(latest).isFalse() + assertThat(underTest.sendLockscreenLayoutJob?.isCancelled).isEqualTo(true) + } + private companion object { val USER_WITH_UNSUPPORTED_WP = UserInfo(/* id= */ 3, /* name= */ "user3", /* flags= */ 0) val UNSUPPORTED_WP = @@ -433,5 +491,10 @@ class WallpaperRepositoryImplTest : SysuiTestCase() { val USER_WITH_SUPPORTED_WP = UserInfo(/* id= */ 4, /* name= */ "user4", /* flags= */ 0) val SUPPORTED_WP = mock().apply { whenever(this.supportsAmbientMode()).thenReturn(true) } + + val MAGIC_PORTRAIT_WP = + mock().apply { + whenever(this.component).thenReturn(ComponentName("", MAGIC_PORTRAIT_CLASSNAME)) + } } } diff --git a/packages/SystemUI/tests/utils/src/com/android/app/WallpaperManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/app/WallpaperManagerKosmos.kt new file mode 100644 index 000000000000..2850ab7b1e41 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/app/WallpaperManagerKosmos.kt @@ -0,0 +1,27 @@ +/* + * 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.app + +import android.app.WallpaperManager +import android.content.applicationContext +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import kotlinx.coroutines.ExperimentalCoroutinesApi + +@OptIn(ExperimentalCoroutinesApi::class) +val Kosmos.wallpaperManager: WallpaperManager by Fixture { + WallpaperManager.getInstance(applicationContext) +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt index 5e5f8cb1055a..159dd34efbbc 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt @@ -46,16 +46,27 @@ class FakeKeyguardClockRepository() : KeyguardClockRepository { private val _previewClock = MutableStateFlow(Mockito.mock(ClockController::class.java)) override val previewClock: Flow get() = _previewClock + + private val _notificationDefaultTop = MutableStateFlow(0F) + override val notificationDefaultTop: StateFlow + get() = _notificationDefaultTop + override val clockEventController: ClockEventController get() = mock() + override val shouldForceSmallClock: Boolean get() = _shouldForceSmallClock + private var _shouldForceSmallClock: Boolean = false override fun setClockSize(size: ClockSize) { _clockSize.value = size } + override fun setNotificationDefaultTop(top: Float) { + _notificationDefaultTop.value = top + } + fun setSelectedClockSize(size: ClockSizeSetting) { _selectedClockSize.value = size } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt index 54a6c0c1d182..e513e8d2a350 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt @@ -131,6 +131,10 @@ class FakeKeyguardRepository @Inject constructor() : KeyguardRepository { private val _isEncryptedOrLockdown = MutableStateFlow(true) override val isEncryptedOrLockdown: Flow = _isEncryptedOrLockdown + private val _shortcutAbsoluteTop = MutableStateFlow(0F) + override val shortcutAbsoluteTop: StateFlow + get() = _shortcutAbsoluteTop.asStateFlow() + private val _isKeyguardEnabled = MutableStateFlow(true) override val isKeyguardEnabled: StateFlow = _isKeyguardEnabled.asStateFlow() @@ -241,7 +245,7 @@ class FakeKeyguardRepository @Inject constructor() : KeyguardRepository { override fun setBiometricUnlockState( mode: BiometricUnlockMode, - source: BiometricUnlockSource? + source: BiometricUnlockSource?, ) { _biometricUnlockState.tryEmit(BiometricUnlockModel(mode, source)) } @@ -294,6 +298,10 @@ class FakeKeyguardRepository @Inject constructor() : KeyguardRepository { return isShowKeyguardWhenReenabled } + override fun setShortcutAbsoluteTop(top: Float) { + _shortcutAbsoluteTop.value = top + } + override fun setCanIgnoreAuthAndReturnToGone(canWake: Boolean) { _canIgnoreAuthAndReturnToGone.value = canWake } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt index 12d7c49194ff..49a8c1866aa2 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt @@ -29,9 +29,10 @@ import com.android.systemui.keyguard.ui.viewmodel.keyguardClockViewModel import com.android.systemui.keyguard.ui.viewmodel.keyguardRootViewModel import com.android.systemui.keyguard.ui.viewmodel.keyguardSmartspaceViewModel import com.android.systemui.kosmos.Kosmos -import com.android.systemui.util.mockito.mock +import com.android.systemui.shade.LargeScreenHeaderHelper import java.util.Optional import org.mockito.Mockito.spy +import org.mockito.kotlin.mock val Kosmos.keyguardClockSection: ClockSection by Kosmos.Fixture { @@ -43,6 +44,7 @@ val Kosmos.keyguardClockSection: ClockSection by blueprintInteractor = { keyguardBlueprintInteractor }, rootViewModel = keyguardRootViewModel, aodBurnInViewModel = aodBurnInViewModel, + largeScreenHeaderHelperLazy = { mock() }, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorKosmos.kt index d52883eb38af..bdb9abb03c5f 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorKosmos.kt @@ -27,13 +27,13 @@ import com.android.systemui.statusbar.notification.stack.domain.interactor.heads val Kosmos.keyguardClockInteractor by Kosmos.Fixture { KeyguardClockInteractor( - keyguardClockRepository = keyguardClockRepository, - applicationScope = applicationCoroutineScope, mediaCarouselInteractor = mediaCarouselInteractor, activeNotificationsInteractor = activeNotificationsInteractor, shadeInteractor = shadeInteractor, keyguardInteractor = keyguardInteractor, keyguardTransitionInteractor = keyguardTransitionInteractor, headsUpNotificationInteractor = headsUpNotificationInteractor, + applicationScope = applicationCoroutineScope, + keyguardClockRepository = keyguardClockRepository, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryKosmos.kt new file mode 100644 index 000000000000..1d8c891679aa --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryKosmos.kt @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.wallpapers.data.repository + +import android.content.applicationContext +import com.android.app.wallpaperManager +import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.keyguard.data.repository.keyguardClockRepository +import com.android.systemui.keyguard.data.repository.keyguardRepository +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.kosmos.testScope +import com.android.systemui.user.data.repository.userRepository +import kotlinx.coroutines.ExperimentalCoroutinesApi + +@OptIn(ExperimentalCoroutinesApi::class) +val Kosmos.wallpaperRepository by Fixture { + WallpaperRepositoryImpl( + context = applicationContext, + scope = testScope, + bgDispatcher = testDispatcher, + broadcastDispatcher = broadcastDispatcher, + userRepository = userRepository, + wallpaperManager = wallpaperManager, + keyguardClockRepository = keyguardClockRepository, + keyguardRepository = keyguardRepository, + ) +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/domain/interactor/WallpaperInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/domain/interactor/WallpaperInteractorKosmos.kt new file mode 100644 index 000000000000..5278351520f3 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/wallpapers/domain/interactor/WallpaperInteractorKosmos.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.wallpapers.domain.interactor + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.wallpapers.data.repository.wallpaperRepository + +val Kosmos.wallpaperInteractor by + Kosmos.Fixture { WallpaperInteractor(wallpaperRepository = wallpaperRepository) } -- GitLab From beff035f43d54783349b4d2d1e267f0bb4d9876a Mon Sep 17 00:00:00 2001 From: Ats Jenk Date: Mon, 7 Oct 2024 16:54:20 -0700 Subject: [PATCH 170/447] Define new events for bubble bar logging Create the event ids. Bug: 349845968 Test: m Flag: EXEMPT metrics changes Change-Id: Ib807551c3e86ddc1d6dfbd74992a781eedc74efc --- .../wm/shell/bubbles/BubbleLogger.java | 86 ++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java index c88a58be1461..1abe11998500 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java @@ -36,6 +36,8 @@ public class BubbleLogger { @VisibleForTesting public enum Event implements UiEventLogger.UiEventEnum { + // region bubble events + @UiEvent(doc = "User dismissed the bubble via gesture, add bubble to overflow.") BUBBLE_OVERFLOW_ADD_USER_GESTURE(483), @@ -64,7 +66,89 @@ public class BubbleLogger { BUBBLE_OVERFLOW_SELECTED(600), @UiEvent(doc = "Restore bubble to overflow after phone reboot.") - BUBBLE_OVERFLOW_RECOVER(691); + BUBBLE_OVERFLOW_RECOVER(691), + + // endregion + + // region bubble bar events + + @UiEvent(doc = "new bubble posted") + BUBBLE_BAR_BUBBLE_POSTED(1927), + + @UiEvent(doc = "existing bubble updated") + BUBBLE_BAR_BUBBLE_UPDATED(1928), + + @UiEvent(doc = "expanded a bubble from bubble bar") + BUBBLE_BAR_EXPANDED(1929), + + @UiEvent(doc = "bubble bar collapsed") + BUBBLE_BAR_COLLAPSED(1930), + + @UiEvent(doc = "dismissed single bubble from bubble bar by dragging it to dismiss target") + BUBBLE_BAR_BUBBLE_DISMISSED_DRAG_BUBBLE(1931), + + @UiEvent(doc = "dismissed single bubble from bubble bar by dragging the expanded view to " + + "dismiss target") + BUBBLE_BAR_BUBBLE_DISMISSED_DRAG_EXP_VIEW(1932), + + @UiEvent(doc = "dismiss bubble from app handle menu") + BUBBLE_BAR_BUBBLE_DISMISSED_APP_MENU(1933), + + @UiEvent(doc = "bubble is dismissed due to app finishing the bubble activity") + BUBBLE_BAR_BUBBLE_ACTIVITY_FINISH(1934), + + @UiEvent(doc = "dismissed the bubble bar by dragging it to dismiss target") + BUBBLE_BAR_DISMISSED_DRAG_BAR(1935), + + @UiEvent(doc = "bubble bar moved to the left edge of the screen by dragging from the " + + "expanded view") + BUBBLE_BAR_MOVED_LEFT_DRAG_EXP_VIEW(1936), + + @UiEvent(doc = "bubble bar moved to the left edge of the screen by dragging from a single" + + " bubble") + BUBBLE_BAR_MOVED_LEFT_DRAG_BUBBLE(1937), + + @UiEvent(doc = "bubble bar moved to the left edge of the screen by dragging the bubble bar") + BUBBLE_BAR_MOVED_LEFT_DRAG_BAR(1938), + + @UiEvent(doc = "bubble bar moved to the right edge of the screen by dragging from the " + + "expanded view") + BUBBLE_BAR_MOVED_RIGHT_DRAG_EXP_VIEW(1939), + + @UiEvent(doc = "bubble bar moved to the right edge of the screen by dragging from a " + + "single bubble") + BUBBLE_BAR_MOVED_RIGHT_DRAG_BUBBLE(1940), + + @UiEvent(doc = "bubble bar moved to the right edge of the screen by dragging the bubble " + + "bar") + BUBBLE_BAR_MOVED_RIGHT_DRAG_BAR(1941), + + @UiEvent(doc = "stop bubbling conversation from app handle menu") + BUBBLE_BAR_APP_MENU_OPT_OUT(1942), + + @UiEvent(doc = "open app settings from app handle menu") + BUBBLE_BAR_APP_MENU_GO_TO_SETTINGS(1943), + + @UiEvent(doc = "flyout shown for a bubble") + BUBBLE_BAR_FLYOUT(1944), + + @UiEvent(doc = "notification for the bubble was canceled") + BUBBLE_BAR_BUBBLE_REMOVED_CANCELED(1945), + + @UiEvent(doc = "user turned off bubbles from settings") + BUBBLE_BAR_BUBBLE_REMOVED_BLOCKED(1946), + + @UiEvent(doc = "bubble bar overflow opened") + BUBBLE_BAR_OVERFLOW_SELECTED(1947), + + @UiEvent(doc = "max number of bubbles was reached in bubble bar, move bubble to overflow") + BUBBLE_BAR_OVERFLOW_ADD_AGED(1948), + + @UiEvent(doc = "bubble promoted from overflow back to bubble bar") + BUBBLE_BAR_OVERFLOW_REMOVE_BACK_TO_BAR(1949), + + // endregion + ; private final int mId; -- GitLab From 8d5ef8141ec3fed0ac91ccd0072831800eaa301a Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 7 Oct 2024 17:39:54 -0700 Subject: [PATCH 171/447] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I8498c8e4c814ea74229b43ffb162b7793be0aaaf --- .../SettingsLib/res/values-af/strings.xml | 7 ++--- .../SettingsLib/res/values-am/strings.xml | 7 ++--- .../SettingsLib/res/values-ar/strings.xml | 7 ++--- .../SettingsLib/res/values-as/strings.xml | 7 ++--- .../SettingsLib/res/values-az/strings.xml | 7 ++--- .../res/values-b+sr+Latn/strings.xml | 7 ++--- .../SettingsLib/res/values-be/strings.xml | 7 ++--- .../SettingsLib/res/values-bg/strings.xml | 9 ++++--- .../SettingsLib/res/values-bn/strings.xml | 7 ++--- .../SettingsLib/res/values-bs/strings.xml | 7 ++--- .../SettingsLib/res/values-ca/strings.xml | 9 ++++--- .../SettingsLib/res/values-cs/strings.xml | 7 ++--- .../SettingsLib/res/values-da/strings.xml | 7 ++--- .../SettingsLib/res/values-de/strings.xml | 7 ++--- .../SettingsLib/res/values-el/strings.xml | 7 ++--- .../SettingsLib/res/values-en-rAU/strings.xml | 7 ++--- .../SettingsLib/res/values-en-rCA/strings.xml | 6 ++--- .../SettingsLib/res/values-en-rGB/strings.xml | 6 ++--- .../SettingsLib/res/values-en-rIN/strings.xml | 7 ++--- .../SettingsLib/res/values-en-rXC/strings.xml | 6 ++--- .../SettingsLib/res/values-es-rUS/strings.xml | 7 ++--- .../SettingsLib/res/values-es/strings.xml | 7 ++--- .../SettingsLib/res/values-et/strings.xml | 7 ++--- .../SettingsLib/res/values-eu/strings.xml | 7 ++--- .../SettingsLib/res/values-fa/strings.xml | 13 ++++----- .../SettingsLib/res/values-fi/strings.xml | 7 ++--- .../SettingsLib/res/values-fr-rCA/strings.xml | 7 ++--- .../SettingsLib/res/values-fr/strings.xml | 7 ++--- .../SettingsLib/res/values-gl/strings.xml | 7 ++--- .../SettingsLib/res/values-gu/strings.xml | 7 ++--- .../SettingsLib/res/values-hi/strings.xml | 7 ++--- .../SettingsLib/res/values-hr/strings.xml | 7 ++--- .../SettingsLib/res/values-hu/strings.xml | 7 ++--- .../SettingsLib/res/values-hy/strings.xml | 7 ++--- .../SettingsLib/res/values-in/strings.xml | 9 ++++--- .../SettingsLib/res/values-is/strings.xml | 7 ++--- .../SettingsLib/res/values-it/strings.xml | 7 ++--- .../SettingsLib/res/values-iw/strings.xml | 7 ++--- .../SettingsLib/res/values-ja/strings.xml | 7 ++--- .../SettingsLib/res/values-ka/strings.xml | 7 ++--- .../SettingsLib/res/values-kk/strings.xml | 7 ++--- .../SettingsLib/res/values-km/strings.xml | 13 ++++----- .../SettingsLib/res/values-kn/strings.xml | 27 ++++++++++--------- .../SettingsLib/res/values-ko/strings.xml | 7 ++--- .../SettingsLib/res/values-ky/strings.xml | 7 ++--- .../SettingsLib/res/values-lo/strings.xml | 7 ++--- .../SettingsLib/res/values-lt/strings.xml | 7 ++--- .../SettingsLib/res/values-lv/strings.xml | 7 ++--- .../SettingsLib/res/values-mk/strings.xml | 7 ++--- .../SettingsLib/res/values-ml/strings.xml | 7 ++--- .../SettingsLib/res/values-mn/strings.xml | 7 ++--- .../SettingsLib/res/values-mr/strings.xml | 7 ++--- .../SettingsLib/res/values-ms/strings.xml | 7 ++--- .../SettingsLib/res/values-my/strings.xml | 9 ++++--- .../SettingsLib/res/values-nb/strings.xml | 7 ++--- .../SettingsLib/res/values-ne/strings.xml | 7 ++--- .../SettingsLib/res/values-nl/strings.xml | 7 ++--- .../SettingsLib/res/values-or/strings.xml | 7 ++--- .../SettingsLib/res/values-pa/strings.xml | 7 ++--- .../SettingsLib/res/values-pl/strings.xml | 7 ++--- .../SettingsLib/res/values-pt-rBR/strings.xml | 6 ++--- .../SettingsLib/res/values-pt-rPT/strings.xml | 7 ++--- .../SettingsLib/res/values-pt/strings.xml | 7 ++--- .../SettingsLib/res/values-ro/strings.xml | 7 ++--- .../SettingsLib/res/values-ru/strings.xml | 7 ++--- .../SettingsLib/res/values-si/strings.xml | 7 ++--- .../SettingsLib/res/values-sk/strings.xml | 7 ++--- .../SettingsLib/res/values-sl/strings.xml | 7 ++--- .../SettingsLib/res/values-sq/strings.xml | 7 ++--- .../SettingsLib/res/values-sr/strings.xml | 7 ++--- .../SettingsLib/res/values-sv/strings.xml | 7 ++--- .../SettingsLib/res/values-sw/strings.xml | 7 ++--- .../SettingsLib/res/values-ta/strings.xml | 7 ++--- .../SettingsLib/res/values-te/strings.xml | 7 ++--- .../SettingsLib/res/values-th/strings.xml | 7 ++--- .../SettingsLib/res/values-tl/strings.xml | 7 ++--- .../SettingsLib/res/values-tr/strings.xml | 7 ++--- .../SettingsLib/res/values-uk/strings.xml | 7 ++--- .../SettingsLib/res/values-ur/strings.xml | 7 ++--- .../SettingsLib/res/values-uz/strings.xml | 7 ++--- .../SettingsLib/res/values-vi/strings.xml | 7 ++--- .../SettingsLib/res/values-zh-rCN/strings.xml | 7 ++--- .../SettingsLib/res/values-zh-rHK/strings.xml | 7 ++--- .../SettingsLib/res/values-zh-rTW/strings.xml | 7 ++--- .../SettingsLib/res/values-zu/strings.xml | 7 ++--- 85 files changed, 356 insertions(+), 275 deletions(-) diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 0a507d12a5cb..0a8c6bfd7bdf 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -585,7 +585,6 @@ "Hierdie rekenaar (intern)" - "Mikrofoon (intern)" "Dokluidspreker" "Eksterne toestel" "Gekoppelde toestel" @@ -688,9 +687,11 @@ "Jou toestel moet herselflaai om hierdie verandering toe te pas. Herselflaai nou of kanselleer." "Bedrade oorfoon" "Oorfoon" - "USB-luidspreker" + "USB-oudio" "Mikrofoonsok" - "USB-mikrofoon" + "USB-mikrofoon" + + "Aan" "Af" "Diensverskaffernetwerk verander tans" diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 66644cb796c4..56420e296287 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -585,7 +585,6 @@ "ይህ ኮምፒውተር (ውስጣዊ)" - "ማይክሮፎን (ውስጣዊ)" "የመትከያ ድምፅ ማውጫ" "የውጭ መሣሪያ" "የተገናኘ መሣሪያ" @@ -688,9 +687,11 @@ "የእርስዎን መሣሪያ ይህ ለው ለማመልከት እንደገና መነሣት አለበት። አሁን እንደገና ያስነሡ ወይም ይተዉት።" "ባለገመድ የራስ ላይ ማዳመጫ" "የጆሮ ማዳመጫ" - "USB ድምፅ ማውጫ" + "USB ኦዲዮ" "የማይክሮፎን መሰኪያ" - "USB ማይክሮፎን" + "USB ማይክሮፎን" + + "አብራ" "አጥፋ" "የአገልግሎት አቅራቢ አውታረ መረብን በመቀየር ላይ" diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index e241c8a9a5a3..88fadbc6cb0a 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -585,7 +585,6 @@ "هذا الكمبيوتر (داخلي)" - "ميكروفون (داخلي)" "مكبّر صوت بقاعدة إرساء" "جهاز خارجي" "جهاز متّصل" @@ -688,9 +687,11 @@ "يجب إعادة تشغيل جهازك ليتم تطبيق هذا التغيير. يمكنك إعادة التشغيل الآن أو إلغاء التغيير." "سماعات رأس سلكية" "سماعات رأس" - "‏مكبّر صوت USB" + "‏مكبر صوت USB" "مقبس الميكروفون" - "‏ميكروفون بمنفذ USB" + "‏ميكروفون USB" + + "مفعّلة" "إيقاف" "جارٍ تغيير شبكة مشغِّل شبكة الجوّال." diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index 4e734b9cf094..fca2953a788c 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -585,7 +585,6 @@ "এই কম্পিউটাৰ (অভ্যন্তৰীণ)" - "মাইক্ৰ’ফ’ন (অভ্যন্তৰীণ)" "ড’ক স্পীকাৰ" "বাহ্যিক ডিভাইচ" "সংযোগ হৈ থকা ডিভাইচ" @@ -688,9 +687,11 @@ "এই সলনিটো কার্যকৰী হ’বলৈ আপোনাৰ ডিভাইচটো ৰিবুট কৰিবই লাগিব। এতিয়াই ৰিবুট কৰক অথবা বাতিল কৰক।" "তাঁৰযুক্ত হেডফ’ন" "হেডফ’ন" - "USB স্পীকাৰ" + "ইউএছবি অডিঅ\'" "মাইকৰ জেক" - "ইউএছবি মাইক" + "ইউএছবি মাইক্ৰ’ফ’ন" + + "অন" "অফ" "বাহক নেটৱৰ্কৰ পৰিৱৰ্তন" diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index 057d49249cc7..5ba618628df9 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -585,7 +585,6 @@ "Bu kompüter (daxili)" - "Mikrofon (daxili)" "Dok dinamiki" "Xarici cihaz" "Qoşulmuş cihaz" @@ -688,9 +687,11 @@ "Bu dəyişikliyin tətbiq edilməsi üçün cihaz yenidən başladılmalıdır. İndi yenidən başladın və ya ləğv edin." "Naqilli qulaqlıq" "Qulaqlıq" - "USB spikeri" + "USB audio" "Mikrofon yuvası" - "USB mikrofon" + "USB mikrofon" + + "Aktiv" "Deaktiv" "Operator şəbəkəsinin dəyişilməsi" diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index fdd969d81a8f..28eaeba986c8 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -585,7 +585,6 @@ "Ovaj računar (interno)" - "Mikrofon (interni)" "Zvučnik bazne stanice" "Spoljni uređaj" "Povezani uređaj" @@ -688,9 +687,11 @@ "Morate da restartujete uređaj da bi se ova promena primenila. Restartujte ga odmah ili otkažite." "Žičane slušalice" "Slušalice" - "USB zvučnik" + "USB audio" "Utikač za mikrofon" - "USB mikrofon" + "USB mikrofon" + + "Uključeno" "Isključeno" "Promena mreže mobilnog operatera" diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index a262901b7992..e1da65e8d5c9 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -585,7 +585,6 @@ "Гэты камп’ютар (унутраны)" - "Мікрафон (унутраны)" "Дынамік док-станцыі" "Знешняя прылада" "Падключаная прылада" @@ -688,9 +687,11 @@ "Перазагрузіце прыладу, каб прымяніць гэта змяненне. Перазагрузіце ці скасуйце." "Правадныя навушнікі" "Навушнікі" - "USB-дынамік" + "Аўдыяпрылада USB" "Раздым для мікрафона" - "Мікрафон USB" + "Мікрафон USB" + + "Уключана" "Выключана" "Змяненне аператара сеткі" diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 244a090aa594..b0c235483782 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -288,7 +288,7 @@ "Да се разреши ли отключване от OEM?" "ПРЕДУПРЕЖДЕНИЕ: Функциите за защита на устройството няма да работят, докато следната настройка е включена." "Избиране на приложение за мнимо местоположение" - "Няма зададено приложение за мнимо местоположение" + "Няма зададено приложение" "Приложение за мнимо местоположение: %1$s" "Мрежи" "Безжичен дисплей" @@ -585,7 +585,6 @@ "Този компютър (вграден)" - "Микрофон (вътрешен)" "Високоговорител докинг станция" "Външно устройство" "Свързано устройство" @@ -688,9 +687,11 @@ "За да бъде приложена тази промяна, устройството ви трябва да бъде рестартирано. Рестартирайте сега или анулирайте." "Слушалки с кабел" "Слушалки" - "Високоговорител с USB" + "Аудиоустройство с USB" "Жак за микрофон" - "Микрофон с USB" + "Микрофон с USB" + + "Включване" "Изключване" "Промяна на мрежата на оператора" diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index 907cee10d23f..e861b579a04b 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -585,7 +585,6 @@ "এই কম্পিউটার (ইন্টার্নাল)" - "মাইক্রোফোন (ইন্টার্নাল)" "ডক স্পিকার" "এক্সটার্নাল ডিভাইস" "কানেক্ট থাকা ডিভাইস" @@ -688,9 +687,11 @@ "এই পরিবর্তনটি প্রয়োগ করার জন্য আপনার ডিভাইসটি অবশ্যই রিবুট করতে হবে। এখনই রিবুট করুন বা বাতিল করুন।" "তারযুক্ত হেডফোন" "হেডফোন" - "USB স্পিকার" + "USB অডিও" "মাইকের জ্যাক" - "USB মাইক" + "USB মাইক্রোফোন" + + "চালু আছে" "বন্ধ আছে" "পরিষেবা প্রদানকারীর নেটওয়ার্ক পরিবর্তন করা হচ্ছে" diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index 6b09b51a2f68..8844503d05a6 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -585,7 +585,6 @@ "Ovaj računar (interno)" - "Mikrofon (interni)" "Zvučnik priključne stanice" "Vanjski uređaj" "Povezani uređaj" @@ -688,9 +687,11 @@ "Morate ponovo pokrenuti uređaj da se ova promjena primijeni. Ponovo pokrenite odmah ili otkažite." "Žičane slušalice" "Slušalice" - "USB zvučnik" + "USB audio" "Priključak za mikrofon" - "USB mikrofon" + "USB mikrofon" + + "Uključi" "Isključi" "Promjena mreže mobilnog operatera" diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 305772989db9..b905ae2a1e81 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -288,7 +288,7 @@ "Permetre el desbloqueig OEM?" "ADVERTIMENT: les funcions de protecció del dispositiu no funcionaran mentre aquesta opció estigui activada." "Selecciona una aplicació d\'ubicació simulada" - "No s\'ha definit cap aplicació d\'ubicació simulada" + "Cap aplicació d\'ubicació simulada definida" "Aplicació d\'ubicació simulada: %1$s" "Xarxes" "Certificació de pantalla sense fil" @@ -585,7 +585,6 @@ "Aquest ordinador (intern)" - "Micròfon (intern)" "Base d\'altaveu" "Dispositiu extern" "Dispositiu connectat" @@ -688,9 +687,11 @@ "Has de reiniciar el teu dispositiu perquè s\'apliquin els canvis. Reinicia\'l ara o cancel·la." "Auriculars amb cable" "Auriculars" - "Altaveu USB" + "Àudio USB" "Connector per al micròfon" - "Micròfon USB" + "Micròfon USB" + + "Activa" "Desactivat" "S\'està canviant la xarxa de l\'operador de telefonia mòbil" diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index d274e850c0f0..a69374f0a91c 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -585,7 +585,6 @@ "Tento počítač (interní)" - "Mikrofon (interní)" "Reproduktor doku" "Externí zařízení" "Připojené zařízení" @@ -688,9 +687,11 @@ "Aby se tato změna projevila, je třeba zařízení restartovat. Restartujte zařízení nebo zrušte akci." "Kabelová sluchátka" "Sluchátka" - "USB reproduktor" + "Zvuk USB" "Konektor mikrofonu" - "USB mikrofon" + "Mikrofon USB" + + "Zapnout" "Vypnout" "Probíhá změna sítě operátora" diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index ef37c658ffeb..f14c04b92992 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -585,7 +585,6 @@ "Denne computer (intern)" - "Mikrofon (indbygget)" "Dockhøjttaler" "Ekstern enhed" "Forbundet enhed" @@ -688,9 +687,11 @@ "Din enhed skal genstartes for at anvende denne ændring. Genstart nu, eller annuller." "Høretelefoner med ledning" "Høretelefoner" - "USB-højttaler" + "USB-lydenhed" "Stik til mikrofon" - "USB-mikrofon" + "USB-mikrofon" + + "Til" "Fra" "Skift af mobilnetværk" diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 44f7329bc8db..972bb1fea866 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -585,7 +585,6 @@ "Dieser Computer (intern)" - "Mikrofon (intern)" "Dock-Lautsprecher" "Externes Gerät" "Verbundenes Gerät" @@ -688,9 +687,11 @@ "Damit diese Änderung übernommen wird, musst du dein Gerät neu starten. Du kannst es jetzt neu starten oder den Vorgang abbrechen." "Kabelgebundene Kopfhörer" "Kopfhörer" - "USB-Lautsprecher" + "USB-Audio" "Mikrofonanschluss" - "USB‑Mikrofon" + "USB-Mikrofon" + + "An" "Aus" "Mobilfunknetzwerk wird gewechselt" diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index 9cfceb56751c..86a4cb9addc3 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -585,7 +585,6 @@ "Αυτός ο υπολογιστής (εσωτερ.)" - "Μικρόφωνο (εσωτερικό)" "Ηχείο βάσης σύνδεσης" "Εξωτερική συσκευή" "Συνδεδεμένη συσκευή" @@ -688,9 +687,11 @@ "Για να εφαρμοστεί αυτή η αλλαγή, θα πρέπει να επανεκκινήσετε τη συσκευή σας. Επανεκκίνηση τώρα ή ακύρωση." "Ενσύρματα ακουστικά" "Ακουστικά" - "Ηχείο USB" + "Ήχος USB" "Υποδοχή μικροφώνου" - "Μικρόφωνο USB" + "Μικρόφωνο USB" + + "Ενεργό" "Ανενεργό" "Αλλαγή δικτύου εταιρείας κινητής τηλεφωνίας" diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index d4e01ded8f59..7296c9696c8c 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -585,7 +585,6 @@ "This computer (internal)" - "Microphone (internal)" "Dock speaker" "External device" "Connected device" @@ -688,9 +687,11 @@ "Your device must be rebooted for this change to apply. Reboot now or cancel." "Wired headphones" "Headphone" - "USB speaker" + "USB audio" "Mic jack" - "USB mic" + "USB microphone" + + "On" "Off" "Operator network changing" diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index 602a0ed5c835..c07bd342e25b 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -585,7 +585,6 @@ "This computer (internal)" - "Microphone (internal)" "Dock speaker" "External Device" "Connected device" @@ -688,9 +687,10 @@ "Your device must be rebooted for this change to apply. Reboot now or cancel." "Wired headphone" "Headphone" - "USB speaker" + "USB audio" "Mic jack" - "USB mic" + "USB microphone" + "BT microphone" "On" "Off" "Carrier network changing" diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index 2fd84f36c664..7296c9696c8c 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -687,10 +687,10 @@ "Your device must be rebooted for this change to apply. Reboot now or cancel." "Wired headphones" "Headphone" - - + "USB audio" "Mic jack" - + "USB microphone" + "On" "Off" diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index d4e01ded8f59..7296c9696c8c 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -585,7 +585,6 @@ "This computer (internal)" - "Microphone (internal)" "Dock speaker" "External device" "Connected device" @@ -688,9 +687,11 @@ "Your device must be rebooted for this change to apply. Reboot now or cancel." "Wired headphones" "Headphone" - "USB speaker" + "USB audio" "Mic jack" - "USB mic" + "USB microphone" + + "On" "Off" "Operator network changing" diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index 0731b72b4b25..c85b12a129a0 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -585,7 +585,6 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎This computer (internal)‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎Microphone (internal)‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‏‏‎‎Dock speaker‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‎‎External Device‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎Connected device‎‏‎‎‏‎" @@ -688,9 +687,10 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‎‎‎‎‎Your device must be rebooted for this change to apply. Reboot now or cancel.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎‎Wired headphone‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎Headphone‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‏‏‎‏‎‏‎‎‎‎USB speaker‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎USB audio‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‏‏‏‎‎‎‏‎‏‎Mic jack‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎USB mic‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‏‎‎USB microphone‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎BT microphone‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎On‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎Off‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‎‎Carrier network changing‎‏‎‎‏‎" diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index d6222ac07660..c933c7e77066 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -585,7 +585,6 @@ "Esta computadora (interna)" - "Micrófono (interno)" "Bocina de la estación de carga" "Dispositivo externo" "Dispositivo conectado" @@ -688,9 +687,11 @@ "Debes reiniciar el dispositivo para que se aplique el cambio. Reinícialo ahora o cancela la acción." "Auriculares con cable" "Auriculares" - "Bocina USB" + "Audio USB" "Conector para micrófono" - "Micrófono USB" + "Micrófono USB" + + "Activar" "Desactivar" "Cambio de proveedor de red" diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index d88634e2e72e..6215e7729f7a 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -585,7 +585,6 @@ "Este ordenador (interno)" - "Micrófono (interno)" "Altavoz de la base" "Dispositivo externo" "Dispositivo conectado" @@ -688,9 +687,11 @@ "Es necesario reiniciar tu dispositivo para que se apliquen los cambios. Reinicia ahora o cancela la acción." "Auriculares con cable" "Auriculares" - "Altavoz USB" + "Audio USB" "Conector jack para micrófono" - "Micrófono USB" + "Micrófono USB" + + "Activado" "Desactivado" "Cambiando la red del operador" diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index e3020be848ab..81926e5a5c03 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -585,7 +585,6 @@ "See arvuti (sisemine)" - "Mikrofon (sisemine)" "Doki kõlar" "Väline seade" "Ühendatud seade" @@ -688,9 +687,11 @@ "Selle muudatuse rakendamiseks tuleb seade taaskäivitada. Taaskäivitage kohe või tühistage." "Juhtmega kõrvaklapid" "Kõrvaklapid" - "USB kõlar" + "USB-heli" "Mikrofoni pistikupesa" - "USB-mikrofon" + "USB-mikrofon" + + "Sees" "Väljas" "Operaatori võrku muudetakse" diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index da47004793bc..45c2daa38f5c 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -585,7 +585,6 @@ "Ordenagailu hau (barnekoa)" - "Mikrofonoa (barnekoa)" "Oinarri bozgorailuduna" "Kanpoko gailua" "Konektatutako gailua" @@ -688,9 +687,11 @@ "Aldaketa aplikatzeko, berrabiarazi egin behar da gailua. Berrabiaraz ezazu orain, edo utzi bertan behera." "Entzungailu kableduna" "Entzungailua" - "USB bidezko bozgorailua" + "USB bidezko audioa" "Mikrofonoaren konektorea" - "USB bidezko mikrofonoa" + "USB bidezko mikrofonoa" + + "Aktibatu" "Desaktibatu" "Operadorearen sarea aldatzen" diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 5996efb9a9a7..af969248aec1 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -397,7 +397,7 @@ "‏غیرفعال کردن مسیریابی خودکار به وسایل جانبی صوتی USB" "نمایش محدوده‌های طرح‌بندی" "نمایش مرزها، حاشیه‌ها و ویژگی‌های دیگر کلیپ." - "اجباری کردن چیدمان راست‌چین" + "الزام جانمایی راست به چپ" "اجباری کردن چیدمان راست‌چین صفحه برای همه زبان‌ها" "نوار پیمایش شفاف" "رنگ پس‌زمینه نوار پیمایش را به‌طور پیش‌فرض شفاف می‌کند" @@ -418,7 +418,7 @@ "به‌طور نامحدود فعال شد" "مقیاس پویانمایی پنجره" "مقیاس پویانمایی انتقالی" - "مقیاس طول مدت انیماتور" + "مقیاس طول مدت مقیاس مدت پویانماساز" "شبیه‌سازی نمایشگر ثانویه" "برنامه‌ها" "فعالیت‌ها نگه داشته نشوند" @@ -585,7 +585,6 @@ "این رایانه (داخلی)" - "میکروفون (داخلی)" "بلندگوی پایه اتصال" "دستگاه خارجی" "دستگاه متصل" @@ -688,9 +687,11 @@ "برای اعمال این تغییر، دستگاه باید بازراه‌اندازی شود. یا اکنون بازراه‌اندازی کنید یا لغو کنید." "هدفون سیمی" "هدفون" - "‏بلندگوی USB" + "‏بلندگوی USB" "فیش میکروفون" - "‏میکروفون USB" + "‏میکروفون USB" + + "روشن" "خاموش" "تغییر شبکه شرکت مخابراتی" @@ -734,7 +735,7 @@ "پویانمایی‌های اشاره برگشت پیش‌گویانه" "پویانمایی‌های سیستم را برای اشاره برگشت پیش‌گویانه فعال کنید." "‏این تنظیم پویانمایی‌های سیستم را برای پویانمایی اشاره برگشت پیش‌بینانه فعال می‌کند. این تنظیم مستلزم تنظیم شدن enableOnBackInvokedCallback مربوط به هر برنامه روی صحیح در فایل مانیفست است." - "%1$d٪" + "‎%%%1$d" "نامشخص" "خنثی" "مؤنث" diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 6877d75de324..ab4ac1ea44c0 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -585,7 +585,6 @@ "Tämä tietokone (sisäinen)" - "Mikrofoni (sisäinen)" "Telinekaiutin" "Ulkoinen laite" "Yhdistetty laite" @@ -688,9 +687,11 @@ "Laitteesi on käynnistettävä uudelleen, jotta muutos tulee voimaan. Käynnistä uudelleen nyt tai peru." "Langalliset kuulokkeet" "Kuulokkeet" - "USB-kaiutin" + "USB-audio" "Mikrofoniliitäntä" - "USB-mikrofoni" + "USB-mikrofoni" + + "Päällä" "Ei käytössä" "Operaattorin verkko muuttuu" diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index b3946ce23688..05157b71d17a 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -585,7 +585,6 @@ "Cet ordinateur (interne)" - "Microphone (interne)" "Haut-parleur du socle" "Appareil externe" "Appareil connecté" @@ -688,9 +687,11 @@ "Votre appareil doit être redémarré pour que ce changement prenne effet. Redémarrez-le maintenant ou annulez la modification." "Écouteurs filaires" "Écouteurs" - "Haut-parleur à port USB" + "Audio par USB" "Prise du microphone" - "Microphone USB" + "Microphone USB" + + "Activé" "Désactivé" "Changer de réseau de fournisseur de services" diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index 13d57ed6ce2d..31616a79f79b 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -585,7 +585,6 @@ "Cet ordinateur (interne)" - "Micro (interne)" "Haut-parleur station d\'accueil" "Appareil externe" "Appareil connecté" @@ -688,9 +687,11 @@ "Vous devez redémarrer l\'appareil pour que cette modification soit appliquée. Redémarrez maintenant ou annulez l\'opération." "Casque filaire" "Casque audio" - "Haut-parleur USB" + "Audio USB" "Connecteur micro" - "Micro USB" + "Micro USB" + + "Allumé" "Éteint" "Modification du réseau de l\'opérateur" diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index d95e676961b0..2fccfba8ff04 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -585,7 +585,6 @@ "Este ordenador (interno)" - "Micrófono (interno)" "Altofalante da base" "Dispositivo externo" "Dispositivo conectado" @@ -688,9 +687,11 @@ "É necesario reiniciar o teu dispositivo para aplicar este cambio. Reiníciao agora ou cancela o cambio." "Auriculares con cable" "Auriculares" - "Altofalante USB" + "Audio USB" "Conector do micrófono" - "Micrófono USB" + "Micrófono USB" + + "Activada" "Desactivada" "Cambio de rede do operador" diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index aa768f879928..3209b07a6faf 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -585,7 +585,6 @@ "આ કમ્પ્યૂટર (આંતરિક)" - "માઇક્રોફોન (આંતરિક)" "ડૉક સ્પીકર" "બહારનું ડિવાઇસ" "કનેક્ટ કરેલું ડિવાઇસ" @@ -688,9 +687,11 @@ "આ ફેરફારને લાગુ કરવા માટે તમારા ડિવાઇસને રીબૂટ કરવાની જરૂર છે. હમણાં જ રીબૂટ કરો કે રદ કરો." "વાયરવાળો હૅડફોન" "હૅડફોન" - "USB સ્પીકર" + "USB ઑડિયો" "માઇક જૅક" - "USB માઇક" + "USB માઇક્રોફોન" + + "ચાલુ" "બંધ" "કૅરીઅર નેટવર્કમાં ફેરફાર થઈ રહ્યો છે" diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index b8e55b50ff03..ef93e78e3090 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -585,7 +585,6 @@ "इस कंप्यूटर पर (इंटरनल)" - "माइक्रोफ़ोन (इंटरनल)" "डॉक स्पीकर" "बाहरी डिवाइस" "कनेक्ट किया गया डिवाइस" @@ -688,9 +687,11 @@ "बदली गई सेटिंग को लागू करने के लिए, डिवाइस को रीस्टार्ट करना होगा. अपने डिवाइस को रीस्टार्ट करें या रद्द करें." "तार वाला हेडफ़ोन" "हेडफ़ोन" - "यूएसबी स्पीकर" + "यूएसबी ऑडियो" "माइक्रोफ़ोन जैक" - "यूएसबी माइक्रोफ़ोन" + "यूएसबी माइक्रोफ़ोन" + + "चालू है" "बंद है" "मोबाइल और इंटरनेट सेवा देने वाली कंपनी का नेटवर्क बदल रहा है" diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index 45ac8c24bcaa..7fda17b0e91c 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -585,7 +585,6 @@ "Ovo računalo (interno)" - "Mikrofon (ugrađeni)" "Zvučnik priključne stanice" "Vanjski uređaj" "Povezani uređaj" @@ -688,9 +687,11 @@ "Uređaj se mora ponovno pokrenuti da bi se ta promjena primijenila. Ponovo pokrenite uređaj odmah ili odustanite." "Žičane slušalice" "Slušalice" - "USB zvučnik" + "USB zvučnik" "Utičnica za mikrofon" - "USB mikrofon" + "USB mikrofon" + + "Uključeno" "Isključeno" "Promjena mreže mobilnog operatera" diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 6cb447ee192d..838965fdeccf 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -585,7 +585,6 @@ "Ez a számítógép (belső)" - "Mikrofon (belső)" "Dokkhangszóró" "Külső eszköz" "Csatlakoztatott eszköz" @@ -688,9 +687,11 @@ "Az eszközt újra kell indítani, hogy a módosítás megtörténjen. Indítsa újra most, vagy vesse el a módosítást." "Vezetékes fejhallgató" "Fejhallgató" - "USB-hangszóró" + "USB-hangeszköz" "Mikrofon jack csatlakozója" - "USB-mikrofon" + "USB-mikrofon" + + "Be" "Ki" "Szolgáltatói hálózat váltása" diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index 0e25b7904548..6ad700750228 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -585,7 +585,6 @@ "Այս համակարգիչը (ներքին)" - "Խոսափող (ներքին)" "Դոկ-կայանով բարձրախոս" "Արտաքին սարք" "Միացված սարք" @@ -688,9 +687,11 @@ "Սարքն անհրաժեշտ է վերագործարկել, որպեսզի փոփոխությունը կիրառվի։ Վերագործարկեք հիմա կամ չեղարկեք փոփոխությունը։" "Լարով ականջակալ" "Ականջակալ" - "USB բարձրախոս" + "USB աուդիո" "Խոսափողի հարակցիչ" - "USB խոսափող" + "USB խոսափող" + + "Միացնել" "Անջատել" "Օպերատորի ցանցի փոփոխություն" diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index ceb948daa72c..c6f0800ead9b 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -288,7 +288,7 @@ "Izinkan buka kunci OEM?" "PERINGATAN: Fitur perlindungan perangkat tidak akan berfungsi di perangkat ini saat setelan diaktifkan." "Pilih aplikasi lokasi palsu" - "Tidak ada aplikasi lokasi palsu yang disetel" + "Tidak ada aplikasi lokasi simulasi yang disetel" "Aplikasi lokasi palsu: %1$s" "Jaringan" "Sertifikasi layar nirkabel" @@ -585,7 +585,6 @@ "Komputer ini (internal)" - "Mikrofon (internal)" "Speaker dok" "Perangkat Eksternal" "Perangkat yang terhubung" @@ -688,9 +687,11 @@ "Perangkat Anda harus di-reboot agar perubahan ini diterapkan. Reboot sekarang atau batalkan." "Headphone berkabel" "Headphone" - "Speaker USB" + "Audio USB" "Colokan mikrofon" - "Mikrofon USB" + "Mikrofon USB" + + "Aktif" "Nonaktif" "Jaringan operator berubah" diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index fd31a6f99c6e..2688e0ba92e8 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -585,7 +585,6 @@ "Þessi tölva (innbyggður)" - "Hljóðnemi (innbyggður)" "Hátalaradokka" "Ytra tæki" "Tengt tæki" @@ -688,9 +687,11 @@ "Endurræsa þarf tækið til að þessi breyting taki gildi. Endurræstu núna eða hættu við." "Heyrnartól með snúru" "Heyrnartól" - "USB-hátalari" + "USB-hljóð" "Hljóðnematengi" - "USB-hljóðnemi" + "USB-hljóðnemi" + + "Kveikt" "Slökkt" "Skiptir um farsímakerfi" diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index c2931fc2d257..c0f1557a3aff 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -585,7 +585,6 @@ "Questo computer (interno)" - "Microfono (interno)" "Base con altoparlante" "Dispositivo esterno" "Dispositivo connesso" @@ -688,9 +687,11 @@ "Per applicare questa modifica, devi riavviare il dispositivo. Riavvia ora o annulla." "Cuffie con cavo" "Cuffie" - "Altoparlante USB" + "Audio USB" "Jack per microfono" - "Microfono USB" + "Microfono USB" + + "On" "Off" "Cambio della rete dell\'operatore" diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index bcf7e92ae375..f1020caa0db0 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -585,7 +585,6 @@ "המחשב הזה (פנימי)" - "מיקרופון (פנימי)" "רמקול של אביזר העגינה" "מכשיר חיצוני" "המכשיר המחובר" @@ -688,9 +687,11 @@ "צריך להפעיל מחדש את המכשיר כדי להחיל את השינוי. יש להפעיל מחדש עכשיו או לבטל." "אוזניות חוטיות" "אוזניות" - "‏רמקול ב-USB" + "‏אודיו ב-USB" "שקע למיקרופון" - "‏מיקרופון USB" + "‏מיקרופון ב-USB" + + "פועלת" "מצב כבוי" "רשת ספק משתנה" diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 185c6c964a5b..ae68a03b7f40 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -585,7 +585,6 @@ "このパソコン(内蔵)" - "マイク(内蔵)" "ホルダー スピーカー" "外部デバイス" "接続済みのデバイス" @@ -688,9 +687,11 @@ "この変更を適用するには、デバイスの再起動が必要です。今すぐ再起動するか、キャンセルしてください。" "有線ヘッドフォン" "ヘッドフォン" - "USB スピーカー" + "USB オーディオ" "マイク差込口" - "USB マイク" + "USB マイク" + + "ON" "OFF" "携帯通信会社のネットワークを変更します" diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index 9532c3a153a9..850ddf19bb42 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -585,7 +585,6 @@ "ეს კომპიუტერი (შიდა)" - "მიკროფონი (შიდა)" "სამაგრის დინამიკი" "გარე მოწყობილობა" "დაკავშირებული მოწყობილობა" @@ -688,9 +687,11 @@ "ამ ცვლილების ასამოქმედებლად თქვენი მოწყობილობა უნდა გადაიტვირთოს. გადატვირთეთ ახლავე ან გააუქმეთ." "სადენიანი ყურსასმენი" "ყურსასმენი" - "USB დინამიკი" + "USB აუდიო" "მიკროფონის ჯეკი" - "USB მიკროფონი" + "USB მიკროფონი" + + "ჩართვა" "გამორთვა" "ოპერატორის ქსელის შეცვლა" diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 4f64bb9cf5d9..0cf0e04e97b6 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -585,7 +585,6 @@ "Осы компьютер (ішкі)" - "Микрофон (ішкі)" "Динамигі бар қондыру станциясы" "Сыртқы құрылғы" "Жалғанған құрылғы" @@ -688,9 +687,11 @@ "Бұл өзгеріс күшіне енуі үшін, құрылғыны қайта жүктеу керек. Қазір қайта жүктеңіз не бас тартыңыз." "Сымды құлақаспап" "Құлақаспап" - "USB динамик" + "USB аудио" "Микрофон ұяшығы" - "USB микрофоны" + "USB микрофон" + + "Қосу" "Өшіру" "Оператор желісін өзгерту" diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 43807a018083..0d22701f69ce 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -388,7 +388,7 @@ "ទិដ្ឋភាព​បញ្ចេញពន្លឺភ្លឹបភ្លែត​នៅក្នុង​វិនដូនៅ​ពេលគូរ" "បង្ហាញ​​បច្ចុប្បន្នភាព​ស្រទាប់​ហាតវែរ" "ស្រទាប់​ហាតវែរ​បញ្ចេញ​ពន្លឺ​បៃ​តង​នៅពេលធ្វើ​បច្ចុប្បន្នភាព" - "ជួសជុល​ការគូរលើស GPU" + "ជួសជុលការដាក់បង្ហាញពីលើច្រើនជ្រុលរបស់ GPU" "បិទ​ការ​ត្រួត HW" "ប្រើ GPU ជា​និច្ច​សម្រាប់​​ផ្សំ​អេក្រង់" "ត្រាប់តាមគំរូពណ៌" @@ -417,8 +417,8 @@ "បិទក្រោយពេលមួយថ្ងៃ" "បានបើកដោយគ្មានពេលកំណត់" "មាត្រដ្ឋាន​ចលនា​វិនដូ" - "មាត្រដ្ឋាន​ដំណើរ​ផ្លាស់ប្ដូរ​ចលនា" - "មាត្រដ្ឋាន​រយៈពេល​នៃ​កម្មវិធី​ចលនា" + "មាត្រដ្ឋាន​ចលនាបែបផែនឆ្លង" + "មាត្រដ្ឋាន​រយៈពេល​ចលនា" "ត្រាប់ជាអេក្រង់​ទី​ពីរ" "កម្មវិធី" "កុំ​រក្សា​ទុកសកម្មភាព" @@ -585,7 +585,6 @@ "កុំព្យូទ័រនេះ (ខាងក្នុង)" - "មីក្រូហ្វូន (ខាងក្នុង)" "ឧបាល័រជើងទម្រ" "ឧបករណ៍ខាងក្រៅ" "​ឧបករណ៍ដែលបាន​ភ្ជាប់" @@ -688,9 +687,11 @@ "ត្រូវតែ​ចាប់ផ្ដើម​ឧបករណ៍​របស់អ្នក​ឡើងវិញ ដើម្បីឱ្យ​ការផ្លាស់ប្ដូរ​នេះ​មានប្រសិទ្ធភាព។ ចាប់ផ្ដើមឡើងវិញ​ឥឡូវនេះ ឬ​បោះបង់​។" "កាស​មានខ្សែ" "កាស" - "ឧបករណ៍បំពងសំឡេង USB" + "ឧបករណ៍បំពងសំឡេង USB" "ឌុយ​មីក្រូហ្វូន" - "មីក្រូហ្វូន USB" + "មីក្រូហ្វូន USB" + + "បើក" "បិទ" "បណ្តាញ​ក្រុមហ៊ុនសេវាទូរសព្ទ​កំពុងផ្លាស់ប្តូរ" diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index 016f8b9d4003..3dc663a78366 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -241,7 +241,7 @@ "ಕ್ಲೋನ್" "ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳು" "ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ" - "ಅಪ್ಲಿಕೇಶನ್ ಅಭಿವೃದ್ಧಿಗಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ಹೊಂದಿಸಿ" + "ಆ್ಯಪ್‌ ಅಭಿವೃದ್ಧಿಗಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ಹೊಂದಿಸಿ" "ಈ ಬಳಕೆದಾರರಿಗೆ ಡೆವಲಪರ್‌ ಆಯ್ಕೆಗಳು ಲಭ್ಯವಿಲ್ಲ" "VPN ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ" "ಟೆಥರಿಂಗ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ" @@ -287,9 +287,9 @@ "ಬೂಟ್‌ಲೋಡರ್‌ ಅನ್‌ಲಾಕ್‌ ಮಾಡಲು ಅನುಮತಿಸಿ" "OEM ಅನ್‌ಲಾಕ್‌ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದೇ?" "ಎಚ್ಚರಿಕೆ: ಈ ಸೆಟ್ಟಿಂಗ್‌ ಆನ್‌ ಇರುವಾಗ ಈ ಸಾಧನದಲ್ಲಿ ಸಾಧನ ಸಂರಕ್ಷಣಾ ವೈಶಿಷ್ಟ್ಯಗಳು ಕಾರ್ಯ ನಿರ್ವಹಿಸುವುದಿಲ್ಲ." - "ಅಣಕು ಸ್ಥಳ ಅಪ್ಲಿಕೇಶನ್ ಆಯ್ಕೆಮಾಡಿ" - "ಯಾವುದೇ ಅಣಕು ಸ್ಥಳ ಅಪ್ಲಿಕೇಶನ್ ಹೊಂದಿಕೆಯಾಗಿಲ್ಲ" - "ಅಣಕು ಸ್ಥಳ ಅಪ್ಲಿಕೇಶನ್: %1$s" + "ಅಣಕು ಸ್ಥಳ ಆ್ಯಪ್‌ ಆಯ್ಕೆಮಾಡಿ" + "ಯಾವುದೇ ಅಣಕು ಸ್ಥಳ ಆ್ಯಪ್‌ ಹೊಂದಿಕೆಯಾಗಿಲ್ಲ" + "ಅಣಕು ಸ್ಥಳ ಆ್ಯಪ್‌: %1$s" "ನೆಟ್‌ವರ್ಕಿಂಗ್" "ವೈರ್‌ಲೆಸ್ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣ" "Wi‑Fi ವೆರ್ಬೋಸ್ ಲಾಗಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ" @@ -356,17 +356,17 @@ "ಬ್ಲೂಟೂತ್ Gabeldorsche ವೈಶಿಷ್ಟ್ಯದ ಸ್ಟ್ಯಾಕ್‌ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ." "ವರ್ಧಿತ ಸಂಪರ್ಕ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ" "ಸ್ಥಳೀಯ ಟರ್ಮಿನಲ್" - "ಸ್ಥಳೀಯ ಶೆಲ್ ಪ್ರವೇಶವನ್ನು ಒದಗಿಸುವ ಟರ್ಮಿನಲ್ ಅಪ್ಲಿಕೇಶನ್ ಸಕ್ರಿಯಗೊಳಿಸಿ" + "ಸ್ಥಳೀಯ ಶೆಲ್ ಪ್ರವೇಶವನ್ನು ಒದಗಿಸುವ ಟರ್ಮಿನಲ್ ಆ್ಯಪ್‌ ಸಕ್ರಿಯಗೊಳಿಸಿ" "HDCP ಪರೀಕ್ಷಿಸುವಿಕೆ" "HDCP ಪರಿಶೀಲನಾ ನಡವಳಿಕೆಯನ್ನು ಹೊಂದಿಸಿ" "ಡೀಬಗ್ ಮಾಡುವಿಕೆ" - "ಡೀಬಗ್ ಅಪ್ಲಿಕೇಶನ್‌ ಆಯ್ಕೆಮಾಡಿ" + "ಡೀಬಗ್ ಆ್ಯಪ್‌ ಆಯ್ಕೆಮಾಡಿ" "ಯಾವುದೇ ಡೀಬಗ್ ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಹೊಂದಿಸಿಲ್ಲ" "ಡೀಬಗ್ ಅಪ್ಲಿಕೇಶನ್‌: %1$s" "ಅಪ್ಲಿಕೇಶನ್ ಆಯ್ಕೆಮಾಡಿ" "ಏನೂ ಇಲ್ಲ" "ಡೀಬಗರ್‌‌ಗಾಗಿ ನಿರೀಕ್ಷಿಸಿ" - "ಲಗತ್ತನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ಮೊದಲು ಡೀಬಗರ್‌‌ಗಾಗಿ ಡೀಬಗ್‌‌‌ ಮಾಡಿದ ಅಪ್ಲಿಕೇಶನ್‌‌ ಕಾಯುತ್ತದೆ" + "ಲಗತ್ತನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ಮೊದಲು ಡೀಬಗರ್‌‌ಗಾಗಿ ಡೀಬಗ್‌‌‌ ಮಾಡಿದ ಆ್ಯಪ್‌ ಕಾಯುತ್ತದೆ" "ಇನ್‌ಪುಟ್" "ಚಿತ್ರಣ" "ಹಾರ್ಡ್‌ವೇರ್‌ ವೇಗವರ್ಧಿತ ರೆಂಡರಿಂಗ್" @@ -425,11 +425,11 @@ "ಬಳಕೆದಾರರು ಹೊರಹೋಗುತ್ತಿದ್ದಂತೆಯೇ ಚಟುವಟಿಕೆ ನಾಶಪಡಿಸು" "ಹಿನ್ನೆಲೆ ಪ್ರಕ್ರಿಯೆ ಮಿತಿ" "ಹಿನ್ನೆಲೆ ANR ಗಳನ್ನು ತೋರಿಸಿ" - "ಹಿನ್ನೆಲೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತಿಲ್ಲ ಎಂಬ ಸಂಭಾಷಣೆ ತೋರಿಸಿ" + "ಹಿನ್ನೆಲೆ ಆ್ಯಪ್‌ಗಳಿಗಾಗಿ ಆ್ಯಪ್‌ ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತಿಲ್ಲ ಎಂಬ ಸಂಭಾಷಣೆ ತೋರಿಸಿ" "ನೋಟಿಫಿಕೇಶನ್ ಎಚ್ಚರಿಕೆ ತೋರಿಸಿ" "ಅಮಾನ್ಯ ಚಾನಲ್ ಅಧಿಸೂಚನೆಗಾಗಿ ಪರದೆಯಲ್ಲಿ ಎಚ್ಚರಿಕೆ" "ಬಾಹ್ಯವಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಒತ್ತಾಯವಾಗಿ ಅನುಮತಿಸಿ" - "ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳು ಯಾವುದೇ ಆಗಿದ್ದರೂ, ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆಗೆ ಬರೆಯಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಅರ್ಹಗೊಳಿಸುತ್ತದೆ" + "ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳು ಯಾವುದೇ ಆಗಿದ್ದರೂ, ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆಗೆ ಬರೆಯಲು ಯಾವುದೇ ಆ್ಯಪ್‌ ಅನ್ನು ಅರ್ಹಗೊಳಿಸುತ್ತದೆ" "ಚಟುವಟಿಕೆಗಳನ್ನು ಮರುಗಾತ್ರಗೊಳಿಸುವಂತೆ ಒತ್ತಾಯ ಮಾಡಿ" "ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳನ್ನು ಪರಿಗಣಿಸದೇ, ಬಹು-ವಿಂಡೊಗೆ ಎಲ್ಲಾ ಚಟುವಟಿಕೆಗಳನ್ನು ಮರುಗಾತ್ರಗೊಳಿಸುವಂತೆ ಮಾಡಿ." "ಮುಕ್ತಸ್ವರೂಪದ ವಿಂಡೊಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ" @@ -453,7 +453,7 @@ "ಸ್ಟ್ಯಾಂಡ್‌ಬೈ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು" "ನಿಷ್ಕ್ರಿಯ. ಟಾಗಲ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ." "ಸಕ್ರಿಯ. ಟಾಗಲ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ." - "ಅಪ್ಲಿಕೇಶನ್ ಸ್ಟ್ಯಾಂಡ್‌ಬೈ ಸ್ಥಿತಿ: %s" + "ಆ್ಯಪ್‌ ಸ್ಟ್ಯಾಂಡ್‌ಬೈ ಸ್ಥಿತಿ: %s" "ಮೀಡಿಯಾ ಟ್ರಾನ್ಸ್‌ಕೋಡಿಂಗ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು" "ಟ್ರಾನ್ಸ್‌ಕೋಡಿಂಗ್ ಡೀಫಾಲ್ಟ್‌ಗಳನ್ನು ಅತಿಕ್ರಮಿಸಿ" "ಟ್ರಾನ್ಸ್‌ಕೋಡಿಂಗ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ" @@ -585,7 +585,6 @@ "ಈ ಕಂಪ್ಯೂಟರ್ (ಆಂತರಿಕ)" - "ಮೈಕ್ರೊಫೋನ್‌ (ಆಂತರಿಕ)" "ಡಾಕ್ ಸ್ಪೀಕರ್" "ಬಾಹ್ಯ ಸಾಧನ" "ಕನೆಕ್ಟ್ ಮಾಡಿರುವ ಸಾಧನ" @@ -688,9 +687,11 @@ "ಈ ಬದಲಾವಣೆ ಅನ್ವಯವಾಗಲು ನಿಮ್ಮ ಸಾಧನವನ್ನು ರೀಬೂಟ್ ಮಾಡಬೇಕು. ಇದೀಗ ರೀಬೂಟ್ ಮಾಡಿ ಅಥವಾ ರದ್ದುಗೊಳಿಸಿ." "ವೈಯರ್ ಹೊಂದಿರುವ ಹೆಡ್‌ಫೋನ್" "ಹೆಡ್‌ಫೋನ್" - "USB ಸ್ಪೀಕರ್" + "USB ಆಡಿಯೋ" "ಮೈಕ್‌ ಜ್ಯಾಕ್‌" - "USB ಮೈಕ್‌" + "USB ಮೈಕ್ರೊಫೋನ್‌" + + "ಆನ್ ಆಗಿದೆ" "ಆಫ್" "ವಾಹಕ ನೆಟ್‌ವರ್ಕ್ ಬದಲಾಯಿಸುವಿಕೆ" diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 0af77dd660c0..9f714e18d8b2 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -585,7 +585,6 @@ "이 컴퓨터(내부)" - "마이크(내부)" "도크 스피커" "외부 기기" "연결된 기기" @@ -688,9 +687,11 @@ "변경사항을 적용하려면 기기를 재부팅해야 합니다. 지금 재부팅하거나 취소하세요." "유선 헤드폰" "헤드폰" - "USB 스피커" + "USB 오디오" "마이크 잭" - "USB 마이크" + "USB 마이크" + + "사용" "사용 안 함" "이동통신사 네트워크 변경" diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index a3ff033ac0f4..d7a39131edf0 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -585,7 +585,6 @@ "Бул компьютер (ички)" - "Микрофон (ички)" "Док бекеттин динамиги" "Тышкы түзмөк" "Туташкан түзмөк" @@ -688,9 +687,11 @@ "Бул өзгөрүү күчүнө кириши үчүн, түзмөктү өчүрүп күйгүзүңүз. Азыр же кийинчерээк өчүрүп күйгүзсөңүз болот." "Зымдуу гарнитура" "Гарнитура" - "USB динамиги" + "USB аудио" "Микрофондун оюкчасы" - "USB микрофон" + "USB микрофон" + + "Күйгүзүү" "Өчүрүү" "Байланыш оператору өзгөртүлүүдө" diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 1d89e3e5e68f..e57dae8d4ea4 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -585,7 +585,6 @@ "ຄອມພິວເຕີນີ້ (ພາຍໃນ)" - "ໄມໂຄຣໂຟນ (ພາຍໃນ)" "ແທ່ນວາງລຳໂພງ" "ອຸປະກອນພາຍນອກ" "ອຸປະກອນທີ່ເຊື່ອມຕໍ່" @@ -688,9 +687,11 @@ "ທ່ານຕ້ອງປິດເປີດອຸປະກອນຄືນໃໝ່ເພື່ອນຳໃຊ້ການປ່ຽນແປງນີ້. ປິດເປີດໃໝ່ດຽວນີ້ ຫຼື ຍົກເລີກ." "ຫູຟັງແບບມີສາຍ" "ຫູຟັງ" - "ລຳໂພງ USB" + "ສຽງ USB" "ຊ່ອງສຽງໄມ" - "ໄມ USB" + "ໄມໂຄຣໂຟນ USB" + + "ເປີດ" "ປິດ" "ການປ່ຽນເຄືອຂ່າຍຜູ້ໃຫ້ບໍລິການ" diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index 265eb9aa0618..a4d5b9bb1581 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -585,7 +585,6 @@ "Šis kompiuteris (vidinis)" - "Mikrofonas (vidinis)" "Doko garsiakalbis" "Išorinis įrenginys" "Prijungtas įrenginys" @@ -688,9 +687,11 @@ "Kad pakeitimas būtų pritaikytas, įrenginį reikia paleisti iš naujo. Dabar paleiskite iš naujo arba atšaukite." "Laidinės ausinės" "Ausinės" - "USB garsiakalbis" + "USB garsas" "Mikrofono jungtis" - "USB mikrofonas" + "USB mikrofonas" + + "Įjungta" "Išjungta" "Keičiamas operatoriaus tinklas" diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index c24dafbaf278..bf6f80cab0db 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -585,7 +585,6 @@ "Šī datora iekšējais skaļrunis" - "Mikrofons (iebūvētais)" "Doka skaļrunis" "Ārēja ierīce" "Pievienotā ierīce" @@ -688,9 +687,11 @@ "Lai šīs izmaiņas tiktu piemērotas, nepieciešama ierīces atkārtota palaišana. Atkārtoti palaidiet to tūlīt vai atceliet izmaiņas." "Vadu austiņas" "Austiņas" - "USB skaļrunis" + "USB audio" "Mikrofona ligzda" - "USB mikrofons" + "USB mikrofons" + + "Ieslēgts" "Izslēgts" "Mobilo sakaru operatora tīkla mainīšana" diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index ea9ff6c5b06b..f664f725b0ab 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -585,7 +585,6 @@ "Овој компјуер (внатрешен)" - "Микрофон (внатрешен)" "Док со звучник" "Надворешен уред" "Поврзан уред" @@ -688,9 +687,11 @@ "За да се примени променава, уредот мора да се рестартира. Рестартирајте сега или откажете." "Жичени слушалки" "Слушалка" - "USB-звучник" + "USB-аудио" "Приклучок за микрофон" - "USB-микрофон" + "USB-микрофон" + + "Вклучено" "Исклучено" "Променување на мрежата на операторот" diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 7af53aad667f..49af83d9851e 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -585,7 +585,6 @@ "ഈ കമ്പ്യൂട്ടർ (ഇന്റേണൽ)" - "മൈക്രോഫോൺ (ഇന്റേണൽ)" "ഡോക്ക് സ്‌പീക്കർ" "ബാഹ്യ ഉപകരണം" "കണക്‌റ്റ് ചെയ്‌ത ഉപകരണം" @@ -688,9 +687,11 @@ "ഈ മാറ്റം ബാധകമാകുന്നതിന് നിങ്ങളുടെ ഉപകരണം റീബൂട്ട് ചെയ്യേണ്ടതുണ്ട്. ഇപ്പോൾ റീബൂട്ട് ചെയ്യുകയോ റദ്ദാക്കുകയോ ചെയ്യുക." "വയേർഡ് ഹെഡ്ഫോൺ" "ഹെഡ്ഫോൺ" - "USB സ്‌പീക്കർ" + "USB ഓഡിയോ" "മൈക്ക് ജാക്ക്" - "USB മൈക്ക്" + "USB മൈക്രോഫോൺ" + + "ഓണാണ്" "ഓഫാണ്" "കാരിയർ നെറ്റ്‌വർക്ക് മാറ്റൽ" diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 9fdbdc693dc8..2d010feba7ad 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -585,7 +585,6 @@ "Энэ компьютер (дотоод)" - "Микрофон (дотоод)" "Суурилуулагчийн чанга яригч" "Гадаад төхөөрөмж" "Холбогдсон төхөөрөмж" @@ -688,9 +687,11 @@ "Энэ өөрчлөлтийг хэрэгжүүлэхийн тулд таны төхөөрөмжийг дахин асаах ёстой. Одоо дахин асаах эсвэл цуцлана уу." "Утастай чихэвч" "Чихэвч" - "USB чанга яригч" + "USB аудио" "Микрофоны чихэвчний оролт" - "USB микрофон" + "USB микрофон" + + "Асаах" "Унтраах" "Оператор компанийн сүлжээг өөрчилж байна" diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index 581545d609b9..bea1500a9874 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -585,7 +585,6 @@ "हा काँप्युटर (अंतर्गत)" - "मायक्रोफोन (अंतर्गत)" "डॉक स्पीकर" "बाह्य डिव्हाइस" "कनेक्ट केलेले डिव्हाइस" @@ -688,9 +687,11 @@ "हा बदल लागू करण्यासाठी तुमचे डिव्हाइस रीबूट करणे आवश्यक आहे. आता रीबूट करा किंवा रद्द करा." "वायर्ड हेडफोन" "हेडफोन" - "USB स्पीकर" + "USB ऑडिओ" "माइक जॅक" - "USB माइक" + "USB मायक्रोफोन" + + "सुरू करा" "बंद करा" "वाहक नेटवर्क बदलत आहे" diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index 7990e0443acf..f04549027e0a 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -585,7 +585,6 @@ "Komputer ini (dalaman)" - "Mikrofon (dalaman)" "Pembesar suara dok" "Peranti Luar" "Peranti yang disambungkan" @@ -688,9 +687,11 @@ "Peranti anda mesti dibut semula supaya perubahan ini berlaku. But semula sekarang atau batalkan." "Fon kepala berwayar" "Fon kepala" - "Pembesar suara USB" + "Audio USB" "Bicu mikrofon" - "Mikrofon USB" + "Mikrofon USB" + + "Hidup" "Mati" "Rangkaian pembawa berubah" diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index 8fbc8bdc867e..4bdb50f50a78 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -376,7 +376,7 @@ "အက်ပ်လုပ်ဆောင်မှု ရှည်ကြာလျှင် စကရင်ပြန်စသည်" "မြား၏တည်နေရာ" "လက်ရှိထိတွေ့မှုဒေတာကို ဖန်သားပေါ်တွင်ထပ်၍ ပြသသည်" - "တို့ခြင်းများကို ပြပါ" + "တို့ချက်များ ပြရန်" "တို့ခြင်းများအတွက် အမြင်ဖြင့် တုံ့ပြန်မှုပြသည်" "ကီးနှိပ်မှုများ ပြပါ" "ပကတိကီးနှိပ်မှုများအတွက် ရုပ်မြင်အကြံပြုချက် ပြပါ" @@ -585,7 +585,6 @@ "ဤကွန်ပျူတာ (စက်တွင်း)" - "မိုက်ခရိုဖုန်း (စက်တွင်း)" "အထိုင် စပီကာ" "ပြင်ပစက်" "ချိတ်ဆက်ကိရိယာ" @@ -688,9 +687,11 @@ "ဤအပြောင်းအလဲ ထည့်သွင်းရန် သင့်စက်ကို ပြန်လည်စတင်ရမည်။ ယခု ပြန်လည်စတင်ပါ သို့မဟုတ် ပယ်ဖျက်ပါ။" "ကြိုးတပ်နားကြပ်" "နားကြပ်" - "USB စပီကာ" + "USB အသံ" "မိုက်ဂျက်ပင်" - "USB မိုက်" + "USB မိုက်ခရိုဖုန်း" + + "ဖွင့်" "ပိတ်" "ဝန်ဆောင်မှုပေးသူ ကွန်ရက် ပြောင်းလဲနေသည်။" diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index 569b900bd524..5de70698c370 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -585,7 +585,6 @@ "Denne datamaskinen (intern)" - "Mikrofon (intern)" "Dokkhøyttaler" "Ekstern enhet" "Tilkoblet enhet" @@ -688,9 +687,11 @@ "Enheten din må startes på nytt for at denne endringen skal tre i kraft. Start på nytt nå eller avbryt." "Hodetelefoner med kabel" "Hodetelefoner" - "USB-høyttaler" + "USB-lyd" "Mikrofonkontakt" - "USB-mikrofon" + "USB-mikrofon" + + "På" "Av" "Bytting av operatørnettverk" diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index 916aba97cdf3..ec5da4572bed 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -585,7 +585,6 @@ "यो कम्प्युटर (आन्तरिक)" - "माइक्रोफोन (आन्तरिक)" "डक स्पिकर" "बाह्य डिभाइस" "कनेक्ट गरिएको डिभाइस" @@ -688,9 +687,11 @@ "यो परिवर्तन लागू गर्न तपाईंको यन्त्र अनिवार्य रूपमा रिबुट गर्नु पर्छ। अहिले रिबुट गर्नुहोस् वा रद्द गर्नुहोस्।" "तारयुक्त हेडफोन" "हेडफोन" - "USB स्पिकर" + "USB अडियो" "माइकको ज्याक" - "USB माइक" + "USB माइक्रोफोन" + + "अन छ" "अफ छ" "सेवा प्रदायकको नेटवर्क परिवर्तन गर्ने आइकन" diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 78dfd35ed855..f6c5c9ca764a 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -585,7 +585,6 @@ "Deze computer (intern)" - "Microfoon (intern)" "Dockspeaker" "Extern apparaat" "Verbonden apparaat" @@ -688,9 +687,11 @@ "Je apparaat moet opnieuw worden opgestart om deze wijziging toe te passen. Start nu opnieuw op of annuleer de wijziging." "Bedrade koptelefoon" "Koptelefoon" - "USB-speaker" + "USB-audio" "Microfoonaansluiting" - "USB-microfoon" + "USB-microfoon" + + "Aan" "Uit" "Netwerk van provider wordt gewijzigd" diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index c2439f9c304a..2ab4d133f2bf 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -585,7 +585,6 @@ "ଏହି କମ୍ପ୍ୟୁଟର (ଇଣ୍ଟର୍ନଲ)" - "ମାଇକ୍ରୋଫୋନ (ଇଣ୍ଟର୍ନଲ)" "ଡକ ସ୍ପିକର" "ଏକ୍ସଟର୍ନଲ ଡିଭାଇସ" "କନେକ୍ଟ କରାଯାଇଥିବା ଡିଭାଇସ" @@ -688,9 +687,11 @@ "ଏହି ପରିବର୍ତ୍ତନ ଲାଗୁ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିଶ୍ଚିତ ରୂପେ ରିବୁଟ୍ କରାଯିବା ଆବଶ୍ୟକ। ବର୍ତ୍ତମାନ ରିବୁଟ୍ କରନ୍ତୁ କିମ୍ବା ବାତିଲ କରନ୍ତୁ।" "ତାରଯୁକ୍ତ ହେଡଫୋନ" "ହେଡଫୋନ" - "USB ସ୍ପିକର" + "USB ଅଡିଓ" "ମାଇକ ଜେକ" - "USB ମାଇକ" + "USB ମାଇକ୍ରୋଫୋନ" + + "ଚାଲୁ ଅଛି" "ବନ୍ଦ ଅଛି" "କେରିଅର୍‍ ନେଟ୍‌ୱର୍କ ବଦଳୁଛି" diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 4a4f9248daba..f054ed538cee 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -585,7 +585,6 @@ "ਇਸ ਕੰਪਿਊਟਰ \'ਤੇ (ਅੰਦਰੂਨੀ)" - "ਮਾਈਕ੍ਰੋਫ਼ੋਨ (ਅੰਦਰੂਨੀ)" "ਡੌਕ ਸਪੀਕਰ" "ਬਾਹਰੀ ਡੀਵਾਈਸ" "ਕਨੈਕਟ ਕੀਤਾ ਡੀਵਾਈਸ" @@ -688,9 +687,11 @@ "ਇਸ ਤਬਦੀਲੀ ਨੂੰ ਲਾਗੂ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨੂੰ ਰੀਬੂਟ ਕਰਨਾ ਲਾਜ਼ਮੀ ਹੈ। ਹੁਣੇ ਰੀਬੂਟ ਕਰੋ ਜਾਂ ਰੱਦ ਕਰੋ।" "ਤਾਰ ਵਾਲੇ ਹੈੱਡਫ਼ੋਨ" "ਹੈੱਡਫ਼ੋਨ" - "USB ਸਪੀਕਰ" + "USB ਆਡੀਓ" "ਮਾਈਕ ਜੈਕ" - "USB ਮਾਈਕ" + "USB ਮਾਈਕ੍ਰੋਫ਼ੋਨ" + + "ਚਾਲੂ" "ਬੰਦ" "ਕੈਰੀਅਰ ਨੈੱਟਵਰਕ ਦੀ ਬਦਲੀ" diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index bb8fe2e40bfe..3786e02a109e 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -585,7 +585,6 @@ "Ten komputer (wewnętrzny)" - "Mikrofon (wewnętrzny)" "Głośnik ze stacją dokującą" "Urządzenie zewnętrzne" "Połączone urządzenie" @@ -688,9 +687,11 @@ "Wprowadzenie zmiany wymaga ponownego uruchomienia urządzenia. Uruchom ponownie teraz lub anuluj." "Słuchawki przewodowe" "Słuchawki" - "Głośnik USB" + "Dźwięk przez USB" "Gniazdo mikrofonu" - "Mikrofon USB" + "Mikrofon USB" + + "Włączono" "Wyłączono" "Zmiana sieci operatora" diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index e286643c5cf5..3a8b2b8ff1bc 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -687,10 +687,10 @@ "É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele." "Fones de ouvido com fio" "Fone de ouvido" - - + "Áudio USB" "Entrada para microfone" - + "Microfone USB" + "Ativado" "Desativado" diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index f489d916fbf0..7dbabb8032c3 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -585,7 +585,6 @@ "Este computador (interno)" - "Microfone (interno)" "Altifalante estação carregamento" "Dispositivo externo" "Dispositivo associado" @@ -688,9 +687,11 @@ "É necessário reiniciar o dispositivo para aplicar esta alteração. Reinicie agora ou cancele." "Auscultadores com fios" "Auscultadores" - "Altifalante USB" + "Áudio USB" "Entrada para microfone" - "Microfone USB" + "Microfone USB" + + "Ligado" "Desligado" "Rede do operador em mudança." diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 7f5bb0fa55dc..3a8b2b8ff1bc 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -585,7 +585,6 @@ "Este computador (interno)" - "Microfone (interno)" "Alto-falante da base" "Dispositivo externo" "Dispositivo conectado" @@ -688,9 +687,11 @@ "É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele." "Fones de ouvido com fio" "Fone de ouvido" - "Alto-falante USB" + "Áudio USB" "Entrada para microfone" - "Microfone USB" + "Microfone USB" + + "Ativado" "Desativado" "Alteração de rede da operadora" diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index f79c2e1e0634..9e0eb4fd7fde 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -585,7 +585,6 @@ "Acest computer (intern)" - "Microfon (intern)" "Difuzorul dispozitivului de andocare" "Dispozitiv extern" "Dispozitiv conectat" @@ -688,9 +687,11 @@ "Pentru ca modificarea să se aplice, trebuie să repornești dispozitivul. Repornește-l acum sau anulează." "Căști cu fir" "Căști" - "Difuzor USB" + "Audio USB" "Mufă pentru microfon" - "Microfon USB" + "Microfon USB" + + "Activat" "Dezactivat" "Se schimbă rețeaua operatorului" diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 1cdef05d8b18..dfde27267308 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -585,7 +585,6 @@ "Встроенный динамик компьютера" - "Микрофон (встроенный)" "Колонка с док-станцией" "Внешнее устройство" "Подключенное устройство" @@ -688,9 +687,11 @@ "Чтобы изменение вступило в силу, необходимо перезапустить устройство. Вы можете сделать это сейчас или позже." "Проводные наушники" "Наушники" - "USB-колонка" + "USB-аудиоустройство" "Микрофонный разъем" - "USB-микрофон" + "USB-микрофон" + + "Вкл." "Выкл." "Сменить сеть" diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index 980f9c884358..fe011c773c2f 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -585,7 +585,6 @@ "මෙම පරිගණකය (අභ්‍යන්තර)" - "මයික්‍රෆෝනය (අභ්‍යන්තර)" "ඩොක් ස්පීකරය" "බාහිර උපාංගය" "සම්බන්ධ කළ උපාංගය" @@ -688,9 +687,11 @@ "මෙම වෙනස යෙදීමට ඔබේ උපාංගය නැවත පණ ගැන්විය යුතුය. දැන් නැවත පණ ගන්වන්න හෝ අවලංගු කරන්න." "රැහැන්ගත හෙඩ්ෆෝන්" "හෙඩ්ෆෝන්" - "USB ස්පීකරය" + "USB ශ්‍රව්‍ය" "මයික් ජැක්කුව" - "USB මයික්" + "USB මයික්‍රෆෝනය" + + "ක්‍රියාත්මකයි" "ක්‍රියාවිරහිතයි" "වාහක ජාලය වෙනස් වෙමින්" diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index b1726498b8ce..46ab80aefb63 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -585,7 +585,6 @@ "Tento počítač (interný)" - "Mikrofón (vnútorný)" "Reproduktor doku" "Externé zariadenie" "Pripojené zariadenie" @@ -688,9 +687,11 @@ "Zmena sa prejaví až po reštarte zariadenia. Môžete ho teraz reštartovať alebo akciu zrušiť." "Slúchadlá s káblom" "Slúchadlá" - "Reproduktor s rozhraním USB" + "Zvuk cez USB" "Konektor mikrofónu" - "Mikrofón USB" + "Mikrofón s rozhraním USB" + + "Zapnúť" "Vypnúť" "Mení sa sieť operátora" diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 2ee12418c38a..0ea0d43eb4cd 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -585,7 +585,6 @@ "Ta računalnik (notranji)" - "Mikrofon (notranji)" "Zvočnik nosilca" "Zunanja naprava" "Povezana naprava" @@ -688,9 +687,11 @@ "Napravo je treba znova zagnati, da bo ta sprememba uveljavljena. Znova zaženite zdaj ali prekličite." "Žične slušalke" "Slušalke" - "Zvočnik USB" + "Zvok USB" "Vtič za mikrofon" - "Mikrofon USB" + "Mikrofon USB" + + "Vklop" "Izklop" "Spreminjanje omrežja operaterja" diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index 7c210637c360..54e75b2d6d61 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -585,7 +585,6 @@ "Ky kompjuter (i brendshëm)" - "Mikrofoni (i brendshëm)" "Altoparlanti i stacionit" "Pajisja e jashtme" "Pajisja e lidhur" @@ -688,9 +687,11 @@ "Pajisja jote duhet të riniset që ky ndryshim të zbatohet. Rinise tani ose anuloje." "Kufje me tela" "Kufje" - "Altoparlant me USB" + "Pajisja audio me USB" "Fisha e mikrofonit" - "Mikrofoni me USB" + "Mikrofoni me USB" + + "Aktive" "Joaktive" "Rrjeti i operatorit celular po ndryshohet" diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 34ccdaf0f19e..742e6ca29160 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -585,7 +585,6 @@ "Овај рачунар (интерно)" - "Микрофон (интерни)" "Звучник базне станице" "Спољни уређај" "Повезани уређај" @@ -688,9 +687,11 @@ "Морате да рестартујете уређај да би се ова промена применила. Рестартујте га одмах или откажите." "Жичане слушалице" "Слушалице" - "USB звучник" + "USB аудио" "Утикач за микрофон" - "USB микрофон" + "USB микрофон" + + "Укључено" "Искључено" "Промена мреже мобилног оператера" diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index c553c1d30125..b7269215e6e1 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -585,7 +585,6 @@ "Den här datorn (intern)" - "Mikrofon (inbyggd)" "Dockningsstationens högtalare" "Extern enhet" "Ansluten enhet" @@ -688,9 +687,11 @@ "Enheten måste startas om för att ändringen ska börja gälla. Starta om nu eller avbryt." "Hörlur med kabel" "Hörlur" - "USB-högtalare" + "USB-ljud" "Mikrofonuttag" - "USB-mikrofon" + "USB-mikrofon" + + "På" "Av" "Byter leverantörsnätverk" diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 6890d550f133..adc21db45db8 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -585,7 +585,6 @@ "Kompyuta hii (spika ya ndani)" - "Maikrofoni (ya ndani)" "Spika ya kituo" "Kifaa cha Nje" "Kifaa kilichounganishwa" @@ -688,9 +687,11 @@ "Ni lazima uwashe tena kifaa chako ili mabadiliko haya yatekelezwe. Washa tena sasa au ughairi." "Kipokea sauti cha kichwani chenye waya" "Kipokea sauti cha kichwani" - "Spika ya USB" + "Sauti ya USB" "Pini ya maikrofoni" - "Maikrofoni ya USB" + "Maikrofoni ya USB" + + "Umewashwa" "Umezimwa" "Mabadiliko katika mtandao wa mtoa huduma" diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 5664290b0061..0e2698582b98 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -585,7 +585,6 @@ "இந்தக் கம்ப்யூட்டர் (அகம்)" - "மைக்ரோஃபோன் (அகம்)" "டாக் ஸ்பீக்கர்" "வெளிப்புறச் சாதனம்" "இணைக்கப்பட்டுள்ள சாதனம்" @@ -688,9 +687,11 @@ "இந்த மாற்றங்கள் செயல்படுத்தப்பட உங்கள் சாதனத்தை மறுபடி தொடங்க வேண்டும். இப்போதே மறுபடி தொடங்கவும் அல்லது ரத்துசெய்யவும்." "வயர்டு ஹெட்ஃபோன்" "ஹெட்ஃபோன்" - "USB ஸ்பீக்கர்" + "USB ஆடியோ" "மைக் ஜாக்" - "USB மைக்" + "USB மைக்ரோஃபோன்" + + "ஆன்" "ஆஃப்" "மொபைல் நிறுவன நெட்வொர்க்கை மாற்றும்" diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index 56d0a7d5014b..0f835fa56d37 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -585,7 +585,6 @@ "ఈ కంప్యూటర్ (ఇంటర్నల్)" - "మైక్రోఫోన్ (అంతర్గతం)" "డాక్ స్పీకర్" "ఎక్స్‌టర్నల్ పరికరం" "కనెక్ట్ చేసిన పరికరం" @@ -688,9 +687,11 @@ "ఈ మార్పును వర్తింపజేయాలంటే మీరు మీ పరికరాన్ని తప్పనిసరిగా రీబూట్ చేయాలి. ఇప్పుడే రీబూట్ చేయండి లేదా రద్దు చేయండి." "వైర్ ఉన్న హెడ్‌ఫోన్" "హెడ్‌ఫోన్" - "USB స్పీకర్" + "USB ఆడియో" "మైక్ జాక్" - "USB మైక్" + "USB మైక్రోఫోన్" + + "ఆన్‌లో ఉంది" "ఆఫ్‌లో ఉంది" "క్యారియర్ నెట్‌వర్క్ మారుతోంది" diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 28a0d64b5c75..b5deb55094a1 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -585,7 +585,6 @@ "คอมพิวเตอร์เครื่องนี้ (ภายใน)" - "ไมโครโฟน (ภายใน)" "แท่นชาร์จที่มีลำโพง" "อุปกรณ์ภายนอก" "อุปกรณ์ที่เชื่อมต่อ" @@ -688,9 +687,11 @@ "คุณต้องรีบูตอุปกรณ์เพื่อให้การเปลี่ยนแปลงนี้มีผล รีบูตเลยหรือยกเลิก" "หูฟังแบบใช้สาย" "หูฟัง" - "ลำโพง USB" + "เสียง USB" "ช่องเสียบไมค์" - "ไมค์ USB" + "ไมโครโฟน USB" + + "เปิด" "ปิด" "การเปลี่ยนเครือข่ายผู้ให้บริการ" diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index 926ce8f65406..b664108ace23 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -585,7 +585,6 @@ "Sa computer na ito (internal)" - "Mikropono (internal)" "Speaker ng dock" "External na Device" "Nakakonektang device" @@ -688,9 +687,11 @@ "Dapat i-reboot ang iyong device para mailapat ang pagbabagong ito. Mag-reboot ngayon o kanselahin." "Wired na headphone" "Headphone" - "USB speaker" + "USB audio" "Jack ng mikropono" - "USB na mikropono" + "USB na mikropono" + + "Naka-on" "Naka-off" "Nagpapalit ng carrier network" diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 14c2108a134f..7cee87ecc6cb 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -585,7 +585,6 @@ "Bu bilgisayar (dahili)" - "Mikrofon (dahili)" "Yuva hoparlörü" "Harici Cihaz" "Bağlı cihaz" @@ -688,9 +687,11 @@ "Bu değişikliğin geçerli olması için cihazınızın yeniden başlatılması gerekir. Şimdi yeniden başlatın veya iptal edin." "Kablolu kulaklık" "Kulaklık" - "USB hoparlör" + "USB ses cihazı" "Mikrofon jakı" - "USB mikrofon" + "USB mikrofon" + + "Açık" "Kapalı" "Operatör ağı değiştiriliyor" diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 25475d573352..dd7f157f47b5 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -585,7 +585,6 @@ "Цей комп’ютер (внутрішній)" - "Мікрофон (внутрішній)" "Динамік док-станції" "Зовнішній пристрій" "Підключений пристрій" @@ -688,9 +687,11 @@ "Щоб застосувати ці зміни, потрібний перезапуск. Перезапустіть пристрій або скасуйте зміни." "Дротові навушники" "Навушники" - "USB-динамік" + "USB-аудіо" "Гніздо для мікрофона" - "USB-мікрофон" + "USB-мікрофон" + + "Увімкнено" "Вимкнено" "Змінення мережі оператора" diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 2157f63325f1..23162cf5a929 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -585,7 +585,6 @@ "یہ کمپیوٹر (داخلی)" - "مائیکروفون (داخلی)" "ڈاک اسپیکر" "بیرونی آلہ" "منسلک آلہ" @@ -688,9 +687,11 @@ "اس تبدیلی کو لاگو کرنے کے ليے آپ کے آلہ کو ریبوٹ کرنا ضروری ہے۔ ابھی ریبوٹ کریں یا منسوخ کریں۔" "تار والا ہیڈ فون" "ہیڈ فون" - "‏‫USB اسپیکر" + "‏‫USB آڈیو" "مائیک جیک" - "‏‫USB مائیک" + "‏‫USB مائیکروفون" + + "آن" "آف" "کیریئر نیٹ ورک کی تبدیلی" diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index 71fdae2a7714..8fa256fdedb0 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -585,7 +585,6 @@ "Bu kompyuter (ichki)" - "Mikrofon (ichki)" "Dok-stansiyali karnay" "Tashqi qurilma" "Ulangan qurilma" @@ -688,9 +687,11 @@ "Oʻzgarishlar kuchga kirishi uchun qurilmani oʻchirib yoqing. Buni hozir yoki keyinroq bajarishingiz mumkin." "Simli quloqlik" "Quloqlik" - "USB karnay" + "USB audio" "Mikrofon ulagichi" - "USB mik" + "USB mikrofon" + + "Yoniq" "Oʻchiq" "Mobil tarmoqni o‘zgartirish" diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index f53e8166c1e1..b4e09e0c36e3 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -585,7 +585,6 @@ "Máy tính này (nội bộ)" - "Micrô (bên trong)" "Loa có gắn đế" "Thiết bị bên ngoài" "Thiết bị đã kết nối" @@ -688,9 +687,11 @@ "Bạn phải khởi động lại thiết bị để áp dụng sự thay đổi này. Hãy khởi động lại ngay hoặc hủy." "Tai nghe có dây" "Tai nghe" - "Loa USB" + "Âm thanh qua cổng USB" "Giắc cắm micrô" - "Micrô có cổng USB" + "Micrô USB" + + "Đang bật" "Đang tắt" "Thay đổi mạng của nhà mạng" diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 9275f1beed73..f9ce1c3df969 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -585,7 +585,6 @@ "此计算机(内部)" - "麦克风(内部)" "基座音箱" "外部设备" "连接的设备" @@ -688,9 +687,11 @@ "设备必须重新启动才能应用此更改。您可以立即重新启动或取消。" "有线耳机" "头戴式耳机" - "USB 音箱" + "USB 音频" "麦克风插孔" - "USB 麦克风" + "USB 麦克风" + + "开启" "关闭" "运营商网络正在更改" diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 4acc52ddc7b9..c50c7ba90165 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -585,7 +585,6 @@ "此電腦 (內置)" - "麥克風 (內置)" "插座喇叭" "外部裝置" "已連接的裝置" @@ -688,9 +687,11 @@ "你的裝置必須重新開機,才能套用此變更。請立即重新開機或取消。" "有線耳機" "耳機" - "USB 喇叭" + "USB 音訊" "麥克風插孔" - "USB 麥克風" + "USB 麥克風" + + "開啟" "關閉" "流動網絡供應商網絡正在變更" diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 8ded5d08edce..c5885dea3ae8 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -585,7 +585,6 @@ "這部電腦 (內部)" - "麥克風 (內部)" "座架喇叭" "外部裝置" "已連結的裝置" @@ -688,9 +687,11 @@ "裝置必須重新啟動才能套用這項變更。請立即重新啟動或取消變更。" "有線耳機" "耳機" - "USB 喇叭" + "USB 音訊" "麥克風插孔" - "USB 麥克風" + "USB 麥克風" + + "開啟" "關閉" "電信業者網路正在進行變更" diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 972eed7be319..a39b436ff652 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -585,7 +585,6 @@ "Le khompyutha (ngaphakathi)" - "Imakrofoni (okwangaphakathi)" "Isipikha sentuba" "Idivayisi Yangaphandle" "Idivayisi exhunyiwe" @@ -688,9 +687,11 @@ "Kufanele idivayisi yakho iqaliswe ukuze lolu shintsho lusebenze. Qalisa manje noma khansela." "Amahedifoni anentambo" "Amahedifoni" - "Isipikha se-USB" + "Umsindo we-USB" "Umgodi we-earphone ye-mic" - "I-mic ye-USB" + "Imakrofoni ye-USB" + + "Vuliwe" "Valiwe" "Inethiwekhi yenkampani yenethiwekhi iyashintsha" -- GitLab From 414f5b6823da27b8aee44b60cf576aaea3621068 Mon Sep 17 00:00:00 2001 From: Yuting Fang Date: Tue, 8 Oct 2024 00:42:12 +0000 Subject: [PATCH 172/447] Revert "[AppOpLogging] Log binder calls for checkOperation and noteOperation" This reverts commit ea042c22eb6b900b2b214deeb4081ab763930317. Reason for revert: Caused BootTimeRegression b/371748585 Change-Id: Ie261cba2b6a9d365eaf3b64215d5af22c0654efd --- .../android/server/appop/AppOpsService.java | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 596e375b439d..e0cf96fbccd0 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -72,9 +72,6 @@ import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS; import static android.content.pm.PermissionInfo.PROTECTION_FLAG_APPOP; import static android.permission.flags.Flags.deviceAwareAppOpNewSchemaEnabled; -import static com.android.internal.util.FrameworkStatsLog.APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED__BINDER_API__CHECK_OPERATION; -import static com.android.internal.util.FrameworkStatsLog.APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED__BINDER_API__NOTE_OPERATION; -import static com.android.internal.util.FrameworkStatsLog.APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED__BINDER_API__NOTE_PROXY_OPERATION; import static com.android.server.appop.AppOpsService.ModeCallback.ALL_OPS; import android.Manifest; @@ -163,7 +160,6 @@ import com.android.internal.os.Clock; import com.android.internal.pm.pkg.component.ParsedAttribution; import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; -import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; import com.android.internal.util.function.pooled.PooledLambda; @@ -2833,26 +2829,12 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public int checkOperation(int code, int uid, String packageName) { - if (Flags.appopAccessTrackingLoggingEnabled()) { - FrameworkStatsLog.write( - FrameworkStatsLog.APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED, - uid, code, - APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED__BINDER_API__CHECK_OPERATION, - false); - } return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, null, Context.DEVICE_ID_DEFAULT, false /*raw*/); } @Override public int checkOperationForDevice(int code, int uid, String packageName, int virtualDeviceId) { - if (Flags.appopAccessTrackingLoggingEnabled()) { - FrameworkStatsLog.write( - FrameworkStatsLog.APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED, - uid, code, - APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED__BINDER_API__CHECK_OPERATION, - false); - } return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, null, virtualDeviceId, false /*raw*/); } @@ -3033,14 +3015,6 @@ public class AppOpsService extends IAppOpsService.Stub { public SyncNotedAppOp noteProxyOperationWithState(int code, AttributionSourceState attributionSourceState, boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage, boolean skipProxyOperation) { - if (Flags.appopAccessTrackingLoggingEnabled()) { - FrameworkStatsLog.write( - FrameworkStatsLog.APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED, - attributionSourceState.uid, code, - APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED__BINDER_API__NOTE_PROXY_OPERATION, - attributionSourceState.attributionTag != null); - } - AttributionSource attributionSource = new AttributionSource(attributionSourceState); return mCheckOpsDelegateDispatcher.noteProxyOperation(code, attributionSource, shouldCollectAsyncNotedOp, message, shouldCollectMessage, skipProxyOperation); @@ -3122,14 +3096,6 @@ public class AppOpsService extends IAppOpsService.Stub { public SyncNotedAppOp noteOperation(int code, int uid, String packageName, String attributionTag, boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage) { - if (Flags.appopAccessTrackingLoggingEnabled()) { - FrameworkStatsLog.write( - FrameworkStatsLog.APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED, - uid, code, - APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED__BINDER_API__NOTE_OPERATION, - attributionTag != null); - } - return mCheckOpsDelegateDispatcher.noteOperation(code, uid, packageName, attributionTag, Context.DEVICE_ID_DEFAULT, shouldCollectAsyncNotedOp, message, shouldCollectMessage); -- GitLab From 1d07441d2951a7e2f35a7c43d6c846f9c5fbfd67 Mon Sep 17 00:00:00 2001 From: chelseahao Date: Thu, 22 Aug 2024 16:02:02 +0800 Subject: [PATCH 173/447] Audio sharing dialog on top of bt qs tile dialog. This CL also created `AudioSharingModule` to provide different implementation based on audio sharing availability. User could choose to set a device to active or to share audio. Button behavior will be in the next CL. Test: atest Bug: 360759048 Flag: com.android.settingslib.flags.audio_sharing_qs_dialog_improvement Change-Id: I08a2b1aaf4240b71d10f12973815a97027dae4fa --- packages/SystemUI/Android.bp | 4 +- .../DeviceItemActionInteractorKosmos.kt | 11 +- .../res/layout/audio_sharing_dialog.xml | 115 ++++++ packages/SystemUI/res/values/strings.xml | 8 + .../qsdialog/AudioSharingButtonViewModel.kt | 98 +++++ ...ioSharingDeviceItemActionInteractorImpl.kt | 148 ++++++++ .../qsdialog/AudioSharingDialogDelegate.kt | 68 ++++ .../qsdialog/AudioSharingDialogViewModel.kt | 97 +++++ .../qsdialog/AudioSharingInteractor.kt | 85 ++--- .../qsdialog/BluetoothStateInteractor.kt | 2 +- .../qsdialog/BluetoothTileDialogUiEvent.kt | 2 + .../qsdialog/BluetoothTileDialogViewModel.kt | 51 +-- .../qsdialog/DeviceItemActionInteractor.kt | 259 +------------ .../bluetooth/qsdialog/DeviceItemFactory.kt | 7 +- .../qsdialog/DeviceItemInteractor.kt | 34 +- .../qsdialog/dagger/AudioSharingModule.kt | 97 +++++ .../connectivity/ConnectivityModule.kt | 3 +- .../AudioSharingButtonViewModelKosmos.kt | 37 ++ ....kt => AudioSharingButtonViewModelTest.kt} | 27 +- ...SharingDeviceItemActionInteractorKosmos.kt | 49 +++ ...ioSharingDeviceItemActionInteractorTest.kt | 189 ++++++++++ .../AudioSharingDialogDelegateTest.kt | 113 ++++++ .../AudioSharingDialogViewModelKosmos.kt | 60 +++ .../AudioSharingDialogViewModelTest.kt | 142 +++++++ .../qsdialog/AudioSharingInteractorKosmos.kt | 28 ++ .../BluetoothStateInteractorKosmos.kt | 31 ++ .../BluetoothTileDialogViewModelTest.kt | 14 +- .../DeviceItemActionInteractorTest.kt | 351 +----------------- .../qsdialog/DeviceItemFactoryTest.kt | 13 - .../qsdialog/DeviceItemInteractorTest.kt | 160 +++++--- 30 files changed, 1500 insertions(+), 803 deletions(-) create mode 100644 packages/SystemUI/res/layout/audio_sharing_dialog.xml create mode 100644 packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModel.kt create mode 100644 packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt create mode 100644 packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegate.kt create mode 100644 packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModel.kt create mode 100644 packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/dagger/AudioSharingModule.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelKosmos.kt rename packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/{AudioSharingInteractorTest.kt => AudioSharingButtonViewModelTest.kt} (86%) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorKosmos.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelKosmos.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelTest.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorKosmos.kt diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index bd7067bc1293..e3570010fbd3 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -425,8 +425,8 @@ filegroup { "tests/src/**/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt", "tests/src/**/systemui/shared/system/RemoteTransitionTest.java", "tests/src/**/systemui/navigationbar/NavigationBarControllerImplTest.java", - "tests/src/**/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt", - "tests/src/**/systemui/bluetooth/qsdialog/DeviceItemActionInteractorTest.kt", + "tests/src/**/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt", + "tests/src/**/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt", "tests/src/**/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt", "tests/src/**/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivityTest.kt", "tests/src/**/systemui/notetask/shortcut/LaunchNoteTaskActivityTest.kt", diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorKosmos.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorKosmos.kt index 5ff46346b386..b5b2f5e3e802 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorKosmos.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorKosmos.kt @@ -20,8 +20,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.systemui.animation.DialogTransitionAnimator import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher -import com.android.systemui.plugins.activityStarter -import com.android.systemui.util.mockito.mock +import org.mockito.kotlin.mock val Kosmos.bluetoothTileDialogLogger: BluetoothTileDialogLogger by Kosmos.Fixture { mock {} } @@ -29,14 +28,10 @@ val Kosmos.localBluetoothManager: LocalBluetoothManager by Kosmos.Fixture { mock val Kosmos.dialogTransitionAnimator: DialogTransitionAnimator by Kosmos.Fixture { mock {} } -val Kosmos.deviceItemActionInteractor: DeviceItemActionInteractor by +val Kosmos.deviceItemActionInteractorImpl: DeviceItemActionInteractorImpl by Kosmos.Fixture { - DeviceItemActionInteractor( - activityStarter, - dialogTransitionAnimator, - localBluetoothManager, + DeviceItemActionInteractorImpl( testDispatcher, - bluetoothTileDialogLogger, uiEventLogger, ) } diff --git a/packages/SystemUI/res/layout/audio_sharing_dialog.xml b/packages/SystemUI/res/layout/audio_sharing_dialog.xml new file mode 100644 index 000000000000..7534e159beb0 --- /dev/null +++ b/packages/SystemUI/res/layout/audio_sharing_dialog.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + +