diff options
828 files changed, 13485 insertions, 7112 deletions
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java index 7bd592155c00..b71d59696642 100644 --- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java +++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java @@ -477,7 +477,7 @@ public class UserLifecycleTests { /** Tests switching to an already-created already-running non-owner background user, with wait * times between iterations */ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) - public void switchUser_running_realistic() throws RemoteException { + public void switchUser_running_initializedUser() throws RemoteException { final int startUser = ActivityManager.getCurrentUser(); final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ false); while (mRunner.keepRunning()) { diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index 2533a0f47ee6..d7163d870d1e 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -4805,10 +4805,14 @@ public class AlarmManagerService extends SystemService { } final ArraySet<UserPackage> triggerPackages = new ArraySet<>(); final IntArray wakeupUids = new IntArray(); + final SparseIntArray countsPerUid = new SparseIntArray(); + final SparseIntArray wakeupCountsPerUid = new SparseIntArray(); for (int i = 0; i < triggerList.size(); i++) { final Alarm a = triggerList.get(i); + increment(countsPerUid, a.uid); if (a.wakeup) { wakeupUids.add(a.uid); + increment(wakeupCountsPerUid, a.uid); } if (mConstants.USE_TARE_POLICY == EconomyManager.ENABLED_MODE_ON) { if (!isExemptFromTare(a)) { @@ -4835,7 +4839,8 @@ public class AlarmManagerService extends SystemService { } rescheduleKernelAlarmsLocked(); updateNextAlarmClockLocked(); - MetricsHelper.pushAlarmBatchDelivered(triggerList.size(), wakeUps); + logAlarmBatchDelivered( + triggerList.size(), wakeUps, countsPerUid, wakeupCountsPerUid); } } @@ -4850,6 +4855,32 @@ public class AlarmManagerService extends SystemService { } } + private static void increment(SparseIntArray array, int key) { + final int index = array.indexOfKey(key); + if (index >= 0) { + array.setValueAt(index, array.valueAt(index) + 1); + } else { + array.put(key, 1); + } + } + + private void logAlarmBatchDelivered( + int alarms, + int wakeups, + SparseIntArray countsPerUid, + SparseIntArray wakeupCountsPerUid) { + final int[] uids = new int[countsPerUid.size()]; + final int[] countsArray = new int[countsPerUid.size()]; + final int[] wakeupCountsArray = new int[countsPerUid.size()]; + for (int i = 0; i < countsPerUid.size(); i++) { + uids[i] = countsPerUid.keyAt(i); + countsArray[i] = countsPerUid.valueAt(i); + wakeupCountsArray[i] = wakeupCountsPerUid.get(uids[i], 0); + } + MetricsHelper.pushAlarmBatchDelivered( + alarms, wakeups, uids, countsArray, wakeupCountsArray); + } + /** * Attribute blame for a WakeLock. * @@ -5766,12 +5797,7 @@ public class AlarmManagerService extends SystemService { } private void incrementAlarmCount(int uid) { - final int uidIndex = mAlarmsPerUid.indexOfKey(uid); - if (uidIndex >= 0) { - mAlarmsPerUid.setValueAt(uidIndex, mAlarmsPerUid.valueAt(uidIndex) + 1); - } else { - mAlarmsPerUid.put(uid, 1); - } + increment(mAlarmsPerUid, uid); } /** diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java b/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java index 28acb451c5f8..eb1848d666f0 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java @@ -117,10 +117,14 @@ class MetricsHelper { ActivityManager.processStateAmToProto(callerProcState)); } - static void pushAlarmBatchDelivered(int numAlarms, int wakeups) { + static void pushAlarmBatchDelivered( + int numAlarms, int wakeups, int[] uids, int[] alarmsPerUid, int[] wakeupAlarmsPerUid) { FrameworkStatsLog.write( FrameworkStatsLog.ALARM_BATCH_DELIVERED, numAlarms, - wakeups); + wakeups, + uids, + alarmsPerUid, + wakeupAlarmsPerUid); } } diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java index 299cb6cddbdf..e8fcdd2979de 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -1584,6 +1584,12 @@ public class JobSchedulerService extends com.android.server.SystemService return reason; } + @VisibleForTesting + @JobScheduler.PendingJobReason + int getPendingJobReason(JobStatus job) { + return getPendingJobReason(job.getUid(), job.getNamespace(), job.getJobId()); + } + @JobScheduler.PendingJobReason @GuardedBy("mLock") private int getPendingJobReasonLocked(int uid, String namespace, int jobId) { @@ -1694,7 +1700,8 @@ public class JobSchedulerService extends com.android.server.SystemService } } - private void stopUserVisibleJobsInternal(@NonNull String packageName, int userId) { + @VisibleForTesting + void stopUserVisibleJobsInternal(@NonNull String packageName, int userId) { final int packageUid = mLocalPM.getPackageUid(packageName, 0, userId); if (packageUid < 0) { Slog.wtf(TAG, "Asked to stop jobs of an unknown package"); @@ -1716,6 +1723,21 @@ public class JobSchedulerService extends com.android.server.SystemService // to stop only that work, B's jobs would be demoted as well. // TODO(255768978): make it possible to demote only the relevant subset of jobs job.addInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER); + + // The app process will be killed soon. There's no point keeping its jobs in + // the pending queue to try and start them. + if (mPendingJobQueue.remove(job)) { + synchronized (mPendingJobReasonCache) { + SparseIntArray jobIdToReason = mPendingJobReasonCache.get( + job.getUid(), job.getNamespace()); + if (jobIdToReason == null) { + jobIdToReason = new SparseIntArray(); + mPendingJobReasonCache.add(job.getUid(), job.getNamespace(), + jobIdToReason); + } + jobIdToReason.put(job.getJobId(), JobScheduler.PENDING_JOB_REASON_USER); + } + } } } } diff --git a/core/api/current.txt b/core/api/current.txt index e87487a750a1..bca9913ff94e 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -20181,6 +20181,7 @@ package android.location { method public boolean hasSatellitePvt(); method public boolean hasScheduling(); method public boolean hasSingleShotFix(); + method public boolean isAccumulatedDeltaRangeCapabilityKnown(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssCapabilities> CREATOR; } @@ -20189,6 +20190,7 @@ package android.location { ctor public GnssCapabilities.Builder(); ctor public GnssCapabilities.Builder(@NonNull android.location.GnssCapabilities); method @NonNull public android.location.GnssCapabilities build(); + method @NonNull public android.location.GnssCapabilities.Builder clearIsAccumulatedDeltaRangeCapabilityKnown(); method @NonNull public android.location.GnssCapabilities.Builder setGnssSignalTypes(@NonNull java.util.List<android.location.GnssSignalType>); method @NonNull public android.location.GnssCapabilities.Builder setHasAccumulatedDeltaRange(boolean); method @NonNull public android.location.GnssCapabilities.Builder setHasAntennaInfo(boolean); @@ -20341,7 +20343,7 @@ package android.location { method @NonNull public android.location.GnssClock getClock(); method @NonNull public java.util.Collection<android.location.GnssAutomaticGainControl> getGnssAutomaticGainControls(); method @NonNull public java.util.Collection<android.location.GnssMeasurement> getMeasurements(); - method public boolean hasFullTracking(); + method public boolean hasIsFullTracking(); method public boolean isFullTracking(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssMeasurementsEvent> CREATOR; @@ -20351,10 +20353,10 @@ package android.location { ctor public GnssMeasurementsEvent.Builder(); ctor public GnssMeasurementsEvent.Builder(@NonNull android.location.GnssMeasurementsEvent); method @NonNull public android.location.GnssMeasurementsEvent build(); - method @NonNull public android.location.GnssMeasurementsEvent.Builder clearFullTracking(); + method @NonNull public android.location.GnssMeasurementsEvent.Builder clearIsFullTracking(); method @NonNull public android.location.GnssMeasurementsEvent.Builder setClock(@NonNull android.location.GnssClock); - method @NonNull public android.location.GnssMeasurementsEvent.Builder setFullTracking(boolean); method @NonNull public android.location.GnssMeasurementsEvent.Builder setGnssAutomaticGainControls(@NonNull java.util.Collection<android.location.GnssAutomaticGainControl>); + method @NonNull public android.location.GnssMeasurementsEvent.Builder setIsFullTracking(boolean); method @NonNull public android.location.GnssMeasurementsEvent.Builder setMeasurements(@NonNull java.util.Collection<android.location.GnssMeasurement>); } @@ -21369,7 +21371,8 @@ package android.media { field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioPlaybackConfiguration> CREATOR; } - public final class AudioPresentation { + public final class AudioPresentation implements android.os.Parcelable { + method public int describeContents(); method public java.util.Map<java.util.Locale,java.lang.String> getLabels(); method public java.util.Locale getLocale(); method public int getMasteringIndication(); @@ -21378,6 +21381,7 @@ package android.media { method public boolean hasAudioDescription(); method public boolean hasDialogueEnhancement(); method public boolean hasSpokenSubtitles(); + method public void writeToParcel(@NonNull android.os.Parcel, int); field public static final int CONTENT_COMMENTARY = 5; // 0x5 field public static final int CONTENT_DIALOG = 4; // 0x4 field public static final int CONTENT_EMERGENCY = 6; // 0x6 @@ -21387,11 +21391,14 @@ package android.media { field public static final int CONTENT_UNKNOWN = -1; // 0xffffffff field public static final int CONTENT_VISUALLY_IMPAIRED = 2; // 0x2 field public static final int CONTENT_VOICEOVER = 7; // 0x7 + field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioPresentation> CREATOR; field public static final int MASTERED_FOR_3D = 3; // 0x3 field public static final int MASTERED_FOR_HEADPHONE = 4; // 0x4 field public static final int MASTERED_FOR_STEREO = 1; // 0x1 field public static final int MASTERED_FOR_SURROUND = 2; // 0x2 field public static final int MASTERING_NOT_INDICATED = 0; // 0x0 + field public static final int PRESENTATION_ID_UNKNOWN = -1; // 0xffffffff + field public static final int PROGRAM_ID_UNKNOWN = -1; // 0xffffffff } public static final class AudioPresentation.Builder { @@ -21646,6 +21653,7 @@ package android.media { field public static final int DUAL_MONO_MODE_RR = 3; // 0x3 field public static final int ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR = 2; // 0x2 field public static final int ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER = 1; // 0x1 + field public static final int ENCAPSULATION_METADATA_TYPE_SUPPLEMENTARY_AUDIO_PLACEMENT = 3; // 0x3 field public static final int ENCAPSULATION_MODE_ELEMENTARY_STREAM = 1; // 0x1 field public static final int ENCAPSULATION_MODE_NONE = 0; // 0x0 field public static final int ERROR = -1; // 0xffffffff @@ -21664,6 +21672,9 @@ package android.media { field public static final int STATE_NO_STATIC_DATA = 2; // 0x2 field public static final int STATE_UNINITIALIZED = 0; // 0x0 field public static final int SUCCESS = 0; // 0x0 + field public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT = 1; // 0x1 + field public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL = 0; // 0x0 + field public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT = 2; // 0x2 field public static final int WRITE_BLOCKING = 0; // 0x0 field public static final int WRITE_NON_BLOCKING = 1; // 0x1 } @@ -24586,6 +24597,7 @@ package android.media { public static final class RouteListingPreference.Item implements android.os.Parcelable { method public int describeContents(); + method @Nullable public CharSequence getCustomDisableReasonMessage(); method public int getDisableReason(); method public int getFlags(); method @NonNull public String getRouteId(); @@ -24593,6 +24605,7 @@ package android.media { method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference.Item> CREATOR; field public static final int DISABLE_REASON_AD = 3; // 0x3 + field public static final int DISABLE_REASON_CUSTOM = 5; // 0x5 field public static final int DISABLE_REASON_DOWNLOADED_CONTENT = 2; // 0x2 field public static final int DISABLE_REASON_IN_APP_ONLY = 4; // 0x4 field public static final int DISABLE_REASON_NONE = 0; // 0x0 @@ -24604,6 +24617,7 @@ package android.media { public static final class RouteListingPreference.Item.Builder { ctor public RouteListingPreference.Item.Builder(@NonNull String); method @NonNull public android.media.RouteListingPreference.Item build(); + method @NonNull public android.media.RouteListingPreference.Item.Builder setCustomDisableReasonMessage(@Nullable CharSequence); method @NonNull public android.media.RouteListingPreference.Item.Builder setDisableReason(int); method @NonNull public android.media.RouteListingPreference.Item.Builder setFlags(int); method @NonNull public android.media.RouteListingPreference.Item.Builder setSessionParticipantCount(@IntRange(from=0) int); @@ -27024,6 +27038,7 @@ package android.media.tv { method @Nullable public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(@NonNull String, @NonNull String); method @Nullable public abstract android.media.tv.TvInputService.Session onCreateSession(@NonNull String); method @Nullable public android.media.tv.TvInputService.Session onCreateSession(@NonNull String, @NonNull String); + method @Nullable public android.media.tv.TvInputService.Session onCreateSession(@NonNull String, @NonNull String, @NonNull android.content.AttributionSource); field public static final int PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND = 100; // 0x64 field public static final int PRIORITY_HINT_USE_CASE_TYPE_LIVE = 400; // 0x190 field public static final int PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK = 300; // 0x12c @@ -27062,6 +27077,8 @@ package android.media.tv { method public void layoutSurface(int, int, int, int); method public void notifyAdResponse(@NonNull android.media.tv.AdResponse); method public void notifyAitInfoUpdated(@NonNull android.media.tv.AitInfo); + method public void notifyAudioPresentationChanged(@NonNull java.util.List<android.media.AudioPresentation>); + method public void notifyAudioPresentationSelected(int, int); method public void notifyBroadcastInfoResponse(@NonNull android.media.tv.BroadcastInfoResponse); method public void notifyChannelRetuned(android.net.Uri); method public void notifyContentAllowed(); @@ -27085,6 +27102,7 @@ package android.media.tv { method public void onRemoveBroadcastInfo(int); method public void onRequestAd(@NonNull android.media.tv.AdRequest); method public void onRequestBroadcastInfo(@NonNull android.media.tv.BroadcastInfoRequest); + method public boolean onSelectAudioPresentation(int, int); method public boolean onSelectTrack(int, @Nullable String); method public abstract void onSetCaptionEnabled(boolean); method public void onSetInteractiveAppNotificationEnabled(boolean); @@ -27214,10 +27232,13 @@ package android.media.tv { ctor public TvView(android.content.Context, android.util.AttributeSet); ctor public TvView(android.content.Context, android.util.AttributeSet, int); method public boolean dispatchUnhandledInputEvent(android.view.InputEvent); + method @NonNull public java.util.List<android.media.AudioPresentation> getAudioPresentations(); method public String getSelectedTrack(int); method public java.util.List<android.media.tv.TvTrackInfo> getTracks(int); method public boolean onUnhandledInputEvent(android.view.InputEvent); + method public void overrideTvAppAttributionSource(@NonNull android.content.AttributionSource); method public void reset(); + method public void selectAudioPresentation(int, int); method public void selectTrack(int, String); method public void sendAppPrivateCommand(@NonNull String, android.os.Bundle); method public void setCallback(@Nullable android.media.tv.TvView.TvInputCallback); @@ -27250,6 +27271,8 @@ package android.media.tv { public abstract static class TvView.TvInputCallback { ctor public TvView.TvInputCallback(); method public void onAitInfoUpdated(@NonNull String, @NonNull android.media.tv.AitInfo); + method public void onAudioPresentationSelected(@NonNull String, int, int); + method public void onAudioPresentationsChanged(@NonNull String, @NonNull java.util.List<android.media.AudioPresentation>); method public void onChannelRetuned(String, android.net.Uri); method public void onConnectionFailed(String); method public void onContentAllowed(String); @@ -41625,9 +41648,7 @@ package android.telecom { } public final class CallEndpointException extends java.lang.RuntimeException implements android.os.Parcelable { - ctor public CallEndpointException(@Nullable String); ctor public CallEndpointException(@Nullable String, int); - ctor public CallEndpointException(@Nullable String, int, @Nullable Throwable); method public int describeContents(); method public int getCode(); method public void writeToParcel(@NonNull android.os.Parcel, int); @@ -49958,16 +49979,24 @@ package android.view { field public static final int CLOCK_TICK = 4; // 0x4 field public static final int CONFIRM = 16; // 0x10 field public static final int CONTEXT_CLICK = 6; // 0x6 + field public static final int DRAG_START = 25; // 0x19 field @Deprecated public static final int FLAG_IGNORE_GLOBAL_SETTING = 2; // 0x2 field public static final int FLAG_IGNORE_VIEW_SETTING = 1; // 0x1 field public static final int GESTURE_END = 13; // 0xd field public static final int GESTURE_START = 12; // 0xc + field public static final int GESTURE_THRESHOLD_ACTIVATE = 23; // 0x17 + field public static final int GESTURE_THRESHOLD_DEACTIVATE = 24; // 0x18 field public static final int KEYBOARD_PRESS = 3; // 0x3 field public static final int KEYBOARD_RELEASE = 7; // 0x7 field public static final int KEYBOARD_TAP = 3; // 0x3 field public static final int LONG_PRESS = 0; // 0x0 + field public static final int NO_HAPTICS = -1; // 0xffffffff field public static final int REJECT = 17; // 0x11 + field public static final int SEGMENT_FREQUENT_TICK = 27; // 0x1b + field public static final int SEGMENT_TICK = 26; // 0x1a field public static final int TEXT_HANDLE_MOVE = 9; // 0x9 + field public static final int TOGGLE_OFF = 22; // 0x16 + field public static final int TOGGLE_ON = 21; // 0x15 field public static final int VIRTUAL_KEY = 1; // 0x1 field public static final int VIRTUAL_KEY_RELEASE = 8; // 0x8 } @@ -51224,6 +51253,7 @@ package android.view { method @NonNull public android.view.SurfaceControl.Transaction addTransactionCommittedListener(@NonNull java.util.concurrent.Executor, @NonNull android.view.SurfaceControl.TransactionCommittedListener); method public void apply(); method @NonNull public android.view.SurfaceControl.Transaction clearFrameRate(@NonNull android.view.SurfaceControl); + method @NonNull public android.view.SurfaceControl.Transaction clearTrustedPresentationCallback(@NonNull android.view.SurfaceControl); method public void close(); method public int describeContents(); method @NonNull public android.view.SurfaceControl.Transaction merge(@NonNull android.view.SurfaceControl.Transaction); @@ -51244,6 +51274,7 @@ package android.view { method @NonNull public android.view.SurfaceControl.Transaction setOpaque(@NonNull android.view.SurfaceControl, boolean); method @NonNull public android.view.SurfaceControl.Transaction setPosition(@NonNull android.view.SurfaceControl, float, float); method @NonNull public android.view.SurfaceControl.Transaction setScale(@NonNull android.view.SurfaceControl, float, float); + method @NonNull public android.view.SurfaceControl.Transaction setTrustedPresentationCallback(@NonNull android.view.SurfaceControl, @NonNull android.view.SurfaceControl.TrustedPresentationThresholds, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @NonNull public android.view.SurfaceControl.Transaction setVisibility(@NonNull android.view.SurfaceControl, boolean); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.view.SurfaceControl.Transaction> CREATOR; @@ -51253,6 +51284,10 @@ package android.view { method public void onTransactionCommitted(); } + public static class SurfaceControl.TrustedPresentationThresholds { + ctor public SurfaceControl.TrustedPresentationThresholds(@FloatRange(from=0.0f, fromInclusive=false, to=1.0f) float, @FloatRange(from=0.0f, fromInclusive=false, to=1.0f) float, @IntRange(from=1) int); + } + public class SurfaceControlViewHost { ctor public SurfaceControlViewHost(@NonNull android.content.Context, @NonNull android.view.Display, @Nullable android.os.IBinder); method @Nullable public android.view.SurfaceControlViewHost.SurfacePackage getSurfacePackage(); @@ -60257,6 +60292,14 @@ package android.window { method @UiThread public void remove(); } + public class SurfaceSyncGroup { + ctor public SurfaceSyncGroup(@NonNull String); + method @UiThread public boolean add(@Nullable android.view.AttachedSurfaceControl, @Nullable Runnable); + method public boolean add(@NonNull android.view.SurfaceControlViewHost.SurfacePackage, @Nullable Runnable); + method public void addTransaction(@NonNull android.view.SurfaceControl.Transaction); + method public void markSyncReady(); + } + } package javax.microedition.khronos.egl { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index a40d97e9525c..c098adb7ea5d 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -303,6 +303,7 @@ package android { field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES"; field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS"; field public static final String ROTATE_SURFACE_FLINGER = "android.permission.ROTATE_SURFACE_FLINGER"; + field public static final String SATELLITE_COMMUNICATION = "android.permission.SATELLITE_COMMUNICATION"; field public static final String SCHEDULE_PRIORITIZED_ALARM = "android.permission.SCHEDULE_PRIORITIZED_ALARM"; field @Deprecated public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS"; field public static final String SECURE_ELEMENT_PRIVILEGED_OPERATION = "android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION"; @@ -456,6 +457,7 @@ package android { field public static final int config_systemAutomotiveProjection = 17039401; // 0x1040029 field public static final int config_systemCompanionDeviceProvider = 17039417; // 0x1040039 field public static final int config_systemContacts = 17039403; // 0x104002b + field public static final int config_systemFinancedDeviceController; field public static final int config_systemGallery = 17039399; // 0x1040027 field public static final int config_systemNotificationIntelligence = 17039413; // 0x1040035 field public static final int config_systemSettingsIntelligence = 17039426; // 0x1040042 diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index ce29937c7cad..0fa1a378ed39 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -955,4 +955,12 @@ public abstract class ActivityManagerInternal { * @hide */ public abstract void stopForegroundServiceDelegate(@NonNull ServiceConnection connection); + + /** + * Called by PowerManager. Return whether a given procstate is allowed to hold + * wake locks in deep doze. Because it's called with the power manager lock held, we can't + * hold AM locks in it. + * @hide + */ + public abstract boolean canHoldWakeLocksInDeepDoze(int uid, int procstate); } diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 9dc8ce6ad9c8..058c38989371 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -795,7 +795,7 @@ interface IActivityManager { // Start (?) of T transactions /** - * Similar to {@link #startUserInBackgroundWithListener(int userId, IProgressListener unlockProgressListener), + * Similar to {@link #startUserInBackgroundWithListener(int userId, IProgressListener unlockProgressListener)}, * but setting the user as the visible user of that display (i.e., allowing the user and its * running profiles to launch activities on that display). * @@ -806,6 +806,12 @@ interface IActivityManager { boolean startUserInBackgroundVisibleOnDisplay(int userid, int displayId); /** + * Similar to {@link #startProfile(int userId)}, but with a listener to report user unlock + * progress. + */ + boolean startProfileWithListener(int userid, IProgressListener unlockProgressListener); + + /** * Gets the ids of displays that can be used on {@link #startUserInBackgroundVisibleOnDisplay(int userId, int displayId)}. * * <p>Typically used only by automotive builds when the vehicle has multiple displays. diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java index 3bd86c1eb94b..92db8b329045 100644 --- a/core/java/android/app/NotificationChannelGroup.java +++ b/core/java/android/app/NotificationChannelGroup.java @@ -20,6 +20,7 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; +import android.content.pm.ParceledListSlice; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -68,7 +69,7 @@ public final class NotificationChannelGroup implements Parcelable { private CharSequence mName; private String mDescription; private boolean mBlocked; - private List<NotificationChannel> mChannels = new ArrayList<>(); + private List<NotificationChannel> mChannels = new ArrayList(); // Bitwise representation of fields that have been changed by the user private int mUserLockedFields; @@ -106,7 +107,12 @@ public final class NotificationChannelGroup implements Parcelable { } else { mDescription = null; } - in.readParcelableList(mChannels, NotificationChannel.class.getClassLoader(), android.app.NotificationChannel.class); + if (in.readByte() != 0) { + mChannels = in.readParcelable(NotificationChannelGroup.class.getClassLoader(), + ParceledListSlice.class).getList(); + } else { + mChannels = new ArrayList<>(); + } mBlocked = in.readBoolean(); mUserLockedFields = in.readInt(); } @@ -138,7 +144,12 @@ public final class NotificationChannelGroup implements Parcelable { } else { dest.writeByte((byte) 0); } - dest.writeParcelableList(mChannels, flags); + if (mChannels != null) { + dest.writeByte((byte) 1); + dest.writeParcelable(new ParceledListSlice<>(mChannels), flags); + } else { + dest.writeByte((byte) 0); + } dest.writeBoolean(mBlocked); dest.writeInt(mUserLockedFields); } diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index 577c8a361f56..42aa608c0ef8 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -902,8 +902,8 @@ public abstract class CameraDevice implements AutoCloseable { * <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV / PRIV}</td><td id="rb">{@code s1440p}</td><td id="rb">{@code VIDEO_CALL}</td> <td colspan="3" id="rb"></td> <td>Preview with video call</td> </tr> * <tr> <td>{@code YUV / PRIV}</td><td id="rb">{@code s1440p}</td><td id="rb">{@code PREVIEW_VIDEO_STILL}</td> <td>{@code YUV / JPEG}</td><td id="rb">{@code MAXIMUM}</td><td id="rb">{@code STILL_CAPTURE}</td> <td colspan="3" id="rb"></td> <td>MultI-purpose stream with JPEG or YUV still capture</td> </tr> * <tr> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code STILL_CAPTURE}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td><td id="rb">{@code STILL_CAPTURE}</td> <td colspan="3" id="rb"></td> <td>YUV and JPEG concurrent still image capture (for testing)</td> </tr> - * <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV / PRIV}</td><td id="rb">{@code RECORD}</td><td id="rb">{@code VIDEO_RECORD}</td> <td>{@code YUV / JPEG}</td><td id="rb">{@code RECORD}</td><td id="rb">{@code STILL_CAPTURE}</td> <td>Preview, video record and JPEG or YUV video snapshot</td> </tr> - * <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV / JPEG}</td><td id="rb">{@code MAXIMUM}</td><td id="rb">{@code STILL_CAPTURE}</td> <td>Preview, in-application image processing, and JPEG or YUV still image capture</td> </tr> + * <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV / PRIV}</td><td id="rb">{@code RECORD}</td><td id="rb">{@code VIDEO_RECORD}</td> <td>{@code JPEG}</td><td id="rb">{@code RECORD}</td><td id="rb">{@code STILL_CAPTURE}</td> <td>Preview, video record and JPEG video snapshot</td> </tr> + * <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code PREVIEW}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td><td id="rb">{@code STILL_CAPTURE}</td> <td>Preview, in-application image processing, and JPEG still image capture</td> </tr> * </table><br> * </p> * diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java index 3fc44f8f84ac..86c453b56c5b 100644 --- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java +++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java @@ -1225,14 +1225,6 @@ public final class MandatoryStreamCombination { new StreamCombinationTemplate(new StreamTemplate [] { new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW, STREAM_USE_CASE_PREVIEW), - new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.RECORD, - STREAM_USE_CASE_RECORD), - new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.RECORD, - STREAM_USE_CASE_STILL_CAPTURE)}, - "Preview, video record and YUV video snapshot"), - new StreamCombinationTemplate(new StreamTemplate [] { - new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW, - STREAM_USE_CASE_PREVIEW), new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.RECORD, STREAM_USE_CASE_RECORD), new StreamTemplate(ImageFormat.JPEG, SizeThreshold.RECORD, @@ -1241,27 +1233,11 @@ public final class MandatoryStreamCombination { new StreamCombinationTemplate(new StreamTemplate [] { new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW, STREAM_USE_CASE_PREVIEW), - new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.RECORD, - STREAM_USE_CASE_RECORD), - new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.RECORD, - STREAM_USE_CASE_STILL_CAPTURE)}, - "Preview, in-application video processing and YUV video snapshot"), - new StreamCombinationTemplate(new StreamTemplate [] { - new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW, - STREAM_USE_CASE_PREVIEW), new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.PREVIEW, STREAM_USE_CASE_PREVIEW), new StreamTemplate(ImageFormat.JPEG, SizeThreshold.MAXIMUM, STREAM_USE_CASE_STILL_CAPTURE)}, "Preview, in-application image processing, and JPEG still image capture"), - new StreamCombinationTemplate(new StreamTemplate [] { - new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW, - STREAM_USE_CASE_PREVIEW), - new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.PREVIEW, - STREAM_USE_CASE_PREVIEW), - new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.MAXIMUM, - STREAM_USE_CASE_STILL_CAPTURE)}, - "Preview, in-application image processing, and YUV still image capture"), }; private static StreamCombinationTemplate sCroppedRawStreamUseCaseCombinations[] = { diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index 3ccc9400e026..657541cfd854 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -51,6 +51,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.SystemClock; +import android.os.UserHandle; import android.os.VibrationEffect; import android.os.Vibrator; import android.os.VibratorManager; @@ -1163,6 +1164,7 @@ public final class InputManager { * * @hide */ + @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setPointerSpeed(Context context, int speed) { if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { throw new IllegalArgumentException("speed out of range"); @@ -2183,9 +2185,9 @@ public final class InputManager { * @hide */ public int getTouchpadPointerSpeed(@NonNull Context context) { - int speed = DEFAULT_POINTER_SPEED; - // TODO: obtain the actual speed from the settings - return speed; + return Settings.System.getIntForUser(context.getContentResolver(), + Settings.System.TOUCHPAD_POINTER_SPEED, DEFAULT_POINTER_SPEED, + UserHandle.USER_CURRENT); } /** @@ -2199,31 +2201,14 @@ public final class InputManager { * * @hide */ + @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadPointerSpeed(@NonNull Context context, int speed) { if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { throw new IllegalArgumentException("speed out of range"); } - // TODO: set the right setting - } - - /** - * Changes the touchpad pointer speed temporarily, but does not save the setting. - * - * The new speed will only apply to gesture-compatible touchpads. - * Requires {@link android.Manifest.permission#SET_POINTER_SPEED}. - * - * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and - * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. - * - * @hide - */ - public void tryTouchpadPointerSpeed(int speed) { - if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { - throw new IllegalArgumentException("speed out of range"); - } - - // TODO: set the touchpad pointer speed on the gesture library + Settings.System.putIntForUser(context.getContentResolver(), + Settings.System.TOUCHPAD_POINTER_SPEED, speed, UserHandle.USER_CURRENT); } /** @@ -2267,8 +2252,8 @@ public final class InputManager { * @hide */ public boolean useTouchpadNaturalScrolling(@NonNull Context context) { - // TODO: obtain the actual behavior from the settings - return true; + return Settings.System.getIntForUser(context.getContentResolver(), + Settings.System.TOUCHPAD_NATURAL_SCROLLING, 0, UserHandle.USER_CURRENT) == 1; } /** @@ -2282,8 +2267,11 @@ public final class InputManager { * * @hide */ + @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadNaturalScrolling(@NonNull Context context, boolean enabled) { - // TODO: set the right setting + Settings.System.putIntForUser(context.getContentResolver(), + Settings.System.TOUCHPAD_NATURAL_SCROLLING, enabled ? 1 : 0, + UserHandle.USER_CURRENT); } /** @@ -2297,8 +2285,8 @@ public final class InputManager { * @hide */ public boolean useTouchpadTapToClick(@NonNull Context context) { - // TODO: obtain the actual behavior from the settings - return true; + return Settings.System.getIntForUser(context.getContentResolver(), + Settings.System.TOUCHPAD_TAP_TO_CLICK, 0, UserHandle.USER_CURRENT) == 1; } /** @@ -2311,8 +2299,11 @@ public final class InputManager { * * @hide */ + @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadTapToClick(@NonNull Context context, boolean enabled) { - // TODO: set the right setting + Settings.System.putIntForUser(context.getContentResolver(), + Settings.System.TOUCHPAD_TAP_TO_CLICK, enabled ? 1 : 0, + UserHandle.USER_CURRENT); } /** @@ -2355,8 +2346,8 @@ public final class InputManager { * @hide */ public boolean useTouchpadRightClickZone(@NonNull Context context) { - // TODO: obtain the actual behavior from the settings - return true; + return Settings.System.getIntForUser(context.getContentResolver(), + Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, 0, UserHandle.USER_CURRENT) == 1; } /** @@ -2369,8 +2360,11 @@ public final class InputManager { * * @hide */ + @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadRightClickZone(@NonNull Context context, boolean enabled) { - // TODO: set the right setting + Settings.System.putIntForUser(context.getContentResolver(), + Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, enabled ? 1 : 0, + UserHandle.USER_CURRENT); } /** diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index a35b088476cf..0307c109517b 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -7828,8 +7828,8 @@ public abstract class BatteryStats { } pw.print("\""); pw.println(); - dumpHistory(pw, flags, histStart, true); } + dumpHistory(pw, flags, histStart, true); } if ((flags & DUMP_HISTORY_ONLY) != 0) { diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 07212a25d2cb..b2d8996279f3 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -5665,6 +5665,44 @@ public final class Settings { public static final String POINTER_SPEED = "pointer_speed"; /** + * Touchpad pointer speed setting. + * This is an integer value in a range between -7 and +7, so there are 15 possible values. + * -7 = slowest + * 0 = default speed + * +7 = fastest + * @hide + */ + public static final String TOUCHPAD_POINTER_SPEED = "touchpad_pointer_speed"; + + /** + * Whether to invert the touchpad scrolling direction. + * + * If set to 1 (the default), moving two fingers downwards on the touchpad will scroll + * upwards, consistent with normal touchscreen scrolling. If set to 0, moving two fingers + * downwards will scroll downwards. + * + * @hide + */ + public static final String TOUCHPAD_NATURAL_SCROLLING = "touchpad_natural_scrolling"; + + /** + * Whether to enable tap-to-click on touchpads. + * + * @hide + */ + public static final String TOUCHPAD_TAP_TO_CLICK = "touchpad_tap_to_click"; + + /** + * Whether to enable a right-click zone on touchpads. + * + * When set to 1, pressing to click in a section on the right-hand side of the touchpad will + * result in a context click (a.k.a. right click). + * + * @hide + */ + public static final String TOUCHPAD_RIGHT_CLICK_ZONE = "touchpad_right_click_zone"; + + /** * Whether lock-to-app will be triggered by long-press on recents. * @hide */ @@ -5850,6 +5888,10 @@ public final class Settings { PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE_VENDOR_HINT); PRIVATE_SETTINGS.add(DESKTOP_MODE); PRIVATE_SETTINGS.add(LOCALE_PREFERENCES); + PRIVATE_SETTINGS.add(TOUCHPAD_POINTER_SPEED); + PRIVATE_SETTINGS.add(TOUCHPAD_NATURAL_SCROLLING); + PRIVATE_SETTINGS.add(TOUCHPAD_TAP_TO_CLICK); + PRIVATE_SETTINGS.add(TOUCHPAD_RIGHT_CLICK_ZONE); } /** diff --git a/core/java/android/service/dreams/DreamOverlayService.java b/core/java/android/service/dreams/DreamOverlayService.java index bf5b970311d0..6e4535b7218a 100644 --- a/core/java/android/service/dreams/DreamOverlayService.java +++ b/core/java/android/service/dreams/DreamOverlayService.java @@ -36,38 +36,100 @@ import android.view.WindowManager; public abstract class DreamOverlayService extends Service { private static final String TAG = "DreamOverlayService"; private static final boolean DEBUG = false; - private boolean mShowComplications; - private ComponentName mDreamComponent; - private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() { + // The last client that started dreaming and hasn't ended + private OverlayClient mCurrentClient; + + // An {@link IDreamOverlayClient} implementation that identifies itself when forwarding + // requests to the {@link DreamOverlayService} + private static class OverlayClient extends IDreamOverlayClient.Stub { + private final DreamOverlayService mService; + private boolean mShowComplications; + private ComponentName mDreamComponent; + IDreamOverlayCallback mDreamOverlayCallback; + + OverlayClient(DreamOverlayService service) { + mService = service; + } + @Override - public void startDream(WindowManager.LayoutParams layoutParams, - IDreamOverlayCallback callback, String dreamComponent, - boolean shouldShowComplications) { - mDreamOverlayCallback = callback; + public void startDream(WindowManager.LayoutParams params, IDreamOverlayCallback callback, + String dreamComponent, boolean shouldShowComplications) throws RemoteException { mDreamComponent = ComponentName.unflattenFromString(dreamComponent); mShowComplications = shouldShowComplications; - onStartDream(layoutParams); + mDreamOverlayCallback = callback; + mService.startDream(this, params); } - @Override - public void endDream() { - onEndDream(); - } + @Override public void wakeUp() { - onWakeUp(() -> { + mService.wakeUp(this, () -> { try { mDreamOverlayCallback.onWakeUpComplete(); } catch (RemoteException e) { - Log.e(TAG, "Could not notify dream of wakeUp:" + e); + Log.e(TAG, "Could not notify dream of wakeUp", e); } }); } - }; - IDreamOverlayCallback mDreamOverlayCallback; + @Override + public void endDream() { + mService.endDream(this); + } + + private void onExitRequested() { + try { + mDreamOverlayCallback.onExitRequested(); + } catch (RemoteException e) { + Log.e(TAG, "Could not request exit:" + e); + } + } + + private boolean shouldShowComplications() { + return mShowComplications; + } + + private ComponentName getComponent() { + return mDreamComponent; + } + } + + private void startDream(OverlayClient client, WindowManager.LayoutParams params) { + endDream(mCurrentClient); + mCurrentClient = client; + onStartDream(params); + } + + private void endDream(OverlayClient client) { + if (client == null || client != mCurrentClient) { + return; + } + + onEndDream(); + mCurrentClient = null; + } + + private void wakeUp(OverlayClient client, Runnable callback) { + if (mCurrentClient != client) { + return; + } + + onWakeUp(callback); + } + + private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() { + @Override + public void getClient(IDreamOverlayClientCallback callback) { + try { + callback.onDreamOverlayClient( + new OverlayClient(DreamOverlayService.this)); + } catch (RemoteException e) { + Log.e(TAG, "could not send client to callback", e); + } + } + }; public DreamOverlayService() { } @@ -110,18 +172,23 @@ public abstract class DreamOverlayService extends Service { * This method is invoked to request the dream exit. */ public final void requestExit() { - try { - mDreamOverlayCallback.onExitRequested(); - } catch (RemoteException e) { - Log.e(TAG, "Could not request exit:" + e); + if (mCurrentClient == null) { + throw new IllegalStateException("requested exit with no dream present"); } + + mCurrentClient.onExitRequested(); } /** * Returns whether to show complications on the dream overlay. */ public final boolean shouldShowComplications() { - return mShowComplications; + if (mCurrentClient == null) { + throw new IllegalStateException( + "requested if should show complication when no dream active"); + } + + return mCurrentClient.shouldShowComplications(); } /** @@ -129,6 +196,10 @@ public abstract class DreamOverlayService extends Service { * @hide */ public final ComponentName getDreamComponent() { - return mDreamComponent; + if (mCurrentClient == null) { + throw new IllegalStateException("requested dream component when no dream active"); + } + + return mCurrentClient.getComponent(); } } diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index d3788862b6c0..6a4710f9475a 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -248,25 +248,39 @@ public class DreamService extends Service implements Window.Callback { private OverlayConnection mOverlayConnection; private static class OverlayConnection extends PersistentServiceConnection<IDreamOverlay> { - // Overlay set during onBind. - private IDreamOverlay mOverlay; + // Retrieved Client + private IDreamOverlayClient mClient; + // A list of pending requests to execute on the overlay. - private final ArrayList<Consumer<IDreamOverlay>> mConsumers = new ArrayList<>(); + private final ArrayList<Consumer<IDreamOverlayClient>> mConsumers = new ArrayList<>(); + + private final IDreamOverlayClientCallback mClientCallback = + new IDreamOverlayClientCallback.Stub() { + @Override + public void onDreamOverlayClient(IDreamOverlayClient client) { + mClient = client; + + for (Consumer<IDreamOverlayClient> consumer : mConsumers) { + consumer.accept(mClient); + } + } + }; private final Callback<IDreamOverlay> mCallback = new Callback<IDreamOverlay>() { @Override public void onConnected(ObservableServiceConnection<IDreamOverlay> connection, IDreamOverlay service) { - mOverlay = service; - for (Consumer<IDreamOverlay> consumer : mConsumers) { - consumer.accept(mOverlay); + try { + service.getClient(mClientCallback); + } catch (RemoteException e) { + Log.e(TAG, "could not get DreamOverlayClient", e); } } @Override public void onDisconnected(ObservableServiceConnection<IDreamOverlay> connection, int reason) { - mOverlay = null; + mClient = null; } }; @@ -296,16 +310,16 @@ public class DreamService extends Service implements Window.Callback { super.unbind(); } - public void addConsumer(Consumer<IDreamOverlay> consumer) { + public void addConsumer(Consumer<IDreamOverlayClient> consumer) { execute(() -> { mConsumers.add(consumer); - if (mOverlay != null) { - consumer.accept(mOverlay); + if (mClient != null) { + consumer.accept(mClient); } }); } - public void removeConsumer(Consumer<IDreamOverlay> consumer) { + public void removeConsumer(Consumer<IDreamOverlayClient> consumer) { execute(() -> mConsumers.remove(consumer)); } @@ -1050,6 +1064,24 @@ public class DreamService extends Service implements Window.Callback { * </p> */ public final void finish() { + // If there is an active overlay connection, signal that the dream is ending before + // continuing. Note that the overlay cannot rely on the unbound state, since another dream + // might have bound to it in the meantime. + if (mOverlayConnection != null) { + mOverlayConnection.addConsumer(overlay -> { + try { + overlay.endDream(); + mOverlayConnection.unbind(); + mOverlayConnection = null; + finish(); + } catch (RemoteException e) { + Log.e(mTag, "could not inform overlay of dream end:" + e); + } + }); + mOverlayConnection.clearConsumers(); + return; + } + if (mDebug) Slog.v(mTag, "finish(): mFinished=" + mFinished); Activity activity = mActivity; @@ -1066,10 +1098,6 @@ public class DreamService extends Service implements Window.Callback { } mFinished = true; - if (mOverlayConnection != null) { - mOverlayConnection.unbind(); - } - if (mDreamToken == null) { if (mDebug) Slog.v(mTag, "finish() called when not attached."); stopSelf(); @@ -1365,7 +1393,7 @@ public class DreamService extends Service implements Window.Callback { mWindow.getDecorView().addOnAttachStateChangeListener( new View.OnAttachStateChangeListener() { - private Consumer<IDreamOverlay> mDreamStartOverlayConsumer; + private Consumer<IDreamOverlayClient> mDreamStartOverlayConsumer; @Override public void onViewAttachedToWindow(View v) { @@ -1389,17 +1417,6 @@ public class DreamService extends Service implements Window.Callback { @Override public void onViewDetachedFromWindow(View v) { - if (mOverlayConnection != null) { - mOverlayConnection.addConsumer(overlay -> { - try { - overlay.endDream(); - } catch (RemoteException e) { - Log.e(mTag, "could not inform overlay of dream end:" + e); - } - }); - mOverlayConnection.clearConsumers(); - } - if (mActivity == null || !mActivity.isChangingConfigurations()) { // Only stop the dream if the view is not detached by relaunching // activity for configuration changes. It is important to also clear @@ -1408,6 +1425,10 @@ public class DreamService extends Service implements Window.Callback { mActivity = null; finish(); } + + if (mOverlayConnection != null && mDreamStartOverlayConsumer != null) { + mOverlayConnection.removeConsumer(mDreamStartOverlayConsumer); + } } }); } diff --git a/core/java/android/service/dreams/IDreamOverlay.aidl b/core/java/android/service/dreams/IDreamOverlay.aidl index 0e4bd3bd547b..7ec75a50ed00 100644 --- a/core/java/android/service/dreams/IDreamOverlay.aidl +++ b/core/java/android/service/dreams/IDreamOverlay.aidl @@ -16,8 +16,7 @@ package android.service.dreams; -import android.service.dreams.IDreamOverlayCallback; -import android.view.WindowManager.LayoutParams; +import android.service.dreams.IDreamOverlayClientCallback; /** * {@link IDreamOverlay} provides a way for a component to annotate a dream with additional view @@ -28,20 +27,7 @@ import android.view.WindowManager.LayoutParams; */ interface IDreamOverlay { /** - * @param params The {@link LayoutParams} for the associated DreamWindow, including the window - token of the Dream Activity. - * @param callback The {@link IDreamOverlayCallback} for requesting actions such as exiting the - * dream. - * @param dreamComponent The component name of the dream service requesting overlay. - * @param shouldShowComplications Whether the dream overlay should show complications, e.g. clock - * and weather. + * Retrieves a client the caller can use to interact with the dream overlay. */ - void startDream(in LayoutParams params, in IDreamOverlayCallback callback, - in String dreamComponent, in boolean shouldShowComplications); - - /** Called when the dream is waking, to do any exit animations */ - void wakeUp(); - - /** Called when the dream has ended. */ - void endDream(); + void getClient(in IDreamOverlayClientCallback callback); } diff --git a/core/java/android/service/dreams/IDreamOverlayClient.aidl b/core/java/android/service/dreams/IDreamOverlayClient.aidl new file mode 100644 index 000000000000..78b7280ae652 --- /dev/null +++ b/core/java/android/service/dreams/IDreamOverlayClient.aidl @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.dreams; + +import android.service.dreams.IDreamOverlayCallback; +import android.view.WindowManager.LayoutParams; + +/** +* {@link IDreamOverlayClient} allows {@link DreamService} instances to act upon the dream overlay. +* +* @hide +*/ +interface IDreamOverlayClient { + /** + * @param params The {@link LayoutParams} for the associated DreamWindow, including the window + token of the Dream Activity. + * @param callback The {@link IDreamOverlayCallback} for requesting actions such as exiting the + * dream. + * @param dreamComponent The component name of the dream service requesting overlay. + * @param shouldShowComplications Whether the dream overlay should show complications, e.g. clock + * and weather. + */ + void startDream(in LayoutParams params, in IDreamOverlayCallback callback, + in String dreamComponent, in boolean shouldShowComplications); + + /** Called when the dream is waking, to do any exit animations */ + void wakeUp(); + + /** Called when the dream has ended. */ + void endDream(); +} diff --git a/core/java/android/service/dreams/IDreamOverlayClientCallback.aidl b/core/java/android/service/dreams/IDreamOverlayClientCallback.aidl new file mode 100644 index 000000000000..244d999c623b --- /dev/null +++ b/core/java/android/service/dreams/IDreamOverlayClientCallback.aidl @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.dreams; + +import android.service.dreams.IDreamOverlayClient; + +/** +* {@link IDreamOverlayClientCallback} allows receiving a requested {@link IDreamOverlayClient}. +* @hide +*/ +interface IDreamOverlayClientCallback { + /** + * Called with a unique {@link IDreamOverlayClient}. + */ + void onDreamOverlayClient(in IDreamOverlayClient client); +} diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java index 7e8622a0e694..21b14f4fe7db 100644 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -2422,6 +2422,7 @@ public class TextToSpeech { @Override public void onDisconnected() { onServiceDisconnected(/* componentName= */ null); + mSession = null; } @Override diff --git a/core/java/android/transparency/BinaryTransparencyManager.java b/core/java/android/transparency/BinaryTransparencyManager.java index f6d7c611e9d9..d77bbcc836ec 100644 --- a/core/java/android/transparency/BinaryTransparencyManager.java +++ b/core/java/android/transparency/BinaryTransparencyManager.java @@ -19,6 +19,7 @@ package android.transparency; import android.annotation.NonNull; import android.annotation.SystemService; import android.content.Context; +import android.os.Bundle; import android.os.RemoteException; import android.util.Slog; @@ -83,4 +84,36 @@ public class BinaryTransparencyManager { } } + /** + * Collects the APEX information on the device. + * + * @param includeTestOnly Whether to include test only data in the returned ApexInfo. + * @return A List containing the APEX info. + * @hide + */ + @NonNull + public List<IBinaryTransparencyService.ApexInfo> collectAllApexInfo(boolean includeTestOnly) { + try { + return mService.collectAllApexInfo(includeTestOnly); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Collects the updated preload information on the device. + * + * @return A List containing the preload info. + * @hide + */ + @NonNull + public List<IBinaryTransparencyService.AppInfo> collectAllUpdatedPreloadInfo( + Bundle packagesToSkip) { + try { + Slog.d(TAG, "Calling backend's collectAllUpdatedPreloadInfo()"); + return mService.collectAllUpdatedPreloadInfo(packagesToSkip); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java index 45b65e551305..6551a1884af0 100644 --- a/core/java/android/view/HapticFeedbackConstants.java +++ b/core/java/android/view/HapticFeedbackConstants.java @@ -25,6 +25,13 @@ public class HapticFeedbackConstants { private HapticFeedbackConstants() {} /** + * No haptic feedback should be performed. Applications may use this value to indicate skipping + * a call to {@link View#performHapticFeedback} entirely, or else rely that it will immediately + * return {@code false}. + */ + public static final int NO_HAPTICS = -1; + + /** * The user has performed a long press on an object that is resulting * in an action being performed. */ @@ -145,6 +152,64 @@ public class HapticFeedbackConstants { public static final int ROTARY_SCROLL_LIMIT = 20; /** + * The user has toggled a switch or button into the on position. + */ + public static final int TOGGLE_ON = 21; + + /** + * The user has toggled a switch or button into the off position. + */ + public static final int TOGGLE_OFF = 22; + + /** + * The user is executing a swipe/drag-style gesture, such as pull-to-refresh, where the + * gesture action is “eligible” at a certain threshold of movement, and can be cancelled by + * moving back past the threshold. This constant indicates that the user's motion has just + * passed the threshold for the action to be activated on release. + * + * @see #GESTURE_THRESHOLD_DEACTIVATE + */ + public static final int GESTURE_THRESHOLD_ACTIVATE = 23; + + /** + * The user is executing a swipe/drag-style gesture, such as pull-to-refresh, where the + * gesture action is “eligible” at a certain threshold of movement, and can be cancelled by + * moving back past the threshold. This constant indicates that the user's motion has just + * re-crossed back "under" the threshold for the action to be activated, meaning the gesture is + * currently in a cancelled state. + * + * @see #GESTURE_THRESHOLD_ACTIVATE + */ + public static final int GESTURE_THRESHOLD_DEACTIVATE = 24; + + /** + * The user has started a drag-and-drop gesture. The drag target has just been "picked up". + */ + public static final int DRAG_START = 25; + + /** + * The user is switching between a series of potential choices, for example items in a list + * or discrete points on a slider. + * + * <p>See also {@link #SEGMENT_FREQUENT_TICK} for cases where density of choices is high, and + * the haptics should be lighter or suppressed for a better user experience. + */ + public static final int SEGMENT_TICK = 26; + + /** + * The user is switching between a series of many potential choices, for example minutes on a + * clock face, or individual percentages. This constant is expected to be very soft, so as + * not to be uncomfortable when performed a lot in quick succession. If the device can’t make + * a suitably soft vibration, then it may not make any vibration. + * + * <p>Some specializations of this constant exist for specific actions, notably + * {@link #CLOCK_TICK} and {@link #TEXT_HANDLE_MOVE}. + * + * <p>See also {@link #SEGMENT_TICK}. + */ + public static final int SEGMENT_FREQUENT_TICK = 27; + + /** * The phone has booted with safe mode enabled. * This is a private constant. Feel free to renumber as desired. * @hide diff --git a/core/java/android/view/MotionPredictor.java b/core/java/android/view/MotionPredictor.java index fa86a4c73fb2..4d32efea9081 100644 --- a/core/java/android/view/MotionPredictor.java +++ b/core/java/android/view/MotionPredictor.java @@ -22,26 +22,27 @@ import android.content.Context; import libcore.util.NativeAllocationRegistry; import java.util.Arrays; +import java.util.Collections; import java.util.List; /** * Calculate motion predictions. * - * Feed motion events to this class in order to generate the predicted events. The prediction - * functionality may not be available on all devices. Check if a specific source is supported on a - * given input device using #isPredictionAvailable. + * Feed motion events to this class in order to generate predicted future events. The prediction + * functionality may not be available on all devices: check if a specific source is supported on a + * given input device using {@link #isPredictionAvailable}. * - * Send all of the events that were received from the system here in order to generate complete, - * accurate predictions. When processing the returned predictions, make sure to consider all of the - * {@link MotionEvent#getHistoricalAxisValue historical samples}. + * Send all of the events that were received from the system to {@link #record} to generate + * complete, accurate predictions from {@link #predict}. When processing the returned predictions, + * make sure to consider all of the {@link MotionEvent#getHistoricalAxisValue historical samples}. */ -// Acts as a pass-through to the native MotionPredictor object. -// Do not store any state in this Java layer, or add any business logic here. All of the -// implementation details should go into the native MotionPredictor. -// The context / resource access must be here rather than in native layer due to the lack of the -// corresponding native API surface. public final class MotionPredictor { + // This is a pass-through to the native MotionPredictor object (mPtr). Do not store any state or + // add any business logic here -- all of the implementation details should go into the native + // MotionPredictor (except for accessing the context/resources, which have no corresponding + // native API). + private static class RegistryHolder { public static final NativeAllocationRegistry REGISTRY = NativeAllocationRegistry.createMalloced( @@ -67,49 +68,63 @@ public final class MotionPredictor { /** * Record a movement so that in the future, a prediction for the current gesture can be - * generated. Ensure to add all motions from the gesture of interest to generate the correct - * prediction. + * generated. Ensure to add all motions from the gesture of interest to generate correct + * predictions. * @param event The received event */ public void record(@NonNull MotionEvent event) { + if (!isPredictionEnabled()) { + return; + } nativeRecord(mPtr, event); } /** - * Get predicted events for all gestures that have been provided to the 'record' function. + * Get predicted events for all gestures that have been provided to {@link #record}. * If events from multiple devices were sent to 'record', this will produce a separate - * {@link MotionEvent} for each device id. The returned list may be empty if no predictions for - * any of the added events are available. + * {@link MotionEvent} for each device. The returned list may be empty if no predictions for + * any of the added events/devices are available. * Predictions may not reach the requested timestamp if the confidence in the prediction results * is low. * * @param predictionTimeNanos The time that the prediction should target, in the * {@link android.os.SystemClock#uptimeMillis} time base, but in nanoseconds. * - * @return the list of predicted motion events, for each device id. Ensure to check the - * historical data in addition to the latest ({@link MotionEvent#getX getX()}, - * {@link MotionEvent#getY getY()}) coordinates for smoothest prediction curves. Empty list is - * returned if predictions are not supported, or not possible for the current set of gestures. + * @return A list of predicted motion events, with at most one for each device observed by + * {@link #record}. Be sure to check the historical data in addition to the latest + * ({@link MotionEvent#getX getX()}, {@link MotionEvent#getY getY()}) coordinates for smooth + * prediction curves. An empty list is returned if predictions are not supported, or not + * possible for the current set of gestures. */ @NonNull public List<MotionEvent> predict(long predictionTimeNanos) { + if (!isPredictionEnabled()) { + return Collections.emptyList(); + } return Arrays.asList(nativePredict(mPtr, predictionTimeNanos)); } - /** - * Check whether this device supports motion predictions for the given source type. - * - * @param deviceId The input device id - * @param source The source of input events - * @return True if the current device supports predictions, false otherwise. - */ - public boolean isPredictionAvailable(int deviceId, int source) { + private boolean isPredictionEnabled() { // Device-specific override if (!mContext.getResources().getBoolean( com.android.internal.R.bool.config_enableMotionPrediction)) { return false; } - return nativeIsPredictionAvailable(mPtr, deviceId, source); + return true; + } + + /** + * Check whether a device supports motion predictions for a given source type. + * + * @param deviceId The input device id. + * @param source The source of input events. + * @return True if the current device supports predictions, false otherwise. + * + * @see MotionEvent#getDeviceId + * @see MotionEvent#getSource + */ + public boolean isPredictionAvailable(int deviceId, int source) { + return isPredictionEnabled() && nativeIsPredictionAvailable(mPtr, deviceId, source); } private static native long nativeInitialize(int offsetNanos); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index fedb09823a99..54e1a53ed7c9 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -280,7 +280,12 @@ public final class SurfaceControl implements Parcelable { private static native void nativeSetDefaultApplyToken(IBinder token); private static native IBinder nativeGetDefaultApplyToken(); private static native boolean nativeBootFinished(); - + private static native long nativeCreateTpc(TrustedPresentationCallback callback); + private static native long getNativeTrustedPresentationCallbackFinalizer(); + private static native void nativeSetTrustedPresentationCallback(long transactionObj, + long nativeObject, long nativeTpc, TrustedPresentationThresholds thresholds); + private static native void nativeClearTrustedPresentationCallback(long transactionObj, + long nativeObject); /** * Transforms that can be applied to buffers as they are displayed to a window. @@ -465,6 +470,8 @@ public final class SurfaceControl implements Parcelable { @GuardedBy("mLock") private int mHeight; + private TrustedPresentationCallback mTrustedPresentationCallback; + private WeakReference<View> mLocalOwnerView; static GlobalTransactionWrapper sGlobalTransaction; @@ -2400,6 +2407,79 @@ public final class SurfaceControl implements Parcelable { } /** + * Threshold values that are sent with + * {@link Transaction#setTrustedPresentationCallback(SurfaceControl, + * TrustedPresentationThresholds, Executor, Consumer)} + */ + public static class TrustedPresentationThresholds { + private float mMinAlpha; + private float mMinFractionRendered; + private int mStabilityRequirementMs; + + /** + * Creates a TrustedPresentationThresholds that's used when calling + * {@link Transaction#setTrustedPresentationCallback(SurfaceControl, + * TrustedPresentationThresholds, Executor, Consumer)} + * + * @param minAlpha The min alpha the {@link SurfaceControl} is required to + * have to be considered inside the threshold. + * @param minFractionRendered The min fraction of the SurfaceControl that was resented + * to the user to be considered inside the threshold. + * @param stabilityRequirementMs The time in milliseconds required for the + * {@link SurfaceControl} to be in the threshold. + * @throws IllegalArgumentException If threshold values are invalid. + */ + public TrustedPresentationThresholds( + @FloatRange(from = 0f, fromInclusive = false, to = 1f) float minAlpha, + @FloatRange(from = 0f, fromInclusive = false, to = 1f) float minFractionRendered, + @IntRange(from = 1) int stabilityRequirementMs) { + mMinAlpha = minAlpha; + mMinFractionRendered = minFractionRendered; + mStabilityRequirementMs = stabilityRequirementMs; + + checkValid(); + } + + private void checkValid() { + if (mMinAlpha <= 0 || mMinFractionRendered <= 0 || mStabilityRequirementMs < 1) { + throw new IllegalArgumentException( + "TrustedPresentationThresholds values are invalid"); + } + } + } + + /** + * Register a TrustedPresentationCallback for a particular SurfaceControl so it can be notified + * when the specified Threshold has been crossed. + * + * @hide + */ + public abstract static class TrustedPresentationCallback { + private final long mNativeObject; + + private static final NativeAllocationRegistry sRegistry = + NativeAllocationRegistry.createMalloced( + TrustedPresentationCallback.class.getClassLoader(), + getNativeTrustedPresentationCallbackFinalizer()); + + private final Runnable mFreeNativeResources; + + private TrustedPresentationCallback() { + mNativeObject = nativeCreateTpc(this); + mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject); + } + + /** + * Invoked when the SurfaceControl that this TrustedPresentationCallback was registered for + * enters or exits the threshold bounds. + * + * @param inTrustedPresentationState true when the SurfaceControl entered the + * presentation state, false when it has left. + */ + public abstract void onTrustedPresentationChanged(boolean inTrustedPresentationState); + } + + /** * An atomic set of changes to a set of SurfaceControl. */ public static class Transaction implements Closeable, Parcelable { @@ -3777,6 +3857,106 @@ public final class SurfaceControl implements Parcelable { } /** + * Sets a callback to receive feedback about the presentation of a {@link SurfaceControl}. + * When the {@link SurfaceControl} is presented according to the passed in + * {@link TrustedPresentationThresholds}, it is said to "enter the state", and receives the + * callback with {@code true}. When the conditions fall out of thresholds, it is then + * said to leave the state. + * <p> + * There are a few simple thresholds: + * <ul> + * <li>minAlpha: Lower bound on computed alpha</li> + * <li>minFractionRendered: Lower bounds on fraction of pixels that were rendered</li> + * <li>stabilityThresholdMs: A time that alpha and fraction rendered must remain within + * bounds before we can "enter the state" </li> + * </ul> + * <p> + * The fraction of pixels rendered is a computation based on scale, crop + * and occlusion. The calculation may be somewhat counterintuitive, so we + * can work through an example. Imagine we have a SurfaceControl with a 100x100 buffer + * which is occluded by (10x100) pixels on the left, and cropped by (100x10) pixels + * on the top. Furthermore imagine this SurfaceControl is scaled by 0.9 in both dimensions. + * (c=crop,o=occluded,b=both,x=none) + * + * <blockquote> + * <table> + * <caption></caption> + * <tr><td>b</td><td>c</td><td>c</td><td>c</td></tr> + * <tr><td>o</td><td>x</td><td>x</td><td>x</td></tr> + * <tr><td>o</td><td>x</td><td>x</td><td>x</td></tr> + * <tr><td>o</td><td>x</td><td>x</td><td>x</td></tr> + * </table> + * </blockquote> + * + *<p> + * We first start by computing fr=xscale*yscale=0.9*0.9=0.81, indicating + * that "81%" of the pixels were rendered. This corresponds to what was 100 + * pixels being displayed in 81 pixels. This is somewhat of an abuse of + * language, as the information of merged pixels isn't totally lost, but + * we err on the conservative side. + * <p> + * We then repeat a similar process for the crop and covered regions and + * accumulate the results: fr = fr * (fractionNotCropped) * (fractionNotCovered) + * So for this example we would get 0.9*0.9*0.9*0.9=0.65... + * <p> + * Notice that this is not completely accurate, as we have double counted + * the region marked as b. However we only wanted a "lower bound" and so it + * is ok to err in this direction. Selection of the threshold will ultimately + * be somewhat arbitrary, and so there are some somewhat arbitrary decisions in + * this API as well. + * <p> + * @param sc The {@link SurfaceControl} to set the + * {@link TrustedPresentationCallback} on + * @param thresholds The {@link TrustedPresentationThresholds} that will specify when the to + * invoke the callback. + * @param executor The {@link Executor} where the callback will be invoked on. + * @param listener The {@link Consumer} that will receive the callbacks when entered or + * exited the threshold. + * @return This transaction + * @see TrustedPresentationThresholds + */ + @NonNull + public Transaction setTrustedPresentationCallback(@NonNull SurfaceControl sc, + @NonNull TrustedPresentationThresholds thresholds, @NonNull Executor executor, + @NonNull Consumer<Boolean> listener) { + checkPreconditions(sc); + TrustedPresentationCallback tpc = new TrustedPresentationCallback() { + @Override + public void onTrustedPresentationChanged(boolean inTrustedPresentationState) { + executor.execute( + () -> listener.accept(inTrustedPresentationState)); + } + }; + + if (sc.mTrustedPresentationCallback != null) { + sc.mTrustedPresentationCallback.mFreeNativeResources.run(); + } + + nativeSetTrustedPresentationCallback(mNativeObject, sc.mNativeObject, + tpc.mNativeObject, thresholds); + sc.mTrustedPresentationCallback = tpc; + return this; + } + + /** + * Clears the {@link TrustedPresentationCallback} for a specific {@link SurfaceControl} + * + * @param sc The SurfaceControl that the {@link TrustedPresentationCallback} should be + * cleared from + * @return This transaction + */ + @NonNull + public Transaction clearTrustedPresentationCallback(@NonNull SurfaceControl sc) { + checkPreconditions(sc); + nativeClearTrustedPresentationCallback(mNativeObject, sc.mNativeObject); + if (sc.mTrustedPresentationCallback != null) { + sc.mTrustedPresentationCallback.mFreeNativeResources.run(); + sc.mTrustedPresentationCallback = null; + } + return this; + } + + /** * Writes the transaction to parcel, clearing the transaction as if it had been applied so * it can be used to store future transactions. It's the responsibility of the parcel * reader to apply the original transaction. diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java index 490091bf2352..f7bdd094ff2c 100644 --- a/core/java/android/view/SurfaceControlViewHost.java +++ b/core/java/android/view/SurfaceControlViewHost.java @@ -97,7 +97,8 @@ public class SurfaceControlViewHost { public ISurfaceSyncGroup getSurfaceSyncGroup() { CompletableFuture<ISurfaceSyncGroup> surfaceSyncGroup = new CompletableFuture<>(); mViewRoot.mHandler.post( - () -> surfaceSyncGroup.complete(mViewRoot.getOrCreateSurfaceSyncGroup())); + () -> surfaceSyncGroup.complete( + mViewRoot.getOrCreateSurfaceSyncGroup().mISurfaceSyncGroup)); try { return surfaceSyncGroup.get(1, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index e559a71757c8..1eb87c9e039e 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -1091,7 +1091,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall t = syncBufferTransactionCallback.waitForTransaction(); } - surfaceSyncGroup.addTransactionToSync(t); + surfaceSyncGroup.addTransaction(t); surfaceSyncGroup.markSyncReady(); onDrawFinished(); }); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 7b53843db568..9fa6c05f4c9d 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -25829,10 +25829,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param selected true if the view must be selected, false otherwise */ public void setSelected(boolean selected) { - setSelected(selected, true); - } - - void setSelected(boolean selected, boolean sendAccessibilityEvent) { //noinspection DoubleNegation if (((mPrivateFlags & PFLAG_SELECTED) != 0) != selected) { mPrivateFlags = (mPrivateFlags & ~PFLAG_SELECTED) | (selected ? PFLAG_SELECTED : 0); @@ -25840,13 +25836,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, invalidate(true); refreshDrawableState(); dispatchSetSelected(selected); - if (sendAccessibilityEvent) { - if (selected) { - sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); - } else { - notifyViewAccessibilityStateChangedIfNeeded( - AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED); - } + if (selected) { + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + } else { + notifyViewAccessibilityStateChangedIfNeeded( + AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED); } } } @@ -27276,7 +27270,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param flags Additional flags as per {@link HapticFeedbackConstants}. */ public boolean performHapticFeedback(int feedbackConstant, int flags) { - if (mAttachInfo == null) { + if (feedbackConstant == HapticFeedbackConstants.NO_HAPTICS + || mAttachInfo == null) { return false; } //noinspection SimplifiableIfStatement diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 9f5015cf4343..0e4ac0109f8e 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -4631,7 +4631,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final View[] children = mChildren; final int count = mChildrenCount; for (int i = 0; i < count; i++) { - children[i].setSelected(selected, false); + children[i].setSelected(selected); } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 84ed845d62f8..9119ea4bab94 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3768,7 +3768,7 @@ public final class ViewRootImpl implements ViewParent, Log.d(mTag, "Setup new sync=" + mWmsRequestSyncGroup.getName()); } - mWmsRequestSyncGroup.addToSync(this); + mWmsRequestSyncGroup.add(this, null /* runnable */); Trace.traceEnd(Trace.TRACE_TAG_VIEW); } @@ -11354,7 +11354,7 @@ public final class ViewRootImpl implements ViewParent, // pendingDrawFinished. if ((syncResult & (SYNC_LOST_SURFACE_REWARD_IF_FOUND | SYNC_CONTEXT_IS_STOPPED)) != 0) { - surfaceSyncGroup.addTransactionToSync( + surfaceSyncGroup.addTransaction( mBlastBufferQueue.gatherPendingTransactions(frame)); surfaceSyncGroup.markSyncReady(); return null; @@ -11368,7 +11368,7 @@ public final class ViewRootImpl implements ViewParent, mBlastBufferQueue.syncNextTransaction(new Consumer<Transaction>() { @Override public void accept(Transaction transaction) { - surfaceSyncGroup.addTransactionToSync(transaction); + surfaceSyncGroup.addTransaction(transaction); surfaceSyncGroup.markSyncReady(); } }); @@ -11391,7 +11391,7 @@ public final class ViewRootImpl implements ViewParent, // since the frame didn't draw on this vsync. It's possible the frame will // draw later, but it's better to not be sync than to block on a frame that // may never come. - surfaceSyncGroup.addTransactionToSync( + surfaceSyncGroup.addTransaction( mBlastBufferQueue.gatherPendingTransactions(frame)); surfaceSyncGroup.markSyncReady(); return; @@ -11481,7 +11481,7 @@ public final class ViewRootImpl implements ViewParent, if (mActiveSurfaceSyncGroup == null) { return; } - mActiveSurfaceSyncGroup.addToSync(syncable, false /* parentSyncGroupMerge */); + mActiveSurfaceSyncGroup.add(syncable, null /* Runnable */); } @Override diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 40898d02b97a..9bec409ea8a1 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -629,114 +629,6 @@ public interface WindowManager extends ViewManager { @interface DisplayImePolicy {} /** - * The root state of all the state. This is an abstract state, and the keyguard should be in - * one of this sub state. - * - * @hide - */ - int KEYGUARD_STATE_ROOT = 0x0; - - /** - * Keyguard is off, so activity can be shown on the screen. - * - * @hide - */ - int KEYGUARD_STATE_OFF = 0x1; - - /** - * The keyguard is off, but lock screen is still rendered on the screen. Waiting for - * starting unlock animation. - * - * @hide - */ - int KEYGUARD_STATE_GOING_AWAY = 0x11; - - /** - * They keyguard is on, so normal activities cannot be shown on the screen. This is an abstract - * state, and the keyguard should be in one of ths sub state. - * - * @hide - */ - int KEYGUARD_STATE_ON = 0x2; - - /** - * The keyguard is on and not occluded. - * @hide - */ - int KEYGUARD_STATE_KEYGUARD_TOP = 0x21; - - /** - * The keyguard is on, and the lock screen is shown. - * - * @hide - */ - int KEYGUARD_STATE_LOCKSCREEN_SHOWN = 0x211; - - /** - * The keyguard is on, and the AOD is shown. - * - * @hide - */ - int KEYGUARD_STATE_AOD_SHOWN = 0x212; - - /** - * The keyguard is on but it's occluded by a normal SHOW_WHEN_LOCKED activity (i.e. non - * occluded by Dream activity). - * - * @hide - */ - int KEYGUARD_STATE_OCCLUDED = 0x22; - - /** - * The keyguard is on but it's occluded by a Dream activity. - * - * @hide - */ - int KEYGUARD_STATE_DREAMING = 0x221; - - /** @hide */ - @IntDef(prefix = { "KEYGUARD_STATE_" }, value = { - KEYGUARD_STATE_ROOT, - KEYGUARD_STATE_OFF, - KEYGUARD_STATE_GOING_AWAY, - KEYGUARD_STATE_ON, - KEYGUARD_STATE_KEYGUARD_TOP, - KEYGUARD_STATE_LOCKSCREEN_SHOWN, - KEYGUARD_STATE_AOD_SHOWN, - KEYGUARD_STATE_OCCLUDED, - KEYGUARD_STATE_DREAMING, - }) - @interface KeyguardState {} - - /** - * @hide - */ - static String keyguardStateToString(@KeyguardState int type) { - switch (type) { - case KEYGUARD_STATE_ROOT: - return "ROOT"; - case KEYGUARD_STATE_OFF: - return "KEYGUARD_OFF"; - case KEYGUARD_STATE_GOING_AWAY: - return "KEYGUARD_GOING_AWAY"; - case KEYGUARD_STATE_ON: - return "KEYGUARD_ON"; - case KEYGUARD_STATE_KEYGUARD_TOP: - return "KEYGUARD_TOP"; - case KEYGUARD_STATE_LOCKSCREEN_SHOWN: - return "KEYGUARD_LOCKSCREEN_SHOWN"; - case KEYGUARD_STATE_AOD_SHOWN: - return "KEYGUARD_AOD_SHOWN"; - case KEYGUARD_STATE_OCCLUDED: - return "KEYGUARD_OCCLUDED"; - case KEYGUARD_STATE_DREAMING: - return "KEYGUARD_DREAMING"; - default: - return "KEYGUARD_STATE_UNKNOWN(" + Integer.toHexString(type) + ")"; - } - } - - /** * Exception that is thrown when trying to add view whose * {@link LayoutParams} {@link LayoutParams#token} * is invalid. diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index f2f455702f5d..f4a8639d3bce 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -1637,6 +1637,10 @@ public class Editor { mSelectionModifierCursorController.resetTouchOffsets(); } + if (mInsertModeController != null) { + mInsertModeController.exitInsertMode(); + } + ensureNoSelectionIfNonSelectable(); } } diff --git a/core/java/android/window/SurfaceSyncGroup.java b/core/java/android/window/SurfaceSyncGroup.java index 12cd3408bf87..2e55041d2e8c 100644 --- a/core/java/android/window/SurfaceSyncGroup.java +++ b/core/java/android/window/SurfaceSyncGroup.java @@ -42,14 +42,18 @@ import java.util.function.Consumer; import java.util.function.Supplier; /** - * Used to organize syncs for surfaces. + * A way for data to be gathered so multiple surfaces can be synced. This is intended to be + * used with AttachedSurfaceControl, SurfaceView, and SurfaceControlViewHost. This allows different + * parts of the system to synchronize different surfaces themselves without having to manage timing + * of different rendering threads. + * This will also allow synchronization of surfaces across multiple processes. The caller can add + * SurfaceControlViewHosts from another process to the SurfaceSyncGroup in a different process + * and this clas will ensure all the surfaces are ready before applying everything together. * </p> - * See SurfaceSyncGroup.md + * see the <a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/window/SurfaceSyncGroup.md">SurfaceSyncGroup documentation</a> * </p> - * - * @hide */ -public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { +public class SurfaceSyncGroup { private static final String TAG = "SurfaceSyncGroup"; private static final boolean DEBUG = false; @@ -93,6 +97,11 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { private ISurfaceSyncGroupCompletedListener mSurfaceSyncGroupCompletedListener; /** + * @hide + */ + public final ISurfaceSyncGroup mISurfaceSyncGroup = new ISurfaceSyncGroupImpl(); + + /** * Token to identify this SurfaceSyncGroup. This is used to register the SurfaceSyncGroup in * WindowManager. This token is also sent to other processes' SurfaceSyncGroup that want to be * included in this SurfaceSyncGroup. @@ -104,8 +113,8 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { } private static SurfaceSyncGroup getSurfaceSyncGroup(ISurfaceSyncGroup iSurfaceSyncGroup) { - if (iSurfaceSyncGroup instanceof SurfaceSyncGroup) { - return (SurfaceSyncGroup) iSurfaceSyncGroup; + if (iSurfaceSyncGroup instanceof ISurfaceSyncGroupImpl) { + return ((ISurfaceSyncGroupImpl) iSurfaceSyncGroup).getSurfaceSyncGroup(); } return null; } @@ -119,8 +128,10 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { /** * Starts a sync and will automatically apply the final, merged transaction. + * + * @param name Used for identifying and debugging. */ - public SurfaceSyncGroup(String name) { + public SurfaceSyncGroup(@NonNull String name) { this(name, transaction -> { if (transaction != null) { if (DEBUG) { @@ -134,6 +145,7 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { /** * Creates a sync. * + * @param name Used for identifying and debugging. * @param transactionReadyConsumer The complete callback that contains the syncId and * transaction with all the sync data merged. The Transaction * passed back can be null. @@ -157,19 +169,23 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { Log.d(TAG, "Sending non null transaction " + transaction + " to callback for " + mName); } - Trace.instant(Trace.TRACE_TAG_VIEW, - "Final TransactionCallback with " + transaction + " for " + mName); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.instant(Trace.TRACE_TAG_VIEW, + "Final TransactionCallback with " + transaction + " for " + mName); + } transactionReadyConsumer.accept(transaction); synchronized (mLock) { // If there's a registered listener with WMS, that means we aren't actually complete // until WMS notifies us that the parent has completed. if (mSurfaceSyncGroupCompletedListener == null) { - invokeSyncCompleteListeners(); + invokeSyncCompleteCallbacks(); } } }; - Trace.instant(Trace.TRACE_TAG_VIEW, "new SurfaceSyncGroup " + mName); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.instant(Trace.TRACE_TAG_VIEW, "new SurfaceSyncGroup " + mName); + } if (DEBUG) { Log.d(TAG, "setupSync " + mName + " " + Debug.getCallers(2)); @@ -177,7 +193,7 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { } @GuardedBy("mLock") - private void invokeSyncCompleteListeners() { + private void invokeSyncCompleteCallbacks() { mSyncCompleteCallbacks.forEach( executorRunnablePair -> executorRunnablePair.first.execute( executorRunnablePair.second)); @@ -188,6 +204,7 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { * * @param executor The Executor to invoke the Runnable on * @param runnable The Runnable to get called + * @hide */ public void addSyncCompleteCallback(Executor executor, Runnable runnable) { synchronized (mLock) { @@ -196,13 +213,16 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { } /** - * Mark the sync set as ready to complete. No more data can be added to the specified - * syncId. - * Once the sync set is marked as ready, it will be able to complete once all Syncables in the - * set have completed their sync + * Mark the SurfaceSyncGroup as ready to complete. No more data can be added to this + * SurfaceSyncGroup. + * <p> + * Once the SurfaceSyncGroup is marked as ready, it will be able to complete once all child + * SurfaceSyncGroup have completed their sync. */ public void markSyncReady() { - Trace.traceBegin(Trace.TRACE_TAG_VIEW, "markSyncReady " + mName); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "markSyncReady " + mName); + } synchronized (mLock) { if (mHasWMSync) { try { @@ -213,28 +233,29 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { mSyncReady = true; checkIfSyncIsComplete(); } - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } } /** - * Add a SurfaceView to a sync set. This is different than - * {@link #addToSync(AttachedSurfaceControl)} because it requires the caller to notify the start - * and finish drawing in order to sync. + * Add a SurfaceView to a SurfaceSyncGroup. This requires the caller to notify the start + * and finish drawing in order to sync since the client owns the rendering of the SurfaceView. * * @param surfaceView The SurfaceView to add to the sync. * @param frameCallbackConsumer The callback that's invoked to allow the caller to notify - * the - * Syncer when the SurfaceView has started drawing and - * finished. + * SurfaceSyncGroup when the SurfaceView has started drawing. * @return true if the SurfaceView was successfully added to the SyncGroup, false otherwise. + * @hide */ @UiThread - public boolean addToSync(SurfaceView surfaceView, + public boolean add(SurfaceView surfaceView, Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) { SurfaceSyncGroup surfaceSyncGroup = new SurfaceSyncGroup(surfaceView.getName()); - if (addToSync(surfaceSyncGroup, false /* parentSyncGroupMerge */)) { + if (add(surfaceSyncGroup.mISurfaceSyncGroup, false /* parentSyncGroupMerge */, + null /* runnable */)) { frameCallbackConsumer.accept(() -> surfaceView.syncNextFrame(transaction -> { - surfaceSyncGroup.addTransactionToSync(transaction); + surfaceSyncGroup.addTransaction(transaction); surfaceSyncGroup.markSyncReady(); })); return true; @@ -243,54 +264,53 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { } /** - * Add an AttachedSurfaceControl to a sync set. - * - * @param viewRoot The viewRoot that will be add to the sync set. - * @return true if the View was successfully added to the SyncGroup, false otherwise. - * @see #addToSync(AttachedSurfaceControl, Runnable) - */ - @UiThread - public boolean addToSync(@Nullable AttachedSurfaceControl viewRoot) { - return addToSync(viewRoot, null /* runnable */); - } - - /** - * Add an AttachedSurfaceControl to a sync set. The AttachedSurfaceControl will pause rendering - * to ensure the runnable can be invoked and the sync picks up the frame that contains the - * changes. + * Add an AttachedSurfaceControl to the SurfaceSyncGroup. The AttachedSurfaceControl will pause + * rendering to ensure the runnable can be invoked and that the sync picks up the frame that + * contains the changes. * - * @param viewRoot The viewRoot that will be add to the sync set. - * @param runnable The runnable to be invoked before adding to the sync group. - * @return true if the View was successfully added to the SyncGroup, false otherwise. - * @see #addToSync(AttachedSurfaceControl) + * @param attachedSurfaceControl The AttachedSurfaceControl that will be add to this + * SurfaceSyncGroup. + * @param runnable This is run on the same thread that the call was made on, but + * after the rendering is paused and before continuing to render + * the next frame. This method will not return until the + * execution of the runnable completes. This can be used to make + * changes to the AttachedSurfaceControl, ensuring that the + * changes are included in the sync. + * @return true if the AttachedSurfaceControl was successfully added to the SurfaceSyncGroup, + * false otherwise. */ @UiThread - public boolean addToSync(@Nullable AttachedSurfaceControl viewRoot, + public boolean add(@Nullable AttachedSurfaceControl attachedSurfaceControl, @Nullable Runnable runnable) { - if (viewRoot == null) { + if (attachedSurfaceControl == null) { return false; } - SurfaceSyncGroup surfaceSyncGroup = viewRoot.getOrCreateSurfaceSyncGroup(); + SurfaceSyncGroup surfaceSyncGroup = attachedSurfaceControl.getOrCreateSurfaceSyncGroup(); if (surfaceSyncGroup == null) { return false; } - return addToSync(surfaceSyncGroup, false /* parentSyncGroupMerge */, runnable); + return add(surfaceSyncGroup, runnable); } /** - * Helper method to add a SurfaceControlViewHost.SurfacePackage to the sync group. This will + * Add a SurfaceControlViewHost.SurfacePackage to the SurfaceSyncGroup. This will * get the SurfaceSyncGroup from the SurfacePackage, which will pause rendering for the * SurfaceControlViewHost. The runnable will be invoked to allow the host to update the SCVH * in a synchronized way. Finally, it will add the SCVH to the SurfaceSyncGroup and unpause * rendering in the SCVH, allowing the changes to get picked up and included in the sync. * - * @param surfacePackage The SurfacePackage that should be synced - * @param runnable The Runnable that's invoked before getting the frame to sync. - * @return true if the SCVH was successfully added to the current SyncGroup, false - * otherwise. + * @param surfacePackage The SurfacePackage that will be added to this SurfaceSyncGroup. + * @param runnable This is run on the same thread that the call was made on, but + * after the rendering is paused and before continuing to render + * the next frame. This method will not return until the + * execution of the runnable completes. This can be used to make + * changes to the SurfaceControlViewHost, ensuring that the + * changes are included in the sync. + * @return true if the SurfaceControlViewHost was successfully added to the current + * SurfaceSyncGroup, false otherwise. */ - public boolean addToSync(@NonNull SurfaceControlViewHost.SurfacePackage surfacePackage, + public boolean add(@NonNull SurfaceControlViewHost.SurfacePackage surfacePackage, @Nullable Runnable runnable) { ISurfaceSyncGroup surfaceSyncGroup; try { @@ -305,20 +325,31 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { + "SCVH returned null SurfaceSyncGroup"); return false; } - return addToSync(surfaceSyncGroup, false /* parentSyncGroupMerge */, runnable); + return add(surfaceSyncGroup, false /* parentSyncGroupMerge */, runnable); } - @Override - public boolean addToSync(ISurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge) { - return addToSync(surfaceSyncGroup, parentSyncGroupMerge, null); + /** + * Add a SurfaceSyncGroup to the current SurfaceSyncGroup. + * + * @param surfaceSyncGroup The SurfaceSyncGroup that will be added to this SurfaceSyncGroup. + * @param runnable This is run on the same thread that the call was made on, This + * method will not return until the execution of the runnable + * completes. This can be used to make changes to the SurfaceSyncGroup, + * ensuring that the changes are included in the sync. + * @return true if the requested SurfaceSyncGroup was successfully added to the + * SurfaceSyncGroup, false otherwise. + * @hide + */ + public boolean add(@NonNull SurfaceSyncGroup surfaceSyncGroup, + @Nullable Runnable runnable) { + return add(surfaceSyncGroup.mISurfaceSyncGroup, false /* parentSyncGroupMerge */, + runnable); } /** - * Add a {@link SurfaceSyncGroup} to a sync set. The sync set will wait for all - * SyncableSurfaces to complete before notifying. + * Add a {@link ISurfaceSyncGroup} to a SurfaceSyncGroup. * - * @param surfaceSyncGroup A SyncableSurface that implements how to handle syncing - * buffers. + * @param surfaceSyncGroup An ISyncableSurface that will be added to this SurfaceSyncGroup. * @param parentSyncGroupMerge true if the ISurfaceSyncGroup is added because its child was * added to a new SurfaceSyncGroup. That would require the code to * call newParent.addToSync(oldParent). When this occurs, we need to @@ -327,15 +358,20 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { * @param runnable The Runnable that's invoked before adding the SurfaceSyncGroup * @return true if the SyncGroup was successfully added to the current SyncGroup, false * otherwise. + * @hide */ - public boolean addToSync(ISurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge, + public boolean add(ISurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge, @Nullable Runnable runnable) { - Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "addToSync token=" + mToken.hashCode() + " parent=" + mName); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, + "addToSync token=" + mToken.hashCode() + " parent=" + mName); + } synchronized (mLock) { if (mSyncReady) { Log.w(TAG, "Trying to add to sync when already marked as ready " + mName); - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } return false; } } @@ -346,7 +382,9 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { if (isLocalBinder(surfaceSyncGroup.asBinder())) { boolean didAddLocalSync = addLocalSync(surfaceSyncGroup, parentSyncGroupMerge); - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } return didAddLocalSync; } @@ -365,14 +403,16 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { @Override public void onSurfaceSyncGroupComplete() { synchronized (mLock) { - invokeSyncCompleteListeners(); + invokeSyncCompleteCallbacks(); } } }; if (!addSyncToWm(mToken, false /* parentSyncGroupMerge */, mSurfaceSyncGroupCompletedListener)) { mSurfaceSyncGroupCompletedListener = null; - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } return false; } mHasWMSync = true; @@ -382,38 +422,35 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { try { surfaceSyncGroup.onAddedToSyncGroup(mToken, parentSyncGroupMerge); } catch (RemoteException e) { - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } return false; } - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } return true; } - @Override - public final boolean onAddedToSyncGroup(IBinder parentSyncGroupToken, - boolean parentSyncGroupMerge) { - Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "onAddedToSyncGroup token=" + parentSyncGroupToken.hashCode() + " child=" + mName); - boolean didAdd = addSyncToWm(parentSyncGroupToken, parentSyncGroupMerge, null); - Trace.traceEnd(Trace.TRACE_TAG_VIEW); - return didAdd; - } - - /** - * Add a Transaction to this sync set. This allows the caller to provide other info that - * should be synced with the transactions. + * Add a Transaction to this SurfaceSyncGroup. This allows the caller to provide other info that + * should be synced with the other transactions in this SurfaceSyncGroup. + * + * @param transaction The transaction to add to the SurfaceSyncGroup. */ - public void addTransactionToSync(Transaction t) { + public void addTransaction(@NonNull Transaction transaction) { synchronized (mLock) { - mTransaction.merge(t); + mTransaction.merge(transaction); } } /** * Invoked when the SurfaceSyncGroup has been added to another SurfaceSyncGroup and is ready * to proceed. + * + * @hide */ public void onSyncReady() { } @@ -425,23 +462,31 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { Log.d(TAG, "Attempting to add remote sync to " + mName + ". Setting up Sync in WindowManager."); } - Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "addSyncToWm=" + token.hashCode() + " group=" + mName); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, + "addSyncToWm=" + token.hashCode() + " group=" + mName); + } AddToSurfaceSyncGroupResult addToSyncGroupResult = new AddToSurfaceSyncGroupResult(); if (!WindowManagerGlobal.getWindowManagerService().addToSurfaceSyncGroup(token, parentSyncGroupMerge, surfaceSyncGroupCompletedListener, addToSyncGroupResult)) { - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } return false; } setTransactionCallbackFromParent(addToSyncGroupResult.mParentSyncGroup, addToSyncGroupResult.mTransactionReadyCallback); } catch (RemoteException e) { - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } return false; } - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } return true; } @@ -457,8 +502,10 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { return false; } - Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "addLocalSync=" + childSurfaceSyncGroup.mName + " parent=" + mName); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, + "addLocalSync=" + childSurfaceSyncGroup.mName + " parent=" + mName); + } ITransactionReadyCallback callback = createTransactionReadyCallback(parentSyncGroupMerge); @@ -466,8 +513,10 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { return false; } - childSurfaceSyncGroup.setTransactionCallbackFromParent(this, callback); - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + childSurfaceSyncGroup.setTransactionCallbackFromParent(mISurfaceSyncGroup, callback); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } return true; } @@ -477,9 +526,11 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { Log.d(TAG, "setTransactionCallbackFromParent " + mName); } boolean finished = false; - Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "setTransactionCallbackFromParent " + mName + " callback=" - + transactionReadyCallback.hashCode()); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, + "setTransactionCallbackFromParent " + mName + " callback=" + + transactionReadyCallback.hashCode()); + } synchronized (mLock) { if (mFinished) { finished = true; @@ -510,9 +561,11 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { Consumer<Transaction> lastCallback = mTransactionReadyConsumer; mParentSyncGroup = parentSyncGroup; mTransactionReadyConsumer = (transaction) -> { - Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "transactionReadyCallback " + mName + " callback=" - + transactionReadyCallback.hashCode()); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, + "transactionReadyCallback " + mName + " callback=" + + transactionReadyCallback.hashCode()); + } lastCallback.accept(null); try { @@ -520,7 +573,9 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { } catch (RemoteException e) { transaction.apply(); } - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } }; } } @@ -535,9 +590,14 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { } else { onSyncReady(); } - Trace.traceEnd(Trace.TRACE_TAG_VIEW); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } } + /** + * @hide + */ public String getName() { return mName; } @@ -552,9 +612,11 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { return; } - Trace.instant(Trace.TRACE_TAG_VIEW, - "checkIfSyncIsComplete " + mName + " mSyncReady=" + mSyncReady + " mPendingSyncs=" - + mPendingSyncs.size()); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.instant(Trace.TRACE_TAG_VIEW, + "checkIfSyncIsComplete " + mName + " mSyncReady=" + mSyncReady + + " mPendingSyncs=" + mPendingSyncs.size()); + } if (!mSyncReady || !mPendingSyncs.isEmpty()) { if (DEBUG) { @@ -574,7 +636,7 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { /** * Create an {@link ITransactionReadyCallback} that the current SurfaceSyncGroup will wait on * before completing. The caller must ensure that the - * {@link ITransactionReadyCallback#onTransactionReady(Transaction)} in order for this + * {@link ITransactionReadyCallback#onTransactionReady(Transaction)} is called in order for this * SurfaceSyncGroup to complete. * * @param parentSyncGroupMerge true if the ISurfaceSyncGroup is added because its child was @@ -582,6 +644,7 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { * call newParent.addToSync(oldParent). When this occurs, we need to * reverse the merge order because the oldParent should always be * considered older than any other SurfaceSyncGroups. + * @hide */ public ITransactionReadyCallback createTransactionReadyCallback(boolean parentSyncGroupMerge) { if (DEBUG) { @@ -603,9 +666,11 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { mTransaction.merge(t); } mPendingSyncs.remove(this); - Trace.instant(Trace.TRACE_TAG_VIEW, - "onTransactionReady group=" + mName + " callback=" - + hashCode()); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.instant(Trace.TRACE_TAG_VIEW, + "onTransactionReady group=" + mName + " callback=" + + hashCode()); + } checkIfSyncIsComplete(); } } @@ -618,19 +683,50 @@ public class SurfaceSyncGroup extends ISurfaceSyncGroup.Stub { return null; } mPendingSyncs.add(transactionReadyCallback); - Trace.instant(Trace.TRACE_TAG_VIEW, - "createTransactionReadyCallback " + mName + " mPendingSyncs=" - + mPendingSyncs.size() + " transactionReady=" - + transactionReadyCallback.hashCode()); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.instant(Trace.TRACE_TAG_VIEW, + "createTransactionReadyCallback " + mName + " mPendingSyncs=" + + mPendingSyncs.size() + " transactionReady=" + + transactionReadyCallback.hashCode()); + } } return transactionReadyCallback; } + private class ISurfaceSyncGroupImpl extends ISurfaceSyncGroup.Stub { + @Override + public boolean onAddedToSyncGroup(IBinder parentSyncGroupToken, + boolean parentSyncGroupMerge) { + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, + "onAddedToSyncGroup token=" + parentSyncGroupToken.hashCode() + " child=" + + mName); + } + boolean didAdd = addSyncToWm(parentSyncGroupToken, parentSyncGroupMerge, null); + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } + return didAdd; + } + + @Override + public boolean addToSync(ISurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge) { + return SurfaceSyncGroup.this.add(surfaceSyncGroup, parentSyncGroupMerge, + null /* runnable */); + } + + SurfaceSyncGroup getSurfaceSyncGroup() { + return SurfaceSyncGroup.this; + } + } + /** * A frame callback that is used to synchronize SurfaceViews. The owner of the SurfaceView must * implement onFrameStarted when trying to sync the SurfaceView. This is to ensure the sync * knows when the frame is ready to add to the sync. + * + * @hide */ public interface SurfaceViewFrameCallback { /** diff --git a/core/java/android/window/SurfaceSyncGroup.md b/core/java/android/window/SurfaceSyncGroup.md index 406c230ad920..04577a26190f 100644 --- a/core/java/android/window/SurfaceSyncGroup.md +++ b/core/java/android/window/SurfaceSyncGroup.md @@ -2,7 +2,7 @@ ### Overview -A generic way for data to be gathered so multiple surfaces can be synced. This is intended to be used with Views, SurfaceView, and any other surface that wants to be involved in a sync. This allows different parts of the Android system to synchronize different windows and layers themselves. +A generic way for data to be gathered so multiple surfaces can be synced. This is intended to be used with AttachedSurfaceControl, SurfaceView, SurfaceControlViewHost, and any other surface that wants to be involved in a sync. This allows different parts of the Android system to synchronize different windows and layers themselves. ### Code diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java index 5b0abd389e7d..b8446da3c5fc 100644 --- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java +++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java @@ -52,6 +52,7 @@ public abstract class AccessibilityTarget implements TargetOperations, OnTargetS private CharSequence mLabel; private Drawable mIcon; private String mKey; + private CharSequence mStateDescription; @VisibleForTesting public AccessibilityTarget(Context context, @ShortcutType int shortcutType, @@ -106,6 +107,10 @@ public abstract class AccessibilityTarget implements TargetOperations, OnTargetS } } + public void setStateDescription(CharSequence stateDescription) { + mStateDescription = stateDescription; + } + /** * Gets the state description of this feature target. * @@ -113,7 +118,7 @@ public abstract class AccessibilityTarget implements TargetOperations, OnTargetS */ @Nullable public CharSequence getStateDescription() { - return null; + return mStateDescription; } public void setShortcutEnabled(boolean enabled) { diff --git a/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java b/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java index 469d10ff98aa..41a0ba2b693a 100644 --- a/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java +++ b/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java @@ -41,6 +41,11 @@ class ToggleAccessibilityServiceTarget extends AccessibilityServiceTarget { shortcutType, AccessibilityFragmentType.TOGGLE, serviceInfo); + + final int statusResId = isAccessibilityServiceEnabled(getContext(), getId()) + ? R.string.accessibility_shortcut_menu_item_status_on + : R.string.accessibility_shortcut_menu_item_status_off; + setStateDescription(getContext().getString(statusResId)); } @Override @@ -53,12 +58,4 @@ class ToggleAccessibilityServiceTarget extends AccessibilityServiceTarget { holder.mStatusView.setVisibility(isEditMenuMode ? View.GONE : View.VISIBLE); holder.mStatusView.setText(getStateDescription()); } - - @Override - public CharSequence getStateDescription() { - final int statusResId = isAccessibilityServiceEnabled(getContext(), getId()) - ? R.string.accessibility_shortcut_menu_item_status_on - : R.string.accessibility_shortcut_menu_item_status_off; - return getContext().getString(statusResId); - } } diff --git a/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java b/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java index ebdaed6dbe39..d2124a00596f 100644 --- a/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java +++ b/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java @@ -38,6 +38,11 @@ class ToggleAllowListingFeatureTarget extends AccessibilityTarget { boolean isShortcutSwitched, String id, CharSequence label, Drawable icon, String key) { super(context, shortcutType, AccessibilityFragmentType.TOGGLE, isShortcutSwitched, id, label, icon, key); + + final int statusResId = isFeatureEnabled() + ? R.string.accessibility_shortcut_menu_item_status_on + : R.string.accessibility_shortcut_menu_item_status_off; + setStateDescription(getContext().getString(statusResId)); } @Override @@ -51,14 +56,6 @@ class ToggleAllowListingFeatureTarget extends AccessibilityTarget { holder.mStatusView.setText(getStateDescription()); } - @Override - public CharSequence getStateDescription() { - final int statusResId = isFeatureEnabled() - ? R.string.accessibility_shortcut_menu_item_status_on - : R.string.accessibility_shortcut_menu_item_status_off; - return getContext().getString(statusResId); - } - private boolean isFeatureEnabled() { return Settings.Secure.getInt(getContext().getContentResolver(), getKey(), /* settingsValueOff */ 0) == /* settingsValueOn */ 1; diff --git a/core/java/com/android/internal/os/IBinaryTransparencyService.aidl b/core/java/com/android/internal/os/IBinaryTransparencyService.aidl index ca7b83ed44f5..e782aa7643a1 100644 --- a/core/java/com/android/internal/os/IBinaryTransparencyService.aidl +++ b/core/java/com/android/internal/os/IBinaryTransparencyService.aidl @@ -16,6 +16,8 @@ package com.android.internal.os; +import android.os.Bundle; + /** * "Backend" interface used by {@link android.os.BinaryTransparencyManager} to talk to the * BinaryTransparencyService that actually implements the measurement and information aggregation @@ -36,6 +38,9 @@ interface IBinaryTransparencyService { byte[] digest; int digestAlgorithm; String[] signerDigests; + + // Test only + String moduleName; } parcelable AppInfo { @@ -51,4 +56,8 @@ interface IBinaryTransparencyService { String installer; String originator; } + + /** Test only */ + List<ApexInfo> collectAllApexInfo(boolean includeTestOnly); + List<AppInfo> collectAllUpdatedPreloadInfo(in Bundle packagesToSkip); }
\ No newline at end of file diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index d9cb72a5daa1..cee8c1a47769 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -178,7 +178,14 @@ public final class Zygote { * GWP-ASan is activated unconditionally (but still, only a small subset of * allocations is protected). */ - public static final int GWP_ASAN_LEVEL_ALWAYS = 1 << 22; + public static final int GWP_ASAN_LEVEL_ALWAYS = 2 << 21; + + /** + * GWP-ASan's `gwpAsanMode` manifest flag was unspecified. Currently, this + * means GWP_ASAN_LEVEL_LOTTERY for system apps, and GWP_ASAN_LEVEL_NONE for + * non-system apps. + */ + public static final int GWP_ASAN_LEVEL_DEFAULT = 3 << 21; /** Enable automatic zero-initialization of native heap memory allocations. */ public static final int NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23; @@ -1356,15 +1363,13 @@ public final class Zygote { ? GWP_ASAN_LEVEL_ALWAYS : GWP_ASAN_LEVEL_NEVER; } - // If the app does not specify gwpAsanMode, the default behavior is lottery among the - // system apps, and disabled for user apps, unless overwritten by the compat feature. if (isCompatChangeEnabled(GWP_ASAN, info, platformCompat, 0)) { return GWP_ASAN_LEVEL_ALWAYS; } if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { return GWP_ASAN_LEVEL_LOTTERY; } - return GWP_ASAN_LEVEL_NEVER; + return GWP_ASAN_LEVEL_DEFAULT; } private static boolean enableNativeHeapZeroInit( diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java index 5adbc583140f..e56c381ead33 100644 --- a/core/java/com/android/internal/widget/LockPatternChecker.java +++ b/core/java/com/android/internal/widget/LockPatternChecker.java @@ -1,7 +1,10 @@ package com.android.internal.widget; +import static android.provider.DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION; + import android.annotation.NonNull; import android.os.AsyncTask; +import android.provider.DeviceConfig; import com.android.internal.widget.LockPatternUtils.RequestThrottledException; @@ -117,6 +120,10 @@ public final class LockPatternChecker { @Override protected void onPostExecute(Boolean result) { callback.onChecked(result, mThrottleTimeout); + if (DeviceConfig.getBoolean(NAMESPACE_AUTO_PIN_CONFIRMATION, + "enable_auto_pin_confirmation", false)) { + utils.setPinLength(userId, credentialCopy.size()); + } credentialCopy.zeroize(); } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 86fd9569c61e..2f514795f342 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -48,6 +48,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManager; +import android.provider.DeviceConfig; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; @@ -151,6 +152,8 @@ public class LockPatternUtils { @Deprecated public final static String LOCKSCREEN_WIDGETS_ENABLED = "lockscreen.widgets_enabled"; + public static final String PIN_LENGTH = "lockscreen.pin_length"; + public final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory"; private static final String LOCK_SCREEN_OWNER_INFO = Settings.Secure.LOCK_SCREEN_OWNER_INFO; @@ -163,9 +166,17 @@ public class LockPatternUtils { private static final String KNOWN_TRUST_AGENTS = "lockscreen.knowntrustagents"; private static final String IS_TRUST_USUALLY_MANAGED = "lockscreen.istrustusuallymanaged"; + private static final String AUTO_PIN_CONFIRM = "lockscreen.auto_pin_confirm"; + public static final String CURRENT_LSKF_BASED_PROTECTOR_ID_KEY = "sp-handle"; public static final String PASSWORD_HISTORY_DELIMITER = ","; + /** + * drives the pin auto confirmation feature availability in code logic. + */ + public static final String FLAG_ENABLE_AUTO_PIN_CONFIRMATION = + "AutoPinConfirmation__enable_auto_pin_confirmation"; + @UnsupportedAppUsage private final Context mContext; @UnsupportedAppUsage @@ -566,6 +577,24 @@ public class LockPatternUtils { } /** + * Used for setting the length of the PIN set by a particular user. + * @param userId user id of the user whose pin length we save + * @param val value of length of pin + */ + public void setPinLength(int userId, long val) { + setLong(PIN_LENGTH, val, userId); + } + + /** + * Returns the length of the PIN set by a particular user. + * @param userId user id of the user whose pin length we have to return + * @return the length of the pin set by user and -1 if nothing + */ + public long getPinLength(int userId) { + return getLong(PIN_LENGTH, -1, userId); + } + + /** * Records that the user has chosen a pattern at some time, even if the pattern is * currently cleared. */ @@ -627,6 +656,38 @@ public class LockPatternUtils { || isDemoUser; } + /** + * Sets the pin auto confirm capability to enabled or disabled + * @param enabled enables pin auto confirm capability when true + * @param userId user ID of the user this has effect on + */ + public void setAutoPinConfirm(boolean enabled, int userId) { + setBoolean(AUTO_PIN_CONFIRM, enabled, userId); + } + + /** + * Determines if the auto pin confirmation feature is enabled or not for current user + * If setting is not available, the default behaviour is disabled + * @param userId user ID of the user this has effect on + * + * @return true, if the entered pin should be auto confirmed + */ + public boolean isAutoPinConfirmEnabled(int userId) { + return getBoolean(AUTO_PIN_CONFIRM, /* defaultValue= */ false, userId); + } + + /** + * Whether the auto pin feature logic is available or not. + * @return true, if deviceConfig flag is set to true or the flag is not propagated and + * defaultValue is true. + */ + public boolean isAutoPinConfirmFeatureAvailable() { + return DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION, + FLAG_ENABLE_AUTO_PIN_CONFIRMATION, + /* defaultValue= */ false); + } + /** Returns if the given quality maps to an alphabetic password */ public static boolean isQualityAlphabeticPassword(int quality) { return quality >= PASSWORD_QUALITY_ALPHABETIC; diff --git a/core/jni/Android.bp b/core/jni/Android.bp index eca85ffe9d80..82f414bfd4d9 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -266,7 +266,6 @@ cc_library_shared { "av-types-aidl-cpp", "android.hardware.camera.device@3.2", "libandroid_net", - "libandroidicu", "libbattery", "libnetdutils", "libmemtrack", @@ -287,6 +286,7 @@ cc_library_shared { "libPlatformProperties", "libsensor", "libinput", + "libicu", "libcamera_client", "libcamera_metadata", "libprocinfo", @@ -326,6 +326,7 @@ cc_library_shared { "libdl", "libdl_android", "libtimeinstate", + "libtflite", "server_configurable_flags", "libimage_io", "libjpegdecoder", @@ -343,7 +344,9 @@ cc_library_shared { header_libs: [ "bionic_libc_platform_headers", "dnsproxyd_protocol_headers", + "flatbuffer_headers", "libtextclassifier_hash_headers", + "tensorflow_headers", ], runtime_libs: [ "libidmap2", diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 225ed2cff762..97a0f50e760d 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -246,6 +246,17 @@ static struct { jmethodID invokeReleaseCallback; } gSurfaceControlClassInfo; +static struct { + jclass clazz; + jfieldID mMinAlpha; + jfieldID mMinFractionRendered; + jfieldID mStabilityRequirementMs; +} gTrustedPresentationThresholdsClassInfo; + +static struct { + jmethodID onTrustedPresentationChanged; +} gTrustedPresentationCallbackClassInfo; + constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) { switch (colorMode) { case ui::ColorMode::DISPLAY_P3: @@ -328,6 +339,47 @@ private: } }; +class TrustedPresentationCallbackWrapper { +public: + explicit TrustedPresentationCallbackWrapper(JNIEnv* env, jobject trustedPresentationListener) { + env->GetJavaVM(&mVm); + mTrustedPresentationCallback = env->NewGlobalRef(trustedPresentationListener); + LOG_ALWAYS_FATAL_IF(!mTrustedPresentationCallback, "Failed to make global ref"); + } + + ~TrustedPresentationCallbackWrapper() { + getenv()->DeleteGlobalRef(mTrustedPresentationCallback); + } + + void onTrustedPresentationChanged(bool inTrustedPresentationState) { + JNIEnv* env = getenv(); + env->CallVoidMethod(mTrustedPresentationCallback, + gTrustedPresentationCallbackClassInfo.onTrustedPresentationChanged, + inTrustedPresentationState); + } + + void addCallbackRef(const sp<SurfaceComposerClient::PresentationCallbackRAII>& callbackRef) { + mCallbackRef = callbackRef; + } + + static void onTrustedPresentationChangedThunk(void* context, bool inTrustedPresentationState) { + TrustedPresentationCallbackWrapper* listener = + reinterpret_cast<TrustedPresentationCallbackWrapper*>(context); + listener->onTrustedPresentationChanged(inTrustedPresentationState); + } + +private: + jobject mTrustedPresentationCallback; + JavaVM* mVm; + sp<SurfaceComposerClient::PresentationCallbackRAII> mCallbackRef; + + JNIEnv* getenv() { + JNIEnv* env; + mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6); + return env; + } +}; + // ---------------------------------------------------------------------------- static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) { @@ -1806,6 +1858,42 @@ static void nativeAddTransactionCommittedListener(JNIEnv* env, jclass clazz, jlo context); } +static void nativeSetTrustedPresentationCallback(JNIEnv* env, jclass clazz, jlong transactionObj, + jlong nativeObject, + jlong trustedPresentationCallbackObject, + jobject trustedPresentationThresholds) { + auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); + auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject); + + TrustedPresentationThresholds thresholds; + thresholds.minAlpha = env->GetFloatField(trustedPresentationThresholds, + gTrustedPresentationThresholdsClassInfo.mMinAlpha); + thresholds.minFractionRendered = + env->GetFloatField(trustedPresentationThresholds, + gTrustedPresentationThresholdsClassInfo.mMinFractionRendered); + thresholds.stabilityRequirementMs = + env->GetIntField(trustedPresentationThresholds, + gTrustedPresentationThresholdsClassInfo.mStabilityRequirementMs); + + sp<SurfaceComposerClient::PresentationCallbackRAII> callbackRef; + TrustedPresentationCallbackWrapper* wrapper = + reinterpret_cast<TrustedPresentationCallbackWrapper*>( + trustedPresentationCallbackObject); + transaction->setTrustedPresentationCallback(ctrl, + TrustedPresentationCallbackWrapper:: + onTrustedPresentationChangedThunk, + thresholds, wrapper, callbackRef); + wrapper->addCallbackRef(callbackRef); +} + +static void nativeClearTrustedPresentationCallback(JNIEnv* env, jclass clazz, jlong transactionObj, + jlong nativeObject) { + auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); + auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject); + + transaction->clearTrustedPresentationCallback(ctrl); +} + class JankDataListenerWrapper : public JankDataListener { public: JankDataListenerWrapper(JNIEnv* env, jobject onJankDataListenerObject) { @@ -1919,6 +2007,21 @@ static jboolean nativeBootFinished(JNIEnv* env, jclass clazz) { return error == OK ? JNI_TRUE : JNI_FALSE; } +jlong nativeCreateTpc(JNIEnv* env, jclass clazz, jobject trustedPresentationCallback) { + return reinterpret_cast<jlong>( + new TrustedPresentationCallbackWrapper(env, trustedPresentationCallback)); +} + +void destroyNativeTpc(void* ptr) { + TrustedPresentationCallbackWrapper* callback = + reinterpret_cast<TrustedPresentationCallbackWrapper*>(ptr); + delete callback; +} + +static jlong getNativeTrustedPresentationCallbackFinalizer(JNIEnv* env, jclass clazz) { + return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyNativeTpc)); +} + // ---------------------------------------------------------------------------- SurfaceControl* android_view_SurfaceControl_getNativeSurfaceControl(JNIEnv* env, @@ -2145,6 +2248,10 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetDropInputMode }, {"nativeAddTransactionCommittedListener", "(JLandroid/view/SurfaceControl$TransactionCommittedListener;)V", (void*) nativeAddTransactionCommittedListener }, + {"nativeSetTrustedPresentationCallback", "(JJJLandroid/view/SurfaceControl$TrustedPresentationThresholds;)V", + (void*) nativeSetTrustedPresentationCallback }, + {"nativeClearTrustedPresentationCallback", "(JJ)V", + (void*) nativeClearTrustedPresentationCallback }, {"nativeSanitize", "(J)V", (void*) nativeSanitize }, {"nativeSetDestinationFrame", "(JJIIII)V", @@ -2155,6 +2262,9 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeGetDefaultApplyToken }, {"nativeBootFinished", "()Z", (void*)nativeBootFinished }, + {"nativeCreateTpc", "(Landroid/view/SurfaceControl$TrustedPresentationCallback;)J", + (void*)nativeCreateTpc}, + {"getNativeTrustedPresentationCallbackFinalizer", "()J", (void*)getNativeTrustedPresentationCallbackFinalizer }, // clang-format on }; @@ -2381,6 +2491,23 @@ int register_android_view_SurfaceControl(JNIEnv* env) gTransactionClassInfo.mNativeObject = GetFieldIDOrDie(env, gTransactionClassInfo.clazz, "mNativeObject", "J"); + jclass trustedPresentationThresholdsClazz = + FindClassOrDie(env, "android/view/SurfaceControl$TrustedPresentationThresholds"); + gTrustedPresentationThresholdsClassInfo.clazz = + MakeGlobalRefOrDie(env, trustedPresentationThresholdsClazz); + gTrustedPresentationThresholdsClassInfo.mMinAlpha = + GetFieldIDOrDie(env, trustedPresentationThresholdsClazz, "mMinAlpha", "F"); + gTrustedPresentationThresholdsClassInfo.mMinFractionRendered = + GetFieldIDOrDie(env, trustedPresentationThresholdsClazz, "mMinFractionRendered", "F"); + gTrustedPresentationThresholdsClassInfo.mStabilityRequirementMs = + GetFieldIDOrDie(env, trustedPresentationThresholdsClazz, "mStabilityRequirementMs", + "I"); + + jclass trustedPresentationCallbackClazz = + FindClassOrDie(env, "android/view/SurfaceControl$TrustedPresentationCallback"); + gTrustedPresentationCallbackClassInfo.onTrustedPresentationChanged = + GetMethodIDOrDie(env, trustedPresentationCallbackClazz, "onTrustedPresentationChanged", + "(Z)V"); return err; } diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 664e964f09ef..6a92581f4040 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -353,6 +353,7 @@ enum RuntimeFlags : uint32_t { GWP_ASAN_LEVEL_NEVER = 0 << 21, GWP_ASAN_LEVEL_LOTTERY = 1 << 21, GWP_ASAN_LEVEL_ALWAYS = 2 << 21, + GWP_ASAN_LEVEL_DEFAULT = 3 << 21, NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23, PROFILEABLE = 1 << 24, }; @@ -1932,6 +1933,13 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, gwp_asan_options.program_name = nice_name_ptr ?: process_name; switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) { default: + case RuntimeFlags::GWP_ASAN_LEVEL_DEFAULT: + // TODO(b/247012630): Switch this to Action::TURN_ON_FOR_APP_SAMPLED_NON_CRASHING once + // performance and syshealth testing is completed, making the default for non-system + // apps that don't specify a `gwpAsanMode` in their manifest to be sampled-recoverable. + gwp_asan_options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN; + android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); + break; case RuntimeFlags::GWP_ASAN_LEVEL_NEVER: gwp_asan_options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN; android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); diff --git a/core/proto/android/providers/settings/system.proto b/core/proto/android/providers/settings/system.proto index e56d55e940e4..146ac9d2c425 100644 --- a/core/proto/android/providers/settings/system.proto +++ b/core/proto/android/providers/settings/system.proto @@ -195,6 +195,17 @@ message SystemSettingsProto { optional Text text = 29; optional SettingProto time_12_24 = 30 [ (android.privacy).dest = DEST_AUTOMATIC ]; + + message Touchpad { + option (android.msg_privacy).dest = DEST_EXPLICIT; + + optional SettingProto natural_scrolling = 1 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto pointer_speed = 2 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto right_click_zone = 3 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto tap_to_click = 4 [ (android.privacy).dest = DEST_AUTOMATIC ]; + } + optional Touchpad touchpad = 36; + optional SettingProto tty_mode = 31 [ (android.privacy).dest = DEST_AUTOMATIC ]; message Vibrate { @@ -252,5 +263,5 @@ message SystemSettingsProto { // Please insert fields in alphabetical order and group them into messages // if possible (to avoid reaching the method limit). - // Next tag = 36; + // Next tag = 37; } diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto index b112e7a366bf..82e1777ab7cb 100644 --- a/core/proto/android/server/windowmanagerservice.proto +++ b/core/proto/android/server/windowmanagerservice.proto @@ -117,7 +117,7 @@ message KeyguardControllerProto { repeated KeyguardOccludedProto keyguard_occluded_states = 2 [deprecated=true]; optional bool aod_showing = 3; repeated KeyguardPerDisplayProto keyguard_per_display = 4; - optional bool keyguard_going_away = 5 [deprecated=true]; + optional bool keyguard_going_away = 5; } message KeyguardOccludedProto { @@ -134,7 +134,7 @@ message KeyguardPerDisplayProto { optional bool keyguard_showing = 2; optional bool aod_showing = 3; optional bool keyguard_occluded = 4; - optional bool keyguard_going_away = 5 [deprecated=true]; + optional bool keyguard_going_away = 5; } /* represents PhoneWindowManager */ diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 7d69d5675eab..81c7fba61704 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1026,6 +1026,11 @@ android:permissionFlags="hardRestricted" android:protectionLevel="dangerous" /> + <!-- @SystemApi @hide Allows an application to communicate over satellite. + Only granted if the application is a system app. --> + <permission android:name="android.permission.SATELLITE_COMMUNICATION" + android:protectionLevel="internal|role" /> + <!-- ====================================================================== --> <!-- Permissions for accessing external storage --> <!-- ====================================================================== --> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 2652da6ef9fd..76a4da025756 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl die program gebruik word."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program op agtergrond is"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl dit op die agtergrond is."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Lees kalendergebeurtenisse en -besonderhede"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Hierdie program kan alle kalendergebeurtenisse lees wat op jou tablet geberg is of jou kalenderdata stoor."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Hierdie program kan alle kalendergeleenthede wat op jou Android TV-toestel geberg is, lees of jou kalenderdata stoor."</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index d47bcabaf8de..39e010e4690d 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"መተግበሪያው ስራ ላይ በሚውልበት ጊዜ እንደ የልብ ምት፣ የሙቀት መጠን እና የደም ኦክሲጅን መቶኛ ያለ የሰውነት ዳሳሽ ውሂብን እንዲደርስ ያስችለዋል።"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ከበስተጀርባ እያለ እንደ የልብ ምት ያለ የሰውነት ዳሳሽ ውሂብን መድረስ"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"መተግበሪያው ከበስተጀርባ እያለ እንደ የልብ ምት፣ የሙቀት መጠን እና የደም ኦክሲጅን መቶኛ ያለ የሰውነት ዳሳሽ ውሂብን እንዲደርስ ያስችለዋል።"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"የቀን መቁጠሪያ ክስተቶችን እና ዝርዝሮችን አንብብ"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ይህ መተግበሪያ ሁሉንም በእርስዎ ጡባዊ ላይ የተከማቹ የቀን መቁጠሪያ ክስተቶችን ማንበብ ወይም የእርስዎን የቀን መቁጠሪያ ውሂብ ማስቀመጥ ይችላል።"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ይህ መተግበሪያ ሁሉንም በእርስዎ Android TV መሣሪያ ላይ የተከማቹ የቀን መቁጠሪያ ክስተቶችን ማንበብ ወይም የእርስዎን የቀን መቁጠሪያ ውሂብ ማስቀመጥ ይችላል።"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index b443e454e117..5a64dbe9c37f 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -462,6 +462,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"يتيح هذا الإذن للتطبيق بالوصول إلى بيانات أجهزة استشعار الجسم، مثل معدّل نبضات القلب ودرجة الحرارة ونسبة الأكسجين في الدم، وذلك عندما يكون التطبيق قيد الاستخدام."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"الوصول في الخلفية إلى بيانات استشعار الجسم، مثل معدّل نبضات القلب"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"يتيح هذا الإذن للتطبيق الوصول إلى بيانات أجهزة استشعار الجسم، مثل معدّل نبضات القلب ودرجة الحرارة ونسبة الأكسجين في الدم، وذلك عند استخدام التطبيق في الخلفية."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"قراءة أحداث التقويم والتفاصيل"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"يمكن لهذا التطبيق قراءة جميع أحداث التقويم المخزَّنة على الجهاز اللوحي ومشاركة بيانات التقويم أو حفظها."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"يمكن لهذا التطبيق قراءة جميع أحداث التقويم المخزَّنة على جهاز Android TV ومشاركة بيانات التقويم أو حفظها."</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index e39a7834a112..608e6284f20d 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"এপ্টো ব্যৱহাৰ কৰি থকাৰ সময়ত এপ্টোক হৃদস্পন্দনৰ হাৰ, উষ্ণতা আৰু তেজত অক্সিজেনৰ শতকৰা হাৰৰ দৰে শৰীৰৰ ছেন্সৰৰ ডেটা এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"নেপথ্যত থকাৰ সময়ত হৃদস্পন্দনৰ হাৰৰ দৰে শৰীৰৰ ছেন্সৰৰ ডেটা এক্সেছ কৰক"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"এপ্টো নেপথ্যত থকাৰ সময়ত এপ্টোক হৃদস্পন্দনৰ হাৰ, উষ্ণতা আৰু তেজত অক্সিজেনৰ শতকৰা হাৰৰ দৰে শৰীৰৰ ছেন্সৰৰ ডেটা এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"কেলেণ্ডাৰৰ কাৰ্যক্ৰম আৰু সবিশেষ পঢ়িব পাৰে"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"এই এপ্টোৱে আপোনাৰ টেবলেটটোত সংৰক্ষিত আটাইবোৰ কেলেণ্ডাৰ কাৰ্যক্ৰম পঢ়িব পাৰে আৰু আপোনাৰ কেলেণ্ডাৰৰ ডেটা শ্বেয়াৰ বা ছেভ কৰিব পাৰে।"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"এই এপ্টোৱে আপোনাৰ Android TV ডিভাইচটোত ষ্ট’ৰ কৰি ৰখা আটাইবোৰ কেলেণ্ডাৰৰ অনুষ্ঠান পঢ়িব পাৰে আৰু আপোনাৰ কেলেণ্ডাৰৰ ডেটা শ্বেয়াৰ অথবা ছেভ কৰিব পাৰে।"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 73bf38b8219a..40af5eb7dcc3 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Tətbiqə istifadə zamanı ürək döyüntüsü, temperatur və qanda oksigen faizi kimi bədən sensoru datasına giriş icazəsi verir."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Arxa fonda olarkən ürək döyüntüsü kimi bədən sensoru datasına giriş"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Tətbiqə arxa fonda olarkən ürək döyüntüsü, temperatur və qanda oksigen faizi kimi bədən sensoru datasına giriş icazəsi verir."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Təqvim təqdirləri və detallarını oxuyun"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Bu tətbiq planşetdə yerləşdirilmiş və təqvim datasında yadda saxlanmış bütün təqvim tədbirlərini oxuya bilər."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Bu tətbiq Android TV cihazında saxlanılan bütün təqvim tədbirlərini oxuya, həmçinin təqvim datasını paylaşa və ya yadda saxlaya bilər."</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 237aea242064..0f39f41dcd26 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Dozvoljava aplikaciji da pristupa podacima senzora za telo, kao što su puls, temperatura i procenat kiseonika u krvi dok se aplikacija koristi."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pristup podacima senzora za telo, kao što je puls, u pozadini"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Dozvoljava aplikaciji da pristupa podacima senzora za telo, kao što su puls, temperatura i procenat kiseonika u krvi dok je aplikacija u pozadini."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Čitanje događaja i podataka iz kalendara"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na tabletu, kao i da deli ili čuva podatke iz kalendara."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na Android TV uređaju, kao i da deli ili čuva podatke iz kalendara."</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index aae5f565da2a..6d1135fb6983 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -460,6 +460,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Праграма ў час яе выкарыстання будзе мець доступ да даных датчыкаў цела, такіх як пульс, тэмпература і працэнт утрымання ў крыві кіслароду."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Доступ да даных датчыкаў цела, такіх як пульс, у фонавым рэжыме"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Праграма ў час яе працы ў фонавым рэжыме будзе мець доступ да даных датчыкаў цела, такіх як пульс, тэмпература і працэнт утрымання ў крыві кіслароду."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Чытаць падзеі календара і падрабязныя звесткі"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Гэта праграма можа чытаць усе падзеі календара, захаваныя на вашым планшэце, і абагульваць ці захоўваць даныя календара."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Гэта праграма можа счытваць усе падзеі календара, захаваныя на прыладзе Android TV, і абагульваць ці захоўваць яго даныя."</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index f4d6749d1a92..cfe18d4739a8 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Разрешава на приложението да осъществява достъп до данните от сензорите за тяло, като например тези за сърдечен ритъм, температура и процент на кислорода в кръвта, докато то се използва."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Достъп до данните от сензорите за тяло (напр. за сърдечен ритъм) на заден план"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Разрешава на приложението да осъществява достъп до данните от сензорите за тяло, като например тези за сърдечен ритъм, температура и процент на кислорода в кръвта, докато то се изпълнява на заден план."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Четене на събития и подробности от календара"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Това приложение може да чете всички съхранявани на таблета ви събития в календара и да споделя или запазва данни в календара ви."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Това приложение може да чете всички съхранявани на устройството ви с Android TV събития в календара и да споделя или запазва данни в календара ви."</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index e669b6d17dc1..e02d75da3d68 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"এই অ্যাপ ব্যবহার করার সময় বডি সেন্সর ডেটা অ্যাক্সেস করার অনুমতি দেওয়া হয়। এর মধ্যে হার্ট রেট, তাপমাত্রা এবং রক্তে অক্সিজেনের পরিমাণের শতাংশ সম্পর্কিত তথ্যও আছে।"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"অ্যাপ ব্যাকগ্রাউন্ডে চলার সময়, হার্ট রেটের মতো বডি সেন্সর ডেটার অ্যাক্সেস দিন"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"এই অ্যাপ ব্যাকগ্রাউন্ডে চলার সময় বডি সেন্সর ডেটা অ্যাক্সেস করার অনুমতি দেওয়া হয়। এর মধ্যে হার্ট রেট, তাপমাত্রা এবং রক্তে অক্সিজেনের পরিমাণের শতাংশ সম্পর্কিত তথ্যও আছে।"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"ক্যালেন্ডারের ইভেন্ট এবং বিশদ বিবরণ পড়ুন"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"এই অ্যাপটি আপনার ট্যাবলেটে সংরক্ষিত সমস্ত ক্যালেন্ডার ইভেন্ট পড়তে এবং আপনার ক্যালেন্ডারের ডেটা শেয়ার বা সংরক্ষণ করতে পারে৷"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"এই অ্যাপ আপনার Android TV ডিভাইসে সেভ করা সব ক্যালেন্ডার ইভেন্ট পড়তে পারে এবং আপনার ক্যালেন্ডারের ডেটা শেয়ার বা সেভ করতে পারে।"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 1e887664db2b..3c1925b5086f 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Dozvoljava aplikaciji dok se koristi da pristupa podacima tjelesnih senzora kao što su puls, temperatura i postotak kisika u krvi."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pristup podacima tjelesnih senzora, kao što je puls, dok je u pozadini"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Dozvoljava aplikaciji dok je u pozadini da pristupa podacima tjelesnih senzora kao što su puls, temperatura i postotak kisika u krvi."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Čitanje događaja kalendara i detalja"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ova aplikacija može čitati sve događaje u kalendaru pohranjene na vašem tabletu i sačuvati podatke kalendara."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ova aplikacija može čitati sve događaje u kalendaru na vašem Android TV uređaju i dijeliti ili sačuvati podatke kalendara."</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 5843095e8075..41496a582888 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet que l\'aplicació accedeixi a les dades del sensor corporal, com ara la freqüència cardíaca, la temperatura i el percentatge d\'oxigen a la sang, mentre s\'utilitza."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accedir a dades del sensor corporal, com la freqüència cardíaca, en segon pla"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet que l\'aplicació accedeixi a les dades del sensor corporal, com ara la freqüència cardíaca, la temperatura i el percentatge d\'oxigen a la sang, mentre es troba en segon pla."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Aquesta aplicació pot llegir els esdeveniments i la informació del calendari"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aquesta aplicació pot llegir tots els esdeveniments del calendari emmagatzemats a la tauleta i compartir o desar les dades del teu calendari."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aquesta aplicació pot llegir tots els esdeveniments del calendari emmagatzemats al dispositiu Android TV i compartir o desar les dades del calendari."</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 7e864a4291fd..2e2c3e25b619 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -460,6 +460,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Poskytuje aplikaci přístup k datům z tělesných senzorů, jako je tepová frekvence, teplota a procento nasycení krve kyslíkem, během používání aplikace."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Přístup k datům z tělesných senzorů, jako je tepová frekvence, při běhu na pozadí"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Poskytuje aplikaci přístup k datům z tělesných senzorů, jako je tepová frekvence, teplota a procento nasycení krve kyslíkem, při běhu na pozadí."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Čtení událostí v kalendáři včetně podrobností"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Tato aplikace může číst všechny události v kalendáři uložené v tabletu a sdílet či ukládat data kalendáře."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Tato aplikace může číst všechny události v kalendáři uložené v zařízení Android TV a sdílet či ukládat data kalendáře."</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 29cb8189edf8..7bd5556fb27a 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Tillader, at appen kan få adgang til kropssensordata, f.eks. pulsen, temperaturen og iltmætningen af blodet, mens appen er i brug."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Få adgang til kropssensordata, f.eks. pulsen, mens appen er i baggrunden"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Tillader, at appen kan få adgang til kropssensordata, f.eks. pulsen, temperaturen og iltmætningen af blodet, mens appen er i baggrunden."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Læs kalenderbegivenheder og -info"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Denne app kan læse alle kalenderbegivenheder, der er gemt på din tablet, og dele eller gemme dine kalenderdata."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Denne app kan læse alle kalenderbegivenheder, der er gemt på din Android TV-enhed, og dele eller gemme dine kalenderdata."</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 29703a52b268..bf79e1387974 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ermöglicht der App den Zugriff auf Daten des Körpersensors, etwa solche zur Herzfrequenz, zur Temperatur und zum Blutsauerstoffanteil, während die App in Benutzung ist."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Zugriff auf Daten des Körpersensors, etwa Herzfrequenz, wenn im Hintergrund"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ermöglicht der App den Zugriff auf Daten des Körpersensors, etwa solche zur Herzfrequenz, zur Temperatur und zum Blutsauerstoffanteil, während die App im Hintergrund ist."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Kalendertermine und Details lesen"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Diese App kann alle auf deinem Tablet gespeicherten Kalendertermine lesen und deine Kalenderdaten teilen oder speichern."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Diese App kann alle auf deinem Android TV-Gerät gespeicherten Kalendertermine lesen und die Kalenderdaten teilen oder speichern."</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 185308fa4384..e17f78fb29df 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Επιτρέπει στην εφαρμογή να αποκτά πρόσβαση σε δεδομένα αισθητήρων σώματος, όπως καρδιακό ρυθμό, θερμοκρασία και ποσοστό οξυγόνου στο αίμα, ενώ η εφαρμογή χρησιμοποιείται."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Πρόσβαση σε δεδομένα αισθητήρων σώματος, όπως καρδιακό ρυθμό, στο παρασκήνιο"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Επιτρέπει στην εφαρμογή να αποκτά πρόσβαση σε δεδομένα αισθητήρων σώματος, όπως καρδιακό ρυθμό, θερμοκρασία και ποσοστό οξυγόνου στο αίμα, ενώ η εφαρμογή βρίσκεται στο παρασκήνιο."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Ανάγνωση συμβάντων ημερολογίου και λεπτομερειών"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Αυτή η εφαρμογή μπορεί να διαβάσει όλα τα συμβάντα ημερολογίου που είναι αποθηκευμένα στο tablet που χρησιμοποιείτε και να μοιραστεί ή να αποθηκεύσει τα δεδομένα ημερολογίου σας."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Αυτή η εφαρμογή μπορεί να διαβάσει όλα τα συμβάντα ημερολογίου που είναι αποθηκευμένα στη συσκευή Android TV και να μοιραστεί ή να αποθηκεύσει τα δεδομένα ημερολογίου σας."</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 94bdb0168551..04cdfd99c38b 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in use."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in the background."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 599d6fcf2f75..cbe80136b754 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in use."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in the background."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index b52f527e036c..a43067a15953 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in use."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in the background."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index dce46b43d2d5..02bea3d29d4b 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in use."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in the background."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index b18ee987f5cd..d111611e4b27 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in use."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in the background."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 93b4dc80b9ff..dad02310d5e8 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que la app acceda a datos del sensor corporal, como el ritmo cardíaco, la temperatura y el porcentaje de oxígeno en sangre, mientras la app está en uso."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accede a datos del sensor corporal, como el ritmo cardíaco, en segundo plano"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que la app acceda a datos del sensor corporal, como el ritmo cardíaco, la temperatura y el porcentaje de oxígeno en sangre, mientras la app está en segundo plano."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Leer eventos y detalles del calendario"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta app puede leer todos los eventos del calendario de tu tablet y compartir o guardar los datos correspondientes."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta app puede leer todos los eventos del calendario guardados en el dispositivo Android TV, así como compartir o almacenar los datos correspondientes."</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index caefd2c1da1e..abec04bca253 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que la aplicación acceda a datos del sensor corporal, como la frecuencia cardiaca, la temperatura y el porcentaje de oxígeno en sangre, mientras se usa."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acceso en segundo plano a datos del sensor corporal, como la frecuencia cardiaca"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que la aplicación acceda a datos del sensor corporal, como la frecuencia cardiaca, la temperatura y el porcentaje de oxígeno en sangre, mientras está en segundo plano."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Leer eventos y detalles del calendario"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta aplicación puede leer los eventos de calendario almacenados en tu tablet y compartir o guardar los datos de tu calendario."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta aplicación puede ver los eventos de calendario almacenados en tu dispositivo Android TV y compartir o guardar los datos de tu calendario."</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 611c4c0eaad3..f246539a1795 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Lubab rakendusel pääseda juurde kehaanduri andmetele, nagu pulss, temperatuur ja vere hapnikusisaldus, kui rakendust kasutatakse."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Juurdepääs kehaanduri andmetele, nagu pulss, kui rakendus töötab taustal"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Lubab rakendusel pääseda juurde kehaanduri andmetele, nagu pulss, temperatuur ja vere hapnikusisaldus, kui rakendus töötab taustal."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Kalendrisündmuste ja üksikasjade lugemine"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"See rakendus saab kõiki teie tahvelarvutisse salvestatud kalendrisündmusi lugeda ja teie kalendriandmeid jagada või salvestada."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"See rakendus saab kõiki teie Android TV seadmesse salvestatud kalendrisündmusi lugeda ja teie kalendriandmeid jagada või salvestada."</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index ccf73083127e..86e804c1684c 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Aplikazioak erabiltzen diren bitartean, gorputz-sentsoreen datuak (besteak beste, bihotz-maiztasuna, tenperatura eta odolean dagoen oxigenoaren ehunekoa) atzitzeko baimena ematen die aplikazio horiei."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Atzitu gorputz-sentsoreen datuak (adib., bihotz-maiztasunarenak) atzeko planoan"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Aplikazioak atzeko planoan egon bitartean, gorputz-sentsoreen datuak (besteak beste, bihotz-maiztasuna, tenperatura eta odolean dagoen oxigenoaren ehunekoa) atzitzeko baimena ematen die aplikazio horiei."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"irakurri egutegiko gertaerak eta xehetasunak"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aplikazioak tabletan gordetako egutegiko gertaerak irakur ditzake eta egutegiko datuak parteka eta gorde ditzake."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aplikazioak Android TV gailuan gordeta dituzun egutegiko gertaerak irakur ditzake, baita egutegiko datuak partekatu eta gorde ere."</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 8d0e8b1ab207..e1a8322b2602 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"به برنامه اجازه میدهد تا زمانی که درحال استفاده است، به دادههای حسگر بدن، مثل ضربان قلب، دما، و درصد اکسیژن خون دسترسی داشته باشد."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"دسترسی به دادههای حسگر بدن، مثل ضربان قلب، درحین اجرا در پسزمینه"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"به برنامه اجازه میدهد تا زمانی که در پسزمینه درحال اجرا است، به دادههای حسگر بدن، مثل ضربان قلب، دما، و درصد اکسیژن خون دسترسی داشته باشد."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"خواندن رویدادها و جزئیات تقویم"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"این برنامه میتواند همه رویدادهای تقویم ذخیرهشده در رایانه لوحی شما را بخواند و دادههای تقویم شما را به اشتراک بگذارد یا ذخیره کند."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"این برنامه میتواند همه رویدادهای تقویم را که در Android TV شما ذخیرهشده بخواند، و دادههای تقویم شما را همرسانی یا ذخیره کند."</string> @@ -607,7 +615,7 @@ <string name="permdesc_mediaLocation" msgid="597912899423578138">"به برنامه اجازه میدهد مکانها را از مجموعه رسانهتان بخواند."</string> <string name="biometric_app_setting_name" msgid="3339209978734534457">"استفاده از زیستسنجشی"</string> <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"استفاده از زیستسنجشی یا قفل صفحه"</string> - <string name="biometric_dialog_default_title" msgid="55026799173208210">"تأیید کنید این شما هستید"</string> + <string name="biometric_dialog_default_title" msgid="55026799173208210">"تأیید کنید این شمایید"</string> <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"برای ادامه، از زیستسنجشی استفاده کنید"</string> <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"برای ادامه، از زیستسنجشی یا قفل صفحه استفاده کنید"</string> <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"سختافزار زیستسنجی دردسترس نیست"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index f327ceacce09..297278ebcc21 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Myöntää sovellukselle pääsyn kehoanturidataan, esim. sykkeeseen, lämpötilaan ja veren happipitoisuuteen, kun sovellusta käytetään."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pääsy kehoanturidataan, esim. sykkeeseen, kun käynnissä taustalla"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Myöntää sovellukselle pääsyn kehoanturidataan, esim. sykkeeseen, lämpötilaan ja veren happipitoisuuteen, kun sovellus on käynnissä taustalla."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Lue kalenterin tapahtumia ja tietoja"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Tämä sovellus voi lukea kaikkia tabletille tallennettuja kalenteritapahtumia sekä jakaa tai tallentaa kalenteritietoja."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Tämä sovellus voi lukea kaikkia Android TV ‑laitteeseen tallennettuja kalenteritapahtumia sekä jakaa tai tallentaa kalenteritietoja."</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 2019938e7a4c..adc0f985c0fd 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant l\'utilisation de l\'application."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données des capteurs corporels (comme la fréq. card.) en arrière-plan"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant que l\'application s\'exécute en arrière-plan."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Lire les événements d\'agenda et leurs détails"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette application peut lire tous les événements d\'agenda stockés sur votre tablette et partager ou enregistrer les données de votre agenda."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Cette application peut lire tous les événements d\'agenda stockés sur votre appareil Android TV et partager ou enregistrer les données de votre agenda."</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index b58d3759e056..ea481cdc0d04 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'appli d\'accéder aux données des capteurs corporels (fréquence cardiaque, température, taux d\'oxygène dans le sang, etc.) quand l\'appli est en cours d\'utilisation."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données de capteurs corporels (comme le pouls) en arrière-plan"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'appli d\'accéder aux données des capteurs corporels (fréquence cardiaque, température, taux d\'oxygène dans le sang, etc.) quand l\'appli est en arrière-plan."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Lire les événements d\'agenda et les détails associés"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette application peut lire tous les événements d\'agenda enregistrés sur votre tablette et partager ou enregistrer vos données d\'agenda."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Cette application peut lire tous les événements de l\'agenda enregistrés sur votre appareil Android TV, et partager ou enregistrer les données de votre agenda."</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index d998addc3d43..735a4d5d4b99 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que a aplicación acceda aos datos dos sensores corporais (por exemplo, a frecuencia cardíaca, a temperatura ou a porcentaxe de osíxeno en sangue) mentres se estea utilizando."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acceso en segundo plano aos datos dos sensores corporais, como a frecuencia cardíaca"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que a aplicación acceda aos datos dos sensores corporais (por exemplo, a frecuencia cardíaca, a temperatura ou a porcentaxe de osíxeno en sangue) mentres se estea executando en segundo plano."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Ler os detalles e os eventos do calendario"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta aplicación pode ler todos os eventos do calendario almacenados na túa tableta e compartir ou gardar os datos do calendario."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta aplicación pode ler todos os eventos do calendario almacenados no dispositivo Android TV e compartir ou gardar os datos do calendario."</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 3be37c9f2b5e..00bddbbea1f7 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ઍપ ઉપયોગમાં હોય, ત્યારે ઍપને હૃદયના ધબકારા, તાપમાન અને લોહીમાં ઑક્સિજનની ટકાવારી જેવા બૉડી સેન્સર ડેટાનો ઍક્સેસ કરવાની મંજૂરી આપે છે."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ઍપ બૅકગ્રાઉન્ડમાં હોય, ત્યારે હૃદયના ધબકારા જેવા બૉડી સેન્સર ડેટાનો ઍક્સેસ કરો"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ઍપ બૅકગ્રાઉન્ડમાં હોય, ત્યારે ઍપને હૃદયના ધબકારા, તાપમાન અને લોહીમાં ઑક્સિજનની ટકાવારી જેવા બૉડી સેન્સર ડેટાનો ઍક્સેસ કરવાની મંજૂરી આપે છે."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"કૅલેન્ડર ઇવેન્ટ્સ અને વિગતો વાંચો"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"આ ઍપ્લિકેશન, તમારા ટેબ્લેટ પર સંગ્રહિત તમામ કૅલેન્ડર ઇવેન્ટ્સને વાંચી શકે છે અને તમારા કૅલેન્ડર ડેટાને શેર કરી અથવા સાચવી શકે છે."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"આ ઍપ, તમારા Android TV ડિવાઇસ પર સંગ્રહિત બધા કૅલેન્ડર ઇવેન્ટને વાંચી શકે છે અને તમારા કૅલેન્ડર ડેટાને શેર કરી અથવા સાચવી શકે છે."</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 06a7b5e60d66..65b1242ab51b 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"इससे ऐप्लिकेशन को इस्तेमाल करने के दौरान, उसे बॉडी सेंसर के डेटा को ऐक्सेस करने की अनुमति मिलती है. इसमें धड़कन की दर, शरीर का तापमान, और खून में ऑक्सीजन का प्रतिशत जैसी जानकारी शामिल होती है."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"बैकग्राउंड में चलने के दौरान, धड़कन की दर जैसे बॉडी सेंसर डेटा का ऐक्सेस दें"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"इससे ऐप्लिकेशन के बैकग्राउंड में चलने के दौरान, उसे बॉडी सेंसर के डेटा को ऐक्सेस करने की अनुमति मिलती है. इसमें धड़कन की दर, शरीर का तापमान, और खून में ऑक्सीजन का प्रतिशत जैसी जानकारी शामिल होती है."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"कैलेंडर इवेंट और विवरण पढ़ें"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"यह ऐप्लिकेशन आपके टैबलेट पर संग्रहित सभी कैलेंडर इवेंट पढ़ सकता है और आपका कैलेंडर डेटा शेयर कर सकता है या सहेज सकता है."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"यह ऐप्लिकेशन आपके टीवी पर सेव किए गए सभी कैलेंडर इवेंट को पढ़ सकता है. इसके अलावा यह आपके कैलेंडर का डेटा शेयर कर सकता है या सेव कर सकता है."</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 135a7c70a492..85a4c4595253 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Omogućuje aplikaciji pristup podacima s biometrijskih senzora, kao što su puls, temperatura i postotak kisika u krvi, dok se aplikacija upotrebljava."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pristup podacima s biometrijskih senzora, kao što je puls, dok je u pozadini"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Omogućuje aplikaciji pristup podacima s biometrijskih senzora, kao što su puls, temperatura i postotak kisika u krvi, dok je aplikacija u pozadini."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Čitanje događaja i pojedinosti kalendara"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aplikacija može čitati sve kalendarske događaje pohranjene na tabletu i dijeliti ili spremati podatke iz vašeg kalendara."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aplikacija može čitati sve kalendarske događaje pohranjene na Android TV uređaju i dijeliti ili spremati podatke iz vašeg kalendara."</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index c4a0a9b59424..0c9a6cd01f9d 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Lehetővé teszi, hogy az alkalmazás hozzáférjen a testérzékelők adataihoz (pl. pulzusszám, testhőmérséklet és véroxigénszint), miközben az alkalmazás használatban van."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Hozzáférés a testérzékelők adataihoz (pl. pulzusszám) a háttérben"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Lehetővé teszi, hogy az alkalmazás hozzáférjen a testérzékelők adataihoz (pl. pulzusszám, testhőmérséklet és véroxigénszint), miközben az alkalmazás a háttérben van."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Naptáresemények és a naptári adatok olvasása"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Az alkalmazás olvashatja a táblagépen tárolt összes naptáreseményt, és megoszthatja vagy mentheti a naptáradatokat."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Az alkalmazás olvashatja az Android TV eszközön tárolt összes naptáreseményt, és megoszthatja vagy mentheti a naptáradatokat."</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index db6046cec74b..3c2b68605507 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Հավելվածին հասանելի է դարձնում մարմնի սենսորների տվյալները (օրինակ՝ սրտի զարկերի հաճախականությունը, ջերմաստիճանը, արյան մեջ թթվածնի տոկոսային պարունակության ցուցանիշները) հավելվածի օգտագործման ժամանակ։"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Մարմնի սենսորների տվյալների հասանելիություն ֆոնային ռեժիմում"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Հավելվածին հասանելի է դարձնում մարմնի սենսորների տվյալները (օրինակ՝ սրտի զարկերի հաճախականությունը, ջերմաստիճանը, արյան մեջ թթվածնի տոկոսային պարունակության ցուցանիշները), երբ հավելվածն աշխատում է ֆոնային ռեժիմում։"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Կարդալ օրացույցի միջոցառումները և տվյալները"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Այս հավելվածը կարող է կարդալ օրացույցի՝ ձեր պլանշետում պահված բոլոր միջոցառումները, ինչպես նաև հրապարակել կամ պահել ձեր օրացույցի տվյալները:"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Այս հավելվածը կարող է կարդալ օրացույցի՝ ձեր Android TV սարքում պահված բոլոր միջոցառումները, ինչպես նաև հրապարակել կամ պահել ձեր օրացույցի տվյալները:"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index c22480a16023..ce78f79629df 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Mengizinkan aplikasi mengakses data sensor tubuh, seperti detak jantung, suhu, dan persentase oksigen dalam darah, saat aplikasi sedang digunakan."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Mengakses data sensor tubuh, seperti detak jantung, saat ada di latar belakang"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Mengizinkan aplikasi mengakses data sensor tubuh, seperti detak jantung, suhu, dan persentase oksigen dalam darah, saat aplikasi berada di latar belakang."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Baca acara kalender dan detailnya"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aplikasi ini dapat membaca semua acara kalender yang tersimpan di tablet dan membagikan atau menyimpan data kalender."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aplikasi ini dapat membaca semua acara kalender yang tersimpan di perangkat Android TV dan membagikan atau menyimpan data kalender."</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index eadd87cadd12..cba0380148a4 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Veitir forritinu aðgang að gögnum frá líkamsskynjurum, svo sem um hjartslátt, hitastig og súrefnismettun í blóði á meðan forritið er í notkun."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Aðgangur að gögnum líkamsskynjara, t.d. um hjartslátt, meðan það er í bakgrunni"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Veitir forritinu aðgang að gögnum frá líkamsskynjurum, svo sem um hjartslátt, hitastig og súrefnismettun í blóði á meðan forritið keyrir í bakgrunni."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Lesa dagatalsviðburði og upplýsingar"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Þetta forrit getur lesið alla dagatalsviðburði sem eru vistaðir í spjaldtölvunni og deilt eða vistað dagatalsgögnin þín."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Þetta forrit getur lesið alla dagatalsviðburði sem eru vistaðir í Android TV og deilt eða vistað dagatalsgögnin þín."</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index e0fa0f422bbe..bfa966643bfb 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Autorizza l\'app ad accedere ai dati dei sensori del corpo, ad esempio battito cardiaco, temperatura e percentuale di ossigeno nel sangue, mentre l\'app è in uso."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accesso ai dati dei sensori del corpo, come il battito cardiaco, in background"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Autorizza l\'app ad accedere ai dati dei sensori del corpo, ad esempio battito cardiaco, temperatura e percentuale di ossigeno nel sangue, mentre l\'app è in background."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"lettura di eventi di calendario e dettagli"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Questa app può leggere tutti gli eventi di calendario memorizzati sul tablet e condividere o salvare i dati di calendario."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Questa app può leggere tutti gli eventi di calendario memorizzati sul dispositivo Android TV e condividere o salvare i dati di calendario."</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index e84252fea61a..7315331b9915 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ההרשאה מאפשרת לאפליקציה לגשת לנתונים של חיישני גוף, כמו דופק, חום גוף ושיעור החמצן בדם, כשנעשה שימוש באפליקציה."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"גישה לנתונים של חיישני גוף, כמו דופק, כשהאפליקציה פועלת ברקע"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ההרשאה מאפשרת לאפליקציה לגשת לנתונים של חיישני גוף, כמו דופק, חום גוף ושיעור החמצן בדם, כשהאפליקציה פועלת ברקע."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"קריאה של אירועי יומן והפרטים שלהם"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"האפליקציה הזו יכולה לקרוא את כל אירועי היומן המאוחסנים בטאבלט, ולשתף או לשמור את נתוני היומן."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"האפליקציה הזו יכולה לקרוא את כל אירועי היומן המאוחסנים במכשיר ה-Android TV, ולשתף או לשמור את נתוני היומן."</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index c384e9965c1d..52d018ce413f 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"アプリの使用時に、心拍数、体温、血中酸素濃度など、ボディセンサー データにアクセスすることをアプリに許可します。"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"バックグラウンド動作時の、心拍数などのボディセンサー データへのアクセス"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"バックグラウンドでのアプリの動作時に、心拍数、体温、血中酸素濃度など、ボディセンサー データにアクセスすることをアプリに許可します。"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"カレンダーの予定と詳細を読み取り"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"このアプリは、お使いのタブレットに保存されたカレンダーの予定をすべて読み取り、カレンダーのデータを共有したり、保存したりできます。"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"このアプリは、Android TV デバイスに保存されているカレンダーの予定をすべて読み取り、カレンダーのデータを共有したり、保存したりできます。"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 5e96865a95d3..c0fa6a07101d 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"საშუალებას აძლევს აპს, მისი გამოყენებისას, წვდომა ჰქონდეს სხეულის სენსორების მონაცემებზე, როგორიცაა გულისცემა, ტემპერატურა და სისხლში ჟანგბადის პროცენტული შემცველობა."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"აპის ფონურ რეჟიმში მუშაობისას, სხეულის სენსორების მონაცემებზე წვდომა, როგორიცაა გულისცემა"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"საშუალებას აძლევს აპს, ფონურ რეჟიმში მუშაობისას, წვდომა ჰქონდეს სხეულის სენსორების მონაცემებზე, როგორიცაა გულისცემა, ტემპერატურა და სისხლში ჟანგბადის პროცენტული შემცველობა."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"კალენდრის მოვლენებისა და დეტალების წაკითხვა"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ამ აპს შეუძლია თქვენს ტაბლეტში შენახული კალენდრის ყველა მოვლენის წაკითხვა და თქვენი კალენდრის მონაცემების გაზიარება ან შენახვა."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ამ აპს შეუძლია თქვენს Android TV მოწყობილობაზე შენახული კალენდრის ყველა მოვლენის წაკითხვა და თქვენი კალენდრის მონაცემების გაზიარება ან შენახვა."</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index eba758aa98c0..68ebba9062d0 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Жұмыс кезінде қолданбаға дене датчигінен алынған жүрек қағысы, температура, қандағы оттегі пайызы сияқты деректі пайдалануға рұқсат береді."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Фондық режимде дене датчигінен алынған жүрек қағысы сияқты деректі пайдалану"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Фондық режимде қолданбаға дене датчигінен алынған жүрек қағысы, температура, қандағы оттегі пайызы сияқты деректі пайдалануға рұқсат береді."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Күнтізбе оқиғалары мен мәліметтерін оқу"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Бұл қолданба планшетте сақталған барлық күнтізбе оқиғаларын оқи алады және күнтізбе деректерін бөлісе не сақтай алады."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Бұл қолданба Android TV құрылғыңызда сақталған барлық күнтізбе оқиғаларын оқи алады және күнтізбе деректерін бөлісе не сақтай алады."</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 85247df69474..ee399249376c 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"អនុញ្ញាតឱ្យកម្មវិធីចូលប្រើទិន្នន័យឧបករណ៍ចាប់សញ្ញារាងកាយ ដូចជាចង្វាក់បេះដូង សីតុណ្ហភាព និងភាគរយនៃអុកស៊ីសែនក្នុងឈាមជាដើម ខណៈពេលកំពុងប្រើកម្មវិធី។"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ចូលប្រើទិន្នន័យឧបករណ៍ចាប់សញ្ញារាងកាយ ដូចជាចង្វាក់បេះដូងជាដើម ខណៈពេលស្ថិតនៅផ្ទៃខាងក្រោយ"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"អនុញ្ញាតឱ្យកម្មវិធីចូលប្រើទិន្នន័យឧបករណ៍ចាប់សញ្ញារាងកាយ ដូចជាចង្វាក់បេះដូង សីតុណ្ហភាព និងភាគរយនៃអុកស៊ីសែនក្នុងឈាមជាដើម ខណៈពេលដែលកម្មវិធីស្ថិតនៅផ្ទៃខាងក្រោយ។"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"អានព្រឹត្តិការណ៍ប្រតិទិន និងព័ត៌មានលម្អិត"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"កម្មវិធីនេះអាចធ្វើការអានព្រឹត្តិការណ៍ប្រតិទិនទាំងអស់ ដែលផ្ទុកនៅលើថេប្លេតរបស់អ្នក និងចែករំលែក ឬរក្សាទុកទិន្នន័យប្រតិទិនរបស់អ្នក។"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"កម្មវិធីនេះអាចអានព្រឹត្តិការណ៍ក្នុងប្រតិទិនទាំងអស់ដែលបានរក្សាទុកនៅក្នុងឧបករណ៍ Android TV របស់អ្នក និងចែករំលែក ឬរក្សាទុកទិន្នន័យប្រតិទិនរបស់អ្នក។"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 2ad020021343..d23a53e285ee 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿರುವಾಗ ಹೃದಯ ಬಡಿತ, ತಾಪಮಾನ ಮತ್ತು ರಕ್ತದ ಆಮ್ಲಜನಕದ ಶೇಕಡಾವಾರು ಎಂಬಂತಹ ದೇಹದ ಸೆನ್ಸರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ಹಿನ್ನಲೆಯಲ್ಲಿರುವಾಗ ಹೃದಯ ಬಡಿತದಂತಹ ದೇಹದ ಸೆನ್ಸರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ಆ್ಯಪ್ ಹಿನ್ನಲೆಯಲ್ಲಿರುವಾಗ ಹೃದಯ ಬಡಿತ, ತಾಪಮಾನ ಮತ್ತು ರಕ್ತದ ಆಮ್ಲಜನಕದ ಶೇಕಡಾವಾರು ಎಂಬಂತಹ ದೇಹದ ಸೆನ್ಸರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್ಗಳು ಮತ್ತು ವಿವರಗಳನ್ನು ಓದಿ"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಸಂಗ್ರಹವಾಗಿರುವ ಎಲ್ಲಾ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್ಗಳನ್ನು ಓದಬಹುದು ಮತ್ತು ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು ಅಥವಾ ಉಳಿಸಬಹುದು."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹವಾಗಿರುವ ಎಲ್ಲಾ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್ಗಳನ್ನು ಓದಬಹುದು ಮತ್ತು ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು ಅಥವಾ ಉಳಿಸಬಹುದು."</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index ad429baf5f90..a52259a44757 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"앱이 사용 중에 심박수, 체온, 혈중 산소 농도와 같은 생체 신호 센서 데이터에 액세스하도록 허용합니다."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"백그라운드에서 심박수와 같은 생체 신호 센서 데이터에 액세스"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"앱이 백그라운드에서 심박수, 체온, 혈중 산소 농도와 같은 생체 신호 센서 데이터에 액세스하도록 허용합니다."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"캘린더 일정 및 세부정보 읽기"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"이 앱은 태블릿에 저장된 모든 캘린더 일정을 읽고 캘린더 데이터를 공유하거나 저장할 수 있습니다."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"앱이 Android TV 기기에 저장된 모든 캘린더 일정을 읽고 캘린더 데이터를 공유하거나 저장할 수 있습니다."</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index d4c4c076cf97..67a890da239a 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Иштеп жатканда колдонмо дене сенсорлорунун көрсөткүчтөрүн, мисалы, жүрөктүн согушу, температура жана кандагы кычкылтектин пайызын көрө алат."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Фондо дене сенсорлорунун көрсөткүчтөрүн, мисалы, жүрөктүн согушун көрүү"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Колдонмо фондо дене сенсорлорунун көрсөткүчтөрүн, мисалы, жүрөктүн согушу, температура жана кандагы кычкылтектин пайызын көрө алат."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Жылнаамадагы иш-чараларды жана алардын чоо-жайын окуу"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Бул колдонмо планшетиңизде сакталган жылнаамадагы иш-чаралардын баарын окуп жана андагы маалыматтарды бөлүшүп же сактай алат."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Бул колдонмо Android TV түзмөгүңүздө сакталган жылнаама иш-чараларынын баарын окуп, ошондой эле жылнаама дайындарын бөлүшүп же сактай алат."</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 13a88ca76b41..e890cc6fa429 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ອະນຸຍາດໃຫ້ແອັບເຂົ້າເຖິງຂໍ້ມູນເຊັນເຊີຮ່າງກາຍ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ອຸນຫະພູມ ແລະ ເປີເຊັນອອກຊິເຈນໃນເລືອດ, ໃນຂະນະທີ່ໃຊ້ແອັບຢູ່."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ເຂົ້າເຖິງຂໍ້ມູນເຊັນເຊີຮ່າງກາຍ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ໃນຂະນະທີ່ແອັບຢູ່ໃນພື້ນຫຼັງ"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ອະນຸຍາດໃຫ້ແອັບເຂົ້າເຖິງຂໍ້ມູນເຊັນເຊີຮ່າງກາຍ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ອຸນຫະພູມ ແລະ ເປີເຊັນອອກຊິເຈນໃນເລືອດ, ໃນຂະນະທີ່ແອັບຢູ່ໃນພື້ນຫຼັງ."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ແອັບນີ້ສາມາດອ່ານນັດໝາຍປະຕິທິນທັງໝົດທີ່ບັນທຶກໄວ້ຢູ່ອຸປະກອນ Android TV ຂອງທ່ານ ແລະ ແບ່ງປັນ ຫຼື ບັນທຶກຂໍ້ມູນປະຕິທິນຂອງທ່ານ."</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 6a66751fde8d..0c4354309dcd 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -460,6 +460,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Leidžiama programai pasiekti kūno jutiklių duomenis, pvz., pulso dažnį, temperatūrą ir deguonies procentinę dalį kraujyje, kai programa naudojama."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Prieiga prie kūno jutiklių duomenų, pvz., pulso dažnio, kai veikia fone"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Leidžiama programai pasiekti kūno jutiklių duomenis, pvz., pulso dažnį, temperatūrą ir deguonies procentinę dalį kraujyje, kai programa veikia fone."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Skaityti kalendoriaus įvykius arba išsamią informaciją"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ši programa gali nuskaityti visus planšetiniame kompiuteryje saugomus kalendoriaus įvykius ir bendrinti arba išsaugoti kalendoriaus duomenis."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ši programa gali nuskaityti visus „Android TV“ įrenginyje saugomus kalendoriaus įvykius ir bendrinti arba išsaugoti kalendoriaus duomenis."</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 2bb12db7b4f6..47233ff00884 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ļauj lietotnei piekļūt ķermeņa sensoru datiem, piemēram, sirdsdarbības ātrumam, temperatūrai un procentuālajam skābekļa daudzumam asinīs, kamēr lietotne tiek izmantota."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Piekļuve ķermeņa sensoru datiem, piemēram, sirdsdarbības ātrumam, fonā"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ļauj lietotnei piekļūt ķermeņa sensoru datiem, piemēram, sirdsdarbības ātrumam, temperatūrai un procentuālajam skābekļa daudzumam asinīs, kamēr lietotne darbojas fonā."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Lasīt kalendāra pasākumus un informāciju"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Šī lietotne var lasīt visus kalendāra pasākumus, kas saglabāti planšetdatorā, un kopīgot vai saglabāt jūsu kalendāra datus."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Šī lietotne var lasīt visus kalendāra pasākumus, kas saglabāti Android TV ierīcē, un kopīgot vai saglabāt jūsu kalendāra datus."</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 52019e44efb3..6c4bcb143bef 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Дозволува апликацијата да пристапува до податоци од телесните сензори, како што се пулс, температура и процент на кислород во телото, додека се користи апликацијата."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Пристап до податоци од телесните сензори, како пулсот, додека работи во заднина"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Дозволува апликацијата да пристапува до податоци од телесните сензори, како што се пулс, температура и процент на кислород во телото, додека апликацијата работи во заднина."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Чита настани и детали од календарот"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Апликацијава може да ги чита сите настани во календарот складирани во вашиот таблет и да ги споделува или зачувува податоците од календарот."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Апликацијава може да ги чита сите настани во календарот складирани во вашиот уред Android TV и да ги споделува или зачувува податоците од календарот."</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 88ce78012ec3..9652af5f8687 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ആപ്പ് ഉപയോഗത്തിലുള്ളപ്പോൾ അതിനെ ഹൃദയമിടിപ്പ്, ശരീരോഷ്മാവ്, രക്തത്തിലെ ഓക്സിജൻ ശതമാനം എന്നിവ പോലുള്ള ബോഡി സെൻസർ ഡാറ്റ ആക്സസ് ചെയ്യാൻ അനുവദിക്കുന്നു."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"പശ്ചാത്തലത്തിലുള്ളപ്പോൾ ഹൃദയമിടിപ്പ് പോലുള്ള ബോഡി സെൻസർ ഡാറ്റ ആക്സസ് ചെയ്യുക"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ആപ്പ് പശ്ചാത്തലത്തിലുള്ളപ്പോൾ അതിനെ ഹൃദയമിടിപ്പ്, ശരീരോഷ്മാവ്, രക്തത്തിലെ ഓക്സിജൻ ശതമാനം എന്നിവ പോലുള്ള ബോഡി സെൻസർ ഡാറ്റ ആക്സസ് ചെയ്യാൻ അനുവദിക്കുന്നു."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"കലണ്ടർ ഇവന്റുകളും വിശദാംശങ്ങളും വായിക്കുക"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ഈ ആപ്പിന് നിങ്ങളുടെ ടാബ്ലെറ്റിൽ സംഭരിച്ചിരിക്കുന്ന എല്ലാ കലണ്ടർ ഇവന്റുകളും വായിക്കാനും നിങ്ങളുടെ കലണ്ടർ വിവരങ്ങൾ പങ്കിടാനും അല്ലെങ്കിൽ സംരക്ഷിക്കാനും കഴിയും."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ഈ ആപ്പിന് നിങ്ങളുടെ Android TV-യിൽ സംഭരിച്ചിരിക്കുന്ന എല്ലാ കലണ്ടർ ഇവന്റുകളും വായിക്കാനും നിങ്ങളുടെ കലണ്ടർ ഡാറ്റ പങ്കിടാനോ സംരക്ഷിക്കാനോ സാധിക്കുകയും ചെയ്യും."</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 0dc530dde940..5f9c268d54e2 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Аппыг ашиглаж байх үедээ зүрхний хэм, температур болон цусны хүчилтөрөгчийн хувь зэрэг биеийн мэдрэгчийн өгөгдөлд хандах боломжтой."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Ард нь байх үед зүрхний хэм зэрэг биеийн мэдрэгчийн өгөгдөлд хандаарай"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Апп ард нь байх үед зүрхний хэм, температур, цусны хүчилтөрөгчийн хувь зэрэг биеийн мэдрэгчийн өгөгдөлд хандах боломжтой."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Календарийн арга хэмжээ, дэлгэрэнгүйг унших"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Энэ апп таны таблетад хадгалсан календарийн бүх арга хэмжээг унших, календарийн өгөгдлийг хуваалцах, хадгалах боломжтой."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Энэ апп таны Android TV төхөөрөмжид хадгалсан календарийн бүх арга хэмжээг унших болон таны календарийн өгөгдлийг хуваалцах эсвэл хадгалах боломжтой."</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 1b899a57e9d3..e6dd0bbfbc7e 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ॲप वापरात असताना हार्ट रेट, तापमान आणि रक्तातील ऑक्सिजनची टक्केवारी यांसारखा शरीर सेन्सर डेटा अॅक्सेस करण्याची अनुमती ॲपला देते."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"बॅकग्राउंडमध्ये असताना, हार्ट रेट यासारखा शरीर सेन्सर डेटा अॅक्सेस करा"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ॲप हे बॅकग्राउंडमध्ये असताना हार्ट रेट, तापमान आणि रक्तातील ऑक्सिजनची टक्केवारी यांसारखा शरीर सेन्सर डेटा अॅक्सेस करण्याची अनुमती ॲपला द्या."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"कॅलेंडर इव्हेंट आणि तपशील वाचा"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"हा अॅप आपल्या टॅब्लेटवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"हे अॅप तुमच्या Android TV डिव्हाइसवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 7419995d143b..364c325a8bf2 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Membenarkan apl mengakses data penderia tubuh, seperti kadar denyut jantung, suhu dan peratusan oksigen darah, semasa apl digunakan."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Akses data penderia tubuh, seperti kadar denyut jantung, semasa di latar"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Membenarkan apl mengakses data penderia tubuh, seperti kadar denyut jantung, suhu dan peratusan oksigen darah, semasa apl berjalan di latar belakang."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Baca acara dan butiran kalendar"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Apl ini boleh membaca semua acara kalendar yang disimpan pada tablet anda dan berkongsi atau menyimpan data kalendar anda."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Apl ini boleh membaca semua acara kalendar yang disimpan pada peranti Android TV anda dan berkongsi atau menyimpan data kalendar anda."</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 8d788064a176..0a8990c36ffe 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"အက်ပ်သုံးစဉ် နှလုံးခုန်နှုန်း၊ အပူချိန်၊ သွေးတွင်း အောက်ဆီဂျင်ရာခိုင်နှုန်းကဲ့သို့ ခန္ဓာကိုယ်အာရုံခံစနစ် ဒေတာများသုံးရန် အက်ပ်ကိုခွင့်ပြုသည်။"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"နောက်ခံတွင်ဖွင့်စဉ် နှလုံးခုန်နှုန်းကဲ့သို့ ခန္ဓာကိုယ်အာရုံခံစနစ် ဒေတာ သုံးခြင်း"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"နောက်ခံတွင်အက်ပ်ဖွင့်စဉ် နှလုံးခုန်နှုန်း၊ အပူချိန်၊ သွေးတွင်း အောက်ဆီဂျင်ရာခိုင်နှုန်းကဲ့သို့ ခန္ဓာကိုယ်အာရုံခံစနစ် ဒေတာများသုံးရန် အက်ပ်ကိုခွင့်ပြုသည်။"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"ပြက္ခဒိန်ဖြစ်ရပ်များနှင့် အသေးစိတ်အချက်အလက်များကို ဖတ်ခြင်း"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ဤအက်ပ်သည် သင့်တက်ဘလက်တွင် သိမ်းဆည်းထားသည့် ပြက္ခဒိန်ဖြစ်ရပ်များကို ကြည့်ရှုနိုင်ပြီး သင့်ပြက္ခဒိန်ဒေတာများကို မျှဝေခြင်းနှင့် သိမ်းဆည်းခြင်းတို့ ပြုလုပ်နိုင်ပါသည်။"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ဤအက်ပ်သည် သင့် Android TV စက်ပစ္စည်းတွင် သိမ်းဆည်းထားသည့် ပြက္ခဒိန်ဖြစ်ရပ်များအားလုံးကို ဖတ်နိုင်ပြီး သင်၏ ပြက္ခဒိန်ဒေတာများကို မျှဝေခြင်း သို့မဟုတ် သိမ်းဆည်းခြင်းတို့ ပြုလုပ်နိုင်သည်။"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 1835ceb41a98..d646c76685e2 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gir appen tilgang til data fra kroppssensorer, for eksempel puls, temperatur og oksygenmetning i blodet, når den er i bruk."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Tilgang til data fra kroppssensorer, for eksempel puls, når den er i bakgrunnen"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gir appen tilgang til data fra kroppssensorer, for eksempel puls, temperatur og oksygenmetning i blodet, når den er i bakgrunnen."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Les kalenderaktivitet og detaljer"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Denne appen kan lese all kalenderaktivitet som er lagret på nettbrettet ditt, og dele eller lagre kalenderdataene."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Denne appen kan lese all kalenderaktivitet som er lagret på Android TV-enheten din, og dele eller lagre kalenderdataene."</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 94924339f70e..d300beb70479 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"यसले यो एप प्रयोग गरिँदै गरेका बेला यसलाई हृदयको गति, शरीरको तापक्रम तथा रगतमा रहेको अक्सिजनको प्रतिशत जस्ता बडी सेन्सरसम्बन्धी डेटा हेर्ने तथा प्रयोग गर्ने अनुमति दिन्छ।"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ब्याकग्राउन्डमा चलेका बेला हृदयको गति जस्ता बडी सेन्सरसम्बन्धी डेटा हेरियोस् र प्रयोग गरियोस्"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"यसले यो एप ब्याकग्राउन्डमा चलेका बेला यसलाई हृदयको गति, शरीरको तापक्रम तथा रगतमा रहेको अक्सिजनको प्रतिशत जस्ता बडी सेन्सरसम्बन्धी डेटा हेर्ने तथा प्रयोग गर्ने अनुमति दिन्छ।"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"पात्रोका कार्यक्रम र विवरणहरू पढ्ने"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"यस एपले तपाईंको ट्याब्लेटमा भण्डारण गरिएका पात्रो सम्बन्धी सबै कार्यक्रमहरू पढ्न र तपाईंको पात्रोको डेटा आदान प्रदान वा सुरक्षित गर्न सक्छ।"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"यस एपले तपाईंको Android टिभी डिभाइसमा भण्डारण गरिएका पात्रोसम्बन्धी सबै कार्यक्रमहरू पढ्न र तपाईंको पात्रोको डेटा आदान प्रदान वा सुरक्षित गर्न सक्छ।"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 8de5fe4038d6..9b6b896e5a4d 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"De app heeft toegang tot gegevens van lichaamssensoren, zoals hartslag, temperatuur en zuurstofpercentage in het bloed, terwijl de app wordt gebruikt."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Toegang tot gegevens van lichaamssensoren, zoals hartslag, op de achtergrond"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"De app heeft toegang tot gegevens van lichaamssensoren, zoals hartslag, temperatuur en zuurstofpercentage in het bloed, terwijl de app op de achtergrond wordt uitgevoerd."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Agenda-afspraken en -gegevens lezen"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Deze app kan alle agenda-afspraken lezen die zijn opgeslagen op je tablet en je agendagegevens delen of opslaan."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Deze app kan alle agenda-afspraken lezen die zijn opgeslagen op je Android TV-apparaat en je agendagegevens delen of opslaan."</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 2dc96a765935..c2560da5ae6f 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ଏହି ଆପଟି ବ୍ୟବହାରରେ ଥିବା ସମୟରେ, ହାର୍ଟ ରେଟ ଏବଂ ତାପମାତ୍ରା, ରକ୍ତରେ ଅମ୍ଳଜାନ ଶତକଡ଼ା ପରି ବଡି ସେନ୍ସର ଡାଟାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ପୃଷ୍ଠପଟରେ ଥିବା ସମୟରେ, ହାର୍ଟ ରେଟ ପରି ବଡି ସେନ୍ସର ଡାଟାକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ଏହି ଆପଟି ପୃଷ୍ଠପଟରେ ଥିବା ସମୟରେ, ହାର୍ଟ ରେଟ, ତାପମାତ୍ରା ଏବଂ ରକ୍ତରେ ଅମ୍ଳଜାନ ଶତକଡ଼ା ପରି ବଡି ସେନ୍ସର ଡାଟାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"କ୍ୟାଲେଣ୍ଡର୍ ଇଭେଣ୍ଟ ଏବଂ ବିବରଣୀ ପଢ଼େ"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ଆପଣଙ୍କ ଟାବଲେଟ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ସମସ୍ତ କ୍ୟାଲେଣ୍ଡର ଇଭେଣ୍ଟ ଏହି ଆପ୍ ପଢ଼ିପାରେ ଏବଂ ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର ଡାଟା ସେୟାର୍ କରିପାରେ କିମ୍ବା ସେଭ୍ କରିପାରେ।"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ଏହି ଆପ୍ ଆପଣଙ୍କ Android TV ଡିଭାଇସ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ସମସ୍ତ କ୍ୟାଲେଣ୍ଡର ଇଭେଣ୍ଟ ପଢ଼ିପାରେ ଏବଂ ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର ଡାଟା ସେୟାର୍ କରିପାରେ କିମ୍ବା ସେଭ୍ କରିପାରେ।"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index a2f3b11b27a6..4086ab7d1fb0 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ਜਦੋਂ ਐਪ ਵਰਤੋਂ ਵਿੱਚ ਹੋਵੇ, ਤਾਂ ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਦਿਲ ਦੀ ਧੜਕਣ, ਤਾਪਮਾਨ, ਖੂਨ ਵਿੱਚ ਮੌਜੂਦ ਆਕਸੀਜਨ ਦੀ ਫ਼ੀਸਦ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ \'ਤੇ ਦਿਲ ਦੀ ਧੜਕਣ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ਜਦੋਂ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੋਵੇ, ਤਾਂ ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਦਿਲ ਦੀ ਧੜਕਣ, ਤਾਪਮਾਨ, ਖੂਨ ਵਿੱਚ ਮੌਜੂਦ ਆਕਸੀਜਨ ਦੀ ਫ਼ੀਸਦ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"ਕੈਲੰਡਰ ਵਰਤਾਰਿਆਂ ਅਤੇ ਵੇਰਵਿਆਂ ਨੂੰ ਪੜ੍ਹੋ"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ਇਹ ਐਪ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index d0857f543c09..f57ec7e9f2eb 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -460,6 +460,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Zezwala aplikacji na dostęp do danych z czujników na ciele, takich jak tętno, temperatura i poziom saturacji, gdy aplikacja ta jest używana."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Zezwól na dostęp do danych z czujników na ciele, np. tętna, podczas używania aplikacji w tle"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Zezwala aplikacji na dostęp do danych z czujników na ciele, takich jak tętno, temperatura i poziom saturacji, gdy aplikacja ta jest używana w tle."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Odczytywanie wydarzeń i informacji z kalendarza"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ta aplikacja może odczytywać wszystkie zapisane na tablecie wydarzenia z kalendarza i udostępniać oraz zapisywać dane kalendarza."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ta aplikacja może odczytywać wszystkie wydarzenia z kalendarza zapisane na urządzeniu z Androidem TV oraz udostępniać i zapisywać dane z kalendarza."</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 8c03ed939565..6fc8ce51da95 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em uso."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acessar dados do sensor corporal, como a frequência cardíaca, segundo plano"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em segundo plano."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Ler detalhes e eventos da agenda"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Este app pode ler todos os eventos da agenda armazenados no seu tablet e compartilhar ou salvar os dados da sua agenda."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Este app pode ler todos os eventos da agenda armazenados no seu dispositivo Android TV e compartilhar ou salvar os dados da sua agenda."</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index fc91fb42dcd0..f7b9e69641ef 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite à app aceder a dados de sensores de corpo, como ritmo cardíaco, temperatura e percentagem de oxigénio no sangue, enquanto está a ser usada."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Aceder a dados de sensores de corpo, como ritmo cardíaco, quando em seg. plano"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite à app aceder a dados de sensores de corpo, como ritmo cardíaco, temperatura e percentagem de oxigénio no sangue, enquanto está em segundo plano."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Ler detalhes e eventos do calendário"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta app pode ler todos os eventos do calendário armazenados no seu tablet e partilhar ou guardar os dados do calendário."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta app pode ler todos os eventos do calendário armazenados no seu dispositivo Android TV e partilhar ou guardar os dados do calendário."</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 8c03ed939565..6fc8ce51da95 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em uso."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acessar dados do sensor corporal, como a frequência cardíaca, segundo plano"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em segundo plano."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Ler detalhes e eventos da agenda"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Este app pode ler todos os eventos da agenda armazenados no seu tablet e compartilhar ou salvar os dados da sua agenda."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Este app pode ler todos os eventos da agenda armazenados no seu dispositivo Android TV e compartilhar ou salvar os dados da sua agenda."</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 77206a1593bf..b9c90b19de9c 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite aplicației să acceseze date de la senzorii corporali, cum ar fi pulsul, temperatura și procentul de oxigen din sânge, în timpul folosirii aplicației."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Să acceseze date de la senzorii corporali, precum pulsul, când rulează în fundal"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite aplicației să acceseze date de la senzorii corporali, cum ar fi pulsul, temperatura și procentul de oxigen din sânge, în timp ce aplicația rulează în fundal."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"să citească evenimentele din calendar și detaliile"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Această aplicație poate să citească toate evenimentele din calendar stocate pe tabletă și să trimită sau să salveze datele din calendar."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Această aplicație poate să citească toate evenimentele din calendar stocate pe dispozitivul Android TV și să trimită sau să salveze datele din calendar."</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 650fc7181725..b7a3f60aa6d7 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -460,6 +460,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Когда приложение используется, это разрешение предоставляет ему доступ к данным нательных датчиков (например, пульсу, температуре, уровню кислорода в крови)."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Доступ к данным нательных датчиков, когда приложение работает в фоновом режиме"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Когда приложение работает в фоновом режиме, это разрешение предоставляет ему доступ к данным нательных датчиков (например, пульсу, температуре, уровню кислорода в крови)."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Чтение мероприятий и данных"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Приложение может считывать, отправлять и сохранять информацию о мероприятиях в календаре планшета."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Приложение может считывать, отправлять и сохранять информацию о мероприятиях в календаре устройства Android TV."</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index d686d8296e2f..edb7dc2409dc 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"යෙදුම භාවිතයේ පවතින අතරතුර හෘද ස්පන්දන වේගය, උෂ්ණත්වය සහ රුධිර ඔක්සිජන් ප්රතිශතය වැනි ශරීර සංවේදක දත්ත වෙත ප්රවේශ වීමට යෙදුමට අවසර දෙයි."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"පසුබිමේ ඇති අතරතුර හෘද ස්පන්දන වේගය වැනි ශරීර සංවේදක දත්ත වෙත ප්රවේශ වන්න"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"යෙදුම පසුබිමේ ඇති අතර හෘද ස්පන්දන වේගය, උෂ්ණත්වය සහ රුධිර ඔක්සිජන් ප්රතිශතය වැනි ශරීර සංවේදක දත්ත වෙත ප්රවේශ වීමට යෙදුමට අවසර දෙයි."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"දින දර්ශන සිදුවීම් හා විස්තර කියවන්න"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"මෙම යෙදුමට ඔබගේ ටැබ්ලට් පරිගණකය මත ගබඩා වී ඇති සියලු දින දර්ශන කියවීමට සහ සහ ඔබගේ දින දර්ශන දත්ත බෙදා ගැනීමට සහ සුරැකීමට හැකිය."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"මෙම යෙදුමට ඔබගේ Android TV මත ගබඩා කර ඇති සියලු දින දර්ශන සිදුවීම් කියවීමට සහ ඔබගේ දින දර්ශන දත්ත බෙදා ගැනීමට හෝ සුරැකීමට හැකිය."</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 123b63c4fc26..af6cc59506f8 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -460,6 +460,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Poskytne aplikácii prístup k dátam telových senzorov, ako sú pulz, teplota a saturácia krvi kyslíkom počas používania aplikácie."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Prístup k dátam telových senzorov (napríklad pulzu) počas spustenia na pozadí"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Poskytne aplikácii prístup k dátam telových senzorov, ako sú pulz, teplota a saturácia krvi kyslíkom počas spustenia aplikácie na pozadí."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Čítanie udalostí kalendára a podrobností"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Táto aplikácia môže čítať všetky udalosti kalendára uložené vo vašom tablete a zdieľať alebo ukladať dáta kalendára."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Táto aplikácia môže čítať všetky udalosti kalendára uložené vo vašom zariadení Android TV a zdieľať alebo ukladať údaje kalendára."</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index ce19c5222bd1..e33b67d19074 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -460,6 +460,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Aplikaciji dovoljuje dostop do podatkov tipal telesnih funkcij, kot so srčni utrip, temperatura, odstotek kisika v krvi, ko je aplikacija v uporabi."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Dostop do podatkov tipal telesnih funkcij, kot je srčni utrip, ko je v ozadju"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Aplikaciji dovoljuje dostop do podatkov tipal telesnih funkcij, kot so srčni utrip, temperatura, odstotek kisika v krvi, ko je aplikacija v ozadju."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Branje dogodkov v koledarjih in podrobnosti koledarjev"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ta aplikacija lahko prebere vse dogodke v koledarju, ki so shranjeni v tabličnem računalniku, ter shrani podatke koledarja ali jih deli z drugimi."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ta aplikacija lahko prebere vse dogodke v koledarju, ki so shranjeni v napravi Android TV, ter shrani podatke koledarja ali jih deli z drugimi."</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 49643492f9b0..b3e3108ec942 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Lejon aplikacionin që të ketë qasje te të dhënat e sensorit të trupit, si p.sh. rrahjet e zemrës, temperatura dhe përqindja e oksigjenit në gjak ndërkohë që aplikacioni është në përdorim."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Qasje te të dhënat e sensorit të trupit, si rrahjet e zemrës kur është në sfond"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Lejon aplikacionin që të ketë qasje te të dhënat e sensorit të trupit, si p.sh. rrahjet e zemrës, temperatura dhe përqindja e oksigjenit në gjak ndërkohë që aplikacioni është në sfond."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Lexo ngjarjet e kalendarit dhe detajet"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ky aplikacion mund të lexojë të gjitha ngjarjet e kalendarit të ruajtura në tabletin tënd dhe të ndajë ose të ruajë të dhënat e kalendarit."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ky aplikacion mund të lexojë të gjitha ngjarjet e kalendarit të ruajtura në pajisjen tënde Android TV dhe të ndajë ose të ruajë të dhënat e kalendarit."</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 914e36ca3f9b..fd55aa2ef688 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -459,6 +459,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Дозвољава апликацији да приступа подацима сензора за тело, као што су пулс, температура и проценат кисеоника у крви док се апликација користи."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Приступ подацима сензора за тело, као што је пулс, у позадини"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Дозвољава апликацији да приступа подацима сензора за тело, као што су пулс, температура и проценат кисеоника у крви док је апликација у позадини."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Читање догађаја и података из календара"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ова апликација може да чита све догађаје из календара које чувате на таблету, као и да дели или чува податке из календара."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ова апликација може да чита све догађаје из календара које чувате на Android TV уређају, као и да дели или чува податке из календара."</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index c45c847c61bd..eec265619d4a 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Tillåter att appen får åtkomst till data från kroppssensorer, t.ex. puls, kroppstemperatur och blodets syrehalt, medan appen används."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Åtkomst till data från kroppssensorer, t.ex. puls, i bakgrunden"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Tillåter att appen får åtkomst till data från kroppssensorer, t.ex. puls, kroppstemperatur och blodets syrehalt, medan appen är i bakgrunden."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Läsa kalenderhändelser och kalenderuppgifter"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Appen kan läsa alla kalenderhändelser som sparats på surfplattan och dela eller spara uppgifter i din kalender."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Appen kan läsa alla kalenderhändelser som sparats på Android TV-enheten och dela eller spara uppgifter i din kalender."</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index cc7aa19f2538..f0bb94b59436 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Hurushusu programu ifikie data ya vitambuzi shughuli za mwili, kama vile mapigo ya moyo, halijoto na asilimia ya oksijeni kwenye damu wakati programu inatumika."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Fikia data ya vitambuzi shughuli za mwili, kama vile mapigo ya moyo, wakati programu inatumika chinichini"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Hurushusu programu ifikie data ya vitambuzi shughuli za mwili, kama vile mapigo ya moyo, halijoto na asilimia ya oksijeni kwenye damu wakati programu inatumika chinichini."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Soma matukio na maelezo ya kalenda"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Programu hii inaweza kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye kompyuta yako kibao na kushiriki au kuhifadhi data yako ya kalenda."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Programu hii inaweza kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye kifaa chako cha Android TV na kushiriki au kuhifadhi data ya kalenda yako."</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 149f89519e85..80a9ee9da582 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ஆப்ஸ் பயன்பாட்டில் இருக்கும்போது இதயத் துடிப்பு, வெப்பநிலை, ரத்த ஆக்ஸிஜன் சதவீதம் போன்ற உடல் சென்சார் தரவை அணுக ஆப்ஸை அனுமதிக்கிறது."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"பின்னணியில் இயங்கும்போது இதயத் துடிப்பு போன்ற உடல் சென்சார் தரவை அணுகுதல்"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ஆப்ஸ் பின்னணியில் இயங்கும்போது இதயத் துடிப்பு, வெப்பநிலை, ரத்த ஆக்ஸிஜன் சதவீதம் போன்ற உடல் சென்சார் தரவை அணுக ஆப்ஸை அனுமதிக்கிறது."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"கேலெண்டர் நிகழ்வுகளையும் விவரங்களையும் படிக்கலாம்"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"இந்த ஆப்ஸ் உங்கள் டேப்லெட்டில் சேமிக்கப்பட்டுள்ள கேலெண்டர் நிகழ்வுகள் அனைத்தையும் படிக்கலாம், உங்கள் கேலெண்டர் தரவைப் பகிரலாம் அல்லது சேமிக்கலாம்."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"உங்கள் Android TVயில் சேமித்துள்ள அனைத்துக் கேலெண்டர் நிகழ்வுகளையும் இந்த ஆப்ஸால் தெரிந்துகொள்ள முடியும். அத்துடன் உங்களின் கேலெண்டர் தரவைப் பகிரவும் சேமிக்கவும் முடியும்."</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 709be1ab732e..e0e232fdccf4 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"యాప్ ఉపయోగంలో ఉన్నప్పుడు గుండె స్పందన రేటు, ఉష్ణోగ్రత, ఇంకా రక్తంలోని ఆక్సిజన్ శాతం వంటి శరీర సెన్సార్ డేటాను యాక్సెస్ చేయడానికి యాప్ను అనుమతిస్తుంది."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"బ్యాక్గ్రౌండ్లో గుండె స్పందన రేటు వంటి శరీర సెన్సార్ డేటాను యాక్సెస్ చేయండి"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"యాప్ బ్యాక్గ్రౌండ్లో ఉన్నప్పుడు గుండె స్పందన రేటు, ఉష్ణోగ్రత, ఇంకా రక్తంలోని ఆక్సిజన్ శాతం వంటి శరీర సెన్సార్ డేటాను యాక్సెస్ చేయడానికి యాప్ను అనుమతిస్తుంది."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"క్యాలెండర్ ఈవెంట్లు మరియు వివరాలను చదవడం"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ఈ యాప్ మీ టాబ్లెట్లో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్లన్నీ చదవగలదు మరియు మీ క్యాలెండర్ డేటాను షేర్ చేయగలదు లేదా సేవ్ చేయగలదు."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ఈ యాప్ మీ Android TV పరికరంలో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్లన్నీ చదవగలదు, మీ క్యాలెండర్ డేటాను షేర్ చేయగలదు లేదా సేవ్ చేయగలదు."</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 3d46e4d4c09b..6c6b406c445f 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"อนุญาตให้แอปเข้าถึงข้อมูลเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ อุณหภูมิ และเปอร์เซ็นต์ออกซิเจนในเลือด ขณะใช้งานแอป"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"เข้าถึงข้อมูลเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ ขณะแอปทำงานในเบื้องหลัง"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"อนุญาตให้แอปเข้าถึงข้อมูลเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ อุณหภูมิ และเปอร์เซ็นต์ออกซิเจนในเลือด ขณะที่แอปทำงานในเบื้องหลัง"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"อ่านกิจกรรมในปฏิทินและรายละเอียด"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"แอปนี้สามารถอ่านกิจกรรมทั้งหมดในปฏิทินที่เก็บไว้ในแท็บเล็ต รวมถึงแชร์หรือบันทึกข้อมูลในปฏิทินของคุณ"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"แอปนี้อ่านกิจกรรมทั้งหมดในปฏิทินที่จัดเก็บไว้ในอุปกรณ์ Android TV ได้ รวมถึงแชร์หรือบันทึกข้อมูลในปฏิทินของคุณได้ด้วย"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index ff0859208b69..21f8e39f5dcf 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Nagpapahintulot sa app na i-access ang data ng sensor ng katawan, gaya ng bilis ng tibok ng puso, temperatura, at porsyento ng oxygen sa dugo, habang ginagamit ang app."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"I-access ang data ng sensor ng katawan gaya ng heart rate habang nasa background"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Nagpapahintulot sa app na i-access ang data ng sensor ng katawan, gaya ng bilis ng tibok ng puso, temperatura, at porsyento ng oxygen sa dugo, habang nasa background ang app."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Magbasa ng mga event sa kalendaryo at detalye"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Mababasa ng app na ito ang lahat ng event sa kalendaryo na naka-store sa iyong tablet at maibabahagi o mase-save nito ang data ng iyong kalendaryo."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Mababasa ng app na ito ang lahat ng event sa kalendaryo na naka-store sa iyong Android TV device at maibabahagi o mase-save nito ang data ng kalendaryo mo."</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 79ba5b559a35..f62560e2bf1b 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Kullanımdaki uygulamanın nabız, vücut ısısı, kandaki oksijen yüzdesi gibi vücut sensörü verilerine erişmesine izin verir."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Arka plandayken nabız gibi vücut sensörü verilerine erişme"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Arka plandaki uygulamanın nabız, vücut ısısı, kandaki oksijen yüzdesi gibi vücut sensörü verilerine erişmesine izin verir."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Takvim etkinlikleri ve ayrıntılarını okuma"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Bu uygulama, tabletinizde kayıtlı tüm takvim etkinliklerini okuyabilir ve takvim verilerinizi paylaşabilir ya da kaydedebilir."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Bu uygulama, Android TV cihazınızda kayıtlı tüm takvim etkinliklerini okuyabilir ve takvim verilerinizi paylaşabilir ya da kaydedebilir."</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index cd8762f74dcf..322929f3de93 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -460,6 +460,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Під час використання додатка він матиме доступ до даних датчиків на тілі, наприклад пульсу, температури та відсотка кисню в крові."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Доступ до показників датчиків на тілі, наприклад пульсу, у фоновому режимі"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Коли додаток працюватиме у фоновому режимі, він матиме доступ до показників датчиків на тілі, наприклад пульсу, температури та відсотка кисню в крові."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Переглядати події календаря й додаткову інформацію"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Цей додаток може переглядати всі події календаря, збережені на вашому планшеті, а також надсилати та зберігати дані календаря."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Додаток може переглядати всі події календаря, збережені на вашому пристрої Android TV, а також надсилати та зберігати дані календаря."</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 88cf7162ce5d..50e79a164c2b 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ایپ کے استعمال میں ہونے کے دوران ایپ کو حرکت قلب کی شرح، درجہ حرارت اور خون میں آکسیجن کا فیصد جیسے باڈی سینسر ڈیٹا تک رسائی کی اجازت دیتا ہے۔"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"پس منظر میں ہونے کے دوران حرکت قلب کی شرح جیسے باڈی سینسر ڈیٹا تک رسائی پائیں"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ایپ کے پس منظر میں ہونے کے دوران ایپ کو حرکت قلب کی شرح، درجہ حرارت اور خون میں آکسیجن کا فیصد جیسے باڈی سینسر ڈیٹا تک رسائی کی اجازت دیتا ہے۔"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"کیلنڈر ایونٹس اور تفاصیل پڑھیں"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"یہ ایپ آپ کے ٹیبلیٹ پر اسٹور کردہ سبھی کیلنڈر ایونٹس کو پڑھ سکتی ہے اور آپ کے کیلنڈر ڈیٹا کا اشتراک یا اسے محفوظ کر سکتی ہے۔"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"یہ ایپ آپ کے Android TV آلہ پر اسٹور کردہ سبھی کیلنڈر ایونٹس کو پڑھ سکتی ہے اور آپ کے کیلنڈر ڈیٹا کا اشتراک یا اسے محفوظ کر سکتی ہے۔"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 6a8811227c6e..ddcb6e15ffbf 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ilovaga yurak urishi, harorat, qondagi kislorod foizi kabi tanadagi sensor maʼlumotlaridan foydalanishga ruxsat beradi."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Fonda ishlaganda yurak urishi kabi tanadagi sensor maʼlumotlariga ruxsat"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ilovaga yurak urishi, harorat, qondagi kislorod foizi kabi tanadagi sensor maʼlumotlaridan ilova fonda ishlaganda foydalanishga ruxsat beradi."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Taqvim tadbirlari va tafsilotlarini o‘qish"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Bu ilova planshetdagi barcha taqvim tadbirlarini o‘qiy olishi hamda taqvim ma’lumotlarini ulashishi yoki saqlashi mumkin."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Bu ilova Android TV qurilmangizda barcha taqvim tadbirlarini oʻqiy olishi hamda taqvim maʼlumotlarini ulashishi yoki saqlashi mumkin."</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index eeb799f25b35..9ae3290f7ba5 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Cho phép ứng dụng truy cập vào dữ liệu cảm biến cơ thể khi đang dùng, chẳng hạn như nhịp tim, thân nhiệt và tỷ lệ phần trăm oxy trong máu."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Truy cập vào dữ liệu cảm biến cơ thể khi ở chế độ nền, chẳng hạn như nhịp tim"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Cho phép ứng dụng truy cập vào dữ liệu cảm biến cơ thể khi ở chế độ nền, chẳng hạn như nhịp tim, thân nhiệt và tỷ lệ phần trăm oxy trong máu."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Đọc chi tiết và sự kiện lịch"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ứng dụng này có thể đọc tất cả các sự kiện lịch được lưu trữ trên máy tính bảng của bạn và chia sẻ hoặc lưu dữ liệu lịch của bạn."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ứng dụng này có thể đọc tất cả sự kiện trên lịch mà bạn lưu vào thiết bị Android TV cũng như chia sẻ hoặc lưu dữ liệu lịch của bạn."</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 820d692947eb..118c52083f35 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"允许应用在使用期间访问身体传感器数据,如心率、体温和血氧浓度。"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"在后台运行时可访问身体传感器数据,如心率"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"允许应用在后台运行时访问身体传感器数据,如心率、体温和血氧浓度。"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"读取日历活动和详情"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"此应用可读取您平板电脑上存储的所有日历活动,并分享或保存您的日历数据。"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"此应用可读取您的 Android TV 设备上存储的所有日历活动,以及分享或保存您的日历数据。"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index b0e5f603c35e..2e44412afbbc 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"允許應用程式在使用時存取人體感應器資料,例如心率、體溫、血氧百分比等。"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"在背景執行時存取人體感應器資料,例如心率"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"允許應用程式在背景執行時存取人體感應器資料,例如心率、體溫、血氧百分比等。"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"讀取日曆活動和詳情"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"此應用程式可以讀取所有儲存在您的平板電腦的日曆活動,並分享或儲存您的日曆資料。"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"此應用程式可以讀取所有儲存在 Android TV 裝置上的日曆活動,並分享或儲存您的日曆資料。"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 79b8bcea43f2..21557905995d 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"允許應用程式在使用期間存取人體感應器資料,例如心跳速率、體溫和血氧比例。"</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"在背景執行時可存取人體感應器資料,例如心跳速率"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"允許應用程式在背景執行時存取人體感應器資料,例如心跳速率、體溫和血氧比例。"</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"讀取日曆活動和詳細資訊"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"這個應用程式可讀取所有儲存在平板電腦上的日曆活動資訊,以及共用或儲存日曆資料。"</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"這個應用程式可讀取所有儲存在 Android TV 裝置上的日曆活動,以及共用或儲存日曆資料。"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 55b5e9abf4a8..c81ab5e8c56c 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -458,6 +458,14 @@ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ivumela i-app ukuthi ifinyelele idatha yenzwa yomzimba, efana nokushaya kwenhliziyo, izinga lokushisa, namaphesenti komoyampilo wegazi, kuyilapho i-app isetshenziswa."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Finyelela kudatha yenzwa yomzimba, njengokushaya kwenhliziyo, ngenkathi ungemuva"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ivumela i-app ukuthi ifinyelele idatha yenzwa yomzimba, efana nokushaya kwenhliziyo, izinga lokushisa, namaphesenti komoyampilo wegazi, kuyilapho i-app ingemuva."</string> + <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) --> + <skip /> + <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) --> + <skip /> + <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) --> + <skip /> + <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) --> + <skip /> <string name="permlab_readCalendar" msgid="6408654259475396200">"Funda imicimbi yekhalenda nemininingwane"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Lolu hlelo lokusebenza lungafunda yonke imicimbi yekhalenda elondolozwe kuthebhulethi yakho nokwabelana noma ukulondoloza idatha yakho yekhalenda."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Lolu hlelo lokusebenza lungafunda yonke imicimbi yekhalenda elondolozwe kudivayisi yakho ye-Android TV nokwabelana noma ukulondoloza idatha yakho yekhalenda."</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index d3aee4329dd2..a07d85e53654 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2180,6 +2180,8 @@ <bool name="config_enableDefaultNotes">false</bool> <!-- Whether the default notes role for work profile should be enabled. --> <bool name="config_enableDefaultNotesForWorkProfile">false</bool> + <!-- The name of the package that will hold the system financed device controller role. --> + <string name="config_systemFinancedDeviceController" translatable="false">com.android.devicelockcontroller</string> <!-- The name of the package that will handle updating the device management role. --> <string name="config_devicePolicyManagementUpdater" translatable="false"></string> @@ -2383,22 +2385,13 @@ display, this value should be true. --> <bool name="config_perDisplayFocusEnabled">false</bool> - <!-- Whether the system enables motion prediction. Only enable this after confirming that the - model works well on your device. To enable system-based prediction, set this value to true. - --> - <bool name="config_enableMotionPrediction">true</bool> + <!-- Whether to use the system motion prediction model. Only set this value to true after + confirming that the model works well on your device. --> + <bool name="config_enableMotionPrediction">false</bool> <!-- Additional offset to use for motion prediction, in nanoseconds. A positive number indicates - that the prediction will take place further in the future. For example, suppose a - MotionEvent arrives with timestamp t=1, and the current expected presentation time is t=2. - Typically, the prediction will target the presentation time, t=2. If you'd like to make - prediction more aggressive, you could set the offset to a positive number. - Setting the offset to 1 here would mean that the prediction will be done for time t=3. - A negative number may also be provided, to make the prediction less aggressive. In general, - the offset here should represent some built-in hardware delays that may not be accounted - for by the "expected present time". See also: - https://developer.android.com/reference/android/view/ - Choreographer.FrameTimeline#getExpectedPresentationTimeNanos() --> + that the prediction will take place further in the future and, in general, should represent + some built-in hardware delays that prediction should try to recover. --> <integer name="config_motionPredictionOffsetNanos">0</integer> <!-- Whether a software navigation bar should be shown. NOTE: in the future this may be diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml index f7ed38ce9bcb..0ec3ef729bc9 100644 --- a/core/res/res/values/public-staging.xml +++ b/core/res/res/values/public-staging.xml @@ -146,6 +146,8 @@ <public name="config_systemWearHealthService" /> <!-- @hide @SystemApi --> <public name="config_defaultNotes" /> + <!-- @hide @SystemApi --> + <public name="config_systemFinancedDeviceController" /> </staging-public-group> <staging-public-group type="dimen" first-id="0x01ca0000"> diff --git a/core/tests/notificationtests/Android.bp b/core/tests/notificationtests/Android.bp deleted file mode 100644 index 1c0e39d9e022..000000000000 --- a/core/tests/notificationtests/Android.bp +++ /dev/null @@ -1,24 +0,0 @@ -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_applicable_licenses: ["frameworks_base_license"], -} - -android_test { - name: "NotificationStressTests", - // Include all test java files. - srcs: ["src/**/*.java"], - libs: [ - "android.test.runner", - "android.test.base", - ], - // Could build against SDK if it wasn't for the @RepetitiveTest annotation. - platform_apis: true, - static_libs: [ - "junit", - "ub-uiautomator", - ], -} diff --git a/core/tests/notificationtests/AndroidManifest.xml b/core/tests/notificationtests/AndroidManifest.xml deleted file mode 100644 index 51e530ab99c5..000000000000 --- a/core/tests/notificationtests/AndroidManifest.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2011 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. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.notification.tests" > - - <application > - <uses-library android:name="android.test.runner" /> - </application> - - <instrumentation - android:name="android.test.InstrumentationTestRunner" - android:targetPackage="com.android.notification.tests" - android:label="Notification Stress Tests" /> - -</manifest> diff --git a/core/tests/notificationtests/OWNERS b/core/tests/notificationtests/OWNERS deleted file mode 100644 index 396fd1213aca..000000000000 --- a/core/tests/notificationtests/OWNERS +++ /dev/null @@ -1 +0,0 @@ -include /services/core/java/com/android/server/notification/OWNERS diff --git a/core/tests/notificationtests/src/android/app/NotificationStressTest.java b/core/tests/notificationtests/src/android/app/NotificationStressTest.java deleted file mode 100644 index b2914d89e4f2..000000000000 --- a/core/tests/notificationtests/src/android/app/NotificationStressTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.os.RemoteException; -import android.os.SystemClock; -import android.support.test.uiautomator.UiDevice; -import android.test.InstrumentationTestCase; -import android.test.RepetitiveTest; -import android.util.Log; - -import java.lang.InterruptedException; -import java.lang.reflect.Method; -import java.util.Random; - -/** - * Test which spams notification manager with a large number of notifications, for both stress and - * performance testing. - */ -public class NotificationStressTest extends InstrumentationTestCase { - - private static final int NUM_ITERATIONS = 200; - private static final int NUM_ITERATIONS_2 = 30; - private static final int LONG_TIMEOUT = 2000; - // 49 notifications per app: defined as Variable MAX_PACKAGE_NOTIFICATIONS in - // NotificationManagerService.java - private static final int MAX_NOTIFCATIONS = 49; - private static final int[] ICONS = new int[] { - android.R.drawable.stat_notify_call_mute, - android.R.drawable.stat_notify_chat, - android.R.drawable.stat_notify_error, - android.R.drawable.stat_notify_missed_call, - android.R.drawable.stat_notify_more, - android.R.drawable.stat_notify_sdcard, - android.R.drawable.stat_notify_sdcard_prepare, - android.R.drawable.stat_notify_sdcard_usb, - android.R.drawable.stat_notify_sync, - android.R.drawable.stat_notify_sync_noanim, - android.R.drawable.stat_notify_voicemail, - }; - - private final Random mRandom = new Random(); - private Context mContext; - private NotificationManager mNotificationManager; - private UiDevice mDevice = null; - private int mNotifyId = 0; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mDevice = UiDevice.getInstance(getInstrumentation()); - mContext = getInstrumentation().getContext(); - mNotificationManager = (NotificationManager) mContext.getSystemService( - Context.NOTIFICATION_SERVICE); - mDevice.setOrientationNatural(); - mNotificationManager.cancelAll(); - } - - @Override - protected void tearDown() throws Exception { - mDevice.unfreezeRotation(); - mNotificationManager.cancelAll(); - mDevice.waitForIdle(); - super.tearDown(); - } - - @RepetitiveTest(numIterations = NUM_ITERATIONS) - public void testNotificationStress() { - // Cancel one of every five notifications to vary load on notification manager - if (mNotifyId % 5 == 4) { - mNotificationManager.cancel(mNotifyId - 4); - } - sendNotification(mNotifyId++, "testNotificationStressNotify"); - } - - @RepetitiveTest(numIterations = NUM_ITERATIONS_2) - public void testNotificationsWithShadeStress() throws Exception { - mDevice.openNotification(); - Thread.sleep(LONG_TIMEOUT); - for (int j = 0; j < MAX_NOTIFCATIONS; j++) { - sendNotification(mNotifyId++, "testNotificationStressNotify"); - } - Thread.sleep(LONG_TIMEOUT); - assertTrue(mNotificationManager.getActiveNotifications().length == MAX_NOTIFCATIONS); - for (int j = 0; j < MAX_NOTIFCATIONS; j++) { - mNotificationManager.cancel(--mNotifyId); - } - if (isLockScreen()) { - fail("Notification stress test failed, back to lockscreen"); - } - } - - private void sendNotification(int id, CharSequence text) { - // Fill in arbitrary content - Intent intent = new Intent(Intent.ACTION_VIEW).setPackage(mContext.getPackageName()); - PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, - PendingIntent.FLAG_MUTABLE); - CharSequence title = text + " " + id; - CharSequence subtitle = String.valueOf(System.currentTimeMillis()); - // Create "typical" notification with random icon - Notification notification = new Notification.Builder(mContext) - .setSmallIcon(ICONS[mRandom.nextInt(ICONS.length)]) - .setTicker(text) - .setWhen(System.currentTimeMillis()) - .setContentTitle(title) - .setContentText(subtitle) - .setContentIntent(pendingIntent) - .setPriority(Notification.PRIORITY_HIGH) - .build(); - mNotificationManager.notify(id, notification); - //update rate limit is 50 notifications/second. - SystemClock.sleep(20); - } - - private boolean isLockScreen() { - KeyguardManager myKM = (KeyguardManager) mContext - .getSystemService(Context.KEYGUARD_SERVICE); - if (myKM.inKeyguardRestrictedInputMode()) { - return true; - } else { - return false; - } - } -} diff --git a/keystore/java/android/security/KeyStoreException.java b/keystore/java/android/security/KeyStoreException.java index 6536e43f67fd..cb757794a11d 100644 --- a/keystore/java/android/security/KeyStoreException.java +++ b/keystore/java/android/security/KeyStoreException.java @@ -265,7 +265,7 @@ public class KeyStoreException extends Exception { private static int initializeRkpStatusForRegularErrors(int errorCode) { // Check if the system code mistakenly called a constructor of KeyStoreException with // the OUT_OF_KEYS error code but without RKP status. - if (isRkpRelatedError(errorCode)) { + if (errorCode == ResponseCode.OUT_OF_KEYS) { Log.e(TAG, "RKP error code without RKP status"); // Set RKP status to RKP_SERVER_REFUSED_ISSUANCE so that the caller never retries. return RKP_SERVER_REFUSED_ISSUANCE; @@ -301,7 +301,7 @@ public class KeyStoreException extends Exception { super(message); mErrorCode = errorCode; mRkpStatus = rkpStatus; - if (!isRkpRelatedError(mErrorCode)) { + if (mErrorCode != ResponseCode.OUT_OF_KEYS) { Log.e(TAG, "Providing RKP status for error code " + errorCode + " has no effect."); } } @@ -338,7 +338,7 @@ public class KeyStoreException extends Exception { public boolean isTransientFailure() { PublicErrorInformation failureInfo = getErrorInformation(mErrorCode); // Special-case handling for RKP failures: - if (mRkpStatus != RKP_SUCCESS && isRkpRelatedError(mErrorCode)) { + if (mRkpStatus != RKP_SUCCESS && mErrorCode == ResponseCode.OUT_OF_KEYS) { switch (mRkpStatus) { case RKP_TEMPORARILY_UNAVAILABLE: case RKP_FETCHING_PENDING_CONNECTIVITY: @@ -376,11 +376,6 @@ public class KeyStoreException extends Exception { return (failureInfo.indicators & IS_SYSTEM_ERROR) != 0; } - private static boolean isRkpRelatedError(int errorCode) { - return errorCode == ResponseCode.OUT_OF_KEYS - || errorCode == ResponseCode.OUT_OF_KEYS_REQUIRES_UPGRADE; - } - /** * Returns the re-try policy for transient failures. Valid only if * {@link #isTransientFailure()} returns {@code True}. @@ -388,7 +383,7 @@ public class KeyStoreException extends Exception { @RetryPolicy public int getRetryPolicy() { PublicErrorInformation failureInfo = getErrorInformation(mErrorCode); - // Special-case handling for RKP failures: + // Special-case handling for RKP failures (To be removed in API 34) if (mRkpStatus != RKP_SUCCESS) { switch (mRkpStatus) { case RKP_TEMPORARILY_UNAVAILABLE: @@ -404,10 +399,14 @@ public class KeyStoreException extends Exception { ? RETRY_WITH_EXPONENTIAL_BACKOFF : RETRY_NEVER; } } - if ((failureInfo.indicators & IS_TRANSIENT_ERROR) != 0) { - return RETRY_WITH_EXPONENTIAL_BACKOFF; - } else { - return RETRY_NEVER; + switch (mErrorCode) { + case ResponseCode.OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE: + return RETRY_AFTER_NEXT_REBOOT; + case ResponseCode.OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY: + return RETRY_WHEN_CONNECTIVITY_AVAILABLE; + default: + return (failureInfo.indicators & IS_TRANSIENT_ERROR) != 0 + ? RETRY_WITH_EXPONENTIAL_BACKOFF : RETRY_NEVER; } } @@ -657,8 +656,16 @@ public class KeyStoreException extends Exception { new PublicErrorInformation(0, ERROR_KEY_DOES_NOT_EXIST)); sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS, new PublicErrorInformation(IS_SYSTEM_ERROR, ERROR_ATTESTATION_KEYS_UNAVAILABLE)); - sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_REQUIRES_UPGRADE, + sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE, new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR, ERROR_DEVICE_REQUIRES_UPGRADE_FOR_ATTESTATION)); + sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY, + new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR, + ERROR_ATTESTATION_KEYS_UNAVAILABLE)); + sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_TRANSIENT_ERROR, + new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR, + ERROR_ATTESTATION_KEYS_UNAVAILABLE)); + sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_PERMANENT_ERROR, + new PublicErrorInformation(IS_SYSTEM_ERROR, ERROR_ATTESTATION_KEYS_UNAVAILABLE)); } } diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp index f615ad6e671b..0f4521951e3d 100644 --- a/libs/WindowManager/Shell/Android.bp +++ b/libs/WindowManager/Shell/Android.bp @@ -47,6 +47,7 @@ filegroup { "src/com/android/wm/shell/sysui/ShellSharedConstants.java", "src/com/android/wm/shell/common/TransactionPool.java", "src/com/android/wm/shell/animation/Interpolators.java", + "src/com/android/wm/shell/pip/PipContentOverlay.java", "src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java", ], path: "src", diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index 904ae860d76d..a93f090cb204 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dubbeltik buite ’n program om dit te herposisioneer"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Het dit"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Vou uit vir meer inligting."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimeer"</string> <string name="minimize_button_text" msgid="271592547935841753">"Maak klein"</string> <string name="close_button_text" msgid="2913281996024033299">"Maak toe"</string> diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index 8b467041ed5f..032767ed7d97 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ቦታውን ለመቀየር ከመተግበሪያው ውጪ ሁለቴ መታ ያድርጉ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ገባኝ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ለተጨማሪ መረጃ ይዘርጉ።"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"አስፋ"</string> <string name="minimize_button_text" msgid="271592547935841753">"አሳንስ"</string> <string name="close_button_text" msgid="2913281996024033299">"ዝጋ"</string> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index 635334db0d64..9bbee532c4c2 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"انقر مرّتين خارج تطبيق لتغيير موضعه."</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"حسنًا"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"التوسيع للحصول على مزيد من المعلومات"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"تكبير"</string> <string name="minimize_button_text" msgid="271592547935841753">"تصغير"</string> <string name="close_button_text" msgid="2913281996024033299">"إغلاق"</string> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index 788fd5c0597a..f7ea1396ee3f 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"এপ্টোৰ স্থান সলনি কৰিবলৈ ইয়াৰ বাহিৰত দুবাৰ টিপক"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"বুজি পালোঁ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"অধিক তথ্যৰ বাবে বিস্তাৰ কৰক।"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"সৰ্বাধিক মাত্ৰালৈ বঢ়াওক"</string> <string name="minimize_button_text" msgid="271592547935841753">"মিনিমাইজ কৰক"</string> <string name="close_button_text" msgid="2913281996024033299">"বন্ধ কৰক"</string> diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index a56918d98592..86b7714133f0 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tətbiqin yerini dəyişmək üçün kənarına iki dəfə toxunun"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Anladım"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Ətraflı məlumat üçün genişləndirin."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Böyüdün"</string> <string name="minimize_button_text" msgid="271592547935841753">"Kiçildin"</string> <string name="close_button_text" msgid="2913281996024033299">"Bağlayın"</string> diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml index dcb03aa0b365..4a1ee7ab321a 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvaput dodirnite izvan aplikacije da biste promenili njenu poziciju"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Važi"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite za još informacija."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Uvećajte"</string> <string name="minimize_button_text" msgid="271592547935841753">"Umanjite"</string> <string name="close_button_text" msgid="2913281996024033299">"Zatvorite"</string> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index f6b285a47f5a..1986699cb889 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Двойчы націсніце экран па-за праграмай, каб перамясціць яе"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Зразумела"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Разгарнуць для дадатковай інфармацыі"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Разгарнуць"</string> <string name="minimize_button_text" msgid="271592547935841753">"Згарнуць"</string> <string name="close_button_text" msgid="2913281996024033299">"Закрыць"</string> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index 044f2a7438dd..b8a0316827ad 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Докоснете два пъти извън дадено приложение, за да промените позицията му"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Разбрах"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Разгъване за още информация."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Увеличаване"</string> <string name="minimize_button_text" msgid="271592547935841753">"Намаляване"</string> <string name="close_button_text" msgid="2913281996024033299">"Затваряне"</string> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index 1fb0292bc56d..40395faebd06 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"কোনও অ্যাপের স্থান পরিবর্তন করতে তার বাইরে ডবল ট্যাপ করুন"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"বুঝেছি"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"আরও তথ্যের জন্য বড় করুন।"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"বড় করুন"</string> <string name="minimize_button_text" msgid="271592547935841753">"ছোট করুন"</string> <string name="close_button_text" msgid="2913281996024033299">"বন্ধ করুন"</string> diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index 8e52d78f2f5f..daef1a0699f7 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvaput dodirnite izvan aplikacije da promijenite njen položaj"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Razumijem"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite za više informacija."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiziranje"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimiziranje"</string> <string name="close_button_text" msgid="2913281996024033299">"Zatvaranje"</string> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index 6bc4f99ee7ef..85edc204771d 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Fes doble toc fora d\'una aplicació per canviar-ne la posició"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entesos"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Desplega per obtenir més informació."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximitza"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimitza"</string> <string name="close_button_text" msgid="2913281996024033299">"Tanca"</string> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index b638b0e5179f..ce1119714fea 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvojitým klepnutím mimo aplikaci změníte její umístění"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Rozbalením zobrazíte další informace."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximalizovat"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimalizovat"</string> <string name="close_button_text" msgid="2913281996024033299">"Zavřít"</string> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index e0b7a8cb44d7..38acf453b89d 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tryk to gange uden for en app for at justere dens placering"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Udvid for at få flere oplysninger."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimér"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string> <string name="close_button_text" msgid="2913281996024033299">"Luk"</string> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index caca8b42154e..d455fc694d06 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Außerhalb einer App doppeltippen, um die Position zu ändern"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ok"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Für weitere Informationen maximieren."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximieren"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimieren"</string> <string name="close_button_text" msgid="2913281996024033299">"Schließen"</string> diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index ffb4fb0169a9..051a20d2eda1 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Πατήστε δύο φορές έξω από μια εφαρμογή για να αλλάξετε τη θέση της"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Το κατάλαβα"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Ανάπτυξη για περισσότερες πληροφορίες."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Μεγιστοποίηση"</string> <string name="minimize_button_text" msgid="271592547935841753">"Ελαχιστοποίηση"</string> <string name="close_button_text" msgid="2913281996024033299">"Κλείσιμο"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index c71011d3b359..68f5de9d9f0a 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -84,6 +84,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Double-tap outside an app to reposition it"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Restart for a better view?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"You can restart the app so that it looks better on your screen, but you may lose your progress or any unsaved changes"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancel"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Restart"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Don\'t show again"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maximise"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimise"</string> <string name="close_button_text" msgid="2913281996024033299">"Close"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index 05091fb11864..204a24fa4efa 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -84,6 +84,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Double-tap outside an app to reposition it"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Restart for a better view?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"You can restart the app so it looks better on your screen, but you may lose your progress or any unsaved changes"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancel"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Restart"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Don’t show again"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maximize"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimize"</string> <string name="close_button_text" msgid="2913281996024033299">"Close"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml index c71011d3b359..68f5de9d9f0a 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -84,6 +84,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Double-tap outside an app to reposition it"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Restart for a better view?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"You can restart the app so that it looks better on your screen, but you may lose your progress or any unsaved changes"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancel"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Restart"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Don\'t show again"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maximise"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimise"</string> <string name="close_button_text" msgid="2913281996024033299">"Close"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml index c71011d3b359..68f5de9d9f0a 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -84,6 +84,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Double-tap outside an app to reposition it"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Restart for a better view?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"You can restart the app so that it looks better on your screen, but you may lose your progress or any unsaved changes"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancel"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Restart"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Don\'t show again"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maximise"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimise"</string> <string name="close_button_text" msgid="2913281996024033299">"Close"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml index 2993fe7b81f4..81e6e05e1ae0 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -84,6 +84,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Double-tap outside an app to reposition it"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Restart for a better view?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"You can restart the app so it looks better on your screen, but you may lose your progress or any unsaved changes"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancel"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Restart"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Don’t show again"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Maximize"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimize"</string> <string name="close_button_text" msgid="2913281996024033299">"Close"</string> diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index 0eaca8ba040f..7b569f255981 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Presiona dos veces fuera de una app para cambiar su ubicación"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expande para obtener más información."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index 9c8fed17859b..b9ee866aded0 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toca dos veces fuera de una aplicación para cambiarla de posición"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Mostrar más información"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index e8cbe5387410..de569e62e761 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Topeltpuudutage rakendusest väljaspool, et selle asendit muuta"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Selge"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Laiendage lisateabe saamiseks."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimeeri"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimeeri"</string> <string name="close_button_text" msgid="2913281996024033299">"Sule"</string> diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index 4417668657e2..c05b3c794dcc 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Aplikazioaren posizioa aldatzeko, sakatu birritan haren kanpoaldea"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ados"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Informazio gehiago lortzeko, zabaldu hau."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximizatu"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizatu"</string> <string name="close_button_text" msgid="2913281996024033299">"Itxi"</string> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index 7375faf8b30f..f7d52f910f42 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"برای جابهجا کردن برنامه، بیرون از آن دوضربه بزنید"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"متوجهام"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"برای اطلاعات بیشتر، گسترده کنید."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"بزرگ کردن"</string> <string name="minimize_button_text" msgid="271592547935841753">"کوچک کردن"</string> <string name="close_button_text" msgid="2913281996024033299">"بستن"</string> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index 7729d1c62f30..91120d4615c5 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Kaksoisnapauta sovelluksen ulkopuolella, jos haluat siirtää sitä"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Katso lisätietoja laajentamalla."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Suurenna"</string> <string name="minimize_button_text" msgid="271592547935841753">"Pienennä"</string> <string name="close_button_text" msgid="2913281996024033299">"Sulje"</string> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index 634880072d47..59bd339c6181 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Touchez deux fois à côté d\'une application pour la repositionner"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développer pour en savoir plus."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string> <string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string> <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index 184221345b23..41de4db9660d 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Appuyez deux fois en dehors d\'une appli pour la repositionner"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développez pour obtenir plus d\'informations"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string> <string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string> <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index 2e05d4c3b548..573e17ed242d 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toca dúas veces fóra da aplicación para cambiala de posición"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Despregar para obter máis información."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> <string name="close_button_text" msgid="2913281996024033299">"Pechar"</string> diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index e680298c90bc..35e960701756 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"કોઈ ઍપની જગ્યા બદલવા માટે, તેની બહાર બે વાર ટૅપ કરો"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"સમજાઈ ગયું"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"વધુ માહિતી માટે મોટું કરો."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"મોટું કરો"</string> <string name="minimize_button_text" msgid="271592547935841753">"નાનું કરો"</string> <string name="close_button_text" msgid="2913281996024033299">"બંધ કરો"</string> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index 9a926d88f7b8..173029a1275c 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"किसी ऐप्लिकेशन की जगह बदलने के लिए, उसके बाहर दो बार टैप करें"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ठीक है"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ज़्यादा जानकारी के लिए बड़ा करें."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"बड़ा करें"</string> <string name="minimize_button_text" msgid="271592547935841753">"विंडो छोटी करें"</string> <string name="close_button_text" msgid="2913281996024033299">"बंद करें"</string> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index 23a5970d805e..c45bb56a6438 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvaput dodirnite izvan aplikacije da biste je premjestili"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Shvaćam"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite da biste saznali više."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiziraj"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimiziraj"</string> <string name="close_button_text" msgid="2913281996024033299">"Zatvori"</string> diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index 1bbbdb7786b4..7c45113a89d0 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Koppintson duplán az alkalmazáson kívül az áthelyezéséhez"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Értem"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Kibontással további információkhoz juthat."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Teljes méret"</string> <string name="minimize_button_text" msgid="271592547935841753">"Kis méret"</string> <string name="close_button_text" msgid="2913281996024033299">"Bezárás"</string> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index 6eef4afda3ff..c26c54031e99 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Կրկնակի հպեք հավելվածի կողքին՝ այն տեղափոխելու համար"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Եղավ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Ծավալեք՝ ավելին իմանալու համար։"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Ծավալել"</string> <string name="minimize_button_text" msgid="271592547935841753">"Ծալել"</string> <string name="close_button_text" msgid="2913281996024033299">"Փակել"</string> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index 61a9558972e0..8247309ce8a0 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ketuk dua kali di luar aplikasi untuk mengubah posisinya"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Oke"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Luaskan untuk melihat informasi selengkapnya."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimalkan"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimalkan"</string> <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index 0b873bc82e63..b64f2d521404 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ýttu tvisvar utan við forrit til að færa það"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ég skil"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Stækka til að sjá frekari upplýsingar."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Stækka"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minnka"</string> <string name="close_button_text" msgid="2913281996024033299">"Loka"</string> diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index da4d0bbe1951..ffb5f30e30c7 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -84,6 +84,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tocca due volte fuori da un\'app per riposizionarla"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Espandi per avere ulteriori informazioni."</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Vuoi riavviare per migliorare la visualizzazione?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Puoi riavviare l\'app affinché venga visualizzata meglio sullo schermo, ma potresti perdere i tuoi progressi o eventuali modifiche non salvate"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Annulla"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Riavvia"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Non mostrare più"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Ingrandisci"</string> <string name="minimize_button_text" msgid="271592547935841753">"Riduci a icona"</string> <string name="close_button_text" msgid="2913281996024033299">"Chiudi"</string> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index e9a53ddcd1e6..5f204b21110b 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"צריך להקיש הקשה כפולה מחוץ לאפליקציה כדי למקם אותה מחדש"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"הבנתי"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"מרחיבים כדי לקבל מידע נוסף."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"הגדלה"</string> <string name="minimize_button_text" msgid="271592547935841753">"מזעור"</string> <string name="close_button_text" msgid="2913281996024033299">"סגירה"</string> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index 2930cc3747b9..8c70341c776e 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -84,6 +84,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"位置を変えるにはアプリの外側をダブルタップしてください"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"開くと詳細が表示されます。"</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"再起動して画面をすっきりさせますか?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"アプリを再起動して画面をすっきりさせることはできますが、進捗状況が失われ、保存されていない変更が消える可能性があります"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"キャンセル"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"再起動"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"次回から表示しない"</string> <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string> <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string> <string name="close_button_text" msgid="2913281996024033299">"閉じる"</string> diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index 848be3f86392..82048c904a3e 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ორმაგად შეეხეთ აპის გარშემო სივრცეს, რათა ის სხვაგან გადაიტანოთ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"გასაგებია"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"დამატებითი ინფორმაციისთვის გააფართოეთ."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"მაქსიმალურად გაშლა"</string> <string name="minimize_button_text" msgid="271592547935841753">"ჩაკეცვა"</string> <string name="close_button_text" msgid="2913281996024033299">"დახურვა"</string> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index 8d08ccabb623..ed4a14bf14cb 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Қолданбаның орнын өзгерту үшін одан тыс жерді екі рет түртіңіз."</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Түсінікті"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Толығырақ ақпарат алу үшін терезені жайыңыз."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Жаю"</string> <string name="minimize_button_text" msgid="271592547935841753">"Кішірейту"</string> <string name="close_button_text" msgid="2913281996024033299">"Жабу"</string> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index 7c4ea57e81d8..e705301e5800 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ចុចពីរដងនៅក្រៅកម្មវិធី ដើម្បីប្ដូរទីតាំងកម្មវិធីនោះ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"យល់ហើយ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ពង្រីកដើម្បីទទួលបានព័ត៌មានបន្ថែម។"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"ពង្រីក"</string> <string name="minimize_button_text" msgid="271592547935841753">"បង្រួម"</string> <string name="close_button_text" msgid="2913281996024033299">"បិទ"</string> diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index 72906174a65c..bebf0c0abcb0 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ಆ್ಯಪ್ ಒಂದರ ಸ್ಥಾನವನ್ನು ಬದಲಾಯಿಸಲು ಅದರ ಹೊರಗೆ ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ಸರಿ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ವಿಸ್ತೃತಗೊಳಿಸಿ."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"ಹಿಗ್ಗಿಸಿ"</string> <string name="minimize_button_text" msgid="271592547935841753">"ಕುಗ್ಗಿಸಿ"</string> <string name="close_button_text" msgid="2913281996024033299">"ಮುಚ್ಚಿರಿ"</string> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index 59b405ff1e72..6c58c3129d01 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"앱 위치를 조정하려면 앱 외부를 두 번 탭합니다."</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"확인"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"추가 정보는 펼쳐서 확인하세요."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"최대화"</string> <string name="minimize_button_text" msgid="271592547935841753">"최소화"</string> <string name="close_button_text" msgid="2913281996024033299">"닫기"</string> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index 6919a8e1f02c..9f4dbb5b193c 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Колдонмону жылдыруу үчүн сырт жагын эки жолу таптаңыз"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Түшүндүм"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Толук маалымат алуу үчүн жайып көрүңүз."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Чоңойтуу"</string> <string name="minimize_button_text" msgid="271592547935841753">"Кичирейтүү"</string> <string name="close_button_text" msgid="2913281996024033299">"Жабуу"</string> diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index d5ea3cf37c8b..97a73446be02 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ແຕະສອງເທື່ອໃສ່ນອກແອັບໃດໜຶ່ງເພື່ອຈັດຕຳແໜ່ງຂອງມັນຄືນໃໝ່"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ເຂົ້າໃຈແລ້ວ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ຂະຫຍາຍເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"ຂະຫຍາຍໃຫຍ່ສຸດ"</string> <string name="minimize_button_text" msgid="271592547935841753">"ຫຍໍ້ລົງ"</string> <string name="close_button_text" msgid="2913281996024033299">"ປິດ"</string> diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index 922f5b59a703..5fc2592edad5 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -84,6 +84,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dukart palieskite už programos ribų, kad pakeistumėte jos poziciją"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Supratau"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Išskleiskite, jei reikia daugiau informacijos."</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Paleisti iš naujo, kad būtų geresnis vaizdas?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Galite iš naujo paleisti programą, kad ji geriau atrodytų ekrane, bet galite prarasti eigą ir neišsaugotus pakeitimus"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Atšaukti"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Paleisti iš naujo"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Daugiau neberodyti"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Padidinti"</string> <string name="minimize_button_text" msgid="271592547935841753">"Sumažinti"</string> <string name="close_button_text" msgid="2913281996024033299">"Uždaryti"</string> diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index 08ac9280bbab..a89545dfea3e 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Lai pārvietotu lietotni, veiciet dubultskārienu ārpus lietotnes"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Labi"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Izvērsiet, lai iegūtu plašāku informāciju."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimizēt"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizēt"</string> <string name="close_button_text" msgid="2913281996024033299">"Aizvērt"</string> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index ae71ae90043f..1aab9effa5fb 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -84,6 +84,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Допрете двапати надвор од некоја апликација за да ја преместите"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Сфатив"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Проширете за повеќе информации."</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Да се рестартира за подобар приказ?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Може да ја рестартирате апликацијата за да изгледа подобро на екранот, но може да го изгубите напредокот или незачуваните промени"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Откажи"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"Рестартирај"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Не прикажувај повторно"</string> <string name="maximize_button_text" msgid="1650859196290301963">"Зголеми"</string> <string name="minimize_button_text" msgid="271592547935841753">"Минимизирај"</string> <string name="close_button_text" msgid="2913281996024033299">"Затвори"</string> diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index 092331284f61..f74738ba9336 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ആപ്പിന്റെ സ്ഥാനം മാറ്റാൻ അതിന് പുറത്ത് ഡബിൾ ടാപ്പ് ചെയ്യുക"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"മനസ്സിലായി"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"കൂടുതൽ വിവരങ്ങൾക്ക് വികസിപ്പിക്കുക."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"വലുതാക്കുക"</string> <string name="minimize_button_text" msgid="271592547935841753">"ചെറുതാക്കുക"</string> <string name="close_button_text" msgid="2913281996024033299">"അടയ്ക്കുക"</string> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index c1950a1d3241..51c45847364c 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Аппыг дахин байрлуулахын тулд гадна талд нь хоёр товшино"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ойлголоо"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Нэмэлт мэдээлэл авах бол дэлгэнэ үү."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Томруулах"</string> <string name="minimize_button_text" msgid="271592547935841753">"Багасгах"</string> <string name="close_button_text" msgid="2913281996024033299">"Хаах"</string> diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index 29821f6a8bbc..cbde558ccf9c 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ॲपची स्थिती पुन्हा बदलण्यासाठी, त्याच्या बाहेर दोनदा टॅप करा"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"समजले"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"अधिक माहितीसाठी विस्तार करा."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"मोठे करा"</string> <string name="minimize_button_text" msgid="271592547935841753">"लहान करा"</string> <string name="close_button_text" msgid="2913281996024033299">"बंद करा"</string> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index c3db19d46a55..23f7e5245c07 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ketik dua kali di luar apl untuk menempatkan semula apl itu"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Kembangkan untuk mendapatkan maklumat lanjut."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimumkan"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimumkan"</string> <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index b2bb37dd7730..2fae552cba47 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"နေရာပြန်ချရန် အက်ပ်အပြင်ဘက်ကို နှစ်ချက်တို့ပါ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"နားလည်ပြီ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"နောက်ထပ်အချက်အလက်များအတွက် ချဲ့နိုင်သည်။"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"ချဲ့ရန်"</string> <string name="minimize_button_text" msgid="271592547935841753">"ချုံ့ရန်"</string> <string name="close_button_text" msgid="2913281996024033299">"ပိတ်ရန်"</string> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index 90b9dfca6116..b34e1349ffa8 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dobbelttrykk utenfor en app for å flytte den"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Greit"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Vis for å få mer informasjon."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimer"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string> <string name="close_button_text" msgid="2913281996024033299">"Lukk"</string> diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index 15f22f7ff2d3..7bcca1a22c83 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"तपाईं जुन एपको स्थिति मिलाउन चाहनुहुन्छ सोही एपको बाहिर डबल ट्याप गर्नुहोस्"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"बुझेँ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"थप जानकारी प्राप्त गर्न चाहनुहुन्छ भने एक्स्पान्ड गर्नुहोस्।"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"ठुलो बनाउनुहोस्"</string> <string name="minimize_button_text" msgid="271592547935841753">"मिनिमाइज गर्नुहोस्"</string> <string name="close_button_text" msgid="2913281996024033299">"बन्द गर्नुहोस्"</string> diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index f9f4ef4a4b63..6ec47396a45e 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dubbeltik naast een app om deze opnieuw te positioneren"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Uitvouwen voor meer informatie."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximaliseren"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimaliseren"</string> <string name="close_button_text" msgid="2913281996024033299">"Sluiten"</string> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index 5a76a6f3f22a..0f27984fa4c0 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ଏକ ଆପକୁ ରିପୋଜିସନ କରିବା ପାଇଁ ଏହାର ବାହାରେ ଦୁଇଥର-ଟାପ କରନ୍ତୁ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ବୁଝିଗଲି"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ଅଧିକ ସୂଚନା ପାଇଁ ବିସ୍ତାର କରନ୍ତୁ।"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"ବଡ଼ କରନ୍ତୁ"</string> <string name="minimize_button_text" msgid="271592547935841753">"ଛୋଟ କରନ୍ତୁ"</string> <string name="close_button_text" msgid="2913281996024033299">"ବନ୍ଦ କରନ୍ତୁ"</string> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index 617c95eec8d9..2baec3c1ab34 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ਕਿਸੇ ਐਪ ਦੀ ਜਗ੍ਹਾ ਬਦਲਣ ਲਈ ਉਸ ਦੇ ਬਾਹਰ ਡਬਲ ਟੈਪ ਕਰੋ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ਸਮਝ ਲਿਆ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਵਿਸਤਾਰ ਕਰੋ।"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"ਵੱਡਾ ਕਰੋ"</string> <string name="minimize_button_text" msgid="271592547935841753">"ਛੋਟਾ ਕਰੋ"</string> <string name="close_button_text" msgid="2913281996024033299">"ਬੰਦ ਕਰੋ"</string> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index 4a17ec74bada..ecf6b4d4a47c 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Kliknij dwukrotnie poza aplikacją, aby ją przenieść"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Rozwiń, aby wyświetlić więcej informacji."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksymalizuj"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimalizuj"</string> <string name="close_button_text" msgid="2913281996024033299">"Zamknij"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index 69be68ead461..847573bec7e4 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toque duas vezes fora de um app para reposicionar"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendi"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Abra para ver mais informações."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index 13e83ac0bcf7..b684c6c88c7e 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toque duas vezes fora de uma app para a reposicionar"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expandir para obter mais informações"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string> diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index 69be68ead461..847573bec7e4 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toque duas vezes fora de um app para reposicionar"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendi"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Abra para ver mais informações."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string> <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index c112a9d26a7c..5342dfb1fc2b 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Atinge de două ori lângă o aplicație pentru a o repoziționa"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Extinde pentru mai multe informații"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximizează"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizează"</string> <string name="close_button_text" msgid="2913281996024033299">"Închide"</string> diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index 489adc06e93d..71925a1d140d 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Чтобы переместить приложение, дважды нажмите рядом с ним."</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ОК"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Развернуть, чтобы узнать больше."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Развернуть"</string> <string name="minimize_button_text" msgid="271592547935841753">"Свернуть"</string> <string name="close_button_text" msgid="2913281996024033299">"Закрыть"</string> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index 32371148fce2..188a1375fab6 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"යෙදුමක් නැවත ස්ථානගත කිරීමට පිටතින් දෙවරක් තට්ටු කරන්න"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"තේරුණා"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"වැඩිදුර තොරතුරු සඳහා දිග හරින්න"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"විහිදන්න"</string> <string name="minimize_button_text" msgid="271592547935841753">"කුඩා කරන්න"</string> <string name="close_button_text" msgid="2913281996024033299">"වසන්න"</string> diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index a7530215d010..0aa4f30198c1 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvojitým klepnutím mimo aplikácie zmeníte jej pozíciu"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Dobre"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Po rozbalení sa dozviete viac."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maximalizovať"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimalizovať"</string> <string name="close_button_text" msgid="2913281996024033299">"Zavrieť"</string> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index b5d87333d85e..a4eb3d0106fc 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvakrat se dotaknite zunaj aplikacije, če jo želite prestaviti."</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"V redu"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Razširitev za več informacij"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiraj"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimiraj"</string> <string name="close_button_text" msgid="2913281996024033299">"Zapri"</string> diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index ebd644c7425f..cc4b7a46a89d 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Trokit dy herë jashtë një aplikacioni për ta ripozicionuar"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"E kuptova"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Zgjeroje për më shumë informacion."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Maksimizo"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimizo"</string> <string name="close_button_text" msgid="2913281996024033299">"Mbyll"</string> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index d051ca350682..80f7aa65cea7 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Двапут додирните изван апликације да бисте променили њену позицију"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Важи"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Проширите за још информација."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Увећајте"</string> <string name="minimize_button_text" msgid="271592547935841753">"Умањите"</string> <string name="close_button_text" msgid="2913281996024033299">"Затворите"</string> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index cd46039b26b5..4a4b6c9fd3f7 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tryck snabbt två gånger utanför en app för att flytta den"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Utöka för mer information."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Utöka"</string> <string name="minimize_button_text" msgid="271592547935841753">"Minimera"</string> <string name="close_button_text" msgid="2913281996024033299">"Stäng"</string> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index 345fbf81cd48..ad331447b83a 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Gusa mara mbili nje ya programu ili uihamishe"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Nimeelewa"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Panua ili upate maelezo zaidi."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Panua"</string> <string name="minimize_button_text" msgid="271592547935841753">"Punguza"</string> <string name="close_button_text" msgid="2913281996024033299">"Funga"</string> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index 525f2ea043fc..52f5e2233345 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ஆப்ஸை இடம் மாற்ற அதன் வெளியில் இருமுறை தட்டலாம்"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"சரி"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"கூடுதல் தகவல்களுக்கு விரிவாக்கலாம்."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"பெரிதாக்கும்"</string> <string name="minimize_button_text" msgid="271592547935841753">"சிறிதாக்கும்"</string> <string name="close_button_text" msgid="2913281996024033299">"மூடும்"</string> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 0c0114afeed2..2eb739d92c33 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"యాప్ స్థానాన్ని మార్చడానికి దాని వెలుపల డబుల్-ట్యాప్ చేయండి"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"అర్థమైంది"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"మరింత సమాచారం కోసం విస్తరించండి."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"గరిష్టీకరించండి"</string> <string name="minimize_button_text" msgid="271592547935841753">"కుదించండి"</string> <string name="close_button_text" msgid="2913281996024033299">"మూసివేయండి"</string> diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index 9f3a14610225..e0b1bb18f67b 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -84,6 +84,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"แตะสองครั้งด้านนอกแอปเพื่อเปลี่ยนตำแหน่ง"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"รับทราบ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ขยายเพื่อดูข้อมูลเพิ่มเติม"</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"รีสตาร์ทเพื่อรับมุมมองที่ดียิ่งขึ้นใช่ไหม"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"คุณรีสตาร์ทแอปเพื่อรับมุมมองที่ดียิ่งขึ้นบนหน้าจอได้ แต่ความคืบหน้าและการเปลี่ยนแปลงใดๆ ที่ไม่ได้บันทึกอาจหายไป"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ยกเลิก"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"รีสตาร์ท"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ไม่ต้องแสดงข้อความนี้อีก"</string> <string name="maximize_button_text" msgid="1650859196290301963">"ขยายใหญ่สุด"</string> <string name="minimize_button_text" msgid="271592547935841753">"ย่อ"</string> <string name="close_button_text" msgid="2913281996024033299">"ปิด"</string> diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index c20a07f1cf90..a49ed27f8476 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -84,6 +84,11 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Mag-double tap sa labas ng app para baguhin ang posisyon nito"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"I-expand para sa higit pang impormasyon."</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"I-restart para sa mas magandang hitsura?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Puwede mong i-restart ang app para maging mas maganda ang itsura nito sa iyong screen, pero posibleng mawala ang pag-usad mo o anumang hindi na-save na pagbabago"</string> + <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Kanselahin"</string> + <string name="letterbox_restart_restart" msgid="8529976234412442973">"I-restart"</string> + <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Huwag nang ipakita ulit"</string> <string name="maximize_button_text" msgid="1650859196290301963">"I-maximize"</string> <string name="minimize_button_text" msgid="271592547935841753">"I-minimize"</string> <string name="close_button_text" msgid="2913281996024033299">"Isara"</string> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index aeb86da2a6ed..c19e0834f332 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Yeniden konumlandırmak için uygulamanın dışına iki kez dokunun"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Anladım"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Daha fazla bilgi için genişletin."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Ekranı Kapla"</string> <string name="minimize_button_text" msgid="271592547935841753">"Küçült"</string> <string name="close_button_text" msgid="2913281996024033299">"Kapat"</string> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index b589ed8c7739..68694019a2f2 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Щоб перемістити додаток, двічі торкніться області поза ним"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ОK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Розгорніть, щоб дізнатися більше."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Збільшити"</string> <string name="minimize_button_text" msgid="271592547935841753">"Згорнути"</string> <string name="close_button_text" msgid="2913281996024033299">"Закрити"</string> diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index 81672bff7545..e3a22eb612cc 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"کسی ایپ کی پوزیشن تبدیل کرنے کے لیے اس ایپ کے باہر دو بار تھپتھپائیں"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"سمجھ آ گئی"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"مزید معلومات کے لیے پھیلائیں۔"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"بڑا کریں"</string> <string name="minimize_button_text" msgid="271592547935841753">"چھوٹا کریں"</string> <string name="close_button_text" msgid="2913281996024033299">"بند کریں"</string> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index d0384e944248..d12dac377322 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Qayta joylash uchun ilova tashqarisiga ikki marta bosing"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Batafsil axborot olish uchun kengaytiring."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Yoyish"</string> <string name="minimize_button_text" msgid="271592547935841753">"Kichraytirish"</string> <string name="close_button_text" msgid="2913281996024033299">"Yopish"</string> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index 49986b591e28..39de38cd2151 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Nhấn đúp bên ngoài ứng dụng để đặt lại vị trí"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Mở rộng để xem thêm thông tin."</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Phóng to"</string> <string name="minimize_button_text" msgid="271592547935841753">"Thu nhỏ"</string> <string name="close_button_text" msgid="2913281996024033299">"Đóng"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index acdb2523597d..c787f6127102 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"在某个应用外连续点按两次,即可调整它的位置"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展开即可了解详情。"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string> <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string> <string name="close_button_text" msgid="2913281996024033299">"关闭"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index b1a957e5c5cf..395b2a9ab3f2 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"在應用程式外輕按兩下即可調整位置"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展開即可查看詳情。"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string> <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string> <string name="close_button_text" msgid="2913281996024033299">"關閉"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index bb3dba17abc7..8a84f15b03a5 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"在應用程式外輕觸兩下即可調整位置"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"我知道了"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展開即可查看詳細資訊。"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string> <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string> <string name="close_button_text" msgid="2913281996024033299">"關閉"</string> diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index 51a23ff64403..fca5a7a01bcd 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -84,6 +84,16 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Thepha kabili ngaphandle kwe-app ukuze uyimise kabusha"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ngiyezwa"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Nweba ukuze uthole ulwazi olwengeziwe"</string> + <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) --> + <skip /> + <!-- no translation found for letterbox_restart_cancel (1342209132692537805) --> + <skip /> + <!-- no translation found for letterbox_restart_restart (8529976234412442973) --> + <skip /> + <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) --> + <skip /> <string name="maximize_button_text" msgid="1650859196290301963">"Khulisa"</string> <string name="minimize_button_text" msgid="271592547935841753">"Nciphisa"</string> <string name="close_button_text" msgid="2913281996024033299">"Vala"</string> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java index 94e01e96730c..5d451a5006e1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java @@ -16,8 +16,6 @@ package com.android.wm.shell; -import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; - import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; @@ -30,27 +28,20 @@ import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; import android.graphics.Rect; import android.graphics.Region; -import android.os.Binder; -import android.util.CloseGuard; import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewTreeObserver; -import android.window.WindowContainerToken; -import android.window.WindowContainerTransaction; - -import com.android.wm.shell.common.SyncTransactionQueue; -import java.io.PrintWriter; import java.util.concurrent.Executor; /** - * View that can display a task. + * A {@link SurfaceView} that can display a task. This is a concrete implementation for + * {@link TaskViewBase} which interacts {@link TaskViewTaskController}. */ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, - ShellTaskOrganizer.TaskListener, ViewTreeObserver.OnComputeInternalInsetsListener { - + ViewTreeObserver.OnComputeInternalInsetsListener, TaskViewBase { /** Callback for listening task state. */ public interface Listener { /** @@ -75,65 +66,33 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, default void onBackPressedOnTaskRoot(int taskId) {} } - private final CloseGuard mGuard = new CloseGuard(); - - private final ShellTaskOrganizer mTaskOrganizer; - private final Executor mShellExecutor; - private final SyncTransactionQueue mSyncQueue; - private final TaskViewTransitions mTaskViewTransitions; - - protected ActivityManager.RunningTaskInfo mTaskInfo; - private WindowContainerToken mTaskToken; - private SurfaceControl mTaskLeash; - private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction(); - private boolean mSurfaceCreated; - private boolean mIsInitialized; - private boolean mNotifiedForInitialized; - private Listener mListener; - private Executor mListenerExecutor; - private Region mObscuredTouchRegion; - private final Rect mTmpRect = new Rect(); private final Rect mTmpRootRect = new Rect(); private final int[] mTmpLocation = new int[2]; + private final TaskViewTaskController mTaskViewTaskController; + private Region mObscuredTouchRegion; - public TaskView(Context context, ShellTaskOrganizer organizer, - TaskViewTransitions taskViewTransitions, SyncTransactionQueue syncQueue) { + public TaskView(Context context, TaskViewTaskController taskViewTaskController) { super(context, null, 0, 0, true /* disableBackgroundLayer */); - - mTaskOrganizer = organizer; - mShellExecutor = organizer.getExecutor(); - mSyncQueue = syncQueue; - mTaskViewTransitions = taskViewTransitions; - if (mTaskViewTransitions != null) { - mTaskViewTransitions.addTaskView(this); - } + mTaskViewTaskController = taskViewTaskController; + // TODO(b/266736992): Think about a better way to set the TaskViewBase on the + // TaskViewTaskController and vice-versa + mTaskViewTaskController.setTaskViewBase(this); getHolder().addCallback(this); - mGuard.open("release"); - } - - /** - * @return {@code True} when the TaskView's surface has been created, {@code False} otherwise. - */ - public boolean isInitialized() { - return mIsInitialized; - } - - /** Until all users are converted, we may have mixed-use (eg. Car). */ - private boolean isUsingShellTransitions() { - return mTaskViewTransitions != null && mTaskViewTransitions.isEnabled(); } /** - * Only one listener may be set on the view, throws an exception otherwise. + * Launch a new activity. + * + * @param pendingIntent Intent used to launch an activity. + * @param fillInIntent Additional Intent data, see {@link Intent#fillIn Intent.fillIn()} + * @param options options for the activity. + * @param launchBounds the bounds (window size and position) that the activity should be + * launched in, in pixels and in screen coordinates. */ - public void setListener(@NonNull Executor executor, Listener listener) { - if (mListener != null) { - throw new IllegalStateException( - "Trying to set a listener when one has already been set"); - } - mListener = listener; - mListenerExecutor = executor; + public void startActivity(@NonNull PendingIntent pendingIntent, @Nullable Intent fillInIntent, + @NonNull ActivityOptions options, @Nullable Rect launchBounds) { + mTaskViewTaskController.startActivity(pendingIntent, fillInIntent, options, launchBounds); } /** @@ -148,61 +107,47 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, */ public void startShortcutActivity(@NonNull ShortcutInfo shortcut, @NonNull ActivityOptions options, @Nullable Rect launchBounds) { - prepareActivityOptions(options, launchBounds); - LauncherApps service = mContext.getSystemService(LauncherApps.class); - if (isUsingShellTransitions()) { - mShellExecutor.execute(() -> { - final WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.startShortcut(mContext.getPackageName(), shortcut, options.toBundle()); - mTaskViewTransitions.startTaskView(wct, this); - }); - return; + mTaskViewTaskController.startShortcutActivity(shortcut, options, launchBounds); + } + + @Override + public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { + onLocationChanged(); + if (taskInfo.taskDescription != null) { + setResizeBackgroundColor(taskInfo.taskDescription.getBackgroundColor()); } - try { - service.startShortcut(shortcut, null /* sourceBounds */, options.toBundle()); - } catch (Exception e) { - throw new RuntimeException(e); + } + + @Override + public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { + if (taskInfo.taskDescription != null) { + setResizeBackgroundColor(taskInfo.taskDescription.getBackgroundColor()); } } /** - * Launch a new activity. - * - * @param pendingIntent Intent used to launch an activity. - * @param fillInIntent Additional Intent data, see {@link Intent#fillIn Intent.fillIn()} - * @param options options for the activity. - * @param launchBounds the bounds (window size and position) that the activity should be - * launched in, in pixels and in screen coordinates. + * @return {@code True} when the TaskView's surface has been created, {@code False} otherwise. */ - public void startActivity(@NonNull PendingIntent pendingIntent, @Nullable Intent fillInIntent, - @NonNull ActivityOptions options, @Nullable Rect launchBounds) { - prepareActivityOptions(options, launchBounds); - if (isUsingShellTransitions()) { - mShellExecutor.execute(() -> { - WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.sendPendingIntent(pendingIntent, fillInIntent, options.toBundle()); - mTaskViewTransitions.startTaskView(wct, this); - }); - return; - } - try { - pendingIntent.send(mContext, 0 /* code */, fillInIntent, - null /* onFinished */, null /* handler */, null /* requiredPermission */, - options.toBundle()); - } catch (Exception e) { - throw new RuntimeException(e); - } + public boolean isInitialized() { + return mTaskViewTaskController.isInitialized(); + } + + @Override + public Rect getCurrentBoundsOnScreen() { + getBoundsOnScreen(mTmpRect); + return mTmpRect; } - private void prepareActivityOptions(ActivityOptions options, Rect launchBounds) { - final Binder launchCookie = new Binder(); - mShellExecutor.execute(() -> { - mTaskOrganizer.setPendingLaunchCookieListener(launchCookie, this); - }); - options.setLaunchBounds(launchBounds); - options.setLaunchCookie(launchCookie); - options.setLaunchWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - options.setRemoveWithTaskOrganizer(true); + @Override + public void setResizeBgColor(SurfaceControl.Transaction t, int bgColor) { + setResizeBackgroundColor(t, bgColor); + } + + /** + * Only one listener may be set on the view, throws an exception otherwise. + */ + public void setListener(@NonNull Executor executor, TaskView.Listener listener) { + mTaskViewTaskController.setListener(executor, listener); } /** @@ -227,251 +172,38 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, * Call when view position or size has changed. Do not call when animating. */ public void onLocationChanged() { - if (mTaskToken == null) { - return; - } - // Sync Transactions can't operate simultaneously with shell transition collection. - // The transition animation (upon showing) will sync the location itself. - if (isUsingShellTransitions() && mTaskViewTransitions.hasPending()) return; - - WindowContainerTransaction wct = new WindowContainerTransaction(); - updateWindowBounds(wct); - mSyncQueue.queue(wct); - } - - private void updateWindowBounds(WindowContainerTransaction wct) { getBoundsOnScreen(mTmpRect); - wct.setBounds(mTaskToken, mTmpRect); + mTaskViewTaskController.onLocationChanged(mTmpRect); } /** * Release this container if it is initialized. */ public void release() { - performRelease(); - } - - @Override - protected void finalize() throws Throwable { - try { - if (mGuard != null) { - mGuard.warnIfOpen(); - performRelease(); - } - } finally { - super.finalize(); - } - } - - private void performRelease() { getHolder().removeCallback(this); - if (mTaskViewTransitions != null) { - mTaskViewTransitions.removeTaskView(this); - } - mShellExecutor.execute(() -> { - mTaskOrganizer.removeListener(this); - resetTaskInfo(); - }); - mGuard.close(); - mIsInitialized = false; - notifyReleased(); - } - - /** Called when the {@link TaskView} has been released. */ - protected void notifyReleased() { - if (mListener != null && mNotifiedForInitialized) { - mListenerExecutor.execute(() -> { - mListener.onReleased(); - }); - mNotifiedForInitialized = false; - } - } - - private void resetTaskInfo() { - mTaskInfo = null; - mTaskToken = null; - mTaskLeash = null; - } - - private void updateTaskVisibility() { - WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.setHidden(mTaskToken, !mSurfaceCreated /* hidden */); - mSyncQueue.queue(wct); - if (mListener == null) { - return; - } - int taskId = mTaskInfo.taskId; - mSyncQueue.runInSync((t) -> { - mListenerExecutor.execute(() -> { - mListener.onTaskVisibilityChanged(taskId, mSurfaceCreated); - }); - }); - } - - @Override - public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, - SurfaceControl leash) { - if (isUsingShellTransitions()) { - // Everything else handled by enter transition. - return; - } - mTaskInfo = taskInfo; - mTaskToken = taskInfo.token; - mTaskLeash = leash; - - if (mSurfaceCreated) { - // Surface is ready, so just reparent the task to this surface control - mTransaction.reparent(mTaskLeash, getSurfaceControl()) - .show(mTaskLeash) - .apply(); - } else { - // The surface has already been destroyed before the task has appeared, - // so go ahead and hide the task entirely - updateTaskVisibility(); - } - mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, true); - onLocationChanged(); - if (taskInfo.taskDescription != null) { - int backgroundColor = taskInfo.taskDescription.getBackgroundColor(); - mSyncQueue.runInSync((t) -> { - setResizeBackgroundColor(t, backgroundColor); - }); - } - - if (mListener != null) { - final int taskId = taskInfo.taskId; - final ComponentName baseActivity = taskInfo.baseActivity; - mListenerExecutor.execute(() -> { - mListener.onTaskCreated(taskId, baseActivity); - }); - } - } - - @Override - public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { - // Unlike Appeared, we can't yet guarantee that vanish will happen within a transition that - // we know about -- so leave clean-up here even if shell transitions are enabled. - if (mTaskToken == null || !mTaskToken.equals(taskInfo.token)) return; - - if (mListener != null) { - final int taskId = taskInfo.taskId; - mListenerExecutor.execute(() -> { - mListener.onTaskRemovalStarted(taskId); - }); - } - mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, false); - - // Unparent the task when this surface is destroyed - mTransaction.reparent(mTaskLeash, null).apply(); - resetTaskInfo(); - } - - @Override - public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { - if (taskInfo.taskDescription != null) { - setResizeBackgroundColor(taskInfo.taskDescription.getBackgroundColor()); - } - } - - @Override - public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) { - if (mTaskToken == null || !mTaskToken.equals(taskInfo.token)) return; - if (mListener != null) { - final int taskId = taskInfo.taskId; - mListenerExecutor.execute(() -> { - mListener.onBackPressedOnTaskRoot(taskId); - }); - } - } - - @Override - public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) { - b.setParent(findTaskSurface(taskId)); - } - - @Override - public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc, - SurfaceControl.Transaction t) { - t.reparent(sc, findTaskSurface(taskId)); - } - - private SurfaceControl findTaskSurface(int taskId) { - if (mTaskInfo == null || mTaskLeash == null || mTaskInfo.taskId != taskId) { - throw new IllegalArgumentException("There is no surface for taskId=" + taskId); - } - return mTaskLeash; - } - - @Override - public void dump(@androidx.annotation.NonNull PrintWriter pw, String prefix) { - final String innerPrefix = prefix + " "; - final String childPrefix = innerPrefix + " "; - pw.println(prefix + this); + mTaskViewTaskController.release(); } @Override public String toString() { - return "TaskView" + ":" + (mTaskInfo != null ? mTaskInfo.taskId : "null"); + return mTaskViewTaskController.toString(); } @Override public void surfaceCreated(SurfaceHolder holder) { - mSurfaceCreated = true; - mIsInitialized = true; - notifyInitialized(); - mShellExecutor.execute(() -> { - if (mTaskToken == null) { - // Nothing to update, task is not yet available - return; - } - if (isUsingShellTransitions()) { - mTaskViewTransitions.setTaskViewVisible(this, true /* visible */); - return; - } - // Reparent the task when this surface is created - mTransaction.reparent(mTaskLeash, getSurfaceControl()) - .show(mTaskLeash) - .apply(); - updateTaskVisibility(); - }); - } - - /** Called when the {@link TaskView} is initialized. */ - protected void notifyInitialized() { - if (mListener != null && !mNotifiedForInitialized) { - mNotifiedForInitialized = true; - mListenerExecutor.execute(() -> { - mListener.onInitialized(); - }); - } + mTaskViewTaskController.surfaceCreated(getSurfaceControl()); } @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - if (mTaskToken == null) { - return; - } - onLocationChanged(); + public void surfaceChanged(@androidx.annotation.NonNull SurfaceHolder holder, int format, + int width, int height) { + getBoundsOnScreen(mTmpRect); + mTaskViewTaskController.surfaceChanged(mTmpRect); } @Override public void surfaceDestroyed(SurfaceHolder holder) { - mSurfaceCreated = false; - mShellExecutor.execute(() -> { - if (mTaskToken == null) { - // Nothing to update, task is not yet available - return; - } - - if (isUsingShellTransitions()) { - mTaskViewTransitions.setTaskViewVisible(this, false /* visible */); - return; - } - - // Unparent the task when this surface is destroyed - mTransaction.reparent(mTaskLeash, null).apply(); - updateTaskVisibility(); - }); + mTaskViewTaskController.surfaceDestroyed(); } @Override @@ -513,89 +245,6 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, /** Returns the task info for the task in the TaskView. */ @Nullable public ActivityManager.RunningTaskInfo getTaskInfo() { - return mTaskInfo; - } - - void prepareHideAnimation(@NonNull SurfaceControl.Transaction finishTransaction) { - if (mTaskToken == null) { - // Nothing to update, task is not yet available - return; - } - - finishTransaction.reparent(mTaskLeash, null).apply(); - - if (mListener != null) { - final int taskId = mTaskInfo.taskId; - mListener.onTaskVisibilityChanged(taskId, mSurfaceCreated /* visible */); - } - } - - /** - * Called when the associated Task closes. If the TaskView is just being hidden, prepareHide - * is used instead. - */ - void prepareCloseAnimation() { - if (mTaskToken != null) { - if (mListener != null) { - final int taskId = mTaskInfo.taskId; - mListenerExecutor.execute(() -> { - mListener.onTaskRemovalStarted(taskId); - }); - } - mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, false); - } - resetTaskInfo(); - } - - void prepareOpenAnimation(final boolean newTask, - @NonNull SurfaceControl.Transaction startTransaction, - @NonNull SurfaceControl.Transaction finishTransaction, - ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash, - WindowContainerTransaction wct) { - mTaskInfo = taskInfo; - mTaskToken = mTaskInfo.token; - mTaskLeash = leash; - if (mSurfaceCreated) { - // Surface is ready, so just reparent the task to this surface control - startTransaction.reparent(mTaskLeash, getSurfaceControl()) - .show(mTaskLeash) - .apply(); - // Also reparent on finishTransaction since the finishTransaction will reparent back - // to its "original" parent by default. - finishTransaction.reparent(mTaskLeash, getSurfaceControl()) - .setPosition(mTaskLeash, 0, 0) - .apply(); - - // TODO: determine if this is really necessary or not - updateWindowBounds(wct); - } else { - // The surface has already been destroyed before the task has appeared, - // so go ahead and hide the task entirely - wct.setHidden(mTaskToken, true /* hidden */); - // listener callback is below - } - if (newTask) { - mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, true /* intercept */); - } - - if (mTaskInfo.taskDescription != null) { - int backgroundColor = mTaskInfo.taskDescription.getBackgroundColor(); - setResizeBackgroundColor(startTransaction, backgroundColor); - } - - if (mListener != null) { - final int taskId = mTaskInfo.taskId; - final ComponentName baseActivity = mTaskInfo.baseActivity; - - mListenerExecutor.execute(() -> { - if (newTask) { - mListener.onTaskCreated(taskId, baseActivity); - } - // Even if newTask, send a visibilityChange if the surface was destroyed. - if (!newTask || !mSurfaceCreated) { - mListener.onTaskVisibilityChanged(taskId, mSurfaceCreated /* visible */); - } - }); - } + return mTaskViewTaskController.getTaskInfo(); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewBase.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewBase.java new file mode 100644 index 000000000000..3d0a8fd83819 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewBase.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell; + +import android.app.ActivityManager; +import android.graphics.Rect; +import android.view.SurfaceControl; + +/** + * A stub for SurfaceView used by {@link TaskViewTaskController} + */ +public interface TaskViewBase { + /** + * Returns the current bounds on screen for the task view. + * @return + */ + // TODO(b/266242294): Remove getBoundsOnScreen() and instead send the bounds from the TaskView + // to TaskViewTaskController. + Rect getCurrentBoundsOnScreen(); + + /** + * This method should set the resize background color on the SurfaceView that is exposed to + * clients. + * See {@link android.view.SurfaceView#setResizeBackgroundColor(SurfaceControl.Transaction, + * int)} + */ + void setResizeBgColor(SurfaceControl.Transaction transaction, int color); + + /** + * Called when a task appears on the TaskView. See + * {@link TaskViewTaskController#onTaskAppeared(ActivityManager.RunningTaskInfo, + * SurfaceControl)} for details. + */ + default void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { + } + + /** + * Called when a task is vanished from the TaskView. See + * {@link TaskViewTaskController#onTaskVanished(ActivityManager.RunningTaskInfo)} for details. + */ + default void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { + } + + /** + * Called when the task in the TaskView is changed. See + * {@link TaskViewTaskController#onTaskInfoChanged(ActivityManager.RunningTaskInfo)} for details. + */ + default void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewFactoryController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewFactoryController.java index 42844b57b92a..735d9bce2059 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewFactoryController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewFactoryController.java @@ -57,7 +57,8 @@ public class TaskViewFactoryController { /** Creates an {@link TaskView} */ public void create(@UiContext Context context, Executor executor, Consumer<TaskView> onCreate) { - TaskView taskView = new TaskView(context, mTaskOrganizer, mTaskViewTransitions, mSyncQueue); + TaskView taskView = new TaskView(context, new TaskViewTaskController(context, + mTaskOrganizer, mTaskViewTransitions, mSyncQueue)); executor.execute(() -> { onCreate.accept(taskView); }); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewTaskController.java new file mode 100644 index 000000000000..69ce35f43401 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewTaskController.java @@ -0,0 +1,527 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell; + +import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.ActivityManager; +import android.app.ActivityOptions; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.LauncherApps; +import android.content.pm.ShortcutInfo; +import android.graphics.Rect; +import android.os.Binder; +import android.util.CloseGuard; +import android.view.SurfaceControl; +import android.window.WindowContainerToken; +import android.window.WindowContainerTransaction; + +import com.android.wm.shell.common.SyncTransactionQueue; + +import java.io.PrintWriter; +import java.util.concurrent.Executor; + +/** + * This class implements the core logic to show a task on the {@link TaskView}. All the {@link + * TaskView} to {@link TaskViewTaskController} interactions are done via direct method calls. + * + * The reverse communication is done via the {@link TaskViewBase} interface. + */ +public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener { + + private final CloseGuard mGuard = new CloseGuard(); + + private final ShellTaskOrganizer mTaskOrganizer; + private final Executor mShellExecutor; + private final SyncTransactionQueue mSyncQueue; + private final TaskViewTransitions mTaskViewTransitions; + private TaskViewBase mTaskViewBase; + private final Context mContext; + + protected ActivityManager.RunningTaskInfo mTaskInfo; + private WindowContainerToken mTaskToken; + private SurfaceControl mTaskLeash; + private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction(); + private boolean mSurfaceCreated; + private SurfaceControl mSurfaceControl; + private boolean mIsInitialized; + private boolean mNotifiedForInitialized; + private TaskView.Listener mListener; + private Executor mListenerExecutor; + + public TaskViewTaskController(Context context, ShellTaskOrganizer organizer, + TaskViewTransitions taskViewTransitions, SyncTransactionQueue syncQueue) { + mContext = context; + mTaskOrganizer = organizer; + mShellExecutor = organizer.getExecutor(); + mSyncQueue = syncQueue; + mTaskViewTransitions = taskViewTransitions; + if (mTaskViewTransitions != null) { + mTaskViewTransitions.addTaskView(this); + } + mGuard.open("release"); + } + + /** + * Sets the provided {@link TaskViewBase}, which is used to notify the client part about the + * task related changes and getting the current bounds. + */ + public void setTaskViewBase(TaskViewBase taskViewBase) { + mTaskViewBase = taskViewBase; + } + + /** + * @return {@code True} when the TaskView's surface has been created, {@code False} otherwise. + */ + public boolean isInitialized() { + return mIsInitialized; + } + + /** Until all users are converted, we may have mixed-use (eg. Car). */ + private boolean isUsingShellTransitions() { + return mTaskViewTransitions != null && mTaskViewTransitions.isEnabled(); + } + + /** + * Only one listener may be set on the view, throws an exception otherwise. + */ + void setListener(@NonNull Executor executor, TaskView.Listener listener) { + if (mListener != null) { + throw new IllegalStateException( + "Trying to set a listener when one has already been set"); + } + mListener = listener; + mListenerExecutor = executor; + } + + /** + * Launch an activity represented by {@link ShortcutInfo}. + * <p>The owner of this container must be allowed to access the shortcut information, + * as defined in {@link LauncherApps#hasShortcutHostPermission()} to use this method. + * + * @param shortcut the shortcut used to launch the activity. + * @param options options for the activity. + * @param launchBounds the bounds (window size and position) that the activity should be + * launched in, in pixels and in screen coordinates. + */ + public void startShortcutActivity(@NonNull ShortcutInfo shortcut, + @NonNull ActivityOptions options, @Nullable Rect launchBounds) { + prepareActivityOptions(options, launchBounds); + LauncherApps service = mContext.getSystemService(LauncherApps.class); + if (isUsingShellTransitions()) { + mShellExecutor.execute(() -> { + final WindowContainerTransaction wct = new WindowContainerTransaction(); + wct.startShortcut(mContext.getPackageName(), shortcut, options.toBundle()); + mTaskViewTransitions.startTaskView(wct, this); + }); + return; + } + try { + service.startShortcut(shortcut, null /* sourceBounds */, options.toBundle()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Launch a new activity. + * + * @param pendingIntent Intent used to launch an activity. + * @param fillInIntent Additional Intent data, see {@link Intent#fillIn Intent.fillIn()} + * @param options options for the activity. + * @param launchBounds the bounds (window size and position) that the activity should be + * launched in, in pixels and in screen coordinates. + */ + public void startActivity(@NonNull PendingIntent pendingIntent, @Nullable Intent fillInIntent, + @NonNull ActivityOptions options, @Nullable Rect launchBounds) { + prepareActivityOptions(options, launchBounds); + if (isUsingShellTransitions()) { + mShellExecutor.execute(() -> { + WindowContainerTransaction wct = new WindowContainerTransaction(); + wct.sendPendingIntent(pendingIntent, fillInIntent, options.toBundle()); + mTaskViewTransitions.startTaskView(wct, this); + }); + return; + } + try { + pendingIntent.send(mContext, 0 /* code */, fillInIntent, + null /* onFinished */, null /* handler */, null /* requiredPermission */, + options.toBundle()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void prepareActivityOptions(ActivityOptions options, Rect launchBounds) { + final Binder launchCookie = new Binder(); + mShellExecutor.execute(() -> { + mTaskOrganizer.setPendingLaunchCookieListener(launchCookie, this); + }); + options.setLaunchBounds(launchBounds); + options.setLaunchCookie(launchCookie); + options.setLaunchWindowingMode(WINDOWING_MODE_MULTI_WINDOW); + options.setRemoveWithTaskOrganizer(true); + } + + /** + * Call when view position or size has changed. Do not call when animating. + */ + public void onLocationChanged(Rect newBounds) { + if (mTaskToken == null) { + return; + } + // Sync Transactions can't operate simultaneously with shell transition collection. + // The transition animation (upon showing) will sync the location itself. + if (isUsingShellTransitions() && mTaskViewTransitions.hasPending()) return; + + WindowContainerTransaction wct = new WindowContainerTransaction(); + updateWindowBounds(wct); + mSyncQueue.queue(wct); + } + + private void updateWindowBounds(WindowContainerTransaction wct) { + wct.setBounds(mTaskToken, mTaskViewBase.getCurrentBoundsOnScreen()); + } + + /** + * Release this container if it is initialized. + */ + public void release() { + performRelease(); + } + + @Override + protected void finalize() throws Throwable { + try { + if (mGuard != null) { + mGuard.warnIfOpen(); + performRelease(); + } + } finally { + super.finalize(); + } + } + + private void performRelease() { + if (mTaskViewTransitions != null) { + mTaskViewTransitions.removeTaskView(this); + } + mShellExecutor.execute(() -> { + mTaskOrganizer.removeListener(this); + resetTaskInfo(); + }); + mGuard.close(); + mIsInitialized = false; + notifyReleased(); + } + + /** Called when the {@link TaskViewTaskController} has been released. */ + protected void notifyReleased() { + if (mListener != null && mNotifiedForInitialized) { + mListenerExecutor.execute(() -> { + mListener.onReleased(); + }); + mNotifiedForInitialized = false; + } + } + + private void resetTaskInfo() { + mTaskInfo = null; + mTaskToken = null; + mTaskLeash = null; + } + + private void updateTaskVisibility() { + WindowContainerTransaction wct = new WindowContainerTransaction(); + wct.setHidden(mTaskToken, !mSurfaceCreated /* hidden */); + mSyncQueue.queue(wct); + if (mListener == null) { + return; + } + int taskId = mTaskInfo.taskId; + mSyncQueue.runInSync((t) -> { + mListenerExecutor.execute(() -> { + mListener.onTaskVisibilityChanged(taskId, mSurfaceCreated); + }); + }); + } + + @Override + public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, + SurfaceControl leash) { + if (isUsingShellTransitions()) { + // Everything else handled by enter transition. + return; + } + mTaskInfo = taskInfo; + mTaskToken = taskInfo.token; + mTaskLeash = leash; + + if (mSurfaceCreated) { + // Surface is ready, so just reparent the task to this surface control + mTransaction.reparent(mTaskLeash, mSurfaceControl) + .show(mTaskLeash) + .apply(); + } else { + // The surface has already been destroyed before the task has appeared, + // so go ahead and hide the task entirely + updateTaskVisibility(); + } + mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, true); + mSyncQueue.runInSync((t) -> { + mTaskViewBase.onTaskAppeared(taskInfo, leash); + }); + + if (mListener != null) { + final int taskId = taskInfo.taskId; + final ComponentName baseActivity = taskInfo.baseActivity; + mListenerExecutor.execute(() -> { + mListener.onTaskCreated(taskId, baseActivity); + }); + } + } + + @Override + public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { + // Unlike Appeared, we can't yet guarantee that vanish will happen within a transition that + // we know about -- so leave clean-up here even if shell transitions are enabled. + if (mTaskToken == null || !mTaskToken.equals(taskInfo.token)) return; + + if (mListener != null) { + final int taskId = taskInfo.taskId; + mListenerExecutor.execute(() -> { + mListener.onTaskRemovalStarted(taskId); + }); + } + mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, false); + + // Unparent the task when this surface is destroyed + mTransaction.reparent(mTaskLeash, null).apply(); + resetTaskInfo(); + mTaskViewBase.onTaskVanished(taskInfo); + } + + @Override + public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { + mTaskViewBase.onTaskInfoChanged(taskInfo); + } + + @Override + public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) { + if (mTaskToken == null || !mTaskToken.equals(taskInfo.token)) return; + if (mListener != null) { + final int taskId = taskInfo.taskId; + mListenerExecutor.execute(() -> { + mListener.onBackPressedOnTaskRoot(taskId); + }); + } + } + + @Override + public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) { + b.setParent(findTaskSurface(taskId)); + } + + @Override + public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc, + SurfaceControl.Transaction t) { + t.reparent(sc, findTaskSurface(taskId)); + } + + private SurfaceControl findTaskSurface(int taskId) { + if (mTaskInfo == null || mTaskLeash == null || mTaskInfo.taskId != taskId) { + throw new IllegalArgumentException("There is no surface for taskId=" + taskId); + } + return mTaskLeash; + } + + @Override + public void dump(@androidx.annotation.NonNull PrintWriter pw, String prefix) { + final String innerPrefix = prefix + " "; + final String childPrefix = innerPrefix + " "; + pw.println(prefix + this); + } + + @Override + public String toString() { + return "TaskViewTaskController" + ":" + (mTaskInfo != null ? mTaskInfo.taskId : "null"); + } + + /** + * Should be called when the client surface is created. + * + * @param surfaceControl the {@link SurfaceControl} for the underlying surface. + */ + public void surfaceCreated(SurfaceControl surfaceControl) { + mSurfaceCreated = true; + mIsInitialized = true; + mSurfaceControl = surfaceControl; + notifyInitialized(); + mShellExecutor.execute(() -> { + if (mTaskToken == null) { + // Nothing to update, task is not yet available + return; + } + if (isUsingShellTransitions()) { + mTaskViewTransitions.setTaskViewVisible(this, true /* visible */); + return; + } + // Reparent the task when this surface is created + mTransaction.reparent(mTaskLeash, mSurfaceControl) + .show(mTaskLeash) + .apply(); + updateTaskVisibility(); + }); + } + + /** + * Should be called when the client surface is changed. + * + * @param boundsOnScreen the on screen bounds of the surface view. + */ + public void surfaceChanged(Rect boundsOnScreen) { + if (mTaskToken == null) { + return; + } + onLocationChanged(boundsOnScreen); + } + + /** Should be called when the client surface is destroyed. */ + public void surfaceDestroyed() { + mSurfaceCreated = false; + mSurfaceControl = null; + mShellExecutor.execute(() -> { + if (mTaskToken == null) { + // Nothing to update, task is not yet available + return; + } + + if (isUsingShellTransitions()) { + mTaskViewTransitions.setTaskViewVisible(this, false /* visible */); + return; + } + + // Unparent the task when this surface is destroyed + mTransaction.reparent(mTaskLeash, null).apply(); + updateTaskVisibility(); + }); + } + + /** Called when the {@link TaskViewTaskController} is initialized. */ + protected void notifyInitialized() { + if (mListener != null && !mNotifiedForInitialized) { + mNotifiedForInitialized = true; + mListenerExecutor.execute(() -> { + mListener.onInitialized(); + }); + } + } + + /** Returns the task info for the task in the TaskView. */ + @Nullable + public ActivityManager.RunningTaskInfo getTaskInfo() { + return mTaskInfo; + } + + void prepareHideAnimation(@NonNull SurfaceControl.Transaction finishTransaction) { + if (mTaskToken == null) { + // Nothing to update, task is not yet available + return; + } + + finishTransaction.reparent(mTaskLeash, null).apply(); + + if (mListener != null) { + final int taskId = mTaskInfo.taskId; + mListener.onTaskVisibilityChanged(taskId, mSurfaceCreated /* visible */); + } + } + + /** + * Called when the associated Task closes. If the TaskView is just being hidden, prepareHide + * is used instead. + */ + void prepareCloseAnimation() { + if (mTaskToken != null) { + if (mListener != null) { + final int taskId = mTaskInfo.taskId; + mListenerExecutor.execute(() -> { + mListener.onTaskRemovalStarted(taskId); + }); + } + mTaskViewBase.onTaskVanished(mTaskInfo); + mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, false); + } + resetTaskInfo(); + } + + void prepareOpenAnimation(final boolean newTask, + @NonNull SurfaceControl.Transaction startTransaction, + @NonNull SurfaceControl.Transaction finishTransaction, + ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash, + WindowContainerTransaction wct) { + mTaskInfo = taskInfo; + mTaskToken = mTaskInfo.token; + mTaskLeash = leash; + if (mSurfaceCreated) { + // Surface is ready, so just reparent the task to this surface control + startTransaction.reparent(mTaskLeash, mSurfaceControl) + .show(mTaskLeash) + .apply(); + // Also reparent on finishTransaction since the finishTransaction will reparent back + // to its "original" parent by default. + finishTransaction.reparent(mTaskLeash, mSurfaceControl) + .setPosition(mTaskLeash, 0, 0) + .apply(); + + updateWindowBounds(wct); + } else { + // The surface has already been destroyed before the task has appeared, + // so go ahead and hide the task entirely + wct.setHidden(mTaskToken, true /* hidden */); + // listener callback is below + } + if (newTask) { + mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, true /* intercept */); + } + + if (mTaskInfo.taskDescription != null) { + int backgroundColor = mTaskInfo.taskDescription.getBackgroundColor(); + mTaskViewBase.setResizeBgColor(startTransaction, backgroundColor); + } + + if (mListener != null) { + final int taskId = mTaskInfo.taskId; + final ComponentName baseActivity = mTaskInfo.baseActivity; + + mListenerExecutor.execute(() -> { + if (newTask) { + mListener.onTaskCreated(taskId, baseActivity); + } + // Even if newTask, send a visibilityChange if the surface was destroyed. + if (!newTask || !mSurfaceCreated) { + mListener.onTaskVisibilityChanged(taskId, mSurfaceCreated /* visible */); + } + }); + } + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewTransitions.java index 07d501201105..aab257ebe885 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewTransitions.java @@ -41,7 +41,7 @@ import java.util.ArrayList; public class TaskViewTransitions implements Transitions.TransitionHandler { private static final String TAG = "TaskViewTransitions"; - private final ArrayList<TaskView> mTaskViews = new ArrayList<>(); + private final ArrayList<TaskViewTaskController> mTaskViews = new ArrayList<>(); private final ArrayList<PendingTransition> mPending = new ArrayList<>(); private final Transitions mTransitions; private final boolean[] mRegistered = new boolean[]{ false }; @@ -54,11 +54,12 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { private static class PendingTransition { final @WindowManager.TransitionType int mType; final WindowContainerTransaction mWct; - final @NonNull TaskView mTaskView; + final @NonNull TaskViewTaskController mTaskView; IBinder mClaimed; PendingTransition(@WindowManager.TransitionType int type, - @Nullable WindowContainerTransaction wct, @NonNull TaskView taskView) { + @Nullable WindowContainerTransaction wct, + @NonNull TaskViewTaskController taskView) { mType = type; mWct = wct; mTaskView = taskView; @@ -72,7 +73,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { // TODO(210041388): register here once we have an explicit ordering mechanism. } - void addTaskView(TaskView tv) { + void addTaskView(TaskViewTaskController tv) { synchronized (mRegistered) { if (!mRegistered[0]) { mRegistered[0] = true; @@ -82,7 +83,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { mTaskViews.add(tv); } - void removeTaskView(TaskView tv) { + void removeTaskView(TaskViewTaskController tv) { mTaskViews.remove(tv); // Note: Don't unregister handler since this is a singleton with lifetime bound to Shell } @@ -101,7 +102,8 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { * if there is a match earlier. The idea behind this is to check the state of * the taskviews "as if all transitions already happened". */ - private PendingTransition findPending(TaskView taskView, boolean closing, boolean latest) { + private PendingTransition findPending(TaskViewTaskController taskView, boolean closing, + boolean latest) { for (int i = mPending.size() - 1; i >= 0; --i) { if (mPending.get(i).mTaskView != taskView) continue; if (Transitions.isClosingType(mPending.get(i).mType) == closing) { @@ -134,7 +136,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { if (triggerTask == null) { return null; } - final TaskView taskView = findTaskView(triggerTask); + final TaskViewTaskController taskView = findTaskView(triggerTask); if (taskView == null) return null; // Opening types should all be initiated by shell if (!Transitions.isClosingType(request.getType())) return null; @@ -150,7 +152,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { return new WindowContainerTransaction(); } - private TaskView findTaskView(ActivityManager.RunningTaskInfo taskInfo) { + private TaskViewTaskController findTaskView(ActivityManager.RunningTaskInfo taskInfo) { for (int i = 0; i < mTaskViews.size(); ++i) { if (mTaskViews.get(i).getTaskInfo() == null) continue; if (taskInfo.token.equals(mTaskViews.get(i).getTaskInfo().token)) { @@ -160,12 +162,12 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { return null; } - void startTaskView(WindowContainerTransaction wct, TaskView taskView) { + void startTaskView(WindowContainerTransaction wct, TaskViewTaskController taskView) { mPending.add(new PendingTransition(TRANSIT_OPEN, wct, taskView)); startNextTransition(); } - void setTaskViewVisible(TaskView taskView, boolean visible) { + void setTaskViewVisible(TaskViewTaskController taskView, boolean visible) { PendingTransition pending = findPending(taskView, !visible, true /* latest */); if (pending != null) { // Already opening or creating a task, so no need to do anything here. @@ -203,7 +205,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { PendingTransition pending = findPending(transition); if (pending == null) return false; mPending.remove(pending); - TaskView taskView = pending.mTaskView; + TaskViewTaskController taskView = pending.mTaskView; final ArrayList<TransitionInfo.Change> tasks = new ArrayList<>(); for (int i = 0; i < info.getChanges().size(); ++i) { final TransitionInfo.Change chg = info.getChanges().get(i); @@ -219,7 +221,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { TransitionInfo.Change chg = tasks.get(i); if (Transitions.isClosingType(chg.getMode())) { final boolean isHide = chg.getMode() == TRANSIT_TO_BACK; - TaskView tv = findTaskView(chg.getTaskInfo()); + TaskViewTaskController tv = findTaskView(chg.getTaskInfo()); if (tv == null) { throw new IllegalStateException("TaskView transition is closing a " + "non-taskview task "); @@ -232,7 +234,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { } else if (Transitions.isOpeningType(chg.getMode())) { final boolean taskIsNew = chg.getMode() == TRANSIT_OPEN; if (wct == null) wct = new WindowContainerTransaction(); - TaskView tv = taskView; + TaskViewTaskController tv = taskView; if (!taskIsNew) { tv = findTaskView(chg.getTaskInfo()); if (tv == null) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java index e85b3c7d5bc3..1feff18fd68e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java @@ -67,6 +67,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.wm.shell.R; import com.android.wm.shell.TaskView; +import com.android.wm.shell.TaskViewTaskController; import com.android.wm.shell.common.AlphaOptimizedButton; import com.android.wm.shell.common.TriangleShape; @@ -140,6 +141,7 @@ public class BubbleExpandedView extends LinearLayout { private AlphaOptimizedButton mManageButton; private TaskView mTaskView; + private TaskViewTaskController mTaskViewTaskController; private BubbleOverflowContainerView mOverflowView; private int mTaskId = INVALID_TASK_ID; @@ -409,8 +411,10 @@ public class BubbleExpandedView extends LinearLayout { bringChildToFront(mOverflowView); mManageButton.setVisibility(GONE); } else { - mTaskView = new TaskView(mContext, mController.getTaskOrganizer(), + mTaskViewTaskController = new TaskViewTaskController(mContext, + mController.getTaskOrganizer(), mController.getTaskViewTransitions(), mController.getSyncTransactionQueue()); + mTaskView = new TaskView(mContext, mTaskViewTaskController); mTaskView.setListener(mController.getMainExecutor(), mTaskViewListener); mExpandedViewContainer.addView(mTaskView); bringChildToFront(mTaskView); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java index c14704d04e3a..fe95d04bad3c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java @@ -215,8 +215,14 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract { : taskStableBounds.right - taskBounds.left - mLayout.getMeasuredWidth(); final int positionY = taskStableBounds.bottom - taskBounds.top - mLayout.getMeasuredHeight(); - + // To secure a proper visualisation, we hide the layout while updating the position of + // the {@link SurfaceControl} it belongs. + final int oldVisibility = mLayout.getVisibility(); + if (oldVisibility == View.VISIBLE) { + mLayout.setVisibility(View.GONE); + } updateSurfacePosition(positionX, positionY); + mLayout.setVisibility(oldVisibility); } private void updateVisibilityOfViews() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java index 7096a645ef85..283b1ec0f752 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java @@ -16,6 +16,7 @@ package com.android.wm.shell.pip; +import android.annotation.Nullable; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; @@ -41,6 +42,11 @@ public abstract class PipContentOverlay { } } + @Nullable + public SurfaceControl getLeash() { + return mLeash; + } + /** * Animates the internal {@link #mLeash} by a given fraction. * @param atomicTx {@link SurfaceControl.Transaction} to operate, you should not explicitly diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index 36ce0a69906a..a3e05f2cf859 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -64,7 +64,6 @@ import static com.android.wm.shell.transition.TransitionAnimationHelper.addBackg import static com.android.wm.shell.transition.TransitionAnimationHelper.edgeExtendWindow; import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet; import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation; -import static com.android.wm.shell.transition.TransitionAnimationHelper.sDisableCustomTaskAnimationProperty; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -568,7 +567,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { final boolean isTask = change.getTaskInfo() != null; final TransitionInfo.AnimationOptions options = info.getAnimationOptions(); final int overrideType = options != null ? options.getType() : ANIM_NONE; - final boolean canCustomContainer = !isTask || !sDisableCustomTaskAnimationProperty; final Rect endBounds = Transitions.isClosingType(changeMode) ? mRotator.getEndBoundsInStartRotation(change) : change.getEndAbsBounds(); @@ -591,7 +589,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { } else if (type == TRANSIT_RELAUNCH) { a = mTransitionAnimation.createRelaunchAnimation(endBounds, mInsets, endBounds); } else if (overrideType == ANIM_CUSTOM - && (canCustomContainer || options.getOverrideTaskTransition())) { + && (!isTask || options.getOverrideTaskTransition())) { a = mTransitionAnimation.loadAnimationRes(options.getPackageName(), enter ? options.getEnterResId() : options.getExitResId()); } else if (overrideType == ANIM_OPEN_CROSS_PROFILE_APPS && enter) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java index 6af81f1eb707..1549355c6b2b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java @@ -43,7 +43,6 @@ import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Shader; -import android.os.SystemProperties; import android.view.Surface; import android.view.SurfaceControl; import android.view.animation.Animation; @@ -59,21 +58,6 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup; /** The helper class that provides methods for adding styles to transition animations. */ public class TransitionAnimationHelper { - /** - * Restrict ability of activities overriding transition animation in a way such that - * an activity can do it only when the transition happens within a same task. - * - * @see android.app.Activity#overridePendingTransition(int, int) - */ - private static final String DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY = - "persist.wm.disable_custom_task_animation"; - - /** - * @see #DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY - */ - static final boolean sDisableCustomTaskAnimationProperty = - SystemProperties.getBoolean(DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY, true); - /** Loads the animation that is defined through attribute id for the given transition. */ @Nullable public static Animation loadAttributeAnimation(@NonNull TransitionInfo info, @@ -86,7 +70,6 @@ public class TransitionAnimationHelper { final boolean isTask = change.getTaskInfo() != null; final TransitionInfo.AnimationOptions options = info.getAnimationOptions(); final int overrideType = options != null ? options.getType() : ANIM_NONE; - final boolean canCustomContainer = !isTask || !sDisableCustomTaskAnimationProperty; final boolean isDream = isTask && change.getTaskInfo().topActivityType == ACTIVITY_TYPE_DREAM; int animAttr = 0; @@ -158,7 +141,7 @@ public class TransitionAnimationHelper { Animation a = null; if (animAttr != 0) { - if (overrideType == ANIM_FROM_STYLE && canCustomContainer) { + if (overrideType == ANIM_FROM_STYLE && !isTask) { a = transitionAnimation .loadAnimationAttr(options.getPackageName(), options.getAnimations(), animAttr, translucent); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java index f77ac81feca8..476a7ec0fdc2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java @@ -174,7 +174,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { final CaptionTouchEventListener touchEventListener = new CaptionTouchEventListener(taskInfo, taskPositioner); windowDecoration.setCaptionListeners(touchEventListener, touchEventListener); - windowDecoration.setDragResizeCallback(taskPositioner); + windowDecoration.setDragPositioningCallback(taskPositioner); windowDecoration.setDragDetector(touchEventListener.mDragDetector); windowDecoration.relayout(taskInfo, startT, finishT); setupCaptionColor(taskInfo, windowDecoration); @@ -185,17 +185,17 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { private final int mTaskId; private final WindowContainerToken mTaskToken; - private final DragResizeCallback mDragResizeCallback; + private final DragPositioningCallback mDragPositioningCallback; private final DragDetector mDragDetector; private int mDragPointerId = -1; private CaptionTouchEventListener( RunningTaskInfo taskInfo, - DragResizeCallback dragResizeCallback) { + DragPositioningCallback dragPositioningCallback) { mTaskId = taskInfo.taskId; mTaskToken = taskInfo.token; - mDragResizeCallback = dragResizeCallback; + mDragPositioningCallback = dragPositioningCallback; mDragDetector = new DragDetector(this); } @@ -247,20 +247,20 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel { switch (e.getActionMasked()) { case MotionEvent.ACTION_DOWN: { mDragPointerId = e.getPointerId(0); - mDragResizeCallback.onDragResizeStart( + mDragPositioningCallback.onDragPositioningStart( 0 /* ctrlType */, e.getRawX(0), e.getRawY(0)); break; } case MotionEvent.ACTION_MOVE: { int dragPointerIdx = e.findPointerIndex(mDragPointerId); - mDragResizeCallback.onDragResizeMove( + mDragPositioningCallback.onDragPositioningMove( e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx)); break; } case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { int dragPointerIdx = e.findPointerIndex(mDragPointerId); - mDragResizeCallback.onDragResizeEnd( + mDragPositioningCallback.onDragPositioningEnd( e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx)); break; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java index f94fbfca9bcf..060dc4e05b46 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java @@ -47,7 +47,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL private View.OnClickListener mOnCaptionButtonClickListener; private View.OnTouchListener mOnCaptionTouchListener; - private DragResizeCallback mDragResizeCallback; + private DragPositioningCallback mDragPositioningCallback; private DragResizeInputListener mDragResizeListener; private DragDetector mDragDetector; @@ -78,8 +78,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL mOnCaptionTouchListener = onCaptionTouchListener; } - void setDragResizeCallback(DragResizeCallback dragResizeCallback) { - mDragResizeCallback = dragResizeCallback; + void setDragPositioningCallback(DragPositioningCallback dragPositioningCallback) { + mDragPositioningCallback = dragPositioningCallback; } void setDragDetector(DragDetector dragDetector) { @@ -151,7 +151,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL mChoreographer, mDisplay.getDisplayId(), mDecorationContainerSurface, - mDragResizeCallback); + mDragPositioningCallback); } final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext()) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index c0c0ab968a9b..606cf2854802 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -209,17 +209,17 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private final int mTaskId; private final WindowContainerToken mTaskToken; - private final DragResizeCallback mDragResizeCallback; + private final DragPositioningCallback mDragPositioningCallback; private final DragDetector mDragDetector; private int mDragPointerId = -1; private DesktopModeTouchEventListener( RunningTaskInfo taskInfo, - DragResizeCallback dragResizeCallback) { + DragPositioningCallback dragPositioningCallback) { mTaskId = taskInfo.taskId; mTaskToken = taskInfo.token; - mDragResizeCallback = dragResizeCallback; + mDragPositioningCallback = dragPositioningCallback; mDragDetector = new DragDetector(this); } @@ -283,13 +283,13 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { switch (e.getActionMasked()) { case MotionEvent.ACTION_DOWN: { mDragPointerId = e.getPointerId(0); - mDragResizeCallback.onDragResizeStart( + mDragPositioningCallback.onDragPositioningStart( 0 /* ctrlType */, e.getRawX(0), e.getRawY(0)); break; } case MotionEvent.ACTION_MOVE: { final int dragPointerIdx = e.findPointerIndex(mDragPointerId); - mDragResizeCallback.onDragResizeMove( + mDragPositioningCallback.onDragPositioningMove( e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx)); break; } @@ -298,7 +298,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { final int dragPointerIdx = e.findPointerIndex(mDragPointerId); final int statusBarHeight = mDisplayController .getDisplayLayout(taskInfo.displayId).stableInsets().top; - mDragResizeCallback.onDragResizeEnd( + mDragPositioningCallback.onDragPositioningEnd( e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx)); if (e.getRawY(dragPointerIdx) <= statusBarHeight) { if (DesktopModeStatus.isProto2Enabled()) { @@ -557,7 +557,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { final DesktopModeTouchEventListener touchEventListener = new DesktopModeTouchEventListener(taskInfo, taskPositioner); windowDecoration.setCaptionListeners(touchEventListener, touchEventListener); - windowDecoration.setDragResizeCallback(taskPositioner); + windowDecoration.setDragPositioningCallback(taskPositioner); windowDecoration.setDragDetector(touchEventListener.mDragDetector); windowDecoration.relayout(taskInfo, startT, finishT); incrementEventReceiverTasks(taskInfo.displayId); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index 31b56d3a1e93..744c18fe7adb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -54,7 +54,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private View.OnClickListener mOnCaptionButtonClickListener; private View.OnTouchListener mOnCaptionTouchListener; - private DragResizeCallback mDragResizeCallback; + private DragPositioningCallback mDragPositioningCallback; private DragResizeInputListener mDragResizeListener; private DragDetector mDragDetector; @@ -90,8 +90,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mOnCaptionTouchListener = onCaptionTouchListener; } - void setDragResizeCallback(DragResizeCallback dragResizeCallback) { - mDragResizeCallback = dragResizeCallback; + void setDragPositioningCallback(DragPositioningCallback dragPositioningCallback) { + mDragPositioningCallback = dragPositioningCallback; } void setDragDetector(DragDetector dragDetector) { @@ -179,7 +179,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mChoreographer, mDisplay.getDisplayId(), mDecorationContainerSurface, - mDragResizeCallback); + mDragPositioningCallback); } final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext()) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java index ee160a15df19..0191c609a8b2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeCallback.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java @@ -19,28 +19,28 @@ package com.android.wm.shell.windowdecor; /** * Callback called when receiving drag-resize or drag-move related input events. */ -public interface DragResizeCallback { +public interface DragPositioningCallback { /** - * Called when a drag resize starts. + * Called when a drag-resize or drag-move starts. * * @param ctrlType {@link TaskPositioner.CtrlType} indicating the direction of resizing, use * {@code 0} to indicate it's a move - * @param x x coordinate in window decoration coordinate system where the drag resize starts - * @param y y coordinate in window decoration coordinate system where the drag resize starts + * @param x x coordinate in window decoration coordinate system where the drag starts + * @param y y coordinate in window decoration coordinate system where the drag starts */ - void onDragResizeStart(@TaskPositioner.CtrlType int ctrlType, float x, float y); + void onDragPositioningStart(@TaskPositioner.CtrlType int ctrlType, float x, float y); /** - * Called when the pointer moves during a drag resize. + * Called when the pointer moves during a drag-resize or drag-move. * @param x x coordinate in window decoration coordinate system of the new pointer location * @param y y coordinate in window decoration coordinate system of the new pointer location */ - void onDragResizeMove(float x, float y); + void onDragPositioningMove(float x, float y); /** - * Called when a drag resize stops. + * Called when a drag-resize or drag-move stops. * @param x x coordinate in window decoration coordinate system where the drag resize stops * @param y y coordinate in window decoration coordinate system where the drag resize stops */ - void onDragResizeEnd(float x, float y); + void onDragPositioningEnd(float x, float y); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java index ea417b1f4c29..3d1edc9206f9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java @@ -62,7 +62,7 @@ class DragResizeInputListener implements AutoCloseable { private final SurfaceControl mDecorationSurface; private final InputChannel mInputChannel; private final TaskResizeInputEventReceiver mInputEventReceiver; - private final com.android.wm.shell.windowdecor.DragResizeCallback mCallback; + private final DragPositioningCallback mCallback; private int mWidth; private int mHeight; @@ -83,7 +83,7 @@ class DragResizeInputListener implements AutoCloseable { Choreographer choreographer, int displayId, SurfaceControl decorationSurface, - DragResizeCallback callback) { + DragPositioningCallback callback) { mInputManager = context.getSystemService(InputManager.class); mHandler = handler; mChoreographer = choreographer; @@ -294,7 +294,7 @@ class DragResizeInputListener implements AutoCloseable { float rawX = e.getRawX(0); float rawY = e.getRawY(0); int ctrlType = calculateCtrlType(isTouch, x, y); - mCallback.onDragResizeStart(ctrlType, rawX, rawY); + mCallback.onDragPositioningStart(ctrlType, rawX, rawY); result = true; } break; @@ -306,7 +306,7 @@ class DragResizeInputListener implements AutoCloseable { int dragPointerIndex = e.findPointerIndex(mDragPointerId); float rawX = e.getRawX(dragPointerIndex); float rawY = e.getRawY(dragPointerIndex); - mCallback.onDragResizeMove(rawX, rawY); + mCallback.onDragPositioningMove(rawX, rawY); result = true; break; } @@ -314,7 +314,7 @@ class DragResizeInputListener implements AutoCloseable { case MotionEvent.ACTION_CANCEL: { if (mShouldHandleEvents) { int dragPointerIndex = e.findPointerIndex(mDragPointerId); - mCallback.onDragResizeEnd( + mCallback.onDragPositioningEnd( e.getRawX(dragPointerIndex), e.getRawY(dragPointerIndex)); } mShouldHandleEvents = false; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java index 8cd2a5946e91..d3f92277bf03 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java @@ -23,7 +23,7 @@ import android.window.WindowContainerTransaction; import com.android.wm.shell.ShellTaskOrganizer; -class TaskPositioner implements DragResizeCallback { +class TaskPositioner implements DragPositioningCallback { @IntDef({CTRL_TYPE_UNDEFINED, CTRL_TYPE_LEFT, CTRL_TYPE_RIGHT, CTRL_TYPE_TOP, CTRL_TYPE_BOTTOM}) @interface CtrlType {} @@ -38,8 +38,8 @@ class TaskPositioner implements DragResizeCallback { private final WindowDecoration mWindowDecoration; private final Rect mTaskBoundsAtDragStart = new Rect(); - private final PointF mResizeStartPoint = new PointF(); - private final Rect mResizeTaskBounds = new Rect(); + private final PointF mRepositionStartPoint = new PointF(); + private final Rect mRepositionTaskBounds = new Rect(); private boolean mHasMoved = false; private int mCtrlType; @@ -57,7 +57,7 @@ class TaskPositioner implements DragResizeCallback { } @Override - public void onDragResizeStart(int ctrlType, float x, float y) { + public void onDragPositioningStart(int ctrlType, float x, float y) { mHasMoved = false; mDragStartListener.onDragStart(mWindowDecoration.mTaskInfo.taskId); @@ -65,11 +65,11 @@ class TaskPositioner implements DragResizeCallback { mTaskBoundsAtDragStart.set( mWindowDecoration.mTaskInfo.configuration.windowConfiguration.getBounds()); - mResizeStartPoint.set(x, y); + mRepositionStartPoint.set(x, y); } @Override - public void onDragResizeMove(float x, float y) { + public void onDragPositioningMove(float x, float y) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (changeBounds(wct, x, y)) { // The task is being resized, send the |dragResizing| hint to core with the first @@ -84,7 +84,7 @@ class TaskPositioner implements DragResizeCallback { } @Override - public void onDragResizeEnd(float x, float y) { + public void onDragPositioningEnd(float x, float y) { // |mHasMoved| being false means there is no real change to the task bounds in WM core, so // we don't need a WCT to finish it. if (mHasMoved) { @@ -96,42 +96,44 @@ class TaskPositioner implements DragResizeCallback { mCtrlType = CTRL_TYPE_UNDEFINED; mTaskBoundsAtDragStart.setEmpty(); - mResizeStartPoint.set(0, 0); + mRepositionStartPoint.set(0, 0); mHasMoved = false; } private boolean changeBounds(WindowContainerTransaction wct, float x, float y) { - // |mResizeTaskBounds| is the bounds last reported if |mHasMoved| is true. If it's not true, - // we can compare it against |mTaskBoundsAtDragStart|. - final int oldLeft = mHasMoved ? mResizeTaskBounds.left : mTaskBoundsAtDragStart.left; - final int oldTop = mHasMoved ? mResizeTaskBounds.top : mTaskBoundsAtDragStart.top; - final int oldRight = mHasMoved ? mResizeTaskBounds.right : mTaskBoundsAtDragStart.right; - final int oldBottom = mHasMoved ? mResizeTaskBounds.bottom : mTaskBoundsAtDragStart.bottom; - - final float deltaX = x - mResizeStartPoint.x; - final float deltaY = y - mResizeStartPoint.y; - mResizeTaskBounds.set(mTaskBoundsAtDragStart); + // |mRepositionTaskBounds| is the bounds last reported if |mHasMoved| is true. If it's not + // true, we can compare it against |mTaskBoundsAtDragStart|. + final int oldLeft = mHasMoved ? mRepositionTaskBounds.left : mTaskBoundsAtDragStart.left; + final int oldTop = mHasMoved ? mRepositionTaskBounds.top : mTaskBoundsAtDragStart.top; + final int oldRight = mHasMoved ? mRepositionTaskBounds.right : mTaskBoundsAtDragStart.right; + final int oldBottom = + mHasMoved ? mRepositionTaskBounds.bottom : mTaskBoundsAtDragStart.bottom; + + final float deltaX = x - mRepositionStartPoint.x; + final float deltaY = y - mRepositionStartPoint.y; + mRepositionTaskBounds.set(mTaskBoundsAtDragStart); if ((mCtrlType & CTRL_TYPE_LEFT) != 0) { - mResizeTaskBounds.left += deltaX; + mRepositionTaskBounds.left += deltaX; } if ((mCtrlType & CTRL_TYPE_RIGHT) != 0) { - mResizeTaskBounds.right += deltaX; + mRepositionTaskBounds.right += deltaX; } if ((mCtrlType & CTRL_TYPE_TOP) != 0) { - mResizeTaskBounds.top += deltaY; + mRepositionTaskBounds.top += deltaY; } if ((mCtrlType & CTRL_TYPE_BOTTOM) != 0) { - mResizeTaskBounds.bottom += deltaY; + mRepositionTaskBounds.bottom += deltaY; } if (mCtrlType == CTRL_TYPE_UNDEFINED) { - mResizeTaskBounds.offset((int) deltaX, (int) deltaY); + mRepositionTaskBounds.offset((int) deltaX, (int) deltaY); } - if (oldLeft == mResizeTaskBounds.left && oldTop == mResizeTaskBounds.top - && oldRight == mResizeTaskBounds.right && oldBottom == mResizeTaskBounds.bottom) { + if (oldLeft == mRepositionTaskBounds.left && oldTop == mRepositionTaskBounds.top + && oldRight == mRepositionTaskBounds.right + && oldBottom == mRepositionTaskBounds.bottom) { return false; } - wct.setBounds(mWindowDecoration.mTaskInfo.token, mResizeTaskBounds); + wct.setBounds(mWindowDecoration.mTaskInfo.token, mRepositionTaskBounds); return true; } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java index d5bb901259bd..62bfd17cefba 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java @@ -92,6 +92,7 @@ public class TaskViewTest extends ShellTestCase { Context mContext; TaskView mTaskView; TaskViewTransitions mTaskViewTransitions; + TaskViewTaskController mTaskViewTaskController; @Before public void setUp() { @@ -125,7 +126,9 @@ public class TaskViewTest extends ShellTestCase { doReturn(true).when(mTransitions).isRegistered(); } mTaskViewTransitions = spy(new TaskViewTransitions(mTransitions)); - mTaskView = new TaskView(mContext, mOrganizer, mTaskViewTransitions, mSyncQueue); + mTaskViewTaskController = new TaskViewTaskController(mContext, mOrganizer, + mTaskViewTransitions, mSyncQueue); + mTaskView = new TaskView(mContext, mTaskViewTaskController); mTaskView.setListener(mExecutor, mViewListener); } @@ -138,7 +141,8 @@ public class TaskViewTest extends ShellTestCase { @Test public void testSetPendingListener_throwsException() { - TaskView taskView = new TaskView(mContext, mOrganizer, mTaskViewTransitions, mSyncQueue); + TaskView taskView = new TaskView(mContext, + new TaskViewTaskController(mContext, mOrganizer, mTaskViewTransitions, mSyncQueue)); taskView.setListener(mExecutor, mViewListener); try { taskView.setListener(mExecutor, mViewListener); @@ -152,16 +156,17 @@ public class TaskViewTest extends ShellTestCase { @Test public void testStartActivity() { ActivityOptions options = ActivityOptions.makeBasic(); - mTaskView.startActivity(mock(PendingIntent.class), null, options, new Rect(0, 0, 100, 100)); + mTaskView.startActivity(mock(PendingIntent.class), null, options, + new Rect(0, 0, 100, 100)); - verify(mOrganizer).setPendingLaunchCookieListener(any(), eq(mTaskView)); + verify(mOrganizer).setPendingLaunchCookieListener(any(), eq(mTaskViewTaskController)); assertThat(options.getLaunchWindowingMode()).isEqualTo(WINDOWING_MODE_MULTI_WINDOW); } @Test public void testOnTaskAppeared_noSurface_legacyTransitions() { assumeFalse(Transitions.ENABLE_SHELL_TRANSITIONS); - mTaskView.onTaskAppeared(mTaskInfo, mLeash); + mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash); verify(mViewListener).onTaskCreated(eq(mTaskInfo.taskId), any()); verify(mViewListener, never()).onInitialized(); @@ -173,7 +178,7 @@ public class TaskViewTest extends ShellTestCase { public void testOnTaskAppeared_withSurface_legacyTransitions() { assumeFalse(Transitions.ENABLE_SHELL_TRANSITIONS); mTaskView.surfaceCreated(mock(SurfaceHolder.class)); - mTaskView.onTaskAppeared(mTaskInfo, mLeash); + mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash); verify(mViewListener).onTaskCreated(eq(mTaskInfo.taskId), any()); assertThat(mTaskView.isInitialized()).isTrue(); @@ -194,7 +199,7 @@ public class TaskViewTest extends ShellTestCase { @Test public void testSurfaceCreated_withTask_legacyTransitions() { assumeFalse(Transitions.ENABLE_SHELL_TRANSITIONS); - mTaskView.onTaskAppeared(mTaskInfo, mLeash); + mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash); mTaskView.surfaceCreated(mock(SurfaceHolder.class)); verify(mViewListener).onInitialized(); @@ -216,7 +221,7 @@ public class TaskViewTest extends ShellTestCase { public void testSurfaceDestroyed_withTask_legacyTransitions() { assumeFalse(Transitions.ENABLE_SHELL_TRANSITIONS); SurfaceHolder sh = mock(SurfaceHolder.class); - mTaskView.onTaskAppeared(mTaskInfo, mLeash); + mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash); mTaskView.surfaceCreated(sh); reset(mViewListener); mTaskView.surfaceDestroyed(sh); @@ -227,11 +232,11 @@ public class TaskViewTest extends ShellTestCase { @Test public void testOnReleased_legacyTransitions() { assumeFalse(Transitions.ENABLE_SHELL_TRANSITIONS); - mTaskView.onTaskAppeared(mTaskInfo, mLeash); + mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash); mTaskView.surfaceCreated(mock(SurfaceHolder.class)); mTaskView.release(); - verify(mOrganizer).removeListener(eq(mTaskView)); + verify(mOrganizer).removeListener(eq(mTaskViewTaskController)); verify(mViewListener).onReleased(); assertThat(mTaskView.isInitialized()).isFalse(); } @@ -239,9 +244,9 @@ public class TaskViewTest extends ShellTestCase { @Test public void testOnTaskVanished_legacyTransitions() { assumeFalse(Transitions.ENABLE_SHELL_TRANSITIONS); - mTaskView.onTaskAppeared(mTaskInfo, mLeash); + mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash); mTaskView.surfaceCreated(mock(SurfaceHolder.class)); - mTaskView.onTaskVanished(mTaskInfo); + mTaskViewTaskController.onTaskVanished(mTaskInfo); verify(mViewListener).onTaskRemovalStarted(eq(mTaskInfo.taskId)); } @@ -249,8 +254,8 @@ public class TaskViewTest extends ShellTestCase { @Test public void testOnBackPressedOnTaskRoot_legacyTransitions() { assumeFalse(Transitions.ENABLE_SHELL_TRANSITIONS); - mTaskView.onTaskAppeared(mTaskInfo, mLeash); - mTaskView.onBackPressedOnTaskRoot(mTaskInfo); + mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash); + mTaskViewTaskController.onBackPressedOnTaskRoot(mTaskInfo); verify(mViewListener).onBackPressedOnTaskRoot(eq(mTaskInfo.taskId)); } @@ -258,17 +263,17 @@ public class TaskViewTest extends ShellTestCase { @Test public void testSetOnBackPressedOnTaskRoot_legacyTransitions() { assumeFalse(Transitions.ENABLE_SHELL_TRANSITIONS); - mTaskView.onTaskAppeared(mTaskInfo, mLeash); + mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash); verify(mOrganizer).setInterceptBackPressedOnTaskRoot(eq(mTaskInfo.token), eq(true)); } @Test public void testUnsetOnBackPressedOnTaskRoot_legacyTransitions() { assumeFalse(Transitions.ENABLE_SHELL_TRANSITIONS); - mTaskView.onTaskAppeared(mTaskInfo, mLeash); + mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash); verify(mOrganizer).setInterceptBackPressedOnTaskRoot(eq(mTaskInfo.token), eq(true)); - mTaskView.onTaskVanished(mTaskInfo); + mTaskViewTaskController.onTaskVanished(mTaskInfo); verify(mOrganizer).setInterceptBackPressedOnTaskRoot(eq(mTaskInfo.token), eq(false)); } @@ -276,8 +281,9 @@ public class TaskViewTest extends ShellTestCase { public void testOnNewTask_noSurface() { assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); WindowContainerTransaction wct = new WindowContainerTransaction(); - mTaskView.prepareOpenAnimation(true /* newTask */, new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); + mTaskViewTaskController.prepareOpenAnimation(true /* newTask */, + new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, + mLeash, wct); verify(mViewListener).onTaskCreated(eq(mTaskInfo.taskId), any()); verify(mViewListener, never()).onInitialized(); @@ -303,8 +309,9 @@ public class TaskViewTest extends ShellTestCase { assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); mTaskView.surfaceCreated(mock(SurfaceHolder.class)); WindowContainerTransaction wct = new WindowContainerTransaction(); - mTaskView.prepareOpenAnimation(true /* newTask */, new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); + mTaskViewTaskController.prepareOpenAnimation(true /* newTask */, + new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, + mLeash, wct); verify(mViewListener).onTaskCreated(eq(mTaskInfo.taskId), any()); verify(mViewListener, never()).onTaskVisibilityChanged(anyInt(), anyBoolean()); @@ -314,15 +321,17 @@ public class TaskViewTest extends ShellTestCase { public void testSurfaceCreated_withTask() { assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); WindowContainerTransaction wct = new WindowContainerTransaction(); - mTaskView.prepareOpenAnimation(true /* newTask */, new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); + mTaskViewTaskController.prepareOpenAnimation(true /* newTask */, + new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, + mLeash, wct); mTaskView.surfaceCreated(mock(SurfaceHolder.class)); verify(mViewListener).onInitialized(); - verify(mTaskViewTransitions).setTaskViewVisible(eq(mTaskView), eq(true)); + verify(mTaskViewTransitions).setTaskViewVisible(eq(mTaskViewTaskController), eq(true)); - mTaskView.prepareOpenAnimation(false /* newTask */, new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); + mTaskViewTaskController.prepareOpenAnimation(false /* newTask */, + new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, + mLeash, wct); verify(mViewListener).onTaskVisibilityChanged(eq(mTaskInfo.taskId), eq(true)); } @@ -342,15 +351,16 @@ public class TaskViewTest extends ShellTestCase { assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); SurfaceHolder sh = mock(SurfaceHolder.class); WindowContainerTransaction wct = new WindowContainerTransaction(); - mTaskView.prepareOpenAnimation(true /* newTask */, new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); + mTaskViewTaskController.prepareOpenAnimation(true /* newTask */, + new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, + mLeash, wct); mTaskView.surfaceCreated(sh); reset(mViewListener); mTaskView.surfaceDestroyed(sh); - verify(mTaskViewTransitions).setTaskViewVisible(eq(mTaskView), eq(false)); + verify(mTaskViewTransitions).setTaskViewVisible(eq(mTaskViewTaskController), eq(false)); - mTaskView.prepareHideAnimation(new SurfaceControl.Transaction()); + mTaskViewTaskController.prepareHideAnimation(new SurfaceControl.Transaction()); verify(mViewListener).onTaskVisibilityChanged(eq(mTaskInfo.taskId), eq(false)); } @@ -359,25 +369,27 @@ public class TaskViewTest extends ShellTestCase { public void testOnReleased() { assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); WindowContainerTransaction wct = new WindowContainerTransaction(); - mTaskView.prepareOpenAnimation(true /* newTask */, new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); + mTaskViewTaskController.prepareOpenAnimation(true /* newTask */, + new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, + mLeash, wct); mTaskView.surfaceCreated(mock(SurfaceHolder.class)); mTaskView.release(); - verify(mOrganizer).removeListener(eq(mTaskView)); + verify(mOrganizer).removeListener(eq(mTaskViewTaskController)); verify(mViewListener).onReleased(); assertThat(mTaskView.isInitialized()).isFalse(); - verify(mTaskViewTransitions).removeTaskView(eq(mTaskView)); + verify(mTaskViewTransitions).removeTaskView(eq(mTaskViewTaskController)); } @Test public void testOnTaskVanished() { assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); WindowContainerTransaction wct = new WindowContainerTransaction(); - mTaskView.prepareOpenAnimation(true /* newTask */, new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); + mTaskViewTaskController.prepareOpenAnimation(true /* newTask */, + new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, + mLeash, wct); mTaskView.surfaceCreated(mock(SurfaceHolder.class)); - mTaskView.prepareCloseAnimation(); + mTaskViewTaskController.prepareCloseAnimation(); verify(mViewListener).onTaskRemovalStarted(eq(mTaskInfo.taskId)); } @@ -386,9 +398,10 @@ public class TaskViewTest extends ShellTestCase { public void testOnBackPressedOnTaskRoot() { assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); WindowContainerTransaction wct = new WindowContainerTransaction(); - mTaskView.prepareOpenAnimation(true /* newTask */, new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); - mTaskView.onBackPressedOnTaskRoot(mTaskInfo); + mTaskViewTaskController.prepareOpenAnimation(true /* newTask */, + new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, + mLeash, wct); + mTaskViewTaskController.onBackPressedOnTaskRoot(mTaskInfo); verify(mViewListener).onBackPressedOnTaskRoot(eq(mTaskInfo.taskId)); } @@ -397,8 +410,9 @@ public class TaskViewTest extends ShellTestCase { public void testSetOnBackPressedOnTaskRoot() { assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); WindowContainerTransaction wct = new WindowContainerTransaction(); - mTaskView.prepareOpenAnimation(true /* newTask */, new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); + mTaskViewTaskController.prepareOpenAnimation(true /* newTask */, + new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, + mLeash, wct); verify(mOrganizer).setInterceptBackPressedOnTaskRoot(eq(mTaskInfo.token), eq(true)); } @@ -406,11 +420,12 @@ public class TaskViewTest extends ShellTestCase { public void testUnsetOnBackPressedOnTaskRoot() { assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); WindowContainerTransaction wct = new WindowContainerTransaction(); - mTaskView.prepareOpenAnimation(true /* newTask */, new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); + mTaskViewTaskController.prepareOpenAnimation(true /* newTask */, + new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, + mLeash, wct); verify(mOrganizer).setInterceptBackPressedOnTaskRoot(eq(mTaskInfo.token), eq(true)); - mTaskView.prepareCloseAnimation(); + mTaskViewTaskController.prepareCloseAnimation(); verify(mOrganizer).setInterceptBackPressedOnTaskRoot(eq(mTaskInfo.token), eq(false)); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java index f24a7f2ca109..f3f615d97a56 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java @@ -29,6 +29,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -360,14 +361,14 @@ public class CompatUIWindowManagerTest extends ShellTestCase { mWindowManager.updateVisibility(/* canShow= */ false); verify(mWindowManager, never()).createLayout(anyBoolean()); - verify(mLayout).setVisibility(View.GONE); + verify(mLayout, atLeastOnce()).setVisibility(View.GONE); // Show button. doReturn(View.GONE).when(mLayout).getVisibility(); mWindowManager.updateVisibility(/* canShow= */ true); verify(mWindowManager, never()).createLayout(anyBoolean()); - verify(mLayout).setVisibility(View.VISIBLE); + verify(mLayout, atLeastOnce()).setVisibility(View.VISIBLE); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/TaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/TaskPositionerTest.kt index 804c416f0cf6..f185a8a80719 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/TaskPositionerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/TaskPositionerTest.kt @@ -66,13 +66,13 @@ class TaskPositionerTest : ShellTestCase() { @Test fun testDragResize_notMove_skipsTransactionOnEnd() { - taskPositioner.onDragResizeStart( + taskPositioner.onDragPositioningStart( CTRL_TYPE_TOP or CTRL_TYPE_RIGHT, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat() ) - taskPositioner.onDragResizeEnd( + taskPositioner.onDragPositioningEnd( STARTING_BOUNDS.left.toFloat() + 10, STARTING_BOUNDS.top.toFloat() + 10 ) @@ -87,18 +87,18 @@ class TaskPositionerTest : ShellTestCase() { @Test fun testDragResize_noEffectiveMove_skipsTransactionOnMoveAndEnd() { - taskPositioner.onDragResizeStart( + taskPositioner.onDragPositioningStart( CTRL_TYPE_TOP or CTRL_TYPE_RIGHT, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat() ) - taskPositioner.onDragResizeMove( + taskPositioner.onDragPositioningMove( STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat() ) - taskPositioner.onDragResizeEnd( + taskPositioner.onDragPositioningEnd( STARTING_BOUNDS.left.toFloat() + 10, STARTING_BOUNDS.top.toFloat() + 10 ) @@ -113,13 +113,13 @@ class TaskPositionerTest : ShellTestCase() { @Test fun testDragResize_hasEffectiveMove_issuesTransactionOnMoveAndEnd() { - taskPositioner.onDragResizeStart( + taskPositioner.onDragPositioningStart( CTRL_TYPE_TOP or CTRL_TYPE_RIGHT, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat() ) - taskPositioner.onDragResizeMove( + taskPositioner.onDragPositioningMove( STARTING_BOUNDS.left.toFloat() + 10, STARTING_BOUNDS.top.toFloat() ) @@ -133,7 +133,7 @@ class TaskPositionerTest : ShellTestCase() { } }) - taskPositioner.onDragResizeEnd( + taskPositioner.onDragPositioningEnd( STARTING_BOUNDS.left.toFloat() + 10, STARTING_BOUNDS.top.toFloat() + 10 ) @@ -150,7 +150,7 @@ class TaskPositionerTest : ShellTestCase() { @Test fun testDragResize_move_skipsDragResizingFlag() { - taskPositioner.onDragResizeStart( + taskPositioner.onDragPositioningStart( CTRL_TYPE_UNDEFINED, // Move STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat() @@ -159,12 +159,12 @@ class TaskPositionerTest : ShellTestCase() { // Move the task 10px to the right. val newX = STARTING_BOUNDS.left.toFloat() + 10 val newY = STARTING_BOUNDS.top.toFloat() - taskPositioner.onDragResizeMove( + taskPositioner.onDragPositioningMove( newX, newY ) - taskPositioner.onDragResizeEnd(newX, newY) + taskPositioner.onDragPositioningEnd(newX, newY) verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> @@ -177,7 +177,7 @@ class TaskPositionerTest : ShellTestCase() { @Test fun testDragResize_resize_setsDragResizingFlag() { - taskPositioner.onDragResizeStart( + taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT, // Resize right STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat() @@ -186,12 +186,12 @@ class TaskPositionerTest : ShellTestCase() { // Resize the task by 10px to the right. val newX = STARTING_BOUNDS.right.toFloat() + 10 val newY = STARTING_BOUNDS.top.toFloat() - taskPositioner.onDragResizeMove( + taskPositioner.onDragPositioningMove( newX, newY ) - taskPositioner.onDragResizeEnd(newX, newY) + taskPositioner.onDragPositioningEnd(newX, newY) verify(mockShellTaskOrganizer).applyTransaction(argThat { wct -> return@argThat wct.changes.any { (token, change) -> diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp index b563627edad9..13357fa25e8c 100644 --- a/libs/hwui/jni/Paint.cpp +++ b/libs/hwui/jni/Paint.cpp @@ -37,7 +37,6 @@ #include "SkShader.h" #include "SkBlendMode.h" #include "unicode/uloc.h" -#include "unicode/ushape.h" #include "utils/Blur.h" #include <hwui/BlurDrawLooper.h> diff --git a/libs/hwui/jni/android_graphics_ColorSpace.cpp b/libs/hwui/jni/android_graphics_ColorSpace.cpp index 232fd71a12b4..63d3f83febd6 100644 --- a/libs/hwui/jni/android_graphics_ColorSpace.cpp +++ b/libs/hwui/jni/android_graphics_ColorSpace.cpp @@ -18,7 +18,6 @@ #include "SkColor.h" #include "SkColorSpace.h" -#include "SkHalf.h" using namespace android; @@ -40,15 +39,58 @@ static skcms_Matrix3x3 getNativeXYZMatrix(JNIEnv* env, jfloatArray xyzD50) { /////////////////////////////////////////////////////////////////////////////// +#if defined(__ANDROID__) // __fp16 is not defined on non-Android builds static float halfToFloat(uint16_t bits) { -#ifdef __ANDROID__ // __fp16 is not defined on non-Android builds __fp16 h; memcpy(&h, &bits, 2); return (float)h; +} #else - return SkHalfToFloat(bits); -#endif +// This is Skia's implementation of SkHalfToFloat, which is +// based on Fabien Giesen's half_to_float_fast2() +// see https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/ +static uint16_t halfMantissa(uint16_t h) { + return h & 0x03ff; +} + +static uint16_t halfExponent(uint16_t h) { + return (h >> 10) & 0x001f; +} + +static uint16_t halfSign(uint16_t h) { + return h >> 15; +} + +union FloatUIntUnion { + uint32_t mUInt; // this must come first for the initializations below to work + float mFloat; +}; + +static float halfToFloat(uint16_t bits) { + static const FloatUIntUnion magic = { 126 << 23 }; + FloatUIntUnion o; + + if (halfExponent(bits) == 0) { + // Zero / Denormal + o.mUInt = magic.mUInt + halfMantissa(bits); + o.mFloat -= magic.mFloat; + } else { + // Set mantissa + o.mUInt = halfMantissa(bits) << 13; + // Set exponent + if (halfExponent(bits) == 0x1f) { + // Inf/NaN + o.mUInt |= (255 << 23); + } else { + o.mUInt |= ((127 - 15 + halfExponent(bits)) << 23); + } + } + + // Set sign + o.mUInt |= (halfSign(bits) << 31); + return o.mFloat; } +#endif // defined(__ANDROID__) SkColor4f GraphicsJNI::convertColorLong(jlong color) { if ((color & 0x3f) == 0) { diff --git a/libs/hwui/tests/common/BitmapAllocationTestUtils.h b/libs/hwui/tests/common/BitmapAllocationTestUtils.h index 312b60bbc067..bbdd98e0c0d1 100644 --- a/libs/hwui/tests/common/BitmapAllocationTestUtils.h +++ b/libs/hwui/tests/common/BitmapAllocationTestUtils.h @@ -56,10 +56,11 @@ public: template <class BaseScene> static bool registerBitmapAllocationScene(std::string name, std::string description) { - TestScene::registerScene({name + "GlTex", description + " (GlTex version).", + TestScene::registerScene({name + "Texture", description + " (Texture version).", createBitmapAllocationScene<BaseScene, &allocateHeapBitmap>}); - TestScene::registerScene({name + "EglImage", description + " (EglImage version).", + TestScene::registerScene({name + "HardwareBuffer", + description + " (HardwareBuffer version).", createBitmapAllocationScene<BaseScene, &allocateHardwareBitmap>}); return true; } diff --git a/location/java/android/location/GnssCapabilities.java b/location/java/android/location/GnssCapabilities.java index 11b5833e35b3..c6f32c2cd387 100644 --- a/location/java/android/location/GnssCapabilities.java +++ b/location/java/android/location/GnssCapabilities.java @@ -129,21 +129,26 @@ public final class GnssCapabilities implements Parcelable { * @hide */ public static GnssCapabilities empty() { - return new GnssCapabilities(0, 0, 0, Collections.emptyList()); + return new GnssCapabilities(/*topFlags=*/ 0, /*isAdrCapabilityKnown=*/ false, + /*measurementCorrectionsFlags=*/ 0, /*powerFlags=*/ 0, /*gnssSignalTypes=*/ + Collections.emptyList()); } private final @TopHalCapabilityFlags int mTopFlags; + private final boolean mIsAdrCapabilityKnown; private final @SubHalMeasurementCorrectionsCapabilityFlags int mMeasurementCorrectionsFlags; private final @SubHalPowerCapabilityFlags int mPowerFlags; private final @NonNull List<GnssSignalType> mGnssSignalTypes; private GnssCapabilities( @TopHalCapabilityFlags int topFlags, + boolean isAdrCapabilityKnown, @SubHalMeasurementCorrectionsCapabilityFlags int measurementCorrectionsFlags, @SubHalPowerCapabilityFlags int powerFlags, @NonNull List<GnssSignalType> gnssSignalTypes) { Objects.requireNonNull(gnssSignalTypes); mTopFlags = topFlags; + mIsAdrCapabilityKnown = isAdrCapabilityKnown; mMeasurementCorrectionsFlags = measurementCorrectionsFlags; mPowerFlags = powerFlags; mGnssSignalTypes = Collections.unmodifiableList(gnssSignalTypes); @@ -154,12 +159,13 @@ public final class GnssCapabilities implements Parcelable { * * @hide */ - public GnssCapabilities withTopHalFlags(@TopHalCapabilityFlags int flags) { - if (mTopFlags == flags) { + public GnssCapabilities withTopHalFlags(@TopHalCapabilityFlags int flags, + boolean isAdrCapabilityKnown) { + if (mTopFlags == flags && mIsAdrCapabilityKnown == isAdrCapabilityKnown) { return this; } else { - return new GnssCapabilities(flags, mMeasurementCorrectionsFlags, mPowerFlags, - mGnssSignalTypes); + return new GnssCapabilities(flags, isAdrCapabilityKnown, + mMeasurementCorrectionsFlags, mPowerFlags, mGnssSignalTypes); } } @@ -174,7 +180,7 @@ public final class GnssCapabilities implements Parcelable { if (mMeasurementCorrectionsFlags == flags) { return this; } else { - return new GnssCapabilities(mTopFlags, flags, mPowerFlags, + return new GnssCapabilities(mTopFlags, mIsAdrCapabilityKnown, flags, mPowerFlags, mGnssSignalTypes); } } @@ -189,8 +195,8 @@ public final class GnssCapabilities implements Parcelable { if (mPowerFlags == flags) { return this; } else { - return new GnssCapabilities(mTopFlags, mMeasurementCorrectionsFlags, flags, - mGnssSignalTypes); + return new GnssCapabilities(mTopFlags, mIsAdrCapabilityKnown, + mMeasurementCorrectionsFlags, flags, mGnssSignalTypes); } } @@ -204,8 +210,8 @@ public final class GnssCapabilities implements Parcelable { if (mGnssSignalTypes.equals(gnssSignalTypes)) { return this; } else { - return new GnssCapabilities(mTopFlags, mMeasurementCorrectionsFlags, mPowerFlags, - new ArrayList<>(gnssSignalTypes)); + return new GnssCapabilities(mTopFlags, mIsAdrCapabilityKnown, + mMeasurementCorrectionsFlags, mPowerFlags, new ArrayList<>(gnssSignalTypes)); } } @@ -372,16 +378,30 @@ public final class GnssCapabilities implements Parcelable { * Returns {@code true} if GNSS chipset supports accumulated delta range, {@code false} * otherwise. * + * <p>The value is only known if {@link #isAccumulatedDeltaRangeCapabilityKnown()} is + * true. + * * <p>The accumulated delta range information can be queried in * {@link android.location.GnssMeasurement#getAccumulatedDeltaRangeState()}, * {@link android.location.GnssMeasurement#getAccumulatedDeltaRangeMeters()}, and * {@link android.location.GnssMeasurement#getAccumulatedDeltaRangeUncertaintyMeters()}. */ public boolean hasAccumulatedDeltaRange() { + if (!mIsAdrCapabilityKnown) { + throw new IllegalStateException("Accumulated delta range capability is unknown."); + } return (mTopFlags & TOP_HAL_CAPABILITY_ACCUMULATED_DELTA_RANGE) != 0; } /** + * Returns {@code true} if {@link #hasAccumulatedDeltaRange()} is known, {@code false} + * otherwise. + */ + public boolean isAccumulatedDeltaRangeCapabilityKnown() { + return mIsAdrCapabilityKnown; + } + + /** * Returns {@code true} if GNSS chipset supports line-of-sight satellite identification * measurement corrections, {@code false} otherwise. */ @@ -488,6 +508,7 @@ public final class GnssCapabilities implements Parcelable { GnssCapabilities that = (GnssCapabilities) o; return mTopFlags == that.mTopFlags + && mIsAdrCapabilityKnown == that.mIsAdrCapabilityKnown && mMeasurementCorrectionsFlags == that.mMeasurementCorrectionsFlags && mPowerFlags == that.mPowerFlags && mGnssSignalTypes.equals(that.mGnssSignalTypes); @@ -495,15 +516,16 @@ public final class GnssCapabilities implements Parcelable { @Override public int hashCode() { - return Objects.hash(mTopFlags, mMeasurementCorrectionsFlags, mPowerFlags, mGnssSignalTypes); + return Objects.hash(mTopFlags, mIsAdrCapabilityKnown, mMeasurementCorrectionsFlags, + mPowerFlags, mGnssSignalTypes); } public static final @NonNull Creator<GnssCapabilities> CREATOR = new Creator<GnssCapabilities>() { @Override public GnssCapabilities createFromParcel(Parcel in) { - return new GnssCapabilities(in.readInt(), in.readInt(), in.readInt(), - in.createTypedArrayList(GnssSignalType.CREATOR)); + return new GnssCapabilities(in.readInt(), in.readBoolean(), in.readInt(), + in.readInt(), in.createTypedArrayList(GnssSignalType.CREATOR)); } @Override @@ -520,6 +542,7 @@ public final class GnssCapabilities implements Parcelable { @Override public void writeToParcel(@NonNull Parcel parcel, int flags) { parcel.writeInt(mTopFlags); + parcel.writeBoolean(mIsAdrCapabilityKnown); parcel.writeInt(mMeasurementCorrectionsFlags); parcel.writeInt(mPowerFlags); parcel.writeTypedList(mGnssSignalTypes); @@ -574,8 +597,10 @@ public final class GnssCapabilities implements Parcelable { if (hasMeasurementCorrectionsForDriving()) { builder.append("MEASUREMENT_CORRECTIONS_FOR_DRIVING "); } - if (hasAccumulatedDeltaRange()) { + if (mIsAdrCapabilityKnown && hasAccumulatedDeltaRange()) { builder.append("ACCUMULATED_DELTA_RANGE "); + } else if (!mIsAdrCapabilityKnown) { + builder.append("ACCUMULATED_DELTA_RANGE(unknown) "); } if (hasMeasurementCorrectionsLosSats()) { builder.append("LOS_SATS "); @@ -622,12 +647,14 @@ public final class GnssCapabilities implements Parcelable { public static final class Builder { private @TopHalCapabilityFlags int mTopFlags; + private boolean mIsAdrCapabilityKnown; private @SubHalMeasurementCorrectionsCapabilityFlags int mMeasurementCorrectionsFlags; private @SubHalPowerCapabilityFlags int mPowerFlags; private @NonNull List<GnssSignalType> mGnssSignalTypes; public Builder() { mTopFlags = 0; + mIsAdrCapabilityKnown = false; mMeasurementCorrectionsFlags = 0; mPowerFlags = 0; mGnssSignalTypes = Collections.emptyList(); @@ -635,6 +662,7 @@ public final class GnssCapabilities implements Parcelable { public Builder(@NonNull GnssCapabilities capabilities) { mTopFlags = capabilities.mTopFlags; + mIsAdrCapabilityKnown = capabilities.mIsAdrCapabilityKnown; mMeasurementCorrectionsFlags = capabilities.mMeasurementCorrectionsFlags; mPowerFlags = capabilities.mPowerFlags; mGnssSignalTypes = capabilities.mGnssSignalTypes; @@ -768,12 +796,22 @@ public final class GnssCapabilities implements Parcelable { * Sets accumulated delta range capability. */ public @NonNull Builder setHasAccumulatedDeltaRange(boolean capable) { + mIsAdrCapabilityKnown = true; mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_ACCUMULATED_DELTA_RANGE, capable); return this; } /** + * Clears accumulated delta range capability and sets it as unknown. + */ + public @NonNull Builder clearIsAccumulatedDeltaRangeCapabilityKnown() { + mIsAdrCapabilityKnown = false; + mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_ACCUMULATED_DELTA_RANGE, false); + return this; + } + + /** * Sets measurement corrections line-of-sight satellites capability. */ public @NonNull Builder setHasMeasurementCorrectionsLosSats(boolean capable) { @@ -864,8 +902,8 @@ public final class GnssCapabilities implements Parcelable { * Builds a new GnssCapabilities. */ public @NonNull GnssCapabilities build() { - return new GnssCapabilities(mTopFlags, mMeasurementCorrectionsFlags, mPowerFlags, - new ArrayList<>(mGnssSignalTypes)); + return new GnssCapabilities(mTopFlags, mIsAdrCapabilityKnown, + mMeasurementCorrectionsFlags, mPowerFlags, new ArrayList<>(mGnssSignalTypes)); } private static int setFlag(int value, int flag, boolean set) { diff --git a/location/java/android/location/GnssMeasurementsEvent.java b/location/java/android/location/GnssMeasurementsEvent.java index d4b861fdb0c1..4fc2ee8b7fb0 100644 --- a/location/java/android/location/GnssMeasurementsEvent.java +++ b/location/java/android/location/GnssMeasurementsEvent.java @@ -43,7 +43,7 @@ public final class GnssMeasurementsEvent implements Parcelable { private final List<GnssAutomaticGainControl> mGnssAgcs; private final boolean mIsFullTracking; - private static final int HAS_FULL_TRACKING = 1; + private static final int HAS_IS_FULL_TRACKING = 1; /** * Used for receiving GNSS satellite measurements from the GNSS engine. @@ -174,7 +174,7 @@ public final class GnssMeasurementsEvent implements Parcelable { * False indicates that the GNSS chipset may optimize power via duty cycling, constellations and * frequency limits, etc. * - * <p>The value is only available if {@link #hasFullTracking()} is {@code true}. + * <p>The value is only available if {@link #hasIsFullTracking()} is {@code true}. */ public boolean isFullTracking() { return mIsFullTracking; @@ -183,8 +183,8 @@ public final class GnssMeasurementsEvent implements Parcelable { /** * Return {@code true} if {@link #isFullTracking()} is available, {@code false} otherwise. */ - public boolean hasFullTracking() { - return (mFlag & HAS_FULL_TRACKING) == HAS_FULL_TRACKING; + public boolean hasIsFullTracking() { + return (mFlag & HAS_IS_FULL_TRACKING) == HAS_IS_FULL_TRACKING; } public static final @android.annotation.NonNull Creator<GnssMeasurementsEvent> CREATOR = @@ -227,7 +227,7 @@ public final class GnssMeasurementsEvent implements Parcelable { builder.append(mClock); builder.append(' ').append(mMeasurements.toString()); builder.append(' ').append(mGnssAgcs.toString()); - if (hasFullTracking()) { + if (hasIsFullTracking()) { builder.append(" isFullTracking=").append(mIsFullTracking); } builder.append("]"); @@ -334,8 +334,8 @@ public final class GnssMeasurementsEvent implements Parcelable { * and frequency limits, etc. */ @NonNull - public Builder setFullTracking(boolean isFullTracking) { - mFlag |= HAS_FULL_TRACKING; + public Builder setIsFullTracking(boolean isFullTracking) { + mFlag |= HAS_IS_FULL_TRACKING; mIsFullTracking = isFullTracking; return this; } @@ -344,8 +344,8 @@ public final class GnssMeasurementsEvent implements Parcelable { * Clears the full tracking mode indicator. */ @NonNull - public Builder clearFullTracking() { - mFlag &= ~HAS_FULL_TRACKING; + public Builder clearIsFullTracking() { + mFlag &= ~HAS_IS_FULL_TRACKING; return this; } diff --git a/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindowCallback.aidl b/media/java/android/media/AudioPresentation.aidl index 92abfc8eea24..3fb5a5b152e2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindowCallback.aidl +++ b/media/java/android/media/AudioPresentation.aidl @@ -14,10 +14,6 @@ * limitations under the License. */ -package com.android.server.wm.scvh; +package android.media; -import android.view.SurfaceControlViewHost.SurfacePackage; - -interface IAttachEmbeddedWindowCallback { - void onEmbeddedWindowAttached(in SurfacePackage surfacePackage); -}
\ No newline at end of file +parcelable AudioPresentation; diff --git a/media/java/android/media/AudioPresentation.java b/media/java/android/media/AudioPresentation.java index 05f3c5a3512b..a413545f3fda 100644 --- a/media/java/android/media/AudioPresentation.java +++ b/media/java/android/media/AudioPresentation.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,9 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.icu.util.ULocale; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -49,7 +52,7 @@ import java.util.Objects; * Applications that parse media streams and extract presentation information on their own * can create instances of AudioPresentation by using {@link AudioPresentation.Builder} class. */ -public final class AudioPresentation { +public final class AudioPresentation implements Parcelable { private final int mPresentationId; private final int mProgramId; private final ULocale mLanguage; @@ -126,7 +129,7 @@ public final class AudioPresentation { private final boolean mAudioDescriptionAvailable; private final boolean mSpokenSubtitlesAvailable; private final boolean mDialogueEnhancementAvailable; - private final Map<ULocale, CharSequence> mLabels; + private final HashMap<ULocale, String> mLabels; /** * No preferred reproduction channel layout. @@ -160,9 +163,14 @@ public final class AudioPresentation { public static final int MASTERED_FOR_HEADPHONE = 4; /** - * This ID is reserved. No items can be explicitly assigned this ID. + * Unknown audio presentation ID, this indicates audio presentation ID is not selected. */ - private static final int UNKNOWN_ID = -1; + public static final int PRESENTATION_ID_UNKNOWN = -1; + + /** + * Unknown audio program ID, this indicates audio program ID is not selected. + */ + public static final int PROGRAM_ID_UNKNOWN = -1; /** * This allows an application developer to construct an AudioPresentation object with all the @@ -191,7 +199,7 @@ public final class AudioPresentation { boolean audioDescriptionAvailable, boolean spokenSubtitlesAvailable, boolean dialogueEnhancementAvailable, - @NonNull Map<ULocale, CharSequence> labels) { + @NonNull Map<ULocale, String> labels) { mPresentationId = presentationId; mProgramId = programId; mLanguage = language; @@ -199,7 +207,18 @@ public final class AudioPresentation { mAudioDescriptionAvailable = audioDescriptionAvailable; mSpokenSubtitlesAvailable = spokenSubtitlesAvailable; mDialogueEnhancementAvailable = dialogueEnhancementAvailable; - mLabels = new HashMap<ULocale, CharSequence>(labels); + mLabels = new HashMap<ULocale, String>(labels); + } + + private AudioPresentation(@NonNull Parcel in) { + mPresentationId = in.readInt(); + mProgramId = in.readInt(); + mLanguage = in.readSerializable(ULocale.class.getClassLoader(), ULocale.class); + mMasteringIndication = in.readInt(); + mAudioDescriptionAvailable = in.readBoolean(); + mSpokenSubtitlesAvailable = in.readBoolean(); + mDialogueEnhancementAvailable = in.readBoolean(); + mLabels = in.readSerializable(HashMap.class.getClassLoader(), HashMap.class); } /** @@ -225,13 +244,13 @@ public final class AudioPresentation { */ public Map<Locale, String> getLabels() { Map<Locale, String> localeLabels = new HashMap<Locale, String>(mLabels.size()); - for (Map.Entry<ULocale, CharSequence> entry : mLabels.entrySet()) { - localeLabels.put(entry.getKey().toLocale(), entry.getValue().toString()); + for (Map.Entry<ULocale, String> entry : mLabels.entrySet()) { + localeLabels.put(entry.getKey().toLocale(), entry.getValue()); } return localeLabels; } - private Map<ULocale, CharSequence> getULabels() { + private Map<ULocale, String> getULabels() { return mLabels; } @@ -335,13 +354,13 @@ public final class AudioPresentation { */ public static final class Builder { private final int mPresentationId; - private int mProgramId = UNKNOWN_ID; + private int mProgramId = PROGRAM_ID_UNKNOWN; private ULocale mLanguage = new ULocale(""); private int mMasteringIndication = MASTERING_NOT_INDICATED; private boolean mAudioDescriptionAvailable = false; private boolean mSpokenSubtitlesAvailable = false; private boolean mDialogueEnhancementAvailable = false; - private Map<ULocale, CharSequence> mLabels = new HashMap<ULocale, CharSequence>(); + private HashMap<ULocale, String> mLabels = new HashMap<ULocale, String>(); /** * Create a {@link Builder}. Any field that should be included in the @@ -402,7 +421,10 @@ public final class AudioPresentation { * @param labels Text label indexed by its locale corresponding to the language code. */ public @NonNull Builder setLabels(@NonNull Map<ULocale, CharSequence> labels) { - mLabels = new HashMap<ULocale, CharSequence>(labels); + mLabels.clear(); + for (Map.Entry<ULocale, CharSequence> entry : labels.entrySet()) { + mLabels.put(entry.getKey(), entry.getValue().toString()); + } return this; } @@ -448,4 +470,35 @@ public final class AudioPresentation { mDialogueEnhancementAvailable, mLabels); } } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(getPresentationId()); + dest.writeInt(getProgramId()); + dest.writeSerializable(getULocale()); + dest.writeInt(getMasteringIndication()); + dest.writeBoolean(hasAudioDescription()); + dest.writeBoolean(hasSpokenSubtitles()); + dest.writeBoolean(hasDialogueEnhancement()); + dest.writeSerializable(mLabels); + } + + @NonNull + public static final Parcelable.Creator<AudioPresentation> CREATOR = + new Parcelable.Creator<AudioPresentation>() { + @Override + public AudioPresentation createFromParcel(@NonNull Parcel in) { + return new AudioPresentation(in); + } + + @Override + public AudioPresentation[] newArray(int size) { + return new AudioPresentation[size]; + } + }; } diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 948fef4d4d8a..194da217a121 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -272,15 +272,19 @@ public class AudioTrack extends PlayerBase @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int ENCAPSULATION_MODE_HANDLE = 2; - /* Enumeration of metadata types permitted for use by + /** + * Enumeration of metadata types permitted for use by * encapsulation mode audio streams. + * @hide */ - /** @hide */ - @IntDef(prefix = { "ENCAPSULATION_METADATA_TYPE_" }, value = { - ENCAPSULATION_METADATA_TYPE_NONE, /* reserved */ - ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER, - ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR, - }) + @IntDef(prefix = {"ENCAPSULATION_METADATA_TYPE_"}, + value = + { + ENCAPSULATION_METADATA_TYPE_NONE, /* reserved */ + ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER, + ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR, + ENCAPSULATION_METADATA_TYPE_SUPPLEMENTARY_AUDIO_PLACEMENT, + }) @Retention(RetentionPolicy.SOURCE) public @interface EncapsulationMetadataType {} @@ -304,6 +308,45 @@ public class AudioTrack extends PlayerBase */ public static final int ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR = 2; + /** + * Encapsulation metadata type for placement of supplementary audio. + * + * A 32 bit integer constant, one of {@link #SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL}, {@link + * #SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT}, {@link #SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT}. + */ + public static final int ENCAPSULATION_METADATA_TYPE_SUPPLEMENTARY_AUDIO_PLACEMENT = 3; + + /** + * Enumeration of supplementary audio placement types. + * @hide + */ + @IntDef(prefix = {"SUPPLEMENTARY_AUDIO_PLACEMENT_"}, + value = + { + SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL, + SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT, + SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SupplementaryAudioPlacement {} + // Important: The SUPPLEMENTARY_AUDIO_PLACEMENT values must be kept in sync with native header + // files. + + /** + * Supplementary audio placement normal. + */ + public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL = 0; + + /** + * Supplementary audio placement left. + */ + public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT = 1; + + /** + * Supplementary audio placement right. + */ + public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT = 2; + /* Dual Mono handling is used when a stereo audio stream * contains separate audio content on the left and right channels. * Such information about the content of the stream may be found, for example, in diff --git a/media/java/android/media/RouteListingPreference.java b/media/java/android/media/RouteListingPreference.java index b03653c07161..ff0a4929a981 100644 --- a/media/java/android/media/RouteListingPreference.java +++ b/media/java/android/media/RouteListingPreference.java @@ -32,6 +32,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Objects; /** @@ -254,7 +255,8 @@ public final class RouteListingPreference implements Parcelable { DISABLE_REASON_SUBSCRIPTION_REQUIRED, DISABLE_REASON_DOWNLOADED_CONTENT, DISABLE_REASON_AD, - DISABLE_REASON_IN_APP_ONLY + DISABLE_REASON_IN_APP_ONLY, + DISABLE_REASON_CUSTOM }) public @interface DisableReason {} @@ -280,6 +282,15 @@ public final class RouteListingPreference implements Parcelable { * will take the user to the app. */ public static final int DISABLE_REASON_IN_APP_ONLY = 4; + /** + * The corresponding route is not available because of the reason described by {@link + * #getCustomDisableReasonMessage()}. + * + * <p>Applications should strongly prefer one of the other disable reasons (for the full + * list, see {@link #getDisableReason()}) in order to guarantee correct localization and + * rendering across all form factors. + */ + public static final int DISABLE_REASON_CUSTOM = 5; @NonNull public static final Creator<Item> CREATOR = @@ -299,12 +310,15 @@ public final class RouteListingPreference implements Parcelable { @Flags private final int mFlags; @DisableReason private final int mDisableReason; private final int mSessionParticipantCount; + @Nullable private final CharSequence mCustomDisableReasonMessage; private Item(@NonNull Builder builder) { mRouteId = builder.mRouteId; mFlags = builder.mFlags; mDisableReason = builder.mDisableReason; mSessionParticipantCount = builder.mSessionParticipantCount; + mCustomDisableReasonMessage = builder.mCustomDisableReasonMessage; + validateCustomDisableReasonMessage(); } private Item(Parcel in) { @@ -314,6 +328,8 @@ public final class RouteListingPreference implements Parcelable { mDisableReason = in.readInt(); mSessionParticipantCount = in.readInt(); Preconditions.checkArgument(mSessionParticipantCount >= 0); + mCustomDisableReasonMessage = in.readCharSequence(); + validateCustomDisableReasonMessage(); } /** @@ -346,6 +362,7 @@ public final class RouteListingPreference implements Parcelable { * @see #DISABLE_REASON_DOWNLOADED_CONTENT * @see #DISABLE_REASON_AD * @see #DISABLE_REASON_IN_APP_ONLY + * @see #DISABLE_REASON_CUSTOM */ @DisableReason public int getDisableReason() { @@ -363,6 +380,25 @@ public final class RouteListingPreference implements Parcelable { return mSessionParticipantCount; } + /** + * Returns a human-readable {@link CharSequence} describing the reason for this route to be + * disabled. May be null if {@link #getDisableReason()} is not {@link + * #DISABLE_REASON_CUSTOM}. + * + * <p>This value is ignored if the {@link #getDisableReason() disable reason} for this item + * is not {@link #DISABLE_REASON_CUSTOM}. + * + * <p>Applications must provide a localized message that matches the system's locale. See + * {@link Locale#getDefault()}. + * + * <p>This message is a hint for the system. Applications should strongly prefer one of the + * other disable reasons listed in {@link #getDisableReason()}. + */ + @Nullable + public CharSequence getCustomDisableReasonMessage() { + return mCustomDisableReasonMessage; + } + // Item Parcelable implementation. @Override @@ -376,6 +412,7 @@ public final class RouteListingPreference implements Parcelable { dest.writeInt(mFlags); dest.writeInt(mDisableReason); dest.writeInt(mSessionParticipantCount); + dest.writeCharSequence(mCustomDisableReasonMessage); } // Equals and hashCode. @@ -392,12 +429,28 @@ public final class RouteListingPreference implements Parcelable { return mRouteId.equals(item.mRouteId) && mFlags == item.mFlags && mDisableReason == item.mDisableReason - && mSessionParticipantCount == item.mSessionParticipantCount; + && mSessionParticipantCount == item.mSessionParticipantCount + && TextUtils.equals( + mCustomDisableReasonMessage, item.mCustomDisableReasonMessage); } @Override public int hashCode() { - return Objects.hash(mRouteId, mFlags, mDisableReason, mSessionParticipantCount); + return Objects.hash( + mRouteId, + mFlags, + mDisableReason, + mSessionParticipantCount, + mCustomDisableReasonMessage); + } + + private void validateCustomDisableReasonMessage() { + if (mDisableReason == DISABLE_REASON_CUSTOM) { + Preconditions.checkArgument( + !TextUtils.isEmpty(mCustomDisableReasonMessage), + "customDisableReasonMessage must not be null or empty if disable reason is" + + " DISABLE_REASON_CUSTOM."); + } } /** Builder for {@link Item}. */ @@ -407,6 +460,7 @@ public final class RouteListingPreference implements Parcelable { private int mFlags; private int mDisableReason; private int mSessionParticipantCount; + private CharSequence mCustomDisableReasonMessage; /** * Constructor. @@ -444,6 +498,14 @@ public final class RouteListingPreference implements Parcelable { return this; } + /** See {@link Item#getCustomDisableReasonMessage()}. */ + @NonNull + public Builder setCustomDisableReasonMessage( + @Nullable CharSequence customDisableReasonMessage) { + mCustomDisableReasonMessage = customDisableReasonMessage; + return this; + } + /** Creates and returns a new {@link Item} with the given parameters. */ @NonNull public Item build() { diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl index d55d2871311f..c4f60c30c547 100644 --- a/media/java/android/media/tv/ITvInputClient.aidl +++ b/media/java/android/media/tv/ITvInputClient.aidl @@ -17,6 +17,7 @@ package android.media.tv; import android.content.ComponentName; +import android.media.AudioPresentation; import android.media.tv.AdBuffer; import android.media.tv.AdResponse; import android.media.tv.AitInfo; @@ -37,6 +38,8 @@ oneway interface ITvInputClient { void onSessionReleased(int seq); void onSessionEvent(in String name, in Bundle args, int seq); void onChannelRetuned(in Uri channelUri, int seq); + void onAudioPresentationsChanged(in List<AudioPresentation> AudioPresentations, int seq); + void onAudioPresentationSelected(int presentationId, int programId, int seq); void onTracksChanged(in List<TvTrackInfo> tracks, int seq); void onTrackSelected(int type, in String trackId, int seq); void onVideoAvailable(int seq); diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl index f7c1e3c8abde..746cfa229b00 100644 --- a/media/java/android/media/tv/ITvInputManager.aidl +++ b/media/java/android/media/tv/ITvInputManager.aidl @@ -16,9 +16,11 @@ package android.media.tv; +import android.content.AttributionSource; import android.content.ComponentName; import android.content.Intent; import android.graphics.Rect; +import android.media.AudioPresentation; import android.media.PlaybackParams; import android.media.tv.AdBuffer; import android.media.tv.AdRequest; @@ -63,7 +65,7 @@ interface ITvInputManager { void addBlockedRating(in String rating, int userId); void removeBlockedRating(in String rating, int userId); - void createSession(in ITvInputClient client, in String inputId, boolean isRecordingSession, + void createSession(in ITvInputClient client, in String inputId, in AttributionSource tvAppAttributionSource, boolean isRecordingSession, int seq, int userId); void releaseSession(in IBinder sessionToken, int userId); int getClientPid(in String sessionId); @@ -77,6 +79,8 @@ interface ITvInputManager { void tune(in IBinder sessionToken, in Uri channelUri, in Bundle params, int userId); void setCaptionEnabled(in IBinder sessionToken, boolean enabled, int userId); void selectTrack(in IBinder sessionToken, int type, in String trackId, int userId); + void selectAudioPresentation(in IBinder sessionToken, int presentationId, int programId, + int userId); void setInteractiveAppNotificationEnabled(in IBinder sessionToken, boolean enabled, int userId); diff --git a/media/java/android/media/tv/ITvInputService.aidl b/media/java/android/media/tv/ITvInputService.aidl index 64a23a2323f6..be73c0cdf43a 100755 --- a/media/java/android/media/tv/ITvInputService.aidl +++ b/media/java/android/media/tv/ITvInputService.aidl @@ -16,6 +16,7 @@ package android.media.tv; +import android.content.AttributionSource; import android.hardware.hdmi.HdmiDeviceInfo; import android.media.tv.ITvInputServiceCallback; import android.media.tv.ITvInputSessionCallback; @@ -30,7 +31,7 @@ interface ITvInputService { oneway void registerCallback(in ITvInputServiceCallback callback); oneway void unregisterCallback(in ITvInputServiceCallback callback); oneway void createSession(in InputChannel channel, in ITvInputSessionCallback callback, - in String inputId, in String sessionId); + in String inputId, in String sessionId, in AttributionSource tvAppAttributionSource); oneway void createRecordingSession(in ITvInputSessionCallback callback, in String inputId, in String sessionId); List<String> getAvailableExtensionInterfaceNames(); diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl index 326b98d99739..e6c09a9df14c 100644 --- a/media/java/android/media/tv/ITvInputSession.aidl +++ b/media/java/android/media/tv/ITvInputSession.aidl @@ -17,6 +17,7 @@ package android.media.tv; import android.graphics.Rect; +import android.media.AudioPresentation; import android.media.PlaybackParams; import android.media.tv.AdBuffer; import android.media.tv.AdRequest; @@ -41,6 +42,7 @@ oneway interface ITvInputSession { void setVolume(float volume); void tune(in Uri channelUri, in Bundle params); void setCaptionEnabled(boolean enabled); + void selectAudioPresentation(int presentationId, int programId); void selectTrack(int type, in String trackId); void setInteractiveAppNotificationEnabled(boolean enable); diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl index 82166223608f..0111f091aaa1 100644 --- a/media/java/android/media/tv/ITvInputSessionCallback.aidl +++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl @@ -16,6 +16,7 @@ package android.media.tv; +import android.media.AudioPresentation; import android.media.tv.AdBuffer; import android.media.tv.AdResponse; import android.media.tv.AitInfo; @@ -34,6 +35,8 @@ oneway interface ITvInputSessionCallback { void onSessionCreated(ITvInputSession session, in IBinder hardwareSessionToken); void onSessionEvent(in String name, in Bundle args); void onChannelRetuned(in Uri channelUri); + void onAudioPresentationsChanged(in List<AudioPresentation> tvAudioPresentations); + void onAudioPresentationSelected(int presentationId, int programId); void onTracksChanged(in List<TvTrackInfo> tracks); void onTrackSelected(int type, in String trackId); void onVideoAvailable(); diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java index 634f1024ab19..847762ffefe2 100644 --- a/media/java/android/media/tv/ITvInputSessionWrapper.java +++ b/media/java/android/media/tv/ITvInputSessionWrapper.java @@ -30,7 +30,6 @@ import android.view.InputChannel; import android.view.InputEvent; import android.view.InputEventReceiver; import android.view.Surface; - import com.android.internal.os.HandlerCaller; import com.android.internal.os.SomeArgs; @@ -75,6 +74,7 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand private static final int DO_SET_IAPP_NOTIFICATION_ENABLED = 26; private static final int DO_REQUEST_AD = 27; private static final int DO_NOTIFY_AD_BUFFER = 28; + private static final int DO_SELECT_AUDIO_PRESENTATION = 29; private final boolean mIsRecordingSession; private final HandlerCaller mCaller; @@ -240,6 +240,12 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand mTvInputRecordingSessionImpl.resumeRecording((Bundle) msg.obj); break; } + case DO_SELECT_AUDIO_PRESENTATION: { + SomeArgs args = (SomeArgs) msg.obj; + mTvInputSessionImpl.selectAudioPresentation(args.argi1, args.argi2); + args.recycle(); + break; + } case DO_REQUEST_BROADCAST_INFO: { mTvInputSessionImpl.requestBroadcastInfo((BroadcastInfoRequest) msg.obj); break; @@ -275,8 +281,8 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand + "Consider handling the tune request in a separate thread."); } if (durationMs > EXECUTE_MESSAGE_TIMEOUT_LONG_MILLIS) { - throw new RuntimeException("Too much time to handle a request. (type=" + msg.what + - ", " + durationMs + "ms > " + EXECUTE_MESSAGE_TIMEOUT_LONG_MILLIS + "ms)."); + throw new RuntimeException("Too much time to handle a request. (type=" + msg.what + + ", " + durationMs + "ms > " + EXECUTE_MESSAGE_TIMEOUT_LONG_MILLIS + "ms)."); } } } @@ -323,6 +329,12 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand } @Override + public void selectAudioPresentation(int presentationId, int programId) { + mCaller.executeOrSendMessage(mCaller.obtainMessageII(DO_SELECT_AUDIO_PRESENTATION, + presentationId, programId)); + } + + @Override public void selectTrack(int type, String trackId) { mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_SELECT_TRACK, type, trackId)); } @@ -436,7 +448,7 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand } private final class TvInputEventReceiver extends InputEventReceiver { - public TvInputEventReceiver(InputChannel inputChannel, Looper looper) { + TvInputEventReceiver(InputChannel inputChannel, Looper looper) { super(inputChannel, looper); } diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index e8127df8ee46..a4e221275d12 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -26,11 +26,13 @@ import android.annotation.StringDef; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; +import android.content.AttributionSource; import android.content.Context; import android.content.Intent; import android.graphics.Rect; import android.media.AudioDeviceInfo; import android.media.AudioFormat.Encoding; +import android.media.AudioPresentation; import android.media.PlaybackParams; import android.media.tv.interactive.TvInteractiveAppManager; import android.net.Uri; @@ -54,9 +56,7 @@ import android.view.InputEventSender; import android.view.KeyEvent; import android.view.Surface; import android.view.View; - import com.android.internal.util.Preconditions; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -550,6 +550,27 @@ public final class TvInputManager { } /** + * This is called when the audio presentation information of the session has been changed. + * + * @param session A {@link TvInputManager.Session} associated with this callback. + * @param audioPresentations An updated list of selectable audio presentations. + */ + public void onAudioPresentationsChanged(Session session, + List<AudioPresentation> audioPresentations) { + } + + /** + * This is called when an audio presentation is selected. + * + * @param session A {@link TvInputManager.Session} associated with this callback. + * @param presentationId The ID of the selected audio presentation. + * @param programId The ID of the program providing the selected audio presentation. + */ + public void onAudioPresentationSelected(Session session, int presentationId, + int programId) { + } + + /** * This is called when the track information of the session has been changed. * * @param session A {@link TvInputManager.Session} associated with this callback. @@ -777,6 +798,25 @@ public final class TvInputManager { }); } + void postAudioPresentationsChanged(final List<AudioPresentation> audioPresentations) { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onAudioPresentationsChanged(mSession, audioPresentations); + } + }); + } + + void postAudioPresentationSelected(final int presentationId, final int programId) { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onAudioPresentationSelected(mSession, presentationId, + programId); + } + }); + } + void postTracksChanged(final List<TvTrackInfo> tracks) { mHandler.post(new Runnable() { @Override @@ -1234,6 +1274,36 @@ public final class TvInputManager { record.postChannelRetuned(channelUri); } } + @Override + public void onAudioPresentationsChanged(List<AudioPresentation> audioPresentations, + int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + if (record.mSession.updateAudioPresentations(audioPresentations)) { + record.postAudioPresentationsChanged(audioPresentations); + } + } + } + + @Override + public void onAudioPresentationSelected(int presentationId, int programId, int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + if (record.mSession.updateAudioPresentationSelection(presentationId, + programId)) { + record.postAudioPresentationSelected(presentationId, programId); + } + } + } + @Override public void onTracksChanged(List<TvTrackInfo> tracks, int seq) { @@ -1910,13 +1980,15 @@ public final class TvInputManager { * of the given TV input. * * @param inputId The ID of the TV input. + * @param tvAppAttributionSource The Attribution Source of the TV App. * @param callback A callback used to receive the created session. * @param handler A {@link Handler} that the session creation will be delivered to. * @hide */ - public void createSession(@NonNull String inputId, @NonNull final SessionCallback callback, - @NonNull Handler handler) { - createSessionInternal(inputId, false, callback, handler); + public void createSession(@NonNull String inputId, + @NonNull AttributionSource tvAppAttributionSource, + @NonNull final SessionCallback callback, @NonNull Handler handler) { + createSessionInternal(inputId, tvAppAttributionSource, false, callback, handler); } /** @@ -1941,7 +2013,7 @@ public final class TvInputManager { * @param useCase the use case type of the client. * {@see TvInputService#PriorityHintUseCaseType}. * @param sessionId the unique id of the session owned by the client. - * {@see TvInputService#onCreateSession(String, String)}. + * {@see TvInputService#onCreateSession(String, String, AttributionSource)}. * * @return the use case priority value for the given use case type and the client's foreground * or background status. @@ -1992,11 +2064,11 @@ public final class TvInputManager { */ public void createRecordingSession(@NonNull String inputId, @NonNull final SessionCallback callback, @NonNull Handler handler) { - createSessionInternal(inputId, true, callback, handler); + createSessionInternal(inputId, null, true, callback, handler); } - private void createSessionInternal(String inputId, boolean isRecordingSession, - SessionCallback callback, Handler handler) { + private void createSessionInternal(String inputId, AttributionSource tvAppAttributionSource, + boolean isRecordingSession, SessionCallback callback, Handler handler) { Preconditions.checkNotNull(inputId); Preconditions.checkNotNull(callback); Preconditions.checkNotNull(handler); @@ -2005,7 +2077,8 @@ public final class TvInputManager { int seq = mNextSeq++; mSessionCallbackRecordMap.put(seq, record); try { - mService.createSession(mClient, inputId, isRecordingSession, seq, mUserId); + mService.createSession( + mClient, inputId, tvAppAttributionSource, isRecordingSession, seq, mUserId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2176,8 +2249,8 @@ public final class TvInputManager { * @param deviceId The device ID to acquire Hardware for. * @param info The TV input which will use the acquired Hardware. * @param tvInputSessionId a String returned to TIS when the session was created. - * {@see TvInputService#onCreateSession(String, String)}. If null, the client will be - * treated as a background app. + * {@see TvInputService#onCreateSession(String, String, AttributionSource)}. If null, the + * client will be treated as a background app. * @param priorityHint The use case of the client. {@see TvInputService#PriorityHintUseCaseType} * @param executor the executor on which the listener would be invoked. * @param callback A callback to receive updates on Hardware. @@ -2399,12 +2472,18 @@ public final class TvInputManager { private final Object mMetadataLock = new Object(); // @GuardedBy("mMetadataLock") + private final List<AudioPresentation> mAudioPresentations = new ArrayList<>(); + // @GuardedBy("mMetadataLock") private final List<TvTrackInfo> mAudioTracks = new ArrayList<>(); // @GuardedBy("mMetadataLock") private final List<TvTrackInfo> mVideoTracks = new ArrayList<>(); // @GuardedBy("mMetadataLock") private final List<TvTrackInfo> mSubtitleTracks = new ArrayList<>(); // @GuardedBy("mMetadataLock") + private int mSelectedAudioProgramId = AudioPresentation.PROGRAM_ID_UNKNOWN; + // @GuardedBy("mMetadataLock") + private int mSelectedAudioPresentationId = AudioPresentation.PRESENTATION_ID_UNKNOWN; + // @GuardedBy("mMetadataLock") private String mSelectedAudioTrackId; // @GuardedBy("mMetadataLock") private String mSelectedVideoTrackId; @@ -2552,9 +2631,12 @@ public final class TvInputManager { return; } synchronized (mMetadataLock) { + mAudioPresentations.clear(); mAudioTracks.clear(); mVideoTracks.clear(); mSubtitleTracks.clear(); + mSelectedAudioProgramId = AudioPresentation.PROGRAM_ID_UNKNOWN; + mSelectedAudioPresentationId = AudioPresentation.PRESENTATION_ID_UNKNOWN; mSelectedAudioTrackId = null; mSelectedVideoTrackId = null; mSelectedSubtitleTrackId = null; @@ -2586,6 +2668,119 @@ public final class TvInputManager { } /** + * Selects an audio presentation + * + * @param presentationId The ID of the audio presentation to select. + * @param programId The ID of the program offering the selected audio presentation. + * @see #getAudioPresentations + */ + public void selectAudioPresentation(int presentationId, int programId) { + synchronized (mMetadataLock) { + if (presentationId != AudioPresentation.PRESENTATION_ID_UNKNOWN + && !containsAudioPresentation(mAudioPresentations, presentationId)) { + Log.w(TAG, "Invalid audio presentation id: " + presentationId); + return; + } + } + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.selectAudioPresentation(mToken, presentationId, programId, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + private boolean containsAudioPresentation(List<AudioPresentation> audioPresentations, + int presentationId) { + synchronized (mMetadataLock) { + for (AudioPresentation audioPresentation : audioPresentations) { + if (audioPresentation.getPresentationId() == presentationId) { + return true; + } + } + return false; + } + } + + /** + * Returns a list of audio presentations. + * + * @return the list of audio presentations. + * Returns empty AudioPresentation list if no presentations are available. + */ + public List<AudioPresentation> getAudioPresentations() { + synchronized (mMetadataLock) { + if (mAudioPresentations == null) { + return new ArrayList<AudioPresentation>(); + } + return new ArrayList<AudioPresentation>(mAudioPresentations); + } + } + + /** + * Returns the program ID of the selected audio presentation. + * + * @return The ID of the program providing the selected audio presentation. + * Returns {@value AudioPresentation.PROGRAM_ID_UNKNOWN} if no audio presentation has + * been selected from a program. + * @see #selectAudioPresentation + */ + public int getSelectedProgramId() { + synchronized (mMetadataLock) { + return mSelectedAudioProgramId; + } + } + + /** + * Returns the presentation ID of the selected audio presentation. + * + * @return The ID of the selected audio presentation. + * Returns {@value AudioPresentation.PRESENTATION_ID_UNKNOWN} if no audio presentation + * has been selected. + * @see #selectAudioPresentation + */ + public int getSelectedAudioPresentationId() { + synchronized (mMetadataLock) { + return mSelectedAudioPresentationId; + } + } + + /** + * Responds to onAudioPresentationsChanged() and updates the internal audio presentation + * information. + * @return true if there is an update. + */ + boolean updateAudioPresentations(List<AudioPresentation> audioPresentations) { + synchronized (mMetadataLock) { + mAudioPresentations.clear(); + for (AudioPresentation presentation : audioPresentations) { + mAudioPresentations.add(presentation); + } + return !mAudioPresentations.isEmpty(); + } + } + + /** + * Responds to onAudioPresentationSelected() and updates the internal audio presentation + * selection information. + * @return true if there is an update. + */ + boolean updateAudioPresentationSelection(int presentationId, int programId) { + synchronized (mMetadataLock) { + if ((programId != mSelectedAudioProgramId) + || (presentationId != mSelectedAudioPresentationId)) { + mSelectedAudioPresentationId = presentationId; + mSelectedAudioProgramId = programId; + return true; + } + } + return false; + } + + /** * Selects a track. * * @param type The type of the track to select. The type can be diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 15f511b960e5..b76975730b59 100755..100644 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -26,11 +26,13 @@ import android.annotation.SystemApi; import android.app.ActivityManager; import android.app.Service; import android.compat.annotation.UnsupportedAppUsage; +import android.content.AttributionSource; import android.content.Context; import android.content.Intent; import android.graphics.PixelFormat; import android.graphics.Rect; import android.hardware.hdmi.HdmiDeviceInfo; +import android.media.AudioPresentation; import android.media.PlaybackParams; import android.net.Uri; import android.os.AsyncTask; @@ -57,10 +59,8 @@ import android.view.ViewRootImpl; import android.view.WindowManager; import android.view.accessibility.CaptioningManager; import android.widget.FrameLayout; - import com.android.internal.os.SomeArgs; import com.android.internal.util.Preconditions; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -171,7 +171,7 @@ public abstract class TvInputService extends Service { @Override public void createSession(InputChannel channel, ITvInputSessionCallback cb, - String inputId, String sessionId) { + String inputId, String sessionId, AttributionSource tvAppAttributionSource) { if (channel == null) { Log.w(TAG, "Creating session without input channel"); } @@ -183,6 +183,7 @@ public abstract class TvInputService extends Service { args.arg2 = cb; args.arg3 = inputId; args.arg4 = sessionId; + args.arg5 = tvAppAttributionSource; mServiceHandler.obtainMessage(ServiceHandler.DO_CREATE_SESSION, args).sendToTarget(); } @@ -370,6 +371,24 @@ public abstract class TvInputService extends Service { } /** + * Returns a concrete implementation of {@link Session}. + * + * <p>For any apps that needs sessionId to request tuner resources from TunerResourceManager and + * needs to specify custom AttributionSource to AudioTrack, it needs to override this method to + * get the sessionId and AttrubutionSource passed. When no overriding, this method calls {@link + * #onCreateSession(String, String)} defaultly. + * + * @param inputId The ID of the TV input associated with the session. + * @param sessionId the unique sessionId created by TIF when session is created. + * @param tvAppAttributionSource The Attribution Source of the TV App. + */ + @Nullable + public Session onCreateSession(@NonNull String inputId, @NonNull String sessionId, + @NonNull AttributionSource tvAppAttributionSource) { + return onCreateSession(inputId, sessionId); + } + + /** * Returns a concrete implementation of {@link RecordingSession}. * * <p>For any apps that needs sessionId to request tuner resources from TunerResourceManager, @@ -739,6 +758,74 @@ public abstract class TvInputService extends Service { } /** + * Sends an updated list of all audio presentations available from a Next Generation Audio + * service. This is used by the framework to maintain the audio presentation information for + * a given track of {@link TvTrackInfo#TYPE_AUDIO}, which in turn is used by + * {@link TvView#getAudioPresentations} for the application to retrieve metadata for the + * current audio track. The TV input service must call this method as soon as the audio + * track presentation information becomes available or is updated. Note that in a case + * where a part of the information for the current track is updated, it is not necessary + * to create a new {@link TvTrackInfo} object with a different track ID. + * + * @param audioPresentations A list of audio presentation information pertaining to the + * selected track. + */ + public void notifyAudioPresentationChanged(@NonNull final List<AudioPresentation> + audioPresentations) { + final List<AudioPresentation> ap = new ArrayList<>(audioPresentations); + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "notifyAudioPresentationsChanged"); + } + if (mSessionCallback != null) { + mSessionCallback.onAudioPresentationsChanged(ap); + } + } catch (RemoteException e) { + Log.e(TAG, "error in notifyAudioPresentationsChanged", e); + } + } + }); + } + + /** + * Sends the presentation and program IDs of the selected audio presentation. This is used + * to inform the application that a specific audio presentation is selected. The TV input + * service must call this method as soon as an audio presentation is selected either by + * default or in response to a call to {@link #onSelectTrack}. The selected audio + * presentation ID for a currently selected audio track is maintained in the framework until + * the next call to this method even after the entire audio presentation list for the track + * is updated (but is reset when the session is tuned to a new channel), so care must be + * taken not to result in an obsolete track audio presentation ID. + * + * @param presentationId The ID of the selected audio presentation for the current track. + * @param programId The ID of the program providing the selected audio presentation. + * @see #onSelectAudioPresentation + */ + public void notifyAudioPresentationSelected(final int presentationId, final int programId) { + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "notifyAudioPresentationSelected"); + } + if (mSessionCallback != null) { + mSessionCallback.onAudioPresentationSelected(presentationId, programId); + } + } catch (RemoteException e) { + Log.e(TAG, "error in notifyAudioPresentationSelected", e); + } + } + }); + } + + + /** * Informs the application that the user is allowed to watch the current program content. * * <p>Each TV input service is required to query the system whether the user is allowed to @@ -1128,7 +1215,7 @@ public abstract class TvInputService extends Service { public abstract void onSetStreamVolume(@FloatRange(from = 0.0, to = 1.0) float volume); /** - * called when broadcast info is requested. + * Called when broadcast info is requested. * * @param request broadcast info request */ @@ -1136,7 +1223,7 @@ public abstract class TvInputService extends Service { } /** - * called when broadcast info is removed. + * Called when broadcast info is removed. */ public void onRemoveBroadcastInfo(int requestId) { } @@ -1246,6 +1333,23 @@ public abstract class TvInputService extends Service { } /** + * Selects an audio presentation. + * + * <p>On successfully selecting the audio presentation, + * {@link #notifyAudioPresentationSelected} is invoked to provide updated information about + * the selected audio presentation to applications. + * + * @param presentationId The ID of the audio presentation to select. + * @param programId The ID of the program providing the selected audio presentation. + * @return {@code true} if the audio presentation selection was successful, + * {@code false} otherwise. + * @see #notifyAudioPresentationSelected + */ + public boolean onSelectAudioPresentation(int presentationId, int programId) { + return false; + } + + /** * Processes a private command sent from the application to the TV input. This can be used * to provide domain-specific features that are only known between certain TV inputs and * their clients. @@ -1579,6 +1683,13 @@ public abstract class TvInputService extends Service { } /** + * Calls {@link #onSelectAudioPresentation}. + */ + void selectAudioPresentation(int presentationId, int programId) { + onSelectAudioPresentation(presentationId, programId); + } + + /** * Calls {@link #onSelectTrack}. */ void selectTrack(int type, String trackId) { @@ -2497,8 +2608,10 @@ public abstract class TvInputService extends Service { ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg2; String inputId = (String) args.arg3; String sessionId = (String) args.arg4; + AttributionSource tvAppAttributionSource = (AttributionSource) args.arg5; args.recycle(); - Session sessionImpl = onCreateSession(inputId, sessionId); + Session sessionImpl = + onCreateSession(inputId, sessionId, tvAppAttributionSource); if (sessionImpl == null) { try { // Failed to create a session. @@ -2534,7 +2647,7 @@ public abstract class TvInputService extends Service { proxySession.mServiceHandler = mServiceHandler; TvInputManager manager = (TvInputManager) getSystemService( Context.TV_INPUT_SERVICE); - manager.createSession(hardwareInputId, + manager.createSession(hardwareInputId, tvAppAttributionSource, proxySession.mHardwareSessionCallback, mServiceHandler); } else { SomeArgs someArgs = SomeArgs.obtain(); diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java index 2fdbc3b29a65..c7a63ac8209a 100644 --- a/media/java/android/media/tv/TvView.java +++ b/media/java/android/media/tv/TvView.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; +import android.content.AttributionSource; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; @@ -30,6 +31,7 @@ import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; +import android.media.AudioPresentation; import android.media.PlaybackParams; import android.media.tv.TvInputManager.Session; import android.media.tv.TvInputManager.Session.FinishedInputEventCallback; @@ -51,9 +53,9 @@ import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.view.ViewRootImpl; - import java.lang.ref.WeakReference; import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.List; import java.util.Queue; @@ -111,6 +113,7 @@ public class TvView extends ViewGroup { private int mSurfaceViewTop; private int mSurfaceViewBottom; private TimeShiftPositionCallback mTimeShiftPositionCallback; + private AttributionSource mTvAppAttributionSource; private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() { @Override @@ -185,6 +188,7 @@ public class TvView extends ViewGroup { mDefStyleAttr = defStyleAttr; resetSurfaceView(); mTvInputManager = (TvInputManager) getContext().getSystemService(Context.TV_INPUT_SERVICE); + mTvAppAttributionSource = getContext().getAttributionSource(); } /** @@ -304,6 +308,22 @@ public class TvView extends ViewGroup { } /** + * Override default attribution source of TV App. + * + * <p>An attribution source of TV App is used to attribute work to TV Input Service. + * The default attribution source is created by {@link Context#getAttributionSource()}. + * Call this method before calling {@link #tune(String, Uri, Bundle)} or {@link + * #timeShiftPlay(String, Uri)} to override the default attribution source. + * + * @param tvAppAttributionSource The attribution source of the TV App. + */ + public void overrideTvAppAttributionSource(@NonNull AttributionSource tvAppAttributionSource) { + if (tvAppAttributionSource != null) { + mTvAppAttributionSource = tvAppAttributionSource; + } + } + + /** * Tunes to a given channel. * * @param inputId The ID of the TV input for the given channel. @@ -355,7 +375,8 @@ public class TvView extends ViewGroup { // is obsolete and should ignore it. mSessionCallback = new MySessionCallback(inputId, channelUri, params); if (mTvInputManager != null) { - mTvInputManager.createSession(inputId, mSessionCallback, mHandler); + mTvInputManager.createSession( + inputId, mTvAppAttributionSource, mSessionCallback, mHandler); } } } @@ -434,6 +455,35 @@ public class TvView extends ViewGroup { } /** + * Selects an audio presentation. + * + * @param presentationId The ID of the audio presentation to select. + * @param programId The ID of the program providing the selected audio presentation. + * @see #getAudioPresentations + */ + public void selectAudioPresentation(int presentationId, int programId) { + if (mSession != null) { + mSession.selectAudioPresentation(presentationId, programId); + } + } + + /** + * Returns the list of audio presentations from the selected track of type + * {@link TvTrackInfo#TYPE_AUDIO}. + * + * @return the list of audio presentations from the selected audio track, or an empty list if no + * audio presentations are available. + * @see #selectAudioPresentation + */ + @NonNull + public List<AudioPresentation> getAudioPresentations() { + if (mSession == null) { + return new ArrayList<AudioPresentation>(); + } + return mSession.getAudioPresentations(); + } + + /** * Selects a track. * * @param type The type of the track to select. The type can be {@link TvTrackInfo#TYPE_AUDIO}, @@ -526,7 +576,8 @@ public class TvView extends ViewGroup { resetInternal(); mSessionCallback = new MySessionCallback(inputId, recordedProgramUri); if (mTvInputManager != null) { - mTvInputManager.createSession(inputId, mSessionCallback, mHandler); + mTvInputManager.createSession( + inputId, mTvAppAttributionSource, mSessionCallback, mHandler); } } } @@ -977,6 +1028,27 @@ public class TvView extends ViewGroup { } /** + * This is called when the audio presentation information has been changed. + * + * @param inputId The ID of the TV input bound to this view. + * @param audioPresentations A list of updated audio presentation information. + */ + public void onAudioPresentationsChanged(@NonNull String inputId, + @NonNull List<AudioPresentation> audioPresentations) { + } + + /** + * This is called when audio presentation selection has changed. + * + * @param inputId The ID of the TV input bound to this view. + * @param presentationId The ID of the audio presentation selected. + * @param programId The ID of the program providing the selected audio presentation. + */ + public void onAudioPresentationSelected(@NonNull String inputId, int presentationId, + int programId) { + } + + /** * This is called when the track information has been changed. * * @param inputId The ID of the TV input bound to this view. @@ -1242,6 +1314,37 @@ public class TvView extends ViewGroup { } @Override + public void onAudioPresentationsChanged(Session session, + List<AudioPresentation> audioPresentations) { + if (DEBUG) { + Log.d(TAG, "onAudioPresentationsChanged(" + audioPresentations + ")"); + } + if (this != mSessionCallback) { + Log.w(TAG, "onAudioPresentationsChanged - session not created"); + return; + } + if (mCallback != null) { + mCallback.onAudioPresentationsChanged(mInputId, audioPresentations); + } + } + + @Override + public void onAudioPresentationSelected(Session session, int presentationId, + int programId) { + if (DEBUG) { + Log.d(TAG, "onAudioPresentationSelected(presentationId=" + presentationId + + ", programId=" + programId + ")"); + } + if (this != mSessionCallback) { + Log.w(TAG, "onAudioPresentationSelected - session not created"); + return; + } + if (mCallback != null) { + mCallback.onAudioPresentationSelected(mInputId, presentationId, programId); + } + } + + @Override public void onTracksChanged(Session session, List<TvTrackInfo> tracks) { if (DEBUG) { Log.d(TAG, "onTracksChanged(" + tracks + ")"); diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java index ac920d270358..7d08b81fd156 100644 --- a/media/java/android/media/tv/tuner/Tuner.java +++ b/media/java/android/media/tv/tuner/Tuner.java @@ -1297,6 +1297,13 @@ public class Tuner implements AutoCloseable { return RESULT_UNAVAILABLE; } } + if (mFrontendType == FrontendSettings.TYPE_IPTV) { + if (!TunerVersionChecker.checkHigherOrEqualVersionTo( + TunerVersionChecker.TUNER_VERSION_3_0, + "Tuner with IPTV Frontend")) { + return RESULT_UNAVAILABLE; + } + } if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, mFrontendLock)) { mScanCallback = scanCallback; diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 35ee3ee969e6..625e842a2db9 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -132,6 +132,11 @@ #include <aidl/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.h> #include <aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.h> #include <aidl/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.h> +#include <aidl/android/hardware/tv/tuner/FrontendIptvSettings.h> +#include <aidl/android/hardware/tv/tuner/FrontendIptvSettingsFec.h> +#include <aidl/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.h> +#include <aidl/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.h> +#include <aidl/android/hardware/tv/tuner/FrontendIptvSettingsFecType.h> #include <aidl/android/hardware/tv/tuner/FrontendModulation.h> #include <aidl/android/hardware/tv/tuner/FrontendModulationStatus.h> #include <aidl/android/hardware/tv/tuner/FrontendRollOff.h> @@ -283,6 +288,11 @@ using ::aidl::android::hardware::tv::tuner::FrontendIsdbtModulation; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtPartialReceptionFlag; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtSettings; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtTimeInterleaveMode; +using ::aidl::android::hardware::tv::tuner::FrontendIptvSettings; +using ::aidl::android::hardware::tv::tuner::FrontendIptvSettingsFec; +using ::aidl::android::hardware::tv::tuner::FrontendIptvSettingsProtocol; +using ::aidl::android::hardware::tv::tuner::FrontendIptvSettingsIgmp; +using ::aidl::android::hardware::tv::tuner::FrontendIptvSettingsFecType; using ::aidl::android::hardware::tv::tuner::FrontendModulation; using ::aidl::android::hardware::tv::tuner::FrontendModulationStatus; using ::aidl::android::hardware::tv::tuner::FrontendRollOff; @@ -3430,6 +3440,106 @@ static FrontendSettings getDtmbFrontendSettings(JNIEnv *env, const jobject &sett return frontendSettings; } +static DemuxIpAddress getDemuxIpAddress(JNIEnv *env, const jobject& config, const char* className) { + jclass clazz = env->FindClass(className); + + jbyteArray jsrcIpAddress = static_cast<jbyteArray>( + env->GetObjectField(config, env->GetFieldID(clazz, "mSrcIpAddress", "[B"))); + jsize srcSize = env->GetArrayLength(jsrcIpAddress); + jbyteArray jdstIpAddress = static_cast<jbyteArray>( + env->GetObjectField(config, env->GetFieldID(clazz, "mDstIpAddress", "[B"))); + jsize dstSize = env->GetArrayLength(jdstIpAddress); + + DemuxIpAddress res; + + if (srcSize != dstSize) { + // should never happen. Validated on Java size. + jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", + "IP address lengths don't match. srcLength=%d, dstLength=%d", srcSize, dstSize); + return res; + } + + if (srcSize == IP_V4_LENGTH) { + vector<uint8_t> srcAddr; + vector<uint8_t> dstAddr; + srcAddr.resize(IP_V4_LENGTH); + dstAddr.resize(IP_V4_LENGTH); + env->GetByteArrayRegion(jsrcIpAddress, 0, srcSize, reinterpret_cast<jbyte *>(&srcAddr[0])); + env->GetByteArrayRegion(jdstIpAddress, 0, dstSize, reinterpret_cast<jbyte *>(&dstAddr[0])); + res.srcIpAddress.set<DemuxIpAddressIpAddress::Tag::v4>(srcAddr); + res.dstIpAddress.set<DemuxIpAddressIpAddress::Tag::v4>(dstAddr); + } else if (srcSize == IP_V6_LENGTH) { + vector<uint8_t> srcAddr; + vector<uint8_t> dstAddr; + srcAddr.resize(IP_V6_LENGTH); + dstAddr.resize(IP_V6_LENGTH); + env->GetByteArrayRegion(jsrcIpAddress, 0, srcSize, reinterpret_cast<jbyte *>(&srcAddr[0])); + env->GetByteArrayRegion(jdstIpAddress, 0, dstSize, reinterpret_cast<jbyte *>(&dstAddr[0])); + res.srcIpAddress.set<DemuxIpAddressIpAddress::Tag::v6>(srcAddr); + res.dstIpAddress.set<DemuxIpAddressIpAddress::Tag::v6>(dstAddr); + } else { + // should never happen. Validated on Java size. + jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", + "Invalid IP address length %d", srcSize); + return res; + } + + res.srcPort = env->GetIntField(config, env->GetFieldID(clazz, "mSrcPort", "I")); + res.dstPort = env->GetIntField(config, env->GetFieldID(clazz, "mDstPort", "I")); + + return res; +} + +static FrontendIptvSettingsFec getIptvFrontendSettingsFec(JNIEnv *env, const jobject &settings) { + jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IptvFrontendSettings"); + jobject fec = env->GetObjectField(settings, env->GetFieldID(clazz, "mFec", + "[Landroid/media/tv/tuner/frontend/IptvFrontendSettingsFec;")); + jclass fecClazz = env->FindClass("android/media/tv/tuner/frontend/IptvFrontendSettingsFec"); + FrontendIptvSettingsFecType fecType = + static_cast<FrontendIptvSettingsFecType>( + env->GetIntField(fec, env->GetFieldID(fecClazz, "mFec", "I"))); + int32_t fecColNum = env->GetIntField(fec, env->GetFieldID(fecClazz, "mFecColNum", "I")); + int32_t fecRowNum = env->GetIntField(fec, env->GetFieldID(fecClazz, "mFecRowNum", "I")); + + FrontendIptvSettingsFec frontendIptvSettingsFec { + .type = fecType, + .fecColNum = fecColNum, + .fecRowNum = fecRowNum, + }; + + return frontendIptvSettingsFec; +} + +static FrontendSettings getIptvFrontendSettings(JNIEnv *env, const jobject &settings) { + FrontendSettings frontendSettings; + const char *clazzName = "android/media/tv/tuner/frontend/IptvFrontendSettings"; + jclass clazz = env->FindClass(clazzName); + FrontendIptvSettingsProtocol protocol = + static_cast<FrontendIptvSettingsProtocol>( + env->GetIntField(settings, env->GetFieldID(clazz, "mProtocol", "I"))); + FrontendIptvSettingsIgmp igmp = + static_cast<FrontendIptvSettingsIgmp>( + env->GetIntField(settings, env->GetFieldID(clazz, "mIgmp", "I"))); + FrontendIptvSettingsFec fec = getIptvFrontendSettingsFec(env, settings); + int64_t bitrate = env->GetIntField(settings, env->GetFieldID(clazz, "mBitrate", "J")); + jstring contentUrlJString = (jstring) env->GetObjectField(settings, env->GetFieldID( + clazz, "mContentUrl", + "[Landroid/media/tv/tuner/frontend/IptvFrontendSettings;")); + const char *contentUrl = env->GetStringUTFChars(contentUrlJString, 0); + DemuxIpAddress ipAddr = getDemuxIpAddress(env, settings, clazzName); + + FrontendIptvSettings frontendIptvSettings{ + .protocol = protocol, + .fec = fec, + .igmp = igmp, + .bitrate = bitrate, + .ipAddr = ipAddr, + .contentUrl = contentUrl, + }; + frontendSettings.set<FrontendSettings::Tag::iptv>(frontendIptvSettings); + return frontendSettings; +} + static FrontendSettings getFrontendSettings(JNIEnv *env, int type, jobject settings) { ALOGV("getFrontendSettings %d", type); FrontendType feType = static_cast<FrontendType>(type); @@ -3454,6 +3564,8 @@ static FrontendSettings getFrontendSettings(JNIEnv *env, int type, jobject setti return getIsdbtFrontendSettings(env, settings); case FrontendType::DTMB: return getDtmbFrontendSettings(env, settings); + case FrontendType::IPTV: + return getIptvFrontendSettings(env, settings); default: // should never happen because a type is associated with a subclass of // FrontendSettings and not set by users @@ -3943,56 +4055,6 @@ static DemuxFilterDownloadSettings getFilterDownloadSettings(JNIEnv *env, const return filterDownloadSettings; } -static DemuxIpAddress getDemuxIpAddress(JNIEnv *env, const jobject& config) { - jclass clazz = env->FindClass("android/media/tv/tuner/filter/IpFilterConfiguration"); - - jbyteArray jsrcIpAddress = static_cast<jbyteArray>( - env->GetObjectField(config, env->GetFieldID(clazz, "mSrcIpAddress", "[B"))); - jsize srcSize = env->GetArrayLength(jsrcIpAddress); - jbyteArray jdstIpAddress = static_cast<jbyteArray>( - env->GetObjectField(config, env->GetFieldID(clazz, "mDstIpAddress", "[B"))); - jsize dstSize = env->GetArrayLength(jdstIpAddress); - - DemuxIpAddress res; - - if (srcSize != dstSize) { - // should never happen. Validated on Java size. - jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", - "IP address lengths don't match. srcLength=%d, dstLength=%d", srcSize, dstSize); - return res; - } - - if (srcSize == IP_V4_LENGTH) { - vector<uint8_t> srcAddr; - vector<uint8_t> dstAddr; - srcAddr.resize(IP_V4_LENGTH); - dstAddr.resize(IP_V4_LENGTH); - env->GetByteArrayRegion(jsrcIpAddress, 0, srcSize, reinterpret_cast<jbyte *>(&srcAddr[0])); - env->GetByteArrayRegion(jdstIpAddress, 0, dstSize, reinterpret_cast<jbyte *>(&dstAddr[0])); - res.srcIpAddress.set<DemuxIpAddressIpAddress::Tag::v4>(srcAddr); - res.dstIpAddress.set<DemuxIpAddressIpAddress::Tag::v4>(dstAddr); - } else if (srcSize == IP_V6_LENGTH) { - vector<uint8_t> srcAddr; - vector<uint8_t> dstAddr; - srcAddr.resize(IP_V6_LENGTH); - dstAddr.resize(IP_V6_LENGTH); - env->GetByteArrayRegion(jsrcIpAddress, 0, srcSize, reinterpret_cast<jbyte *>(&srcAddr[0])); - env->GetByteArrayRegion(jdstIpAddress, 0, dstSize, reinterpret_cast<jbyte *>(&dstAddr[0])); - res.srcIpAddress.set<DemuxIpAddressIpAddress::Tag::v6>(srcAddr); - res.dstIpAddress.set<DemuxIpAddressIpAddress::Tag::v6>(dstAddr); - } else { - // should never happen. Validated on Java size. - jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", - "Invalid IP address length %d", srcSize); - return res; - } - - res.srcPort = env->GetIntField(config, env->GetFieldID(clazz, "mSrcPort", "I")); - res.dstPort = env->GetIntField(config, env->GetFieldID(clazz, "mDstPort", "I")); - - return res; -} - static DemuxFilterSettings getFilterConfiguration( JNIEnv *env, int type, int subtype, jobject filterConfigObj) { DemuxFilterSettings filterSettings; @@ -4088,7 +4150,8 @@ static DemuxFilterSettings getFilterConfiguration( break; } case DemuxFilterMainType::IP: { - DemuxIpAddress ipAddr = getDemuxIpAddress(env, filterConfigObj); + DemuxIpAddress ipAddr = getDemuxIpAddress(env, filterConfigObj, + "android/media/tv/tuner/filter/IpFilterConfiguration"); DemuxIpFilterSettings ipFilterSettings { .ipAddr = ipAddr, }; diff --git a/packages/CarrierDefaultApp/res/values-ar/strings.xml b/packages/CarrierDefaultApp/res/values-ar/strings.xml index 55a7c0fd33a7..c2e5ba80db46 100644 --- a/packages/CarrierDefaultApp/res/values-ar/strings.xml +++ b/packages/CarrierDefaultApp/res/values-ar/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"على سبيل المثال، قد لا تنتمي صفحة تسجيل الدخول إلى المؤسسة المعروضة."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"المتابعة على أي حال عبر المتصفح"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"تطبيق تعزيز الأداء"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"تحسين تجربة شبكة الجيل الخامس"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"هناك اقتراح من \"%1$s\" لشراء خطة لتعزيز الأداء. انقر للشراء من خلال \"%2$s\"."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"لاحقًا"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"إدارة"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"شراء تطبيق تعزيز الأداء"</string> diff --git a/packages/CarrierDefaultApp/res/values-as/strings.xml b/packages/CarrierDefaultApp/res/values-as/strings.xml index 755d28d25190..8881940ff71a 100644 --- a/packages/CarrierDefaultApp/res/values-as/strings.xml +++ b/packages/CarrierDefaultApp/res/values-as/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"উদাহৰণস্বৰূপে, আপোনাক দেখুওৱা লগ ইনৰ পৃষ্ঠাটো প্ৰতিষ্ঠানটোৰ নিজা নহ\'বও পাৰে।"</string> <string name="ssl_error_continue" msgid="1138548463994095584">"তথাপিও ব্ৰাউজাৰৰ জৰিয়তে অব্যাহত ৰাখক"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"কাৰ্যক্ষমতা পৰিৱৰ্ধন"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"আপোনাৰ 5G অভিজ্ঞতা উন্নত কৰক"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$sএ এখন কাৰ্যক্ষমতা পৰিৱৰ্ধন অঁচনি ক্ৰয় কৰাৰ চুপাৰিছ কৰে। %2$sৰ জৰিয়তে ক্ৰয় কৰিবলৈ টিপক।"</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"এতিয়া নহয়"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"পৰিচালনা কৰক"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"এটা কাৰ্যক্ষমতা পৰিৱৰ্ধন ক্ৰয় কৰক।"</string> diff --git a/packages/CarrierDefaultApp/res/values-bg/strings.xml b/packages/CarrierDefaultApp/res/values-bg/strings.xml index f055acc8c0b4..a37e0a36454e 100644 --- a/packages/CarrierDefaultApp/res/values-bg/strings.xml +++ b/packages/CarrierDefaultApp/res/values-bg/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Например страницата за вход може да не принадлежи на показаната организация."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Продължаване през браузър въпреки това"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Увеличаване на ефективността"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Подобряване на практическата работа с 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s препоръчва да купите план за увеличаване на ефективността. Докоснете, за да купите чрез %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не сега"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Управление"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Купете пакет за увеличаване на ефективността."</string> diff --git a/packages/CarrierDefaultApp/res/values-bn/strings.xml b/packages/CarrierDefaultApp/res/values-bn/strings.xml index 5eb9e1630740..f78449c8aa98 100644 --- a/packages/CarrierDefaultApp/res/values-bn/strings.xml +++ b/packages/CarrierDefaultApp/res/values-bn/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"যেমন, লগ-ইন পৃষ্ঠাটি যে প্রতিষ্ঠানের পৃষ্ঠা বলে দেখানো আছে, আসলে তা নাও হতে পারে৷"</string> <string name="ssl_error_continue" msgid="1138548463994095584">"যাই হোক, ব্রাউজারের মাধ্যমে চালিয়ে যান"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"পারফর্ম্যান্স বুস্ট"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"আপনার 5G অভিজ্ঞতা উন্নত করুন"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s পারফর্ম্যান্স বুস্ট প্ল্যান কেনার সাজেশন দেয়। %2$s-এর মাধ্যমে কিনতে ট্যাপ করুন।"</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"এখন নয়"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ম্যানেজ করুন"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"পারফর্ম্যান্স বুস্ট সংক্রান্ত ফিচার কিনুন।"</string> diff --git a/packages/CarrierDefaultApp/res/values-ca/strings.xml b/packages/CarrierDefaultApp/res/values-ca/strings.xml index 40181ef2fa11..54c9e6ed43f1 100644 --- a/packages/CarrierDefaultApp/res/values-ca/strings.xml +++ b/packages/CarrierDefaultApp/res/values-ca/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Per exemple, la pàgina d\'inici de sessió podria no pertànyer a l\'organització que es mostra."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Continua igualment mitjançant el navegador"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Optimització de rendiment"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Millora l\'experiència 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s recomana comprar un pla d\'optimització de rendiment. Toca per comprar-lo mitjançant %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ara no"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gestiona"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Compra una optimització de rendiment."</string> diff --git a/packages/CarrierDefaultApp/res/values-da/strings.xml b/packages/CarrierDefaultApp/res/values-da/strings.xml index b1d6b089e4fd..cd411c917fb6 100644 --- a/packages/CarrierDefaultApp/res/values-da/strings.xml +++ b/packages/CarrierDefaultApp/res/values-da/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Det er f.eks. ikke sikkert, at loginsiden tilhører den anførte organisation."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Fortsæt alligevel via browseren"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Ydeevneboost"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Få en bedre 5G-oplevelse"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s anbefaler, at du køber et abonnement med ydeevneboost. Tryk for at købe via %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ikke nu"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Administrer"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Køb et ydeevneboost."</string> diff --git a/packages/CarrierDefaultApp/res/values-de/strings.xml b/packages/CarrierDefaultApp/res/values-de/strings.xml index 21242534fabc..d20a1e88fcda 100644 --- a/packages/CarrierDefaultApp/res/values-de/strings.xml +++ b/packages/CarrierDefaultApp/res/values-de/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Beispiel: Die Log-in-Seite gehört eventuell nicht zur angezeigten Organisation."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Trotzdem in einem Browser fortfahren"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Leistungs-Boost"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"5G-Nutzung verbessern"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s empfiehlt den Kauf eines Tarifs mit Leistungs-Boost. Du kannst tippen, um über %2$s einen zu kaufen."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Nicht jetzt"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Verwalten"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Leistungs-Boost erwerben."</string> diff --git a/packages/CarrierDefaultApp/res/values-el/strings.xml b/packages/CarrierDefaultApp/res/values-el/strings.xml index 58a8490a636a..0759011f5f39 100644 --- a/packages/CarrierDefaultApp/res/values-el/strings.xml +++ b/packages/CarrierDefaultApp/res/values-el/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Για παράδειγμα, η σελίδα σύνδεσης ενδέχεται να μην ανήκει στον οργανισμό που εμφανίζεται."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Συνέχεια ούτως ή άλλως μέσω του προγράμματος περιήγησης"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Ενίσχυση απόδοσης"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Βελτιώστε την εμπειρία 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"Το %1$s προτείνει την αγορά ενός προγράμματος ενίσχυσης απόδοσης. Πατήστε για αγορά μέσω %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Όχι τώρα"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Διαχείριση"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Αγοράστε μια ενίσχυση απόδοσης."</string> diff --git a/packages/CarrierDefaultApp/res/values-es/strings.xml b/packages/CarrierDefaultApp/res/values-es/strings.xml index 5a405a9d8293..85642b8d7934 100644 --- a/packages/CarrierDefaultApp/res/values-es/strings.xml +++ b/packages/CarrierDefaultApp/res/values-es/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Por ejemplo, es posible que la página de inicio de sesión no pertenezca a la organización mostrada."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Continuar de todos modos a través del navegador"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Mejora de rendimiento"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Mejora tu experiencia 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s recomienda comprar un plan de mejora del rendimiento. Toca para comprarlo mediante %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ahora no"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gestionar"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Comprar una mejora de rendimiento."</string> diff --git a/packages/CarrierDefaultApp/res/values-et/strings.xml b/packages/CarrierDefaultApp/res/values-et/strings.xml index 9435c293e7c0..769f24001c68 100644 --- a/packages/CarrierDefaultApp/res/values-et/strings.xml +++ b/packages/CarrierDefaultApp/res/values-et/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Näiteks ei pruugi sisselogimisleht kuuluda kuvatavale organisatsioonile."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Jätka siiski brauseris"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Jõudluse võimendus"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Täiustage oma 5G-kogemust"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s soovitab osta jõudluse võimendusega paketi. Puudutage teenuse %2$s kaudu ostmiseks."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Mitte praegu"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Haldamine"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Ostke jõudluse võimendus."</string> diff --git a/packages/CarrierDefaultApp/res/values-eu/strings.xml b/packages/CarrierDefaultApp/res/values-eu/strings.xml index e47e5fe60caa..7274bce1b492 100644 --- a/packages/CarrierDefaultApp/res/values-eu/strings.xml +++ b/packages/CarrierDefaultApp/res/values-eu/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Adibidez, baliteke saioa hasteko orria adierazitako erakundearena ez izatea."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Jarraitu arakatzailearen bidez, halere"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Errendimendu-hobekuntza"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Hobetu 5G bidezko konexioa"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s zerbitzuak errendimendua hobetzeko kidetza bat erostea gomendatzen du. Sakatu hau %2$s bidez erosteko."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Orain ez"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Kudeatu"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Erosi errendimendu-hobekuntza bat."</string> diff --git a/packages/CarrierDefaultApp/res/values-fa/strings.xml b/packages/CarrierDefaultApp/res/values-fa/strings.xml index 60f8dbbfbf21..2cbe29793ada 100644 --- a/packages/CarrierDefaultApp/res/values-fa/strings.xml +++ b/packages/CarrierDefaultApp/res/values-fa/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"به عنوان مثال، صفحه ورود به سیستم ممکن است متعلق به سازمان نشان داده شده نباشد."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"درهر صورت ازطریق مرورگر ادامه یابد"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"تقویتکننده عملکرد"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"تجربه نسل پنجم شبکه تلفن همراه را بهبود دهید"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s توصیه میکند طرح تقویت عملکرد خریداری شود. برای خرید ازطریق %2$s، ضربه بزنید."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"اکنون نه"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"مدیریت"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"تقویتکننده عملکرد خریداری کنید."</string> diff --git a/packages/CarrierDefaultApp/res/values-fi/strings.xml b/packages/CarrierDefaultApp/res/values-fi/strings.xml index d4c612b0b0cb..1a388cdc52ef 100644 --- a/packages/CarrierDefaultApp/res/values-fi/strings.xml +++ b/packages/CarrierDefaultApp/res/values-fi/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Kirjautumissivu ei välttämättä kuulu näytetylle organisaatiolle."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Jatka selaimen kautta"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Suorituskykyboosti"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Paranna 5G-kokemusta"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s suosittelee suorituskykyboostipaketin ostamista. Napauta ja tee ostos operaattorilla %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ei nyt"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Muuta"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Osta suorituskykyboosti."</string> diff --git a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml index 5ae71fd15650..ad6c794db5f4 100644 --- a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml +++ b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Par exemple, la page de connexion pourrait ne pas appartenir à l\'organisation représentée."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Continuer quand même dans un navigateur"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Optimiseur de performances"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Améliorer votre expérience de la 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s recommande d\'acheter un forfait d\'amélioration des performances. Touchez pour acheter par l\'intermédiaire de %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Plus tard"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gérer"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Achetez un optimiseur de performances."</string> diff --git a/packages/CarrierDefaultApp/res/values-fr/strings.xml b/packages/CarrierDefaultApp/res/values-fr/strings.xml index bd711cc1f2cf..92b47bed7065 100644 --- a/packages/CarrierDefaultApp/res/values-fr/strings.xml +++ b/packages/CarrierDefaultApp/res/values-fr/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Par exemple, la page de connexion peut ne pas appartenir à l\'organisation représentée."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Continuer quand même dans le navigateur"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Boost de performances"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Améliorer votre expérience 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s recommande d\'acheter un forfait d\'amélioration des performances. Appuyez pour acheter via %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Pas maintenant"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gérer"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Achetez un boost de performances."</string> diff --git a/packages/CarrierDefaultApp/res/values-gl/strings.xml b/packages/CarrierDefaultApp/res/values-gl/strings.xml index 36f48e00e7d9..2c1be52bdabd 100644 --- a/packages/CarrierDefaultApp/res/values-gl/strings.xml +++ b/packages/CarrierDefaultApp/res/values-gl/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, é posible que a páxina de inicio de sesión non pertenza á organización que se mostra."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Continuar igualmente co navegador"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Mellora de rendemento"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Mellora a túa experiencia 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s recomenda comprar un plan de mellora do rendemento. Toca para realizar a compra a través de %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Agora non"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Xestionar"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Comprar unha mellora de rendemento."</string> diff --git a/packages/CarrierDefaultApp/res/values-hu/strings.xml b/packages/CarrierDefaultApp/res/values-hu/strings.xml index bd75210fa6fa..a841cb24dc19 100644 --- a/packages/CarrierDefaultApp/res/values-hu/strings.xml +++ b/packages/CarrierDefaultApp/res/values-hu/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Például lehetséges, hogy a bejelentkezési oldal nem a megjelenített szervezethez tartozik."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Folytatás ennek ellenére böngészőn keresztül"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Teljesítménynövelés"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Az 5G-élmény javítása"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"A(z) %1$s teljesítménynövelő csomag vásárlását javasolja. Koppintson a(z) %2$s szolgáltatón keresztüli vásárláshoz."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Most nem"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Kezelés"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Vásároljon teljesítménynövelést."</string> diff --git a/packages/CarrierDefaultApp/res/values-in/strings.xml b/packages/CarrierDefaultApp/res/values-in/strings.xml index ef0478189caf..170bd76ca4e6 100644 --- a/packages/CarrierDefaultApp/res/values-in/strings.xml +++ b/packages/CarrierDefaultApp/res/values-in/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Misalnya, halaman login mungkin bukan milik organisasi yang ditampilkan."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Tetap lanjutkan melalui browser"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Penguat sinyal"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Tingkatkan pengalaman 5G Anda"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s merekomendasikan pembelian paket penguat sinyal. Ketuk untuk membeli melalui %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Lain kali"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Kelola"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Beli penguat sinyal."</string> diff --git a/packages/CarrierDefaultApp/res/values-is/strings.xml b/packages/CarrierDefaultApp/res/values-is/strings.xml index 2a3894146821..8684ee62d626 100644 --- a/packages/CarrierDefaultApp/res/values-is/strings.xml +++ b/packages/CarrierDefaultApp/res/values-is/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Til dæmis getur verið að innskráningarsíðan tilheyri ekki fyrirtækinu sem birtist."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Halda samt áfram í vafra"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Afkastaaukning"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Bættu upplifun þína af 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s mælir með að kaupa áskrift sem eykur afköst. Ýttu til að kaupa í gegnum %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ekki núna"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Stjórna"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Kaupa afkastaaukningu."</string> diff --git a/packages/CarrierDefaultApp/res/values-it/strings.xml b/packages/CarrierDefaultApp/res/values-it/strings.xml index a3f00175638e..ea884571303f 100644 --- a/packages/CarrierDefaultApp/res/values-it/strings.xml +++ b/packages/CarrierDefaultApp/res/values-it/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Ad esempio, la pagina di accesso potrebbe non appartenere all\'organizzazione indicata."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Continua comunque dal browser"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Aumento di prestazioni"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Migliora la tua esperienza 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s consiglia l\'acquisto di un piano di miglioramento delle prestazioni. Tocca per acquistare tramite %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Non ora"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gestisci"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Acquista un aumento di prestazioni."</string> diff --git a/packages/CarrierDefaultApp/res/values-kk/strings.xml b/packages/CarrierDefaultApp/res/values-kk/strings.xml index 2ce3285c1f60..4a895f47e461 100644 --- a/packages/CarrierDefaultApp/res/values-kk/strings.xml +++ b/packages/CarrierDefaultApp/res/values-kk/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Мысалы, кіру беті көрсетілген ұйымға тиесілі болмауы мүмкін."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Бәрібір браузер арқылы жалғастыру"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Өнімділікті арттыру"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"5G желісімен жұмысыңызды жақсартыңыз"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s өнімділікті арттыру жоспарын сатып алуды ұсынады. %2$s операторынан сатып алу үшін түртіңіз."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Қазір емес"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Басқару"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Өнімділікті арттыру құралын сатып алыңыз."</string> diff --git a/packages/CarrierDefaultApp/res/values-km/strings.xml b/packages/CarrierDefaultApp/res/values-km/strings.xml index 66085702eca9..51a51ff9698f 100644 --- a/packages/CarrierDefaultApp/res/values-km/strings.xml +++ b/packages/CarrierDefaultApp/res/values-km/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"ឧទាហរណ៍៖ ទំព័រចូលនេះអាចនឹងមិនមែនជាកម្មសិទ្ធិរបស់ស្ថាប័នដែលបានបង្ហាញនេះទេ។"</string> <string name="ssl_error_continue" msgid="1138548463994095584">"យ៉ាងណាក៏ដោយនៅតែបន្តតាមរយៈកម្មវិធីរុករកតាមអ៊ីនធឺណិត"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"ការបង្កើនប្រតិបត្តិការ"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"កែលម្អបទពិសោធន៍ប្រើ 5G របស់អ្នក"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s ណែនាំឱ្យទិញផែនការជំរុញប្រតិបត្តិការ។ ចុចដើម្បីទិញតាមរយៈ %2$s។"</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"កុំទាន់"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"គ្រប់គ្រង"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"ទិញការបង្កើនប្រតិបត្តិការ។"</string> diff --git a/packages/CarrierDefaultApp/res/values-lv/strings.xml b/packages/CarrierDefaultApp/res/values-lv/strings.xml index dcf800e6228e..1fefe92669b1 100644 --- a/packages/CarrierDefaultApp/res/values-lv/strings.xml +++ b/packages/CarrierDefaultApp/res/values-lv/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Piemēram, pieteikšanās lapa, iespējams, nepieder norādītajai organizācijai."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Tomēr turpināt, izmantojot pārlūkprogrammu"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Veiktspējas uzlabojums"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Uzlabojiet 5G iespējas"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s iesaka iegādāties veiktspējas uzlabošanas plānu. Pieskarieties, lai to iegādātos no %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Vēlāk"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Pārvaldīt"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Iegādājieties veiktspējas uzlabojumu."</string> diff --git a/packages/CarrierDefaultApp/res/values-mr/strings.xml b/packages/CarrierDefaultApp/res/values-mr/strings.xml index ee8cbf7ab793..a48c60518be1 100644 --- a/packages/CarrierDefaultApp/res/values-mr/strings.xml +++ b/packages/CarrierDefaultApp/res/values-mr/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"उदाहरणार्थ, लॉग इन पृष्ठ दर्शवलेल्या संस्थेच्या मालकीचे नसू शकते."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"तरीही ब्राउझरद्वारे सुरू ठेवा"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"परफॉर्मन्स बूस्ट"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"तुमच्या 5G अनुभवामध्ये सुधारणा करा"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s हे परफॉर्मन्स बूस्ट प्लॅन खरेदी करण्याची शिफारस करते. %2$s वरून खरेदी करण्यासाठी टॅप करा."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"आता नको"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"व्यवस्थापित करा"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"परफॉर्मन्स बूस्ट खरेदी करा."</string> diff --git a/packages/CarrierDefaultApp/res/values-nl/strings.xml b/packages/CarrierDefaultApp/res/values-nl/strings.xml index 8abf26be4b43..6a4642c618dd 100644 --- a/packages/CarrierDefaultApp/res/values-nl/strings.xml +++ b/packages/CarrierDefaultApp/res/values-nl/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Zo hoort de weergegeven inlogpagina misschien niet bij de weergegeven organisatie."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Toch doorgaan via browser"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Prestatieboost"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Verbeter je 5G-functionaliteit"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s beveelt je aan een prestatieboostabonnement te kopen. Tik om er een te kopen via %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Niet nu"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Beheren"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Koop een prestatieboost."</string> diff --git a/packages/CarrierDefaultApp/res/values-or/strings.xml b/packages/CarrierDefaultApp/res/values-or/strings.xml index 48ce1c7db4b8..f7349f9e68a7 100644 --- a/packages/CarrierDefaultApp/res/values-or/strings.xml +++ b/packages/CarrierDefaultApp/res/values-or/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"ଉଦାହରଣସ୍ୱରୂପ, ଲଗଇନ୍ ପୃଷ୍ଠା ଦେଖାଯାଇଥିବା ସଂସ୍ଥାର ହୋଇନଥାଇପାରେ।"</string> <string name="ssl_error_continue" msgid="1138548463994095584">"ବ୍ରାଉଜର୍ ଜରିଆରେ ଯେମିତିବି ହେଉ ଜାରି ରଖନ୍ତୁ"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"ପରଫରମାନ୍ସ ବୁଷ୍ଟ"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"ଆପଣଙ୍କ 5G ଅନୁଭୂତିକୁ ଉନ୍ନତ କରନ୍ତୁ"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s ଏକ ପରଫରମାନ୍ସ ବୁଷ୍ଟ ପ୍ଲାନ କିଣିବା ପାଇଁ ସୁପାରିଶ କରେ। %2$s ମାଧ୍ୟମରେ କିଣିବା ପାଇଁ ଟାପ କରନ୍ତୁ।"</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ବର୍ତ୍ତମାନ ନୁହେଁ"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ପରିଚାଳନା କରନ୍ତୁ"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"ଏକ ପରଫରମାନ୍ସ ବୁଷ୍ଟ କିଣନ୍ତୁ।"</string> diff --git a/packages/CarrierDefaultApp/res/values-pa/strings.xml b/packages/CarrierDefaultApp/res/values-pa/strings.xml index aca2a3898920..540a54cc267e 100644 --- a/packages/CarrierDefaultApp/res/values-pa/strings.xml +++ b/packages/CarrierDefaultApp/res/values-pa/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"ਉਦਾਹਰਣ ਵੱਜੋਂ, ਲੌਗ-ਇਨ ਪੰਨਾ ਦਿਖਾਈ ਗਈ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ।"</string> <string name="ssl_error_continue" msgid="1138548463994095584">"ਬ੍ਰਾਊਜ਼ਰ ਰਾਹੀਂ ਫਿਰ ਵੀ ਜਾਰੀ ਰੱਖੋ"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"ਕਾਰਗੁਜ਼ਾਰੀ ਬੂਸਟ"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"ਆਪਣਾ 5G ਅਨੁਭਵ ਬਿਹਤਰ ਬਣਾਓ"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s ਵੱਲੋਂ ਕਾਰਗੁਜ਼ਾਰੀ ਬੂਸਟ ਪਲਾਨ ਖਰੀਦਣ ਦੀ ਸਿਫ਼ਾਰਸ਼ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। %2$s ਰਾਹੀਂ ਖਰੀਦਣ ਲਈ ਟੈਪ ਕਰੋ।"</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ਹੁਣੇ ਨਹੀਂ"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"ਕਾਰਗੁਜ਼ਾਰੀ ਬੂਸਟ ਖਰੀਦੋ।"</string> diff --git a/packages/CarrierDefaultApp/res/values-pl/strings.xml b/packages/CarrierDefaultApp/res/values-pl/strings.xml index 7f4a089efcca..de957a934d5e 100644 --- a/packages/CarrierDefaultApp/res/values-pl/strings.xml +++ b/packages/CarrierDefaultApp/res/values-pl/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Na przykład strona logowania może nie należeć do wyświetlanej organizacji."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Kontynuuj mimo to w przeglądarce"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Zwiększenie wydajności"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Lepiej wykorzystaj potencjał 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"Operator %1$s zaleca zakup abonamentu o zwiększonej wydajności. Kliknij, aby kupić u operatora %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Nie teraz"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Zarządzaj"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Kup wzmocnienie wydajności"</string> diff --git a/packages/CarrierDefaultApp/res/values-si/strings.xml b/packages/CarrierDefaultApp/res/values-si/strings.xml index 943d80676449..166af5a86a7c 100644 --- a/packages/CarrierDefaultApp/res/values-si/strings.xml +++ b/packages/CarrierDefaultApp/res/values-si/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"උදාහරණයක් ලෙස, පුරනය වන පිටුව පෙන්වා ඇති සංවිධානයට අයිති නැති විය හැක."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"කෙසේ වුවත් බ්රවුසරය හරහා ඉදිරියට යන්න"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"කාර්ය සාධනය ඉහළ නැංවීම"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"ඔබේ 5G අත්දැකීම වැඩි දියුණු කරන්න"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s කාර්ය සාධනය වැඩි කිරීමේ සැලසුමක් මිල දී ගැනීම නිර්දේශ කරයි. %2$s හරහා මිල දී ගැනීමට තට්ටු කරන්න."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"දැන් නොවේ"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"කළමනාකරණය කරන්න"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"කාර්ය සාධනය ඉහළ නැංවීමක් මිල දී ගන්න."</string> diff --git a/packages/CarrierDefaultApp/res/values-sk/strings.xml b/packages/CarrierDefaultApp/res/values-sk/strings.xml index 950c78940ef2..a58bd06491c5 100644 --- a/packages/CarrierDefaultApp/res/values-sk/strings.xml +++ b/packages/CarrierDefaultApp/res/values-sk/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Napríklad prihlasovacia stránka nemusí patriť uvedenej organizácii."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Pokračovať pomocou prehliadača"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Zvýšenie výkonu"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Zlepšite svoje prostredie 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s odporúča zakúpiť tarifu na zvýšenie výkonnosti. Klepnutím kúpte cez %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Teraz nie"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Spravovať"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Kúpte si zvýšenie výkonu."</string> diff --git a/packages/CarrierDefaultApp/res/values-sq/strings.xml b/packages/CarrierDefaultApp/res/values-sq/strings.xml index 7029c867b016..618e33573486 100644 --- a/packages/CarrierDefaultApp/res/values-sq/strings.xml +++ b/packages/CarrierDefaultApp/res/values-sq/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"për shembull, faqja e identifikimit mund të mos i përkasë organizatës së shfaqur."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Vazhdo gjithsesi nëpërmjet shfletuesit"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Përforcimi i performancës"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Përmirëso përvojën tënde 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s rekomandon blerjen e një plani të përforcimit të performancës. Trokit për të blerë nëpërmjet %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Jo tani"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Menaxho"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Bli një paketë përforcimi të performancës."</string> diff --git a/packages/CarrierDefaultApp/res/values-sv/strings.xml b/packages/CarrierDefaultApp/res/values-sv/strings.xml index 1eac728f85d1..ac044ec517b9 100644 --- a/packages/CarrierDefaultApp/res/values-sv/strings.xml +++ b/packages/CarrierDefaultApp/res/values-sv/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Det kan t.ex. hända att inloggningssidan inte tillhör den organisation som visas."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Fortsätt ändå via webbläsaren"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Prestandahöjning"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Förbättra din 5G-upplevelse"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s rekommenderar att du köper en prenumeration som kan höja prestandan. Tryck för att köpa via %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Inte nu"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Hantera"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Köp en prestandahöjning."</string> diff --git a/packages/CarrierDefaultApp/res/values-sw/strings.xml b/packages/CarrierDefaultApp/res/values-sw/strings.xml index b6c5d9615a4b..1c72f30bbc45 100644 --- a/packages/CarrierDefaultApp/res/values-sw/strings.xml +++ b/packages/CarrierDefaultApp/res/values-sw/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Kwa mfano, ukurasa wa kuingia katika akaunti unaweza usiwe unamilikiwa na shirika lililoonyeshwa."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Endelea hata hivyo kupitia kivinjari"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Kuongeza utendaji"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Boresha hali yako ya utumiaji wa 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s anapendekeza ununue mpango wa kuongeza utendaji. Gusa ili ununue kupitia %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Si sasa"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Dhibiti"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Nunua programu ya kuongeza utendaji."</string> diff --git a/packages/CarrierDefaultApp/res/values-ta/strings.xml b/packages/CarrierDefaultApp/res/values-ta/strings.xml index 7c24542ea4d9..cfc46e869515 100644 --- a/packages/CarrierDefaultApp/res/values-ta/strings.xml +++ b/packages/CarrierDefaultApp/res/values-ta/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"எடுத்துக்காட்டாக, உள்நுழைவுப் பக்கமானது காட்டப்படும் அமைப்பிற்குச் சொந்தமானதாக இல்லாமல் இருக்கலாம்."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"பரவாயில்லை, உலாவி வழியாகத் தொடர்க"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"பெர்ஃபார்மென்ஸ் பூஸ்ட்"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"உங்கள் 5G அனுபவத்தை மேம்படுத்துங்கள்"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"செயல்திறன் மேம்பாட்டுத் திட்டத்தை வாங்க %1$s பரிந்துரைக்கிறது. %2$s மூலம் வாங்க தட்டவும்."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"இப்போது வேண்டாம்"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"நிர்வகியுங்கள்"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"ஒரு பெர்ஃபார்மென்ஸ் பூஸ்ட்டைப் பர்ச்சேஸ் செய்யுங்கள்."</string> diff --git a/packages/CarrierDefaultApp/res/values-tr/strings.xml b/packages/CarrierDefaultApp/res/values-tr/strings.xml index 8484fdd8b946..c8fb73b42da2 100644 --- a/packages/CarrierDefaultApp/res/values-tr/strings.xml +++ b/packages/CarrierDefaultApp/res/values-tr/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Örneğin, giriş sayfası, gösterilen kuruluşa ait olmayabilir."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Yine de tarayıcıyla devam et"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performans artışı"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"5G deneyiminizi iyileştirin"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s, performans artırma planı satın almanızı öneriyor. %2$s aracılığıyla satın almak için dokunun."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Şimdi değil"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Yönet"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Performans artışı satın alın."</string> diff --git a/packages/CarrierDefaultApp/res/values-uk/strings.xml b/packages/CarrierDefaultApp/res/values-uk/strings.xml index 5e553b4af2a2..9927ea05bb3f 100644 --- a/packages/CarrierDefaultApp/res/values-uk/strings.xml +++ b/packages/CarrierDefaultApp/res/values-uk/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"Наприклад, сторінка входу може не належати вказаній організації."</string> <string name="ssl_error_continue" msgid="1138548463994095584">"Усе одно продовжити у веб-переглядачі"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Підвищення продуктивності"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"Покращте продуктивність свого з’єднання 5G"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s рекомендує придбати тарифний план для підвищення продуктивності. Натисніть, щоб придбати через оператора %2$s."</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не зараз"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Керувати"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"Придбайте підвищення продуктивності."</string> diff --git a/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml index 48cc440280db..563117f83aab 100644 --- a/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml +++ b/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml @@ -15,10 +15,8 @@ <string name="ssl_error_example" msgid="6188711843183058764">"例如,登录页面可能并不属于页面上显示的单位。"</string> <string name="ssl_error_continue" msgid="1138548463994095584">"仍然通过浏览器继续操作"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"性能提升方案"</string> - <!-- no translation found for performance_boost_notification_title (946857427149305992) --> - <skip /> - <!-- no translation found for performance_boost_notification_detail (362407668982648351) --> - <skip /> + <string name="performance_boost_notification_title" msgid="946857427149305992">"改善 5G 体验"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"%1$s建议购买性能提升计划。点按即可通过%2$s进行购买。"</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"以后再说"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"管理"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"购买一份性能提升方案。"</string> diff --git a/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml index 53b71ab2080a..7ed0c3c03897 100644 --- a/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml +++ b/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml @@ -16,7 +16,7 @@ <string name="ssl_error_continue" msgid="1138548463994095584">"仍要透過瀏覽器繼續操作"</string> <string name="performance_boost_notification_channel" msgid="3475440855635538592">"效能提升服務"</string> <string name="performance_boost_notification_title" msgid="946857427149305992">"改善 5G 體驗"</string> - <string name="performance_boost_notification_detail" msgid="362407668982648351">"「%1$s」建議購買效能提升方案,輕觸即可透過「%2$s」購買。"</string> + <string name="performance_boost_notification_detail" msgid="362407668982648351">"「%1$s」建議購買效能提升服務計劃。輕按即可透過「%2$s」購買。"</string> <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"暫時不要"</string> <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"管理"</string> <string name="slice_purchase_app_label" msgid="7170191659233241166">"購買效能提升服務。"</string> diff --git a/packages/CredentialManager/res/values-af/strings.xml b/packages/CredentialManager/res/values-af/strings.xml index 723f21c89801..f62b72da0616 100644 --- a/packages/CredentialManager/res/values-af/strings.xml +++ b/packages/CredentialManager/res/values-af/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Kanselleer"</string> <string name="string_continue" msgid="1346732695941131882">"Gaan voort"</string> <string name="string_more_options" msgid="7990658711962795124">"Meer opsies"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Kom meer te wete"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Veiliger met wagwoordsleutels"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Met wagwoordsleutels hoef jy nie komplekse wagwoorde te skep of te onthou nie"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Wagwoordsleutels is geënkripteerde digitale sleutels wat jy met jou vingerafdruk, gesig of skermslot skep"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Hulle word in ’n wagwoordbestuurder gestoor sodat jy op ander toestelle kan aanmeld"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Meer oor wagwoordsleutels"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Wagwoordlose tegnologie"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Met wagwoordsleutels kan jy aanmeld sonder om op wagwoorde staat te maak. Jy moet net jou vingerafdruk, gesigherkenning, PIN of swieppatroon gebruik om jou identiteit te verifieer en ’n wagwoordsleutel te skep."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Publiekesleutelkriptografie"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Gegrond op FIDO Alliance (wat Google, Apple, Microsoft en meer insluit) en W3C-standaarde, gebruik wagwoordsleutels kriptografiese sleutelpare. Anders as die gebruikernaam en string karakters wat ons vir wagwoorde gebruik, word ’n private-publieke-sleutelpaar vir ’n app of webwerf geskep. Die private sleutel word veilig op jou toestel of wagwoordbestuurder geberg en bevestig jou identiteit. Die publieke sleutel word met die app of webwerfbediener gedeel. Met passende sleutels kan jy dadelik registreer en aanmeld."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Verbeterde rekeningsekuriteit"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Elke sleutel is uitsluitlik gekoppel aan die app of webwerf waarvoor dit geskep is, en daarom kan jy nooit per ongeluk by ’n bedrieglike app of webwerf aanmeld nie. En omdat bedieners net publieke sleutels hou, is kuberkrakery baie moeiliker."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Moeitevrye oorgang"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Wagwoorde sal steeds saam met wagwoordsleutels beskikbaar wees terwyl ons na ’n wagwoordlose toekoms beweeg."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Kies waar om jou <xliff:g id="CREATETYPES">%1$s</xliff:g> te stoor"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Kies ’n wagwoordbestuurder om jou inligting te stoor en volgende keer vinniger aan te meld"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Skep wagwoordsleutel vir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-am/strings.xml b/packages/CredentialManager/res/values-am/strings.xml index 3d482f95ccb0..5a35369c9c63 100644 --- a/packages/CredentialManager/res/values-am/strings.xml +++ b/packages/CredentialManager/res/values-am/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"ይቅር"</string> <string name="string_continue" msgid="1346732695941131882">"ቀጥል"</string> <string name="string_more_options" msgid="7990658711962795124">"ተጨማሪ አማራጮች"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"የበለጠ ለመረዳት"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"በይለፍ ቃል ይበልጥ ደህንነቱ የተጠበቀ"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"በይለፍ ቁልፎች ውስብስብ የይለፍ ቁልፎችን መፍጠር ወይም ማስታወስ አያስፈልግዎትም"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"የይለፍ ቁልፎች የእርስዎን የጣት አሻራ፣ መልክ ወይም የማያ ገጽ መቆለፊያ በመጠቀም የሚፈጥሯቸው የተመሰጠሩ ዲጂታል ቆልፎች ናቸው"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"በሌሎች መሣሪያዎች ላይ መግባት እንዲችሉ በሚስጥር ቁልፍ አስተዳዳሪ ላይ ይቀመጣሉ"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"ስለየይለፍ ቁልፎች ተጨማሪ"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"የይለፍ ቃል የሌለው ቴክኖሎጂ"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"የይለፍ ቁልፎች የይለፍ ቃላት ላይ ሳይተማመኑ እንዲገቡ ይፈቅዱልዎታል። ማንነትዎን ለማረጋገጥ እና የይለፍ ቁልፍ ለመፍጠር ማድረግ ያለብዎት የእርስዎን የጣት አሻራ፣ የመልክ ለይቶ ማወቂያ፣ ፒን ወይም የማንሸራተት ስርዓተ ጥለትን መጠቀም ነው።"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"ይፋዊ ቁልፍ ሥነ-መሰውር"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"በFIDO Alliance (ይህም Google፣ Apple፣ Microsoft እና ሌሎችንም ያካትታል) እና W3C መስፈርቶች መሰረት የይለፍ ቁልፎች ሥነ-መሰውራዊ የቁልፍ ጥንዶች ይጠቀማሉ። ለይለፍ ቃሎች ከምንጠቀማቸው የተጠቃሚ ስም እና የቁምፊዎች ሕብረቁምፊ በተቃራኒ ለመተግበሪያ ወይም ድር ጣቢያ የግል-ይፋዊ የቁልፍ ጥንድ ተፈጥሯል። የግል ቁልፉ በእርስዎ መሣሪያ ወይም የሚስጥር ቁልፍ አስተዳዳሪ ላይ ደህንነቱ ተጠብቆ ይከማቻል እና ማንነትዎን ያረጋግጣል። ይፋዊ ቁልፉ ከመተግበሪያው ወይም ድር ጣቢያ አገልጋዩ ጋር ይጋራል። በተጓዳኝ ቁልፎች በቅጽበት መመዝገብ እና መግባት ይችላሉ።"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"የተሻሻለ የመለያ ደህንነት"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"ወደ አጭበርባሪ መተግበሪያ ወይም ድር ጣቢያ በስህተት መቼም መግባት እንዳይችሉ እያንዳንዱ ቁልፍ ከተፈጠረለት መተግበሪያ ወይም ድር ጣቢያ ጋር ለሚመለከተው ተወስኖ የተገናኘ ነው። በተጨማሪም አገልጋዮች ይፋዊ ቁልፎችን ብቻ ስለሚጠብቁ ሰርጎ መግባት የበለጠ ከባድ ነው።"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"እንከን አልባ ትርጉም"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"ወደ የይለፍ ቃል የሌለው ወደፊት ስንሄድ የይለፍ ቃላት ከይለፍ ቁልፎች ጎን ለጎን ይገኛሉ።"</string> <string name="choose_provider_title" msgid="8870795677024868108">"የእርስዎን <xliff:g id="CREATETYPES">%1$s</xliff:g> የት እንደሚያስቀምጡ ይምረጡ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"መረጃዎን ለማስቀመጥ እና በቀጣይ ጊዜ በፍጥነት በመለያ ለመግባት የሚስጥር ቁልፍ አስተዳዳሪን ይምረጡ"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"ለ<xliff:g id="APPNAME">%1$s</xliff:g> የይለፍ ቁልፍ ይፈጠር?"</string> diff --git a/packages/CredentialManager/res/values-ar/strings.xml b/packages/CredentialManager/res/values-ar/strings.xml index 47e41a74a2da..7244489028eb 100644 --- a/packages/CredentialManager/res/values-ar/strings.xml +++ b/packages/CredentialManager/res/values-ar/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"إلغاء"</string> <string name="string_continue" msgid="1346732695941131882">"متابعة"</string> <string name="string_more_options" msgid="7990658711962795124">"خيارات إضافية"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"مزيد من المعلومات"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"توفير المزيد من الأمان باستخدام مفاتيح المرور"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"باستخدام مفاتيح المرور، لا حاجة لإنشاء كلمات مرور معقدة أو تذكّرها."</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"مفاتيح المرور هي مفاتيح رقمية مشفّرة يمكنك إنشاؤها باستخدام بصمة الإصبع أو التعرّف على الوجه أو قفل الشاشة."</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"يتم حفظها في مدير كلمات مرور، حتى تتمكن من تسجيل الدخول على أجهزة أخرى."</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"مزيد من المعلومات حول مفاتيح المرور"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"تكنولوجيا بدون استخدام كلمات المرور"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"توفّر لك مفاتيح المرور إمكانية تسجيل الدخول بدون الاعتماد على كلمات المرور. تحتاج فقط إلى استخدام بصمة إصبعك أو ميزة \"التعرّف على الوجه\" أو رقم التعريف الشخصي أو نقش التمرير السريع لإثبات هويتك وإنشاء مفتاح مرور."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"تشفير المفتاح العام"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"تستخدم مفاتيح المرور أزواجًا من مفاتيح التشفير وذلك وفقًا لمعايير W3C وتحالف FIDO Alliance (الذي يضم شركات Google وApple وMicrosoft وغيرها). يتم إنشاء زوج مفاتيح خاص/عام للتطبيق أو الموقع الإلكتروني وذلك على عكس اسم المستخدم وسلسلة الأحرف التي نستخدمها لإنشاء كلمات المرور. يتم تخزين المفتاح الخاص بأمان على جهازك أو في مدير كلمات المرور ويتم تأكيد هويتك. تتم مشاركة المفتاح العام مع خادم التطبيق أو الموقع الإلكتروني. يمكنك التسجيل وتسجيل الدخول على الفور باستخدام المفاتيح المقابلة."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"تحسين أمان الحساب"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"يرتبط كل مفتاح حصريًا بالتطبيق أو الموقع الإلكتروني الذي تم إنشاؤه من أجله، لذلك لا يمكن أبدًا أن تسجّل الدخول إلى تطبيق أو موقع إلكتروني احتيالي عن طريق الخطأ. بالإضافة إلى ذلك، تكون عملية الاختراق أكثر صعوبة لأن الخوادم تحتفظ بالمفاتيح العامة فقط."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"النقل السلس"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"بينما ننطلق نحو مستقبل بدون كلمات مرور، ستظل كلمات المرور متوفّرة إلى جانب مفاتيح المرور."</string> <string name="choose_provider_title" msgid="8870795677024868108">"اختَر الموقع الذي تريد حفظ <xliff:g id="CREATETYPES">%1$s</xliff:g> فيه"</string> <string name="choose_provider_body" msgid="4967074531845147434">"اختَر مدير كلمات مرور لحفظ معلوماتك وتسجيل الدخول بشكل أسرع في المرة القادمة."</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"إنشاء مفتاح مرور لتطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string> diff --git a/packages/CredentialManager/res/values-as/strings.xml b/packages/CredentialManager/res/values-as/strings.xml index 2cea9c8ef812..6f68adbac9bc 100644 --- a/packages/CredentialManager/res/values-as/strings.xml +++ b/packages/CredentialManager/res/values-as/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"বাতিল কৰক"</string> <string name="string_continue" msgid="1346732695941131882">"অব্যাহত ৰাখক"</string> <string name="string_more_options" msgid="7990658711962795124">"অধিক বিকল্প"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"অধিক জানক"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"পাছকীৰ জৰিয়তে অধিক সুৰক্ষিত"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"পাছকী ব্যৱহাৰ কৰিলে আপুনি জটিল পাছৱৰ্ড সৃষ্টি কৰিব অথবা মনত ৰাখিব নালাগে"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"পাছকীসমূহ হৈছে আপুনি আপোনাৰ ফিংগাৰপ্ৰিণ্ট, মুখাৱয়ব অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰি সৃষ্টি কৰা এনক্ৰিপ্ট কৰা ডিজিটেল চাবি"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"সেইসমূহ এটা পাছৱৰ্ড পৰিচালকত ছেভ কৰা হয়, যাতে আপুনি অন্য ডিভাইচসমূহত ছাইন ইন কৰিব পাৰে"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"পাছকীৰ বিষয়ে অধিক"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"পাছৱৰ্ডবিহীন প্ৰযুক্তি"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"পাছকীসমূহে আপোনাক পাছৱৰ্ডৰ ওপৰত নিৰ্ভৰ নকৰাকৈ ছাইন ইন কৰাৰ অনুমতি দিয়ে। আপুনি আপোনাৰ পৰিচয় সত্যাপন কৰিবলৈ আৰু এটা পাছকী সৃষ্টি কৰিবলৈ কেৱল আপোনাৰ ফিংগাৰপ্ৰিণ্ট, মুখাৱয়ব চিনাক্তকৰণ, পিন অথবা ছোৱাইপ কৰাৰ আৰ্হি ব্যৱহাৰ কৰিলেই হ’ল।"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"ৰাজহুৱা চাবি ক্ৰিপ্ট’গ্ৰাফী"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO জোঁট (য’ত Google, Apple, Microsoft আৰু অধিক অন্তৰ্ভুক্ত) আৰু W3C মানকসমূহৰ ওপৰত ভিত্তি কৰি, পাছকীসমূহে ক্ৰিপ্ট’গ্ৰাফিক চাবিৰ যোৰা ব্যৱহাৰ কৰে। আমি পাছৱৰ্ডৰ বাবে ব্যৱহাৰ কৰা ব্যৱহাৰকাৰীৰ নাম আৰু বৰ্ণৰ ষ্ট্ৰিঙৰ বিপৰীতে, এটা এপ্ অথবা ৱেবছাইটৰ বাবে এটা ব্যক্তিগত-ৰাজহুৱা কীৰ যোৰা সৃষ্টি কৰা হয়। ব্যক্তিগত চাবিটো আপোনাৰ ডিভাইচ অথবা পাছৱৰ্ড পৰিচালকত সুৰক্ষিতভাৱে ষ্ট’ৰ কৰা হয় আৰু ই আপোনাৰ পৰিচয় নিশ্চিত কৰে। ৰাজহুৱা চাবিটো এপ্ অথবা ৱেবছাইটৰ ছাৰ্ভাৰৰ সৈতে শ্বেয়াৰ কৰা হয়। সংশ্লিষ্ট চাবিসমূহৰ জৰিয়তে আপুনি তাৎক্ষণিকভাৱে পঞ্জীয়ন আৰু ছাইন ইন কৰিব পাৰিব।"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"একাউণ্টৰ উন্নত সুৰক্ষা"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"প্ৰতিটো চাবি বিশেষভাৱে সেই এপ্ অথবা ৱেবছাইটৰ সৈতে লিংক কৰা হয় যাৰ বাবে সেইটো সৃষ্টি কৰা হৈছে, সেয়ে আপুনি কেতিয়াও ভুলতে কোনো প্ৰৱঞ্চনামূলক এপ্ অথবা ৱেবছাইটত ছাইন ইন কৰিব নোৱাৰে। ইয়াৰ উপৰিও, কেৱল ৰাজহুৱা চাবিসমূহ ৰখা ছাৰ্ভাৰৰ ক্ষেত্ৰত হেক কৰাটো বহুত কঠিন হৈ পৰে।"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"বাধাহীন স্থানান্তৰণ"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"আমি পাছৱৰ্ডবিহীন ভৱিষ্যতৰ দিশে আগবঢ়াৰ লগে লগে পাছকীৰ লগতে পাছৱৰ্ডসমূহো উপলব্ধ হ’ব।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"আপোনাৰ <xliff:g id="CREATETYPES">%1$s</xliff:g> ক’ত ছেভ কৰিব লাগে সেয়া বাছনি কৰক"</string> <string name="choose_provider_body" msgid="4967074531845147434">"আপোনাৰ তথ্য ছেভ কৰি পৰৱৰ্তী সময়ত দ্ৰুতভাৱে ছাইন ইন কৰিবলৈ এটা পাছৱৰ্ড পৰিচালক বাছনি কৰক"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>ৰ বাবে পাছকী সৃষ্টি কৰিবনে?"</string> diff --git a/packages/CredentialManager/res/values-az/strings.xml b/packages/CredentialManager/res/values-az/strings.xml index a987b66b7569..bb359632985e 100644 --- a/packages/CredentialManager/res/values-az/strings.xml +++ b/packages/CredentialManager/res/values-az/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Ləğv edin"</string> <string name="string_continue" msgid="1346732695941131882">"Davam edin"</string> <string name="string_more_options" msgid="7990658711962795124">"Digər seçimlər"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Ətraflı məlumat"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Giriş açarları ilə daha təhlükəsiz"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Giriş açarları ilə mürəkkəb parollar yaratmağa və ya yadda saxlamağa ehtiyac yoxdur"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Giriş açarları barmaq izi, üz və ya ekran kilidindən istifadə edərək yaratdığınız şifrələnmiş rəqəmsal açarlardır"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Onlar parol menecerində saxlanılır ki, digər cihazlarda daxil ola biləsiniz"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Giriş açarları haqqında ətraflı"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Parolsuz texnologiya"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Giriş açarları parollara etibar etmədən daxil olmağa imkan verir. Kimliyinizi doğrulamaq və giriş açarı yaratmaq üçün sadəcə barmaq izi, üz tanıma, PIN və ya sürüşdürmə modelindən istifadə etməlisiniz."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"İctimai açar kriptoqrafiyası"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (Google, Apple, Microsoft və s. daxildir) və W3C standartlarına əsaslanaraq giriş açarları kriptoqrafik açar cütlərindən istifadə edir. İstifadəçi adı və parollar üçün istifadə etdiyimiz simvol sətrindən fərqli olaraq, tətbiq və ya vebsayt üçün şəxsi-ictimai açar cütü yaradılır. Şəxsi açar cihazınızda və ya parol menecerinizdə təhlükəsiz şəkildə saxlanılır və kimliyinizi təsdiq edir. İctimai açar tətbiq və ya vebsayt serveri ilə paylaşılır. Müvafiq açarlarla dərhal qeydiyyatdan keçə və daxil ola bilərsiniz."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Təkmilləşdirilmiş hesab təhlükəsizliyi"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Hər bir açar eksklüziv olaraq onların yaradıldığı tətbiq və ya vebsaytla əlaqələndirilib, ona görə də heç vaxt səhvən saxta tətbiqə və ya vebsayta daxil ola bilməzsiniz. Üstəlik, yalnız ictimai açarları saxlayan serverlərlə hekinq daha çətindir."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Rahat keçid"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsuz gələcəyə doğru irəlilədikcə parollar hələ də giriş açarları ilə yanaşı əlçatan olacaq."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> elementinin saxlanacağı yeri seçin"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Məlumatlarınızı yadda saxlamaq və növbəti dəfə daha sürətli daxil olmaq üçün parol meneceri seçin"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> üçün giriş açarı yaradılsın?"</string> diff --git a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml index 5a52190d918c..3182c13bbeb6 100644 --- a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml +++ b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Otkaži"</string> <string name="string_continue" msgid="1346732695941131882">"Nastavi"</string> <string name="string_more_options" msgid="7990658711962795124">"Još opcija"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Saznajte više"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Bezbednije uz pristupne kodove"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Uz pristupne kodove nema potrebe da pravite ili pamtite složene lozinke"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Pristupni kodovi su šifrovani digitalni kodovi koje pravite pomoću otiska prsta, lica ili zaključavanja ekrana"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Čuvaju se u menadžeru lozinki da biste mogli da se prijavljujete na drugim uređajima"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Više o pristupnim kodovima"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Tehnologija bez lozinke"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Pristupni kodovi vam omogućavaju da se prijavite bez oslanjanja na lozinke. Dovoljno je samo da koristite otisak prsta, prepoznavanje lica, PIN ili šablon da biste verifikovali identitet i napravili pristupni kôd."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kriptografija preko javnog ključa"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Na osnovu standarda udruženja FIDO (Google, Apple, Microsoft i drugi) i W3C, pristupni kodovi koriste parove ključeva za šifrovanje. Za razliku od korisničkog imena i stringa znakova koji koristimo za lozinke, za aplikaciju ili sajt prave se parovi privatnih i javnih ključeva. Privatni ključ se bezbedno čuva na uređaju ili u menadžeru lozinki i potvrđuje vaš identitet. Javni ključ se deli sa serverom aplikacije ili veb-sajta. Pomoću odgovarajućih ključeva možete trenutno da se registrujete i prijavite."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Poboljšana bezbednost naloga"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Svaki ključ je isključivo povezan sa aplikacijom ili veb-sajtom za koje je napravljen, pa nikad ne možete greškom da se prijavite u aplikaciju ili na veb-sajt koji služe za prevaru. Osim toga, sa serverima koji čuvaju samo javne ključeve hakovanje je mnogo teže."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Besprekoran prelaz"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako se krećemo ka budućnosti bez lozinki, lozinke će i dalje biti dostupne uz pristupne kodove."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Odaberite gde ćete sačuvati stavke <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Izaberite menadžera lozinki da biste sačuvali podatke i brže se prijavili sledeći put"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Želite da napravite pristupni kôd za: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-be/strings.xml b/packages/CredentialManager/res/values-be/strings.xml index 6cad43d95003..2979cffe5e00 100644 --- a/packages/CredentialManager/res/values-be/strings.xml +++ b/packages/CredentialManager/res/values-be/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Скасаваць"</string> <string name="string_continue" msgid="1346732695941131882">"Далей"</string> <string name="string_more_options" msgid="7990658711962795124">"Дадатковыя параметры"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Даведацца больш"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"З ключамі доступу вам будзе бяспечней."</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Дзякуючы ключам доступу вам не трэба ствараць і запамінаць складаныя паролі."</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Ключы доступу – гэта зашыфраваныя лючбавыя ключы, створаныя вамі з дапамогай адбітка пальца, твару ці блакіроўкі экрана."</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Яны захаваны ў менеджары пароляў. Дзякуючы гэтаму вы можаце ўваходзіць на іншых прыладах"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Падрабязней пра ключы доступу"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Тэхналогія ідэнтыфікацыі без выкарыстання пароляў"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Ключы доступу дазваляюць уваходзіць ва ўліковы запіс без выкарыстання пароляў. Каб спраўдзіць асобу і стварыць ключ доступу, дастаткова скарыстаць адбітак пальца, распазнаванне твару, PIN-код або ўзор разблакіроўкі."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Крыптаграфія адкрытых ключоў"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"З улікам стандартаў FIDO Alliance (Google, Apple, Microsoft і іншыя кампаніі) і W3C ключы доступу выкарыстоўваюць крыптаграфічныя пары ключоў. Для праграмы ці вэб-сайта замест імя карыстальніка і набору сімвалаў у якасці пароля ствараецца пара з закрытага і адкрытага ключоў. Закрыты ключ бяспечна захоўваецца на прыладзе ці ў менеджары пароляў і пацвярджае асобу. Адкрыты ключ абагульваецца з серверам праграмы ці сайта. Адпаведныя ключы дазваляюць імгненна рэгістравацца і ўваходзіць у сістэму."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Павышаная бяспека ўліковага запісу"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Кожны ключ звязаны толькі з праграмай або вэб-сайтам, для якіх ён быў створаны, таму вы не зможаце памылкова ўвайсці ў праграму ці на вэб-сайт, створаныя ў мэтах махлярства. Акрамя таго, на серверах захоўваюцца толькі адкрытыя ключы, таму правесці ўзлом намнога складаней."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Плаўны пераход"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Хоць мы ўжо рухаемся ў бок будучыні без выкарыстання пароляў, яны па-ранейшаму застануцца даступнымі нароўні з ключамі доступу."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Выберыце, куды захаваць <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Выберыце менеджар пароляў, каб захаваць свае даныя і забяспечыць хуткі ўваход у наступныя разы"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Стварыце ключ доступу да праграмы \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string> diff --git a/packages/CredentialManager/res/values-bg/strings.xml b/packages/CredentialManager/res/values-bg/strings.xml index 163398e929ae..759f2d46f11b 100644 --- a/packages/CredentialManager/res/values-bg/strings.xml +++ b/packages/CredentialManager/res/values-bg/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Отказ"</string> <string name="string_continue" msgid="1346732695941131882">"Напред"</string> <string name="string_more_options" msgid="7990658711962795124">"Още опции"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Научете повече"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"По-сигурно с помощта на кодове за достъп"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Когато използвате кодове за достъп, не е необходимо да създавате, нито да помните сложни пароли"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Кодовете за достъп са шифровани дигитални ключове, които създавате посредством отпечатъка, лицето си или опцията си за заключване на екрана"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Данните се запазват в мениджър на пароли, за да можете да влизате в профила си на други устройства"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Още за кодовете за достъп"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Заменяща паролите технология"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Кодовете за достъп ви дават възможност да влизате в профила си без парола. Трябва само да използвате отпечатъка, лицето, ПИН кода или фигурата си, за да потвърдите самоличността си и да създадете код за достъп."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Криптография с публичен ключ"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Според съюза FIDO (Google, Apple, Microsoft и др.) и стандартите на W3C кодовете за достъп ползват двойки криптографски ключове. Вместо потребителско име и парола за дадено приложение или уебсайт се създава двойка ключове – частен и публичен. Първият се съхранява надеждно на устройството ви или в мениджъра на пароли и служи за потвърждаване на самоличността ви. Вторият се споделя със съответния сървър. С двойката ключове можете да се регистрирате и да влезете в профила си незабавно."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Подобрена сигурност на профила"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Всеки ключ е свързан само с приложението или уебсайта, за които е създаден. Затова не е възможно да влезете в измамно приложение или уебсайт по погрешка. Освен това сървърите съхраняват само публичните ключове, което значително затруднява опитите за хакерство."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Безпроблемен преход"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Паролите ще продължат да са налице заедно с кодовете за достъп по пътя ни към бъдеще без пароли."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Изберете къде да запазите своите <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Изберете мениджър на пароли, в който да се запазят данните ви, така че следващия път да влезете по-бързо в профила си"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Да се създаде ли код за достъп за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-bn/strings.xml b/packages/CredentialManager/res/values-bn/strings.xml index 408ccb1da212..17905ee7810e 100644 --- a/packages/CredentialManager/res/values-bn/strings.xml +++ b/packages/CredentialManager/res/values-bn/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"বাতিল করুন"</string> <string name="string_continue" msgid="1346732695941131882">"চালিয়ে যান"</string> <string name="string_more_options" msgid="7990658711962795124">"আরও বিকল্প"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"আরও জানুন"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"\'পাসকী\'-এর সাথে সুরক্ষিত"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"\'পাসকী\' ব্যবহার করলে জটিল পাসওয়ার্ড তৈরি করার বা মনে রাখার কোনও প্রয়োজন নেই"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"আপনার ফিঙ্গারপ্রিন্ট, ফেস মডেল বা \'স্ক্রিন লক\' ব্যবহার করে আপনি যে এনক্রিপটেড ডিজিটাল \'কী\' তৈরি করেন সেগুলিই হল \'পাসকী\'"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"আপনি যাতে অন্যান্য ডিভাইসে সাইন-ইন করতে পারেন তার জন্য Password Manager-এ এগুলি সেভ করা হয়"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"\'পাসকী\' সম্পর্কে আরও বিবরণ"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"পাসওয়ার্ডবিহীন প্রযুক্তি"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"পাসওয়ার্ড ছাড়াই \'পাসকী\' আপনাকে সাইন-ইন করার অনুমতি দেয়। আপনার পরিচয় যাচাই ও \'পাসকী\' তৈরি করতে, আপনাকে শুধু ফিঙ্গারপ্রিন্ট, ফেস শনাক্তকরণ, পিন বা সোয়াইপ প্যাটার্ন ব্যবহার করতে হবে।"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"সর্বজনীন \'কী\' সংক্রান্ত ক্রিপ্টোগ্রাফি"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (এতে Google, Apple, Microsoft ও আরও রয়েছে) ও W3C-এর স্ট্যান্ডার্ডের ভিত্তিতে \'পাসকী\' ক্রিপ্টোগ্রাফিক \'কী পেয়ার\' ব্যবহার করে। পাসওয়ার্ডের জন্য অক্ষরের স্ট্রিং ও ইউজারনেম ব্যবহার করা হলেও এক্ষেত্রে তা হয় না, কোনও অ্যাপ বা ওয়েবসাইটের ক্ষেত্রে ব্যক্তিগত ও সর্বজনীন \'কী পেয়ার\' তৈরি করা হয়। ব্যক্তিগত \'কী\' নিরাপদে আপনার ডিভাইস বা Password Manager-এ সেভ থাকে ও তা আপনার পরিচয় যাচাই করে। সর্বজনীন \'কী\', অ্যাপ বা ওয়েবসাইট সার্ভারের সাথে শেয়ার করা হয়। সংশ্লিষ্ট \'কী\'-এর মাধ্যমে ঝটপট রেজিস্টার ও সাইন-ইন করতে পারবেন।"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"অ্যাকাউন্টের জন্য উন্নত সুরক্ষা"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"প্রতিটি \'কী\' যে অ্যাপ বা ওয়েবসাইটের জন্য তৈরি করা হয়েছে, সেগুলির সাথে এই \'কী\' বিশেষভাবে লিঙ্ক করা থাকে। তাই কখনই আপনি ভুলবশত কোনও ভুয়ো অ্যাপ বা ওয়েবসাইটে সাইন-ইন করতে পারবেন না। পাশাপাশি, যেসব সার্ভারে শুধু সর্বজনীন \'কী\' রয়েছে, তা হ্যাক করা খুবই কঠিন।"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"নির্বিঘ্ন ট্রানজিশন"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"আমরা পাসওয়ার্ডবিহীন ভবিষ্যতের দিকে এগিয়ে গেলেও, এখনও \'পাসকী\'-এর পাশাপাশি পাসওয়ার্ড ব্যবহার করা যাবে।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"আপনার <xliff:g id="CREATETYPES">%1$s</xliff:g> কোথায় সেভ করবেন তা বেছে নিন"</string> <string name="choose_provider_body" msgid="4967074531845147434">"আপনার তথ্য সেভ করতে একটি Password Manager বেছে নিন এবং পরের বার আরও দ্রুত সাইন-ইন করুন"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>-এর জন্য \'পাসকী\' তৈরি করবেন?"</string> diff --git a/packages/CredentialManager/res/values-bs/strings.xml b/packages/CredentialManager/res/values-bs/strings.xml index 6d3a1849b3f2..e8d8ecc043c3 100644 --- a/packages/CredentialManager/res/values-bs/strings.xml +++ b/packages/CredentialManager/res/values-bs/strings.xml @@ -10,15 +10,15 @@ <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Uz pristupne ključeve ne morate kreirati ili pamtiti složene lozinke"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Pristupni ključevi su šifrirani digitalni ključevi koje kreirate pomoću otiska prsta, lica ili zaključavanja ekrana"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Pristupni ključevi se pohranjuju u upravitelju lozinki da se možete prijaviti na drugim uređajima"</string> - <string name="more_about_passkeys_title" msgid="7797903098728837795">"Više informacija o pristupnim ključevima"</string> - <string name="passwordless_technology_title" msgid="2497513482056606668">"Tehnologija bez upotrebe zaporke"</string> - <string name="passwordless_technology_detail" msgid="6853928846532955882">"Pristupni ključevi omogućuju prijavu bez upotrebe zaporki. Treba vam samo otisak prsta, prepoznavanje lica, PIN ili uzorak pokreta prstom da biste potvrdili svoj identitet i izradili pristupni ključ."</string> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Više o pristupnim ključevima"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Tehnologija bez lozinki"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Pristupni ključevi vam omogućavaju da se prijavite bez oslanjanja na lozinke. Samo trebate upotrijebiti otisak prsta, prepoznavanje lica, PIN ili uzorak prevlačenja da potvrdite svoj identitet i kreirate pristupni ključ."</string> <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kriptografija javnog ključa"</string> - <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Na temelju saveza FIDO (koji uključuje Google, Apple, Microsoft i mnoge druge) i standarda W3C pristupni ključevi koriste kriptografske ključeve. Za razliku od korisničkog imena i niza znakova za zaporke, privatno-javni ključ izrađen je za aplikaciju ili web-lokaciju. Privatni ključ pohranjen je na vašem uređaju ili upravitelju zaporki i potvrđuje vaš identitet. Javni se ključ dijeli s poslužiteljem aplikacije ili web-lokacije. Uz odgovarajuće ključeve možete se odmah registrirati i prijaviti."</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Na osnovu standarda FIDO Alliance (obuhvata Google, Apple, Microsoft i dr.) i W3C, pristupni ključevi koriste parove kriptografskih ključeva. Za razliku od korisničkog imena i niza znakova za lozinke, par privatno-javnih ključeva se kreira za aplikaciju ili web lokaciju. Privatni ključ se sigurno pohranjuje na uređaju ili u upravitelju lozinki i potvrđuje vaš identitet. Javni ključ se dijeli sa serverom aplikacije ili web lokacije. S odgovarajućim ključevima se možete odmah registrirati i prijaviti."</string> <string name="improved_account_security_title" msgid="1069841917893513424">"Poboljšana sigurnost računa"</string> - <string name="improved_account_security_detail" msgid="9123750251551844860">"Svaki ključ povezan isključivo s aplikacijom ili web-lokacijom za koju je izrađen, stoga se nikad ne možete pogreškom prijaviti u prijevarnu aplikaciju ili na web-lokaciju. Osim toga, kad je riječ o poslužiteljima na kojem se nalaze samo javni ključevi, hakiranje je mnogo teže."</string> - <string name="seamless_transition_title" msgid="5335622196351371961">"Besprijekorni prijelaz"</string> - <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako idemo u smjeru budućnosti bez zaporki, one će i dalje biti dostupne uz pristupne ključeve."</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Svaki ključ je isključivo povezan s aplikacijom ili web lokacijom za koju je kreiran, tako da se nikada ne možete greškom prijaviti u prevarantsku aplikaciju ili na prevarantsku web lokaciju. Osim toga, hakiranje je puno teže zahvaljujući serverima koji čuvaju samo javne ključeve."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Neometani prijelaz"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako se krećemo prema budućnosti bez lozinki, lozinke će i dalje biti dostupne uz pristupne ključeve."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Odaberite gdje sačuvati stavku <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Odaberite upravitelja lozinki da sačuvate svoje informacije i brže se prijavite sljedeći put"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Kreirati pristupni ključ za aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-ca/strings.xml b/packages/CredentialManager/res/values-ca/strings.xml index 5d594846b8c6..300c95f98bd1 100644 --- a/packages/CredentialManager/res/values-ca/strings.xml +++ b/packages/CredentialManager/res/values-ca/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Cancel·la"</string> <string name="string_continue" msgid="1346732695941131882">"Continua"</string> <string name="string_more_options" msgid="7990658711962795124">"Més opcions"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Més informació"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Més seguretat amb les claus d\'accés"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Amb les claus d\'accés, no cal que creïs ni recordis contrasenyes difícils"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Les claus d\'accés són claus digitals encriptades que pots crear amb la teva cara, l\'empremta digital o el bloqueig de pantalla"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Es desen a un gestor de contrasenyes perquè puguis iniciar la sessió en altres dispositius"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Més sobre les claus d\'accés"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Tecnologia sense contrasenyes"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Les claus d\'accés et permeten iniciar la sessió sense dependre de cap contrasenya. Només necessites utilitzar l\'empremta digital, el reconeixement facial, el PIN o lliscar el patró per verificar la teva identitat i crear una clau d\'accés."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Criptografia de la clau pública"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"D\'acord amb FIDO Alliance i els estàndards W3C, les claus d\'accés utilitzen parells de claus criptogràfiques. En lloc del nom d\'usuari i la cadena de caràcters que utilitzem per a les contrasenyes, es crea un parell de claus per a una app o web. La clau privada es desa de manera segura al dispositiu o al gestor de contrasenyes i confirma la teva identitat. La clau pública es comparteix amb l\'app o el servidor del lloc web. Amb les claus corresponents, pots registrar-te i iniciar sessió a l\'instant."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Seguretat dels comptes millorada"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Cada clau està exclusivament enllaçada a l\'aplicació o al lloc web per als quals s\'ha creat. D\'aquesta manera, mai iniciaràs la sessió en una aplicació o un lloc web fraudulents per error. A més, com que els servidors només conserven les claus públiques, el hacking és molt més difícil."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Transició fluida"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Tot i que avancem cap a un futur sense contrasenyes, continuaran estant disponibles juntament amb les claus d\'accés."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Tria on vols desar les <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un gestor de contrasenyes per desar la teva informació i iniciar la sessió més ràpidament la pròxima vegada"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vols crear la clau d\'accés per a <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-da/strings.xml b/packages/CredentialManager/res/values-da/strings.xml index 86135b016b26..b214c04cddb2 100644 --- a/packages/CredentialManager/res/values-da/strings.xml +++ b/packages/CredentialManager/res/values-da/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Annuller"</string> <string name="string_continue" msgid="1346732695941131882">"Fortsæt"</string> <string name="string_more_options" msgid="7990658711962795124">"Flere valgmuligheder"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Få flere oplysninger"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Øget beskyttelse med adgangsnøgler"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Når du bruger adgangsnøgler, behøver du ikke at oprette eller huske avancerede adgangskoder"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Adgangsnøgler er krypterede digitale nøgler, som du opretter ved hjælp af fingeraftryk, ansigtsgenkendelse eller skærmlås"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Disse gemmes i en adgangskodeadministrator, så du kan logge ind på andre enheder"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Mere om adgangsnøgler"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Teknologi uden adgangskoder"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Adgangsnøgler giver dig mulighed for at logge ind uden brug af adgangskoder. Du skal bare bruge fingeraftryk, ansigtsgenkendelse, pinkode eller mønster for at verificere din identitet og oprette en adgangsnøgle."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kryptering for offentlig nøgle"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Baseret på FIDO Alliance (omfatter Google, Apple, Microsoft m.fl.) og W3C-standarder bruger adgangsnøgler kryptografiske nøglepar. Modsat det brugernavn og den streng af tegn, vi bruger til adgangskoder, oprettes der et privat-offentligt nøglepar til en app eller et website. Den private nøgle gemmes sikkert på din enhed eller adgangskodeadministrator og verificerer din identitet. Den offentlige nøgle deles med appen eller websiteserveren. Med de tilsvarende nøgler kan du logge ind med det samme."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Forbedret kontosikkerhed"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Hver nøgle er udelukkende tilknyttet den app eller det website, som nøglen blev oprettet til. På denne måde kan du aldrig logge ind i en svigagtig app eller på et svigagtigt website ved en fejl. Og da serverne kun opbevarer offentlige nøgler, er kontoer meget sværere at hacke."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Problemfri overgang"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Selvom vi nærmer os en fremtid, hvor adgangskoder er mindre fremtrædende, kan de stadig bruges i samspil med adgangsnøgler."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Vælg, hvor du vil gemme dine <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Vælg en adgangskodeadministrator for at gemme dine oplysninger, så du kan logge ind hurtigere næste gang"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vil du oprette en adgangsnøgle til <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-de/strings.xml b/packages/CredentialManager/res/values-de/strings.xml index 8da48c17df72..91afe23a15fc 100644 --- a/packages/CredentialManager/res/values-de/strings.xml +++ b/packages/CredentialManager/res/values-de/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Abbrechen"</string> <string name="string_continue" msgid="1346732695941131882">"Weiter"</string> <string name="string_more_options" msgid="7990658711962795124">"Weitere Optionen"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Weitere Informationen"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mehr Sicherheit mit Passkeys"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Mit Passkeys musst du keine komplizierten Passwörter erstellen oder dir merken"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Passkeys sind verschlüsselte digitale Schlüssel, die du mithilfe deines Fingerabdrucks, Gesichts oder deiner Displaysperre erstellst"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Sie werden in einem Passwortmanager gespeichert, damit du dich auf anderen Geräten anmelden kannst"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Weitere Informationen zu Passkeys"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Passwortlose Technologie"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Passkeys ermöglichen die Anmeldung, ohne dass Passwörter erforderlich sind. Du verwendest einfach die Fingerabdruck- oder Gesichtserkennung, eine PIN oder ein Muster, um deine Identität zu bestätigen und einen Passkey zu erstellen."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Asymmetrisches Kryptosystem"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Passkeys beruhen auf FIDO Alliance- (zu der auch Google und Apple gehören) und W3C-Standards. Anstelle von Nutzername und Passwort wird ein kryptografisches Paar aus privatem und öffentlichem Schlüssel für eine App oder Website erstellt. Der private Schlüssel wird sicher auf deinem Gerät oder im Passwortmanager gespeichert und bestätigt deine Identität. Der öffentliche Schlüssel wird mit dem App- oder Websiteserver geteilt. Stimmen beide überein, kannst du dich sofort registrieren und anmelden."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Verbesserte Kontosicherheit"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Jeder Schlüssel ist ausschließlich mit der App oder Website verknüpft, für die er erstellt wurde. Du kannst dich also nicht aus Versehen bei einer betrügerischen App oder Website anmelden. Da auf Servern nur öffentliche Schlüssel verwaltet werden, wird das Hacking außerdem erheblich erschwert."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Nahtlose Umstellung"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Auch wenn wir uns auf eine passwortlose Zukunft zubewegen, werden neben Passkeys weiter Passwörter verfügbar sein."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Wähle aus, wo deine <xliff:g id="CREATETYPES">%1$s</xliff:g> gespeichert werden sollen"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Du kannst einen Passwortmanager auswählen, um deine Anmeldedaten zu speichern, damit du dich nächstes Mal schneller anmelden kannst"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Passkey für <xliff:g id="APPNAME">%1$s</xliff:g> erstellen?"</string> diff --git a/packages/CredentialManager/res/values-el/strings.xml b/packages/CredentialManager/res/values-el/strings.xml index f99b5f0a3070..2797b3797245 100644 --- a/packages/CredentialManager/res/values-el/strings.xml +++ b/packages/CredentialManager/res/values-el/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Ακύρωση"</string> <string name="string_continue" msgid="1346732695941131882">"Συνέχεια"</string> <string name="string_more_options" msgid="7990658711962795124">"Περισσότερες επιλογές"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Μάθετε περισσότερα"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Μεγαλύτερη ασφάλεια με κλειδιά πρόσβασης"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Με τα κλειδιά πρόσβασης, δεν χρειάζεται να δημιουργείτε ή να θυμάστε σύνθετους κωδικούς πρόσβασης."</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Τα κλειδιά πρόσβασης είναι κρυπτογραφημένα ψηφιακά κλειδιά που δημιουργείτε χρησιμοποιώντας το δακτυλικό σας αποτύπωμα, το πρόσωπο ή το κλείδωμα οθόνης."</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Αποθηκεύονται σε ένα πρόγραμμα διαχείρισης κωδικών πρόσβασης, για να μπορείτε να συνδέεστε από άλλες συσκευές."</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Περισσότερες πληροφορίες για τα κλειδιά πρόσβασης"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Τεχνολογία χωρίς χρήση κωδικού πρόσβασης"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Τα κλειδιά πρόσβασης σάς επιτρέπουν να συνδέεστε χωρίς να εξαρτάστε από κωδικούς πρόσβασης. Χρειάζεται μόνο να χρησιμοποιήσετε το δακτυλικό αποτύπωμά σας, την αναγνώριση προσώπου, ένα PIN ή ένα μοτίβο σάρωσης για να επαληθεύσετε την ταυτότητά σας και να δημιουργήσετε ένα κλειδί πρόσβασης."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Κρυπτογραφία δημόσιου κλειδιού"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Βάσει του FIDO Alliance (συμμετ. οι Google, Apple, Microsoft κ.ά.) και προτύπων W3C, τα κλειδιά πρόσβ. χρησιμ. συζεύξεις κλειδιών κρυπτογρ. Σε αντίθεση με το όνομα χρήστη και τη συμβολοσειρά χαρακτ. για κωδ. πρόσβ., δημιουργείται μια σύζευξη ιδιωτικού-δημόσιου κλειδ. για εφαρμ./ιστοτόπους. Το ιδιωτ. κλειδί αποθηκεύεται με ασφάλεια στη συσκευή ή στον διαχειρ. κωδ. πρόσβ. και επιβεβαιώνει την ταυτότητά σας. Το δημόσιο κλειδί κοινοπ. στον διακομιστή εφαρμ./ιστοτόπου. Τα αντίστοιχα κλειδιά επιτρέπουν άμεση εγγραφή και σύνδεση."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Βελτιωμένη ασφάλεια λογαριασμού"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Κάθε κλειδί συνδέεται αποκλειστικά με την εφαρμογή ή τον ιστότοπο για τον οποίο δημιουργήθηκε ώστε να μην συνδέεστε ποτέ κατά λάθος σε μη νόμιμες εφαρμογές ή ιστοτόπους. Επιπλέον, οι παραβιάσεις είναι πολύ πιο δύσκολες, επειδή οι διακομιστές διατηρούν μόνο δημόσια κλειδιά."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Απρόσκοπτη μετάβαση"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Καθώς κινούμαστε προς ένα μέλλον χωρίς κωδικούς πρόσβασης, οι κωδικοί πρόσβασης θα εξακολουθούν να είναι διαθέσιμοι μαζί με τα κλειδιά πρόσβασης."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Επιλέξτε πού θα αποθηκεύονται τα <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Επιλέξτε ένα πρόγραμμα διαχείρισης κωδικών πρόσβασης για να αποθηκεύσετε τα στοιχεία σας και να συνδεθείτε πιο γρήγορα την επόμενη φορά."</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Δημιουργία κλειδιού πρόσβασης για <xliff:g id="APPNAME">%1$s</xliff:g>;"</string> diff --git a/packages/CredentialManager/res/values-es-rUS/strings.xml b/packages/CredentialManager/res/values-es-rUS/strings.xml index 5ea787f5f574..c096d1360c89 100644 --- a/packages/CredentialManager/res/values-es-rUS/strings.xml +++ b/packages/CredentialManager/res/values-es-rUS/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Cancelar"</string> <string name="string_continue" msgid="1346732695941131882">"Continuar"</string> <string name="string_more_options" msgid="7990658711962795124">"Más opciones"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Más información"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Más seguridad con llaves de acceso"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Con las llaves de acceso, no es necesario crear ni recordar contraseñas complejas"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Las llaves de acceso son claves digitales encriptadas que puedes crear usando tu huella dactilar, rostro o bloqueo de pantalla"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Se guardan en un administrador de contraseñas para que puedas acceder en otros dispositivos"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Más información sobre las llaves de acceso"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Tecnología sin contraseñas"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Las llaves de acceso permiten acceder sin depender de contraseñas. Solo tienes que usar tu huella dactilar, reconocimiento facial, PIN o patrón de deslizamiento para verificar tu identidad y crear una clave de acceso."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Criptografía de claves públicas"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Basadas en la Alianza FIDO (Google, Apple, Microsoft, etc.) y en estándares del W3C, las llaves de acceso usan pares de claves criptográficas. A diferencia de la cadena de caracteres de las contraseñas, para una app o sitio web se crean claves privadas y públicas. La clave privada se guarda en tu dispositivo/administrador de contraseñas, y confirma tu identidad. La clave pública se comparte con el servidor de la app o sitio web. Las claves adecuadas te permiten registrarte y acceder al instante."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Mayor seguridad para las cuentas"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Cada llave está vinculada exclusivamente con el sitio web o la app para la que fue creada, por lo que nunca podrás acceder por error a una app o sitio web fraudulentos. Además, como los servidores solo guardan claves públicas, hackearlas es mucho más difícil."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Transición fluida"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"A medida que avanzamos hacia un futuro sin contraseñas, estas seguirán estando disponibles junto a las llaves de acceso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Elige dónde guardar tus <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un administrador de contraseñas para guardar tu información y acceder más rápido la próxima vez"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"¿Quieres crear una llave de acceso para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-es/strings.xml b/packages/CredentialManager/res/values-es/strings.xml index c685bc2558aa..c6e67cf5dc04 100644 --- a/packages/CredentialManager/res/values-es/strings.xml +++ b/packages/CredentialManager/res/values-es/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Cancelar"</string> <string name="string_continue" msgid="1346732695941131882">"Continuar"</string> <string name="string_more_options" msgid="7990658711962795124">"Más opciones"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Más información"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Más seguridad con las llaves de acceso"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Con las llaves de acceso, no tienes que crear ni recordar contraseñas complicadas"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Las llaves de acceso son claves digitales cifradas que puedes crear con tu huella digital, cara o bloqueo de pantalla"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Se guardan en un gestor de contraseñas para que puedas iniciar sesión en otros dispositivos"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Más información sobre llaves de acceso"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Tecnología sin contraseñas"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Las llaves de acceso te permiten iniciar sesión sin necesidad de contraseñas. Solo necesitas usar la huella digital, el reconocimiento facial, el PIN o patrón para verificar tu identidad y crear una llave de acceso."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Criptografía de claves públicas"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Las llaves de acceso usan pares de claves criptográficas basándose en normativas de W3C y FIDO Alliance (que incluye Google, Apple, Microsoft y más). A diferencia del nombre de usuario y la cadena de caracteres que utilizamos en las contraseñas, un par de claves pública y privada se crea para una aplicación o sitio web. La clave privada se almacena con seguridad en tu dispositivo o gestor de contraseñas y confirma tu identidad. La clave pública se comparte con el servidor de la aplicación o el sitio web. Con las correspondientes llaves, puedes registrarte e iniciar sesión de forma instantánea."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Seguridad de las cuentas mejorada"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Cada llave está vinculada exclusivamente con la aplicación o sitio web para los que se crearon, por lo que nunca puedes iniciar sesión en una aplicación o sitio web fraudulentos por error. Además, dado que los servidores solo mantienen claves públicas, es muy difícil que las pirateen."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Transición fluida"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Aunque nos dirigimos hacia un mundo sin contraseñas, estas seguirán estando disponibles junto con las llaves de acceso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Elige dónde guardar tus <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un gestor de contraseñas para guardar tu información e iniciar sesión más rápido la próxima vez"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"¿Crear llave de acceso para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-et/strings.xml b/packages/CredentialManager/res/values-et/strings.xml index 30a823df9805..875460dd8f8c 100644 --- a/packages/CredentialManager/res/values-et/strings.xml +++ b/packages/CredentialManager/res/values-et/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Tühista"</string> <string name="string_continue" msgid="1346732695941131882">"Jätka"</string> <string name="string_more_options" msgid="7990658711962795124">"Rohkem valikuid"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Lisateave"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Pääsuvõtmed suurendavad turvalisust"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Pääsuvõtmetega ei pea te looma ega meelde jätma keerukaid paroole"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Pääsuvõtmed on digitaalsed krüpteeritud võtmed, mille loote sõrmejälje, näo või ekraanilukuga"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Need salvestatakse paroolihaldurisse, et saaksite teistes seadmetes sisse logida"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Rohkem pääsuvõtmete kohta"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Paroolivaba tehnoloogia"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Pääsuvõtmed võimaldavad teil sisse logida ilma paroole kasutamata. Peate vaid kasutama oma sõrmejälge, näotuvastust, PIN-koodi või pühkimismustrit, et oma isik kinnitada ja pääsuvõti luua."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Avaliku võtme krüptograafia"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Pääsuvõtmed kasutavad FIDO Alliance\'i (hõlmab Google\'it, Apple\'it, Microsofti jt) ja W3C standardite põhjal krüptograafilisi võtmepaare. Erinevalt paroolide puhul kasutatavast kasutajanimest ja tähemärkide stringist luuakse rakenduse või veebisaidi jaoks privaatne-avalik võtmepaar. Privaatne võti salvestatakse turvaliselt seadmesse või paroolihaldurisse ja see kinnitab teie isiku. Avalikku võtit jagatakse rakenduse või veebisaidi serveriga. Õigete võtmete abil saate kohe registreeruda ja sisse logida."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Konto täiustatud turvalisus"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Iga võti on lingitud vaid rakenduse või veebisaidiga, mille jaoks see loodi, seega ei saa te petturlikku rakendusse või veebisaidile kunagi kogemata sisse logida. Ja kuna serverid säilitavad vaid avalikke võtmeid, on häkkimine palju keerulisem."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Sujuv üleminek"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Liikudes paroolivaba tuleviku poole, jäävad paroolid pääsuvõtmete kõrval siiski kättesaadavaks."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Valige, kuhu soovite oma <xliff:g id="CREATETYPES">%1$s</xliff:g> salvestada"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Valige paroolihaldur, et salvestada oma teave ja järgmisel korral kiiremini sisse logida"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Kas luua rakenduse <xliff:g id="APPNAME">%1$s</xliff:g> jaoks pääsuvõti?"</string> diff --git a/packages/CredentialManager/res/values-eu/strings.xml b/packages/CredentialManager/res/values-eu/strings.xml index 0ca9df7df3d2..a037d786708d 100644 --- a/packages/CredentialManager/res/values-eu/strings.xml +++ b/packages/CredentialManager/res/values-eu/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Utzi"</string> <string name="string_continue" msgid="1346732695941131882">"Egin aurrera"</string> <string name="string_more_options" msgid="7990658711962795124">"Aukera gehiago"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Lortu informazio gehiago"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Sarbide-gako seguruagoak"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Sarbide-gakoei esker, ez duzu pasahitz konplexurik sortu edo gogoratu beharrik"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Hatz-marka, aurpegia edo pantailaren blokeoa erabilita sortzen dituzun giltza digital enkriptatuak dira sarbide-gakoak"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Pasahitz-kudeatzaile batean gordetzen dira, beste gailu batzuen bidez saioa hasi ahal izateko"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Sarbide-gakoei buruzko informazio gehiago"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Pasahitzik gabeko teknologia"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Sarbide-gakoekin, pasahitzik erabili behar gabe has dezakezu saioa. Hatz-marka, aurpegi-hautematea, PINa edo desblokeatzeko eredua baino ez duzu erabili behar zure identitatea egiaztatu, eta sarbide-gako bat sortzeko."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Gako publikoen kriptografia"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO itunean (Google, Apple, Microsoft eta beste enpresa batzuk daude sartuta) eta W3C-ren arauetan oinarritzen dira sarbide-gakoak, eta giltza pare kriptografikoak erabiltzen dituzte. Pasahitzetarako erabiltzen diren erabiltzaile-izenak eta karaktere-kateak ez bezala, giltza pare bat sortzen da (bata pribatua, eta bestea publikoa) aplikazio edo webgune bakoitzerako. Gako pribatua gailuan edo pasahitz-kudeatzailean gordetzen da modu seguruan, eta zure identitatea berresteko balio du. Gako publikoa, aldiz, aplikazioaren edo webgunearen zerbitzariarekin partekatzen da. Aplikazio edo webgune bakoitzari dagokion giltzarekin, berehala erregistra zaitezke, bai eta saioa hasi ere."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Kontuaren segurtasun areagotua"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Gako bakoitza harekin batera erabili behar den aplikazioarekin edo webgunearekin soilik lotzen da. Hala, ezingo duzu inoiz hasi saioa nahi gabe iruzurrezko aplikazio edo webgune batean. Gainera, zerbitzarietan gako publikoak soilik gordetzen direnez, askoz zailagoa da sarbide-gakoak hackeatzea."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Etenik gabeko trantsizioa"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Pasahitzik gabeko etorkizun baterantz goazen arren, pasahitzek sarbide-gakoen bizikide izaten jarraituko dute."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Aukeratu non gorde <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Hautatu informazioa gordetzeko pasahitz-kudeatzaile bat eta hasi saioa bizkorrago hurrengoan"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> atzitzeko sarbide-gako bat sortu nahi duzu?"</string> diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml index 47325b51114d..c83302411869 100644 --- a/packages/CredentialManager/res/values-fa/strings.xml +++ b/packages/CredentialManager/res/values-fa/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"لغو"</string> <string name="string_continue" msgid="1346732695941131882">"ادامه"</string> <string name="string_more_options" msgid="7990658711962795124">"گزینههای بیشتر"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"بیشتر بدانید"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"فضایی ایمنتر با گذرکلید"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"با گذرکلیدها، لازم نیست گذرواژه پیچیدهای بسازید یا آن را بهخاطر بسپارید"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"گذرکلیدها کلیدهای دیجیتالی رمزگذاریشدهای هستند که بااستفاده از اثر انگشت، چهره، یا قفل صفحه ایجاد میکنید"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"گذرکلیدها در «مدیر گذرواژه» ذخیره میشود تا بتوانید در دستگاههای دیگر به سیستم وارد شوید"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"اطلاعات بیشتر درباره گذرکلیدها"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"فناوری بدون گذرواژه"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"گذرکلیدها به شما اجازه میدهند بدون اتکا به گذرواژه به سیستم وارد شوید. برای بهتأیید رساندن هویت خود و ایجاد گذرکلید، کافی است از اثر انگشت، تشخیص چهره، پین، یا الگوی کشیدنی استفاده کنید."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"رمزنگاری کلید عمومی"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"براساس «اتحاد FIDO» (که شامل Google، Apple، Microsoft، و غیره میشود) و استانداردهای W3C، گذرکلیدها از جفت کلیدهای رمزنگاریشده استفاده میکنند. برخلاف نام کاربری و رشته نویسههایی که برای گذرواژهها استفاده میکنیم، یک جفت کلید خصوصی-عمومی برای برنامه یا وبسایت ایجاد میشود. کلید خصوصی بهطور امن در دستگاه یا مدیر گذرواژه شما ذخیره میشود و هویت شما را تأیید میکند. کلید عمومی با سرور وبسایت یا برنامه همرسانی میشود. با کلیدهای مربوطه میتوانید بیدرنگ ثبتنام کنید و به سیستم وارد شوید."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"بهبود امنیت حساب"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"هر کلید با برنامه یا وبسایتی که برای آن ایجاد شده است پیوند انحصاری دارد، بنابراین هرگز نمیتوانید بهاشتباه به سیستم برنامه یا وبسایتی جعلی وارد شوید. بهعلاوه، با سرورهایی که فقط کلیدهای عمومی را نگه میدارند رخنهگری بسیار سختتر است."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"انتقال یکپارچه"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"با اینکه بهسوی آیندهای بدون گذرواژه حرکت میکنیم، گذرواژهها همچنان در کنار گذرکلیدها دردسترس خواهند بود."</string> <string name="choose_provider_title" msgid="8870795677024868108">"جایی را برای ذخیره کردن <xliff:g id="CREATETYPES">%1$s</xliff:g> انتخاب کنید"</string> <string name="choose_provider_body" msgid="4967074531845147434">"مدیر گذرواژهای انتخاب کنید تا اطلاعاتتان ذخیره شود و دفعه بعدی سریعتر به سیستم وارد شوید"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"برای <xliff:g id="APPNAME">%1$s</xliff:g> گذرکلید ایجاد شود؟"</string> diff --git a/packages/CredentialManager/res/values-fi/strings.xml b/packages/CredentialManager/res/values-fi/strings.xml index 6dff90938239..08dd73975d4f 100644 --- a/packages/CredentialManager/res/values-fi/strings.xml +++ b/packages/CredentialManager/res/values-fi/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Peru"</string> <string name="string_continue" msgid="1346732695941131882">"Jatka"</string> <string name="string_more_options" msgid="7990658711962795124">"Lisäasetukset"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Lue lisää"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Turvallisuutta avainkoodeilla"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Kun käytät avainkoodeja, sinun ei tarvitse luoda tai muistaa monimutkaisia salasanoja"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Avainkoodit ovat salattuja digitaalisia avaimia, joita voit luoda sormenjäljen, kasvojen tai näytön lukituksen avulla"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Ne tallennetaan salasanojen ylläpito-ohjelmaan, jotta voit kirjautua sisään muilla laitteilla"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Lisätietoa avainkoodeista"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Salasanaton teknologia"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Avainkoodien avulla voit kirjautua sisään ilman salasanaa. Voit vahvistaa henkilöllisyytesi ja luoda avainkoodin sormenjäljen, kasvojentunnistuksen, PIN-koodin tai pyyhkäisykuvion avulla."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Julkisen avaimen salaus"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliancen (johon kuuluvat Google, Apple, Microsoft ja muita) ja W3C:n standardien mukaan avainkoodit käyttävät salausavainpareja. Käyttäjätunnuksen ja salasanan sijaan sovellusta tai sivustoa varten luodaan pari, jossa on yksityinen ja julkinen avain. Yksityinen avain tallennetaan suojatusti laitteelle tai Salasanoihin, ja se vahvistaa henkilöllisyytesi. Julkinen avain jaetaan sovelluksen tai sivuston palvelimelle. Yhteensopivalla avainparilla voit rekisteröityä ja kirjautua sisään heti."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Parempi tilin tietoturva"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Kukin avain yhdistetään vain sovellukseen tai sivustoon, jota varten se on luotu, joten et voi koskaan kirjautua vilpilliseen sovellukseen tai sivustolle vahingossa. Lisäksi palvelimet säilyttävät vain julkisia avaimia, mikä tekee hakkeroinnista paljon vaikeampaa."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Saumaton siirtymä"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Kehitys kulkee kohti salasanatonta tulevaisuutta, mutta salasanat ovat edelleen käytettävissä avainkoodien ohella."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Valitse, minne <xliff:g id="CREATETYPES">%1$s</xliff:g> tallennetaan"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Valitse salasanojen ylläpitotyökalu, niin voit tallentaa tietosi ja kirjautua ensi kerralla nopeammin sisään"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Luodaanko avainkoodi (<xliff:g id="APPNAME">%1$s</xliff:g>)?"</string> diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml index c5011781e84e..445284d150d0 100644 --- a/packages/CredentialManager/res/values-fr-rCA/strings.xml +++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Annuler"</string> <string name="string_continue" msgid="1346732695941131882">"Continuer"</string> <string name="string_more_options" msgid="7990658711962795124">"Autres options"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"En savoir plus"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Une sécurité accrue grâce aux clés d\'accès"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Avec les clés d\'accès, nul besoin de créer ou de mémoriser des mots de passe complexes"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Les clés d\'accès sont des clés numériques chiffrées que vous créez en utilisant votre empreinte digitale, votre visage ou le verrouillage de votre écran"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Ils sont enregistrés dans un gestionnaire de mots de passe pour vous permettre de vous connecter sur d\'autres appareils"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"En savoir plus sur les clés d\'accès"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Technologie sans mot de passe"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Les clés d\'accès vous permettent de vous connecter sans utiliser de mots de passe. Il vous suffit d\'utiliser votre empreinte digitale, la reconnaissance faciale, un NIP ou un schéma de balayage pour vérifier votre identité et créer un mot de passe."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Cryptographie des clés publiques"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Selon les normes de l\'Alliance FIDO (y compris Google, Apple, Microsoft et plus) et du W3C, les clés d\'accès utilisent des biclés cryptographiques. Contrairement au nom d\'utilisateur et à la chaîne de caractères que nous utilisons pour les mots de passe, une biclé privée-publique est créée pour une appli ou un site Web. La clé privée est stockée en toute sécurité sur votre appareil ou votre gestionnaire de mots de passe et confirme votre identité. La clé publique est partagée avec le serveur de l\'appli ou du site Web. Avec les clés correspondantes, vous pouvez vous inscrire et vous connecter instantanément."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Sécurité accrue du compte"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Chaque clé est exclusivement liée à l\'application ou au site Web pour lequel elle a été créée, de sorte que vous ne pourrez jamais vous connecter par erreur à une application ou un site Web frauduleux. En outre, comme les serveurs ne conservent que les clés publiques, le piratage informatique est beaucoup plus difficile."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Transition fluide"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"À mesure que nous nous dirigeons vers un avenir sans mot de passe, les mots de passe seront toujours utilisés parallèlement aux clés d\'accès."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choisir où sauvegarder vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Sélectionnez un gestionnaire de mots de passe pour enregistrer vos renseignements et vous connecter plus rapidement la prochaine fois"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Créer une clé d\'accès pour <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-fr/strings.xml b/packages/CredentialManager/res/values-fr/strings.xml index 05a060107794..cc39214210c6 100644 --- a/packages/CredentialManager/res/values-fr/strings.xml +++ b/packages/CredentialManager/res/values-fr/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Annuler"</string> <string name="string_continue" msgid="1346732695941131882">"Continuer"</string> <string name="string_more_options" msgid="7990658711962795124">"Autres options"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"En savoir plus"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Sécurité renforcée grâce aux clés d\'accès"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Avec les clés d\'accès, plus besoin de créer ni de mémoriser des mots de passe complexes"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Les clés d\'accès sont des clés numériques chiffrées que vous créez à l\'aide de votre empreinte digitale, de votre visage ou du verrouillage de l\'écran"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Elles sont enregistrées dans un gestionnaire de mots de passe pour que vous puissiez vous connecter sur d\'autres appareils"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"En savoir plus sur les clés d\'accès"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Une technologie sans mot de passe"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Les clés d\'accès vous permettent de vous connecter sans dépendre d\'un mot de passe. Il vous suffit d\'utiliser votre empreinte digitale, la reconnaissance faciale, un code ou un schéma afin de vérifier votre identité et de créer une clé d\'accès."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Cryptographie à clé publique"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Les clés d\'accès, basées sur standards W3C et FIDO Alliance (Google, Apple, Microsoft, etc.), utilisent paires de clés cryptographiques. Une paire est créée pour appli ou site, contrairement au nom d\'utilisateur et au mot de passe. La clé privée, stockée en sécurité sur votre appareil ou sur un gestionnaire de mots de passe, confirme votre identité. La clé publique est partagée avec le serveur de l\'appli ou du site. Avec des clés correspondantes, l\'inscription et la connexion sont instantanées."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Des comptes plus sécurisés"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Chaque clé est liée exclusivement à l\'appli ou au site Web pour lequel elle a été créée, pour que vous ne puissiez jamais vous connecter par erreur à une appli ou un site Web frauduleux. De plus, le piratage est bien plus difficile, car les serveurs ne conservent que les clés publiques."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Une transition fluide"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Nous nous dirigeons vers un futur sans mots de passe, mais ceux-ci resteront disponibles en plus des clés d\'accès."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choisissez où enregistrer vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Sélectionnez un gestionnaire de mots de passe pour enregistrer vos informations et vous connecter plus rapidement la prochaine fois"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Créer une clé d\'accès pour <xliff:g id="APPNAME">%1$s</xliff:g> ?"</string> diff --git a/packages/CredentialManager/res/values-hi/strings.xml b/packages/CredentialManager/res/values-hi/strings.xml index 6cc26c5633a1..71ee22bae89c 100644 --- a/packages/CredentialManager/res/values-hi/strings.xml +++ b/packages/CredentialManager/res/values-hi/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"रद्द करें"</string> <string name="string_continue" msgid="1346732695941131882">"जारी रखें"</string> <string name="string_more_options" msgid="7990658711962795124">"ज़्यादा विकल्प"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"ज़्यादा जानें"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"पासकी के साथ सुरक्षित रहें"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"पासकी होने पर, आपको जटिल पासवर्ड बनाने या याद रखने की ज़रूरत नहीं पड़ती"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"पासकी, एन्क्रिप्ट (सुरक्षित) की गई डिजिटल की होती हैं. इन्हें फ़िंगरप्रिंट, चेहरे या स्क्रीन लॉक का इस्तेमाल करके बनाया जाता है"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"पासकी को पासवर्ड मैनेजर में सेव किया जाता है, ताकि इनका इस्तेमाल करके आप अन्य डिवाइसों में साइन इन कर सकें"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"पासकी के बारे में ज़्यादा जानकारी"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"बिना पासवर्ड वाली टेक्नोलॉजी"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"पासकी की मदद से, पासवर्ड के बिना साइन इन किया जा सकता है. अपनी पहचान की पुष्टि करने और पासकी बनाने के लिए, फ़िंगरप्रिंट, चेहरे की पहचान करने की सुविधा, पिन या स्वाइप पैटर्न का इस्तेमाल करें."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"सार्वजनिक कुंजी क्रिप्टोग्राफ़ी"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"W3C के तय मानकों और FIDO एलायंस (Google, Apple, Microsoft वगैरह) के मुताबिक, पासकी में क्रिप्टोग्राफ़िक कुंजी के जोड़े इस्तेमाल किए जाते हैं. पासवर्ड में उपयोगकर्ता नाम और वर्णों की स्ट्रिंग इस्तेमाल की जाती है, जबकि ऐप्लिकेशन या वेबसाइट के लिए निजी-सार्वजनिक कुंजी का जोड़ा बनाया जाता है. निजी कुंजी, Password Manager या डिवाइस में सुरक्षित रहती है और आपकी पहचान की पुष्टि करती है. सार्वजनिक कुंजी, ऐप्लिकेशन या वेबसाइट सर्वर के साथ शेयर होती है. दोनों कुंजियों से, ऐप्लिकेशन या वेबसाइट पर तुरंत रजिस्टर और साइन इन किया जा सकता है."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"खाते की बेहतर सुरक्षा"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"हर कुंजी खास तौर पर उस ऐप्लिकेशन या वेबसाइट से लिंक होती है जिसके लिए उसे बनाया गया है. ऐसा इसलिए किया जाता है, ताकि कोई भी व्यक्ति धोखाधड़ी करने वाले ऐप्लिकेशन या वेबसाइट पर कभी भी गलती से साइन इन न करे. साथ ही, जिन सर्वर के पास सिर्फ़ सार्वजनिक कुंजी होती हैं उन्हें हैक करना काफ़ी मुश्किल होता है."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"अपने-आप होने वाला ट्रांज़िशन"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"आने वाले समय में टेक्नोलॉजी का इस्तेमाल बिना पासवर्ड के किया जा सकेगा. हालांकि, पासकी के साथ पासवर्ड भी इस्तेमाल किए जा सकेंगे."</string> <string name="choose_provider_title" msgid="8870795677024868108">"चुनें कि अपनी <xliff:g id="CREATETYPES">%1$s</xliff:g> कहां सेव करनी हैं"</string> <string name="choose_provider_body" msgid="4967074531845147434">"अपनी जानकारी सेव करने के लिए, कोई पासवर्ड मैनेजर चुनें और अगली बार तेज़ी से साइन इन करें"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"क्या आपको <xliff:g id="APPNAME">%1$s</xliff:g> के लिए पासकी बनानी है?"</string> diff --git a/packages/CredentialManager/res/values-hu/strings.xml b/packages/CredentialManager/res/values-hu/strings.xml index f9efc85b25e7..71e8cb3f0786 100644 --- a/packages/CredentialManager/res/values-hu/strings.xml +++ b/packages/CredentialManager/res/values-hu/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Mégse"</string> <string name="string_continue" msgid="1346732695941131882">"Folytatás"</string> <string name="string_more_options" msgid="7990658711962795124">"További lehetőségek"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"További információ"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Fokozott biztonság – azonosítókulccsal"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Azonosítókulcs birtokában nincs szükség összetett jelszavak létrehozására vagy megjegyzésére"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Az azonosítókulcsok olyan digitális kulcsok, amelyeket ujjlenyomata, arca vagy képernyőzár használatával hoz létre"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Az azonosítókulcsokat a rendszer jelszókezelőbe menti, így más eszközökbe is be tud jelentkezni"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Bővebben az azonosítókulcsokról"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Jelszó nélküli technológia"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Az azonosítókulcsok lehetővé teszik a jelszó nélküli bejelentkezést. Csak ujjlenyomatát, arcfelismerést, PIN-kódot vagy csúsztatási mintát kell használnia személyazonosságának igazolásához és azonosítókulcs létrehozásához."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"A nyilvános kulcs kriptográfiája"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Az azonosítókulcsok a FIDO Alliance (amely tagja a Google, az Apple és a Microsoft is) és a W3C szabványai alapján titkosítási kulcspárokat használnak. A felhasználónevekkel és a jelszavaknál megszokott karaktersorozattal ellentétben az adott apphoz vagy webhelyhez egy titkos és egy nyilvános kulcsból álló kulcspárt hoz létre a rendszer. A titkos kulcs tárolása biztonságosan történik az eszközén vagy a Jelszókezelőben, és ez a kulcs igazolja az Ön személyazonosságát. A nyilvános kulcsot osztja meg a rendszer az appal vagy a webhely szerverével. A kapcsolódó kulcsok révén Ön azonnal regisztrálhat és bejelentkezhet."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Nagyobb fiókbiztonság"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Minden kulcs kizárólag ahhoz az alkalmazáshoz vagy weboldalhoz kapcsolódik, amelyhez létrehozták, így soha nem fordulhat elő, hogy Ön tévedésből csalárd alkalmazásba vagy webhelyre jelentkezik be. Ráadásul – mivel a szerverek csak nyilvános kulcsokat tárolnak – a hackelés jóval nehezebb."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Zökkenőmentes átmenet"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Miközben a jelszó nélküli jövő felé haladunk, a jelszavak továbbra is rendelkezésre állnak majd az azonosítókulcsok mellett."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Válassza ki, hogy hova szeretné menteni <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Válasszon jelszókezelőt, hogy menthesse az adatait, és gyorsabban jelentkezhessen be a következő alkalommal."</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Létrehoz azonosítókulcsot a következőhöz: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-hy/strings.xml b/packages/CredentialManager/res/values-hy/strings.xml index 790ee8f54267..66aa664b108f 100644 --- a/packages/CredentialManager/res/values-hy/strings.xml +++ b/packages/CredentialManager/res/values-hy/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Չեղարկել"</string> <string name="string_continue" msgid="1346732695941131882">"Շարունակել"</string> <string name="string_more_options" msgid="7990658711962795124">"Այլ տարբերակներ"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Իմանալ ավելին"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Անցաբառերի հետ ավելի ապահով է"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Անցաբառերի շնորհիվ դուք բարդ գաղտնաբառեր ստեղծելու կամ հիշելու անհրաժեշտություն չեք ունենա"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Անցաբառերը գաղտնագրված թվային բանալիներ են, որոնք ստեղծվում են մատնահետքի, դեմքով ապակողպման կամ էկրանի կողպման օգտագործմամբ"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Դուք կարող եք մուտք գործել այլ սարքերում, քանի որ անցաբառերը պահվում են գաղտնաբառերի կառավարիչում"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Մանրամասն անցաբառերի մասին"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Գաղտնաբառեր չպահանջող տեխնոլոգիա"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Անցաբառերը ձեզ թույլ են տալիս մուտք գործել առանց գաղտնաբառերի։ Ձեզ պարզապես հարկավոր է օգտագործել ձեր մատնահետքը, դիմաճանաչումը, PIN կոդը կամ նախշը՝ ձեր ինքնությունը հաստատելու և անցաբառ ստեղծելու համար։"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Բաց բանալու կրիպտոգրաֆիա"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Ըստ FIDO դաշինքի (որը ներառում է Google-ը, Apple-ը, Microsoft-ը և այլ ընկերություններ) և W3C ստանդարտների՝ անցաբառերն օգտագործում են կրիպտոգրաֆիկ բանալիների զույգ։ Օգտանվան և գաղտնաբառի փոխարեն հավելվածի կամ կայքի համար մենք ստեղծում ենք բաց-փակ բանալիների զույգ։ Փակ բանալին ապահով պահվում է ձեր սարքում կամ գաղտնաբառերի կառավարիչում և հաստատում է ձեր ինքնությունը։ Բաց բանալին փոխանցվում է հավելվածի կամ կայքի սերվերին։ Համապատասխան բանալիների միջոցով կարող եք ակնթարթորեն գրանցվել և մուտք գործել։"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Հաշվի բարելավված անվտանգություն"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Յուրաքանչյուր բանալի բացառապես կապված է հավելվածի կամ կայքի հետ, որի համար այն ստեղծվել է, ուստի դուք երբեք չեք կարող սխալմամբ մուտք գործել կեղծ հավելված կամ կայք։ Բացի այդ՝ սերվերներում պահվում են միայն բաց բանալիներ, ինչը զգալիորեն դժվարացնում է կոտրումը։"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Սահուն անցում"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Թեև մենք առանց գաղտնաբառերի ապագայի ճանապարհին ենք, դրանք դեռ հասանելի կլինեն անցաբառերի հետ մեկտեղ։"</string> <string name="choose_provider_title" msgid="8870795677024868108">"Նշեք, թե որտեղ եք ուզում պահել ձեր <xliff:g id="CREATETYPES">%1$s</xliff:g>ը"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Ընտրեք գաղտնաբառերի կառավարիչ՝ ձեր տեղեկությունները պահելու և հաջորդ անգամ ավելի արագ մուտք գործելու համար"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Ստեղծե՞լ անցաբառ «<xliff:g id="APPNAME">%1$s</xliff:g>» հավելվածի համար"</string> diff --git a/packages/CredentialManager/res/values-in/strings.xml b/packages/CredentialManager/res/values-in/strings.xml index b3d42d005670..81713356a67a 100644 --- a/packages/CredentialManager/res/values-in/strings.xml +++ b/packages/CredentialManager/res/values-in/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Batal"</string> <string name="string_continue" msgid="1346732695941131882">"Lanjutkan"</string> <string name="string_more_options" msgid="7990658711962795124">"Opsi lainnya"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Pelajari lebih lanjut"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Lebih aman dengan kunci sandi"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Dengan kunci sandi, Anda tidak perlu membuat atau mengingat sandi yang rumit"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Kunci sandi adalah kunci digital terenkripsi yang Anda buat menggunakan sidik jari, wajah, atau kunci layar"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Kunci sandi disimpan ke pengelola sandi, sehingga Anda dapat login di perangkat lainnya"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Selengkapnya tentang kunci sandi"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Teknologi tanpa sandi"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Kunci sandi memungkinkan Anda login tanpa mengandalkan sandi. Anda hanya perlu menggunakan sidik jari, pengenalan wajah, PIN, atau pola geser untuk memverifikasi identitas Anda dan membuat kunci sandi."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kriptografi kunci publik"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Berdasarkan FIDO Alliance (yang mencakup Google, Apple, Microsoft, dan lainnya) dan standar W3C, kunci sandi menggunakan pasangan kunci kriptografis. Tidak seperti nama pengguna dan string karakter yang digunakan untuk sandi, pasangan kunci pribadi-publik dibuat untuk aplikasi atau situs. Kunci pribadi disimpan dengan aman di perangkat atau pengelola sandi dan mengonfirmasi identitas Anda. Kunci publik dibagikan ke server aplikasi atau situs. Dengan kunci yang sesuai, Anda dapat langsung mendaftar dan login."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Keamanan akun yang ditingkatkan"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Setiap kunci ditautkan secara eksklusif dengan aplikasi atau situs tempatnya dibuat, sehingga Anda tidak akan login ke aplikasi atau situs yang menipu secara tidak sengaja. Selain itu, peretasan lebih sulit dilakukan karena server hanya menyimpan kunci publik."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Transisi yang lancar"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Seiring kita menuju masa depan tanpa sandi, sandi akan tetap tersedia bersama kunci sandi."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Pilih tempat penyimpanan <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Pilih pengelola sandi untuk menyimpan info Anda dan login lebih cepat pada waktu berikutnya"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Buat kunci sandi untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-is/strings.xml b/packages/CredentialManager/res/values-is/strings.xml index d13c991e759d..2e5218cb02d4 100644 --- a/packages/CredentialManager/res/values-is/strings.xml +++ b/packages/CredentialManager/res/values-is/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Hætta við"</string> <string name="string_continue" msgid="1346732695941131882">"Áfram"</string> <string name="string_more_options" msgid="7990658711962795124">"Fleiri valkostir"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Nánar"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Aukið öryggi með aðgangslyklum"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Með aðgangslyklum þarftu hvorki að búa til né muna flókin aðgangsorð"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Aðgangslyklar eru dulkóðaðir stafrænir lyklar sem þú býrð til með fingrafarinu þínu, andliti eða skjálás."</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Þeir eru vistaðir í aðgangsorðastjórnun svo þú getir skráð þig inn í öðrum tækjum"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Nánar um aðgangslykla"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Aðgangsorðalaus tækni"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Aðgangslyklar gera þér kleift að skrá þig inn án þess að þurfa aðgangsorð. Þú þarft aðeins og nota fingrafarið, andlitsgreiningu, PIN-númer eða strokmynstur til að staðfesta hver þú ert og búa til aðgangslykil."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Dulritun opinberra lykla"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Aðgangslyklar nota dulkóðuð lyklasett byggð á stöðlum FIDO Alliance (sem nær til Google, Apple, Microsoft og fleiri) og W3C. Ólíkt notandanafni og stafarunu aðgangsorðs er lyklasett opinbers lykils og einkalykils búið til fyrir forrit eða vefsvæði. Einkalykillinn er vistaður á öruggan hátt í tækinu eða í aðgangsorðastjórnun og hann staðfestir auðkenni þitt. Opinbera lyklinum er deilt með þjóni forritsins eða vefsvæðisins. Samsvarandi lyklar tryggja tafarlausa skráningu og innskráningu."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Bætt reikningsöryggi"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Hver lykill er eingöngu tengdur forritinu eða vefsvæðinu sem hann var búinn til fyrir. Því er engin hætta á að þú skráir þig óvart inn á sviksamlegt forrit eða vefsvæði. Einnig er erfiðara að hakka þegar þjónar geyma aðeins opinbera lykla."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Snurðulaus skipti"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Við stefnum að framtíð án aðgangsorða en aðgangsorð verða áfram í boði samhliða aðgangslyklum."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Veldu hvar þú vilt vista <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Veldu aðgangsorðastjórnun til að vista upplýsingarnar og vera fljótari að skrá þig inn næst"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Viltu búa til aðgangslykil fyrir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-iw/strings.xml b/packages/CredentialManager/res/values-iw/strings.xml index 1637a946493b..2082e7ef07e7 100644 --- a/packages/CredentialManager/res/values-iw/strings.xml +++ b/packages/CredentialManager/res/values-iw/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"ביטול"</string> <string name="string_continue" msgid="1346732695941131882">"המשך"</string> <string name="string_more_options" msgid="7990658711962795124">"אפשרויות נוספות"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"מידע נוסף"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"בטוח יותר להשתמש במפתחות גישה"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"עם מפתחות הגישה לא צריך יותר ליצור או לזכור סיסמאות מורכבות"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"מפתחות גישה הם מפתחות דיגיטליים מוצפנים שניתן ליצור באמצעות טביעת האצבע, זיהוי הפנים או נעילת המסך"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"מפתחות הגישה והסיסמאות נשמרים במנהל הסיסמאות כך שניתן להיכנס לחשבון במכשירים אחרים"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"מידע נוסף על מפתחות גישה"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"טכנולוגיה ללא סיסמאות"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"מפתחות גישה מאפשרים לך להיכנס לחשבון בלי להסתמך על סיסמאות. עליך רק להשתמש בטביעת אצבע, בזיהוי הפנים, בקוד אימות או בקו ביטול נעילה כדי לאמת את זהותך וליצור מפתח גישה."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"קריפטוגרפיה של מפתח ציבורי"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"על סמך תקן FIDO (ארגון שכולל חברות כמו Google, Apple, Microsoft ועוד) ותקני W3C, מפתחות הגישה מבוססים על זוגות של מפתחות קריפטוגרפיים. בניגוד למחרוזות תווים ולשם המשתמש שבהם אנחנו משתמשים בסיסמאות, זוג מפתחות – מפתח פרטי ומפתח ציבורי – נוצר עבור אפליקציה או אתר. המפתח הפרטי מאוחסן בבטחה במכשיר או במנהל הסיסמאות שלך, ומאמת את זהותך. המפתח הציבורי משותף עם השרת של האפליקציה או האתר. בעזרת המפתחות התואמים אפשר מיד להירשם ולהיכנס לחשבון."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"אבטחה טובה יותר של החשבון"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"כל מפתח מקושר אך ורק לאפליקציה או לאתר שעבורם הוא נוצר, ולכן אף פעם אי אפשר להיכנס בטעות לחשבון באפליקציה או באתר שמטרתם להונות. בנוסף, כיוון שהשרתים שומרים רק מפתחות ציבוריים, קשה יותר לפרוץ לחשבון."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"מעבר חלק"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"אנחנו מתקדמים לעבר עתיד ללא סיסמאות, אבל עדיין אפשר יהיה להשתמש בסיסמאות וגם במפתחות גישה."</string> <string name="choose_provider_title" msgid="8870795677024868108">"בחירת המקום לשמירה של <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"אפשר לבחור באחד משירותי ניהול הסיסמאות כדי לשמור את הפרטים ולהיכנס לחשבון מהר יותר בפעם הבאה"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"ליצור מפתח גישה ל-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-kk/strings.xml b/packages/CredentialManager/res/values-kk/strings.xml index 88c3cb6da37a..7daf55281556 100644 --- a/packages/CredentialManager/res/values-kk/strings.xml +++ b/packages/CredentialManager/res/values-kk/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Бас тарту"</string> <string name="string_continue" msgid="1346732695941131882">"Жалғастыру"</string> <string name="string_more_options" msgid="7990658711962795124">"Басқа опциялар"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Толық ақпарат"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Кіру кілттерімен қауіпсіздеу"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Кіру кілттері бар кезде күрделі құпия сөздер жасаудың немесе оларды есте сақтаудың қажеті жоқ."</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Кіру кілттері — саусақ ізі, бет не экран құлпы арқылы жасалатын шифрланған цифрлық кілттер."</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Олар құпия сөз менеджеріне сақталады. Соның арқасында басқа құрылғылардан кіре аласыз."</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Кіру кілттері туралы қосымша ақпарат"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Құпия сөзсіз технология"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Кіру кілттері сізге құпия сөзге сүйенбей-ақ кіруге мүмкіндік береді. Жеке басыңызды растап, кіру кілтін жасау үшін тек саусақ ізі, бет тану функциясы, PIN коды немесе сырғыту өрнегі қажет."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Ашық кілт криптографиясы"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (оған Google, Apple, Microsoft, т.б. кіреді) және W3C стандарттары бойынша кіру кілттерінде криптографиялық кілт жұптары қолданылады. Құпия сөз үшін пайдаланушы аты мен таңбалар қолданылады, ал қолданба немесе веб-сайт үшін жеке-ашық кілт жұбы жасалады. Жеке кілт құрылғыңызда немесе құпия сөз менеджерінде қорғалып, сақталады. Ол жеке басыңызды растау үшін қажет. Ашық кілт қолданба немесе веб-сайт серверіне жіберіледі. Кілттер сәйкес келсе, бірден тіркеліп, аккаунтқа кіре аласыз."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Аккаунттың қосымша қауіпсіздігі"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Әрбір кілт өзі арнайы жасалған қолданбамен немесе веб-сайтпен ғана байланысты болады, сондықтан алаяқтар қолданбасына немесе веб-сайтына байқаусызда кіру мүмкін емес. Онымен қоса тек ашық кілттер сақталатын серверлер арқасында хакерлердің бұзып кіруі айтарлықтай қиындады."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Оңай ауысу"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Құпия сөзсіз болашақ жақын болғанына қарамастан, келешекте құпия сөздерді кіру кілттерімен қатар қолдана беруге болады."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> қайда сақталатынын таңдаңыз"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Мәліметіңізді сақтап, келесіде жылдам кіру үшін құпия сөз менеджерін таңдаңыз."</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> үшін кіру кілтін жасау керек пе?"</string> diff --git a/packages/CredentialManager/res/values-km/strings.xml b/packages/CredentialManager/res/values-km/strings.xml index f40ddfbc38c5..dce384d25663 100644 --- a/packages/CredentialManager/res/values-km/strings.xml +++ b/packages/CredentialManager/res/values-km/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"បោះបង់"</string> <string name="string_continue" msgid="1346732695941131882">"បន្ត"</string> <string name="string_more_options" msgid="7990658711962795124">"ជម្រើសច្រើនទៀត"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"ស្វែងយល់បន្ថែម"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"កាន់តែមានសុវត្ថិភាពដោយប្រើកូដសម្ងាត់"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"តាមរយៈកូដសម្ងាត់ អ្នកមិនចាំបាច់បង្កើត ឬចងចាំពាក្យសម្ងាត់ស្មុគស្មាញនោះទេ"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"កូដសម្ងាត់ត្រូវបានអ៊ីនគ្រីបឃីឌីជីថលដែលអ្នកបង្កើតដោយប្រើស្នាមម្រាមដៃ មុខ ឬចាក់សោអេក្រង់របស់អ្នក"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"កូដសម្ងាត់ត្រូវបានរក្សាទុកទៅក្នុងកម្មវិធីគ្រប់គ្រងពាក្យសម្ងាត់ ដូច្នេះអ្នកអាចចូលនៅលើឧបករណ៍ផ្សេងទៀត"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"ច្រើនទៀតអំពីកូដសម្ងាត់"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"បច្ចេកវិទ្យាគ្មានពាក្យសម្ងាត់"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"កូដសម្ងាត់អនុញ្ញាតឱ្យអ្នកចូលគណនីដោយមិនចាំបាច់ពឹងផ្អែកលើពាក្យសម្ងាត់។ អ្នកគ្រាន់តែត្រូវប្រើស្នាមម្រាមដៃ ការសម្គាល់មុខ កូដ PIN របស់អ្នក ឬអូសលំនាំដើម្បីផ្ទៀងផ្ទាត់អត្តសញ្ញាណរបស់អ្នក និងបង្កើតកូដសម្ងាត់។"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"គ្រីបតូសាស្ត្រកូដសាធារណៈ"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"ផ្អែកលើ FIDO Alliance (ដែលរួមបញ្ចូល Google, Apple, Microsoft និងច្រើនទៀត) និងស្តង់ដារ W3C កូដសម្ងាត់ប្រើគូសោគ្រីបតូសាស្ត្រ។ ខុសពីឈ្មោះអ្នកប្រើប្រាស់ និងតួអក្សរដែលយើងប្រើសម្រាប់ពាក្យសម្ងាត់ កូដសាធារណៈឯកជនមួយត្រូវបានបង្កើតឡើងសម្រាប់កម្មវិធី ឬគេហទំព័រមួយ។ កូដឯកជនត្រូវបានរក្សាទុកដោយសុវត្ថិភាពនៅលើឧបករណ៍របស់អ្នក ឬកម្មវិធីគ្រប់គ្រងពាក្យសម្ងាត់ ហើយវាបញ្ជាក់ពីអត្តសញ្ញាណរបស់អ្នក។ កូដសាធារណៈត្រូវបានចែករំលែកជាមួយម៉ាស៊ីនមេកម្មវិធី ឬគេហទំព័រ។ ជាមួយកូដដែលត្រូវគ្នា អ្នកអាចចុះឈ្មោះ និងចូលគណនីបានភ្លាមៗ។"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"សុវត្ថិភាពគណនីដែលប្រសើរឡើង"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"កូដនីមួយៗត្រូវបានភ្ជាប់ផ្តាច់មុខជាមួយកម្មវិធី ឬគេហទំព័រដែលវាត្រូវបានបង្កើតឡើង ដូច្នេះអ្នកមិនអាចចូលទៅក្នុងកម្មវិធី ឬគេហទំព័រក្លែងបន្លំដោយច្រឡំបានឡើយ។ លើសពីនេះ ជាមួយនឹងម៉ាស៊ីនមេដែលរក្សាតែកូដសាធារណៈប៉ុណ្ណោះ ការលួចចូលគឺពិបាកខ្លាំង។"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"ដំណើរផ្លាស់ប្ដូរយ៉ាងរលូន"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"នៅពេលដែលយើងឈានទៅរកអនាគតដែលគ្មានពាក្យសម្ងាត់ ពាក្យសម្ងាត់នៅតែអាចប្រើបានរួមជាមួយកូដសម្ងាត់។"</string> <string name="choose_provider_title" msgid="8870795677024868108">"ជ្រើសរើសកន្លែងដែលត្រូវរក្សាទុក<xliff:g id="CREATETYPES">%1$s</xliff:g>របស់អ្នក"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ជ្រើសរើសកម្មវិធីគ្រប់គ្រងពាក្យសម្ងាត់ ដើម្បីរក្សាទុកព័ត៌មានរបស់អ្នក និងចូលគណនីបានកាន់តែរហ័សនៅពេលលើកក្រោយ"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"បង្កើតកូដសម្ងាត់សម្រាប់ <xliff:g id="APPNAME">%1$s</xliff:g> ឬ?"</string> diff --git a/packages/CredentialManager/res/values-ko/strings.xml b/packages/CredentialManager/res/values-ko/strings.xml index beef76fb7d05..4af16b33117a 100644 --- a/packages/CredentialManager/res/values-ko/strings.xml +++ b/packages/CredentialManager/res/values-ko/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"취소"</string> <string name="string_continue" msgid="1346732695941131882">"계속"</string> <string name="string_more_options" msgid="7990658711962795124">"옵션 더보기"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"자세히 알아보기"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"패스키로 더 안전하게"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"패스키를 사용하면 복잡한 비밀번호를 만들거나 기억하지 않아도 됩니다."</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"패스키는 지문, 얼굴 또는 화면 잠금으로 생성하는 암호화된 디지털 키입니다."</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"비밀번호 관리자에 저장되므로 다른 기기에서 로그인할 수 있습니다."</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"패스키 자세히 알아보기"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"비밀번호 없는 기술"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"패스키를 이용하면 비밀번호에 의존하지 않고 로그인할 수 있습니다. 지문, 얼굴 인식, PIN 또는 스와이프 패턴만으로 본인 인증을 하고 패스키를 만들 수 있습니다."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"공개 키 암호화"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO 연합(Google, Apple, Microsoft 등 포함) 및 W3C 표준을 토대로 패스키는 암호화 키 쌍을 사용합니다. 사용자 이름과 비밀번호로 사용하는 문자열과는 달리 비공개-공개 키 쌍은 특정 앱 또는 웹사이트를 대상으로 생성됩니다. 비공개 키는 안전하게 기기 또는 비밀번호 관리자에 저장되며 사용자 본인 인증에 사용됩니다. 공개 키는 앱 또는 웹사이트 서버와 공유됩니다. 해당하는 키를 사용하면 즉시 등록하고 로그인할 수 있습니다."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"계정 보안 향상"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"각 키는 생성 시 대상으로 설정된 앱 또는 웹사이트와 단독으로 연결되어 있으므로 실수로 사기 앱 또는 웹사이트에 로그인할 일이 없습니다. 또한 서버에만 공개 키가 보관되므로 해킹이 더욱 까다롭습니다."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"원활한 이전"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"비밀번호 없는 미래로 나아가는 과정에서 비밀번호는 여전히 패스키와 함께 사용될 것입니다."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> 저장 위치 선택"</string> <string name="choose_provider_body" msgid="4967074531845147434">"정보를 저장해서 다음에 더 빠르게 로그인하려면 비밀번호 관리자를 선택하세요."</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>의 패스키를 만드시겠습니까?"</string> diff --git a/packages/CredentialManager/res/values-ky/strings.xml b/packages/CredentialManager/res/values-ky/strings.xml index 6afbb08d913a..ac15c5b1dd3f 100644 --- a/packages/CredentialManager/res/values-ky/strings.xml +++ b/packages/CredentialManager/res/values-ky/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Жок"</string> <string name="string_continue" msgid="1346732695941131882">"Улантуу"</string> <string name="string_more_options" msgid="7990658711962795124">"Башка варианттар"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Кеңири маалымат"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Мүмкүндүк алуу ачкычтары менен коопсузураак болот"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Мүмкүндүк алуу ачкычтары менен татаал сырсөздөрдү түзүп же эстеп калуунун кереги жок"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Мүмкүндүк алуу ачкычтары – манжаңыздын изи, жүзүңүз же экранды кулпулоо функциясы аркылуу түзгөн шифрленген санариптик ачкычтар"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Алар сырсөздөрдү башкаргычка сакталып, аккаунтуңузга башка түзмөктөрдөн кире аласыз"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Мүмкүндүк алуу ачкычтары тууралуу кеңири маалымат"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Сырсөзсүз технология"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Мүмкүндүк алуу ачкычтары аркылуу сырсөздөрсүз эле аккаунтуңузга кире аласыз. Ким экениңизди ырастоо жана мүмкүндүк алуу ачкычын түзүү үчүн жөн гана манжаңыздын изин, жүзүнөн таануу функциясын, PIN кодду же графикалык ачкычты колдонушуңуз керек болот."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Жалпыга ачык ачкыч менен криптография"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (Google, Apple, Microsoft ж.б.) жана W3C стандартына ылайык, мүмкүндүк алуу ачкычтары криптографиялык жуп ачкычтарды колдонот. Колдонмо же вебсайтта колдонуучунун аты жана сырсөз үчүн колдонулган символ сабы эмес, купуя жана жалпыга ачык жуп ачкыч түзүлөт. Купуя ачкыч түзмөктө же сырсөздөрдү башкаргычта коопсуз сакталып, өздүгүңүздү ырастоо үчүн колдонулат. Жалпыга ачык ачкыч колдонмо же вебсайттын серверине жөнөтүлөт. Туура келген ачкычтар аркылуу тез катталып жана кире аласыз."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Аккаунттун коопсуздугу жакшыртылды"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Ар бир ачкыч өзү арналган колдонмо же вебсайт менен гана байланыштырылгандыктан, эч качан шылуундардын колдонмолоруна же вебсайттарына жаңылыштык менен кирип албайсыз. Мындан тышкары, серверлерде жалпыга ачык ачкычтар гана сакталгандыктан, хакерлик кылуу кыйла кыйын."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Тез которулуу"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Сырсөзсүз келечекти көздөй баратсак да, аларды мүмкүндүк алуу ачкычтары менен бирге колдоно берүүгө болот."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> кайда сакталарын тандаңыз"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Маалыматыңызды сактоо жана кийинки жолу тезирээк кирүү үчүн сырсөздөрдү башкаргычты тандаңыз"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> үчүн мүмкүндүк алуу ачкычын түзөсүзбү?"</string> diff --git a/packages/CredentialManager/res/values-lo/strings.xml b/packages/CredentialManager/res/values-lo/strings.xml index b061db481ad8..30d9219f4dea 100644 --- a/packages/CredentialManager/res/values-lo/strings.xml +++ b/packages/CredentialManager/res/values-lo/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"ຍົກເລີກ"</string> <string name="string_continue" msgid="1346732695941131882">"ສືບຕໍ່"</string> <string name="string_more_options" msgid="7990658711962795124">"ຕົວເລືອກເພີ່ມເຕີມ"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"ສຶກສາເພີ່ມເຕີມ"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"ປອດໄພຂຶ້ນດ້ວຍກະແຈຜ່ານ"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"ໂດຍການໃຊ້ກະແຈຜ່ານ, ທ່ານບໍ່ຈຳເປັນຕ້ອງສ້າງ ຫຼື ຈື່ລະຫັດຜ່ານທີ່ຊັບຊ້ອນ"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"ກະແຈຜ່ານແມ່ນກະແຈດິຈິຕອນທີ່ໄດ້ຖືກເຂົ້າລະຫັດໄວ້ເຊິ່ງທ່ານສ້າງຂຶ້ນໂດຍໃຊ້ລາຍນິ້ວມື, ໃບໜ້າ ຫຼື ການລັອກໜ້າຈໍຂອງທ່ານ"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"ພວກມັນຖືກບັນທຶກໄວ້ຢູ່ໃນຕົວຈັດການລະຫັດຜ່ານ, ດັ່ງນັ້ນທ່ານສາມາດເຂົ້າສູ່ລະບົບຢູ່ອຸປະກອນອື່ນໆໄດ້"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"ເພີ່ມເຕີມກ່ຽວກັບກະແຈຜ່ານ"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"ເທັກໂນໂລຢີທີ່ບໍ່ມີລະຫັດຜ່ານ"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"ກະແຈຜ່ານເຮັດໃຫ້ທ່ານສາມາດເຂົ້າສູ່ລະບົບໄດ້ໂດຍບໍ່ຕ້ອງອີງອາໄສລະຫັດຜ່ານ. ທ່ານພຽງແຕ່ຕ້ອງໃຊ້ລາຍນິ້ວມືຂອງທ່ານ, ການຈຳແນກໃບໜ້າ, PIN ຫຼື ຮູບແບບການປັດເພື່ອຢັ້ງຢືນຕົວຕົນຂອງທ່ານ ແລະ ສ້າງກະແຈຜ່ານ."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"ການເຂົ້າລະຫັດກະແຈສາທາລະນະ"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"ໂດຍອ້າງອີງໃສ່ພັນທະມິດ FIDO (ເຊິ່ງຮວມມີ Google, Apple, Microsoft ແລະ ອື່ນໆ) ແລະ ມາດຕະຖານ W3C, ກະແຈຜ່ານຈະໃຊ້ຈັບຄູ່ກະແຈການເຂົ້າລະຫັດ. ບໍ່ຄືກັນກັບຊື່ຜູ້ໃຊ້ ແລະ ສະຕຣິງຕົວອັກສອນທີ່ພວກເຮົາໃຊ້ສຳລັບລະຫັດຜ່ານ, ກະແຈສາທາລະນະ-ສ່ວນຕົວແມ່ນຖືກສ້າງມາສຳລັບແອັບ ຫຼື ເວັບໄຊ. ກະແຈສ່ວນຕົວແມ່ນຖືກຈັດເກັບໄວ້ຢ່າງປອດໄພຢູ່ອຸປະກອນຂອງທ່ານ ຫຼື ຕົວຈັດການລະຫັດຜ່ານ ແລະ ມັນຢືນຢັນຕົວຕົນຂອງທ່ານ. ກະແຈສາທາລະນະແມ່ນແບ່ງປັນກັບແອັບ ຫຼື ເຊີບເວີເວັບໄຊ. ດ້ວຍກະແຈທີ່ກົງກັນ, ທ່ານຈະສາມາດລົງທະບຽນ ແລະ ເຂົ້າສູ່ລະບົບໄດ້ທັນທີ."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"ປັບປຸງຄວາມປອດໄພບັນຊີ"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"ກະແຈແຕ່ລະອັນແມ່ນລິ້ງເຈາະຈົງກັບແອັບ ຫຼື ເວັບໄຊທີ່ພວກມັນຖືກສ້າງໃຫ້, ດັ່ງນັ້ນທ່ານຈະບໍ່ສາມາດເຂົ້າສູ່ລະບົບຫາແອັບ ຫຼື ເວັບໄຊສໍ້ໂກງຕ່າງໆໂດຍບໍ່ໄດ້ຕັ້ງໃຈໄດ້. ນອກຈາກນັ້ນ, ເຊີບເວີຍັງມີການເກັບກະແຈສາທາລະນະໄວ້ເທົ່ານັ້ນ, ການແຮັກຈຶ່ງເປັນເລື່ອງຍາກຂຶ້ນຫຼາຍ."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"ການປ່ຽນຜ່ານທີ່ຕໍ່ເນື່ອງ"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"ໃນຂະນະທີ່ພວກເຮົາກ້າວໄປສູ່ອະນາຄົດທີ່ບໍ່ຕ້ອງໃຊ້ລະຫັດຜ່ານ, ລະຫັດຜ່ານຈະຍັງຄົງໃຊ້ໄດ້ຄວບຄູ່ໄປກັບລະຫັດຜ່ານ."</string> <string name="choose_provider_title" msgid="8870795677024868108">"ເລືອກບ່ອນທີ່ຈະບັນທຶກ <xliff:g id="CREATETYPES">%1$s</xliff:g> ຂອງທ່ານ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ເລືອກຕົວຈັດການລະຫັດຜ່ານເພື່ອບັນທຶກຂໍ້ມູນຂອງທ່ານ ແລະ ເຂົ້າສູ່ລະບົບໄວຂຶ້ນໃນເທື່ອຕໍ່ໄປ"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"ສ້າງກະແຈຜ່ານສຳລັບ <xliff:g id="APPNAME">%1$s</xliff:g> ບໍ?"</string> diff --git a/packages/CredentialManager/res/values-lv/strings.xml b/packages/CredentialManager/res/values-lv/strings.xml index 1ba1ef17a3ee..d18dd15ca3d7 100644 --- a/packages/CredentialManager/res/values-lv/strings.xml +++ b/packages/CredentialManager/res/values-lv/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Atcelt"</string> <string name="string_continue" msgid="1346732695941131882">"Turpināt"</string> <string name="string_more_options" msgid="7990658711962795124">"Citas opcijas"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Uzzināt vairāk"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Lielāka drošība ar piekļuves atslēgām"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Izmantojot piekļuves atslēgas, nav jāveido vai jāatceras sarežģītas paroles."</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Piekļuves atslēgas ir šifrētas digitālas atslēgas, ko varat izveidot, izmantojot pirksta nospiedumu, seju vai ekrāna bloķēšanas informāciju."</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Tās tiek saglabātas paroļu pārvaldniekā, lai jūs varētu pierakstīties citās ierīcēs."</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Vairāk par piekļuves atslēgām"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Bezparoles tehnoloģija"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Piekļuves atslēgas sniedz iespēju pierakstīties, nepaļaujoties uz parolēm. Jums tikai jāizmanto pirksta nospiedums, autorizācija pēc sejas, PIN vai atbloķēšanas kombinācija, lai apliecinātu savu identitāti un izveidotu piekļuves atslēgu."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Publisko atslēgu kriptogrāfija"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Saskaņā ar FIDO Alliance (Google, Apple, Microsoft u.c. organizācijas) un W3C standartiem piekļuves atslēgās tiek izmantoti kriptogrāfisko atslēgu pāri. Nav vajadzīgs lietotājvārds un parole, jo lietotnei vai vietnei tiek izveidots privātas un publiskas atslēgas pāris. Privātā atslēga tiek glabāta jūsu ierīcē vai paroļu pārvaldniekā un apliecina jūsu identitāti. Publiskā atslēga tiek kopīgota ar lietotni vai vietnes serveri. Ja atslēgas atbilst, varat nekavējoties reģistrēties un pierakstīties."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Uzlabota kontu drošība"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Katra atslēga ir saistīta tikai ar to lietotni vai vietni, kurai tā tika izveidota, tādēļ jūs nevarēsiet nejauši pierakstīties krāpnieciskā lietotnē vai vietnē. Turklāt uzlaušanu ievērojami sarežģī tas, ka serveros tiek glabātas tikai publiskās atslēgas."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Ērta pāreja"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Lai arī pamazām notiek pāreja uz darbu bez parolēm, tās joprojām būs pieejamas līdzās piekļuves atslēgām."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Izvēlieties, kur saglabāt savas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Lai saglabātu informāciju un nākamreiz varētu pierakstīties ātrāk, atlasiet paroļu pārvaldnieku."</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vai izveidot piekļuves atslēgu lietotnei <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-mk/strings.xml b/packages/CredentialManager/res/values-mk/strings.xml index 1be7ca50c85d..a75dbc24631e 100644 --- a/packages/CredentialManager/res/values-mk/strings.xml +++ b/packages/CredentialManager/res/values-mk/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Откажи"</string> <string name="string_continue" msgid="1346732695941131882">"Продолжи"</string> <string name="string_more_options" msgid="7990658711962795124">"Повеќе опции"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Дознајте повеќе"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Побезбедно со криптографски клучеви"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Со криптографските клучеви нема потреба да создавате или да помните сложени лозинки"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Криптографските клучеви се шифрирани дигитални клучеви што ги создавате со вашиот отпечаток, лик или заклучување екран"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Се зачувуваат во управник со лозинки за да може да се најавувате на други уреди"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Повеќе за криптографските клучеви"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Технологија без лозинки"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Криптографските клучеви дозволуваат да се најавувате без да се потпирате на лозинки. Треба само да користите отпечаток, препознавање лик, PIN или шема на повлекување за да го потврдите идентитетот и да создадете криптографски клуч."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Криптографија за јавни клучеви"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Според FIDO Alliance (во која членуваат Google, Apple, Microsoft и др.) и W3C-стандардите, криптографските клучеви користат криптографски парови на клучеви. За разлика од корисничките имиња и знаците што ги користиме за лозинки, се создава приватно-јавен пар клучеви за апликација или сајт. Приватниот клуч безбедно се чува на уредот или управникот со лозинки и го потврдува вашиот идентитет. Јавниот клуч се споделува со серверот на апликацијата или сајтот. Со соодветните клучеви, може инстантно да се регистрирате и најавувате."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Подобрена безбедност на сметката"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Секој клуч е поврзан само со апликацијата или веб-сајтот за кој бил создаден за да не може никогаш по грешка да се најавите на измамничка апликација или веб-сајт. Плус, кога серверите ги чуваат само јавните клучеви, хакирањето е многу потешко."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Беспрекорна транзиција"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Како што се движиме кон иднина без лозинки, лозинките сепак ќе бидат достапни покрај криптографските клучеви."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Изберете каде да ги зачувате вашите <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Изберете Password Manager за да ги зачувате вашите податоци и да се најавите побрзо следниот пат"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Да се создаде криптографски клуч за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-mn/strings.xml b/packages/CredentialManager/res/values-mn/strings.xml index 309a10b99640..2e4ed38909e1 100644 --- a/packages/CredentialManager/res/values-mn/strings.xml +++ b/packages/CredentialManager/res/values-mn/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Цуцлах"</string> <string name="string_continue" msgid="1346732695941131882">"Үргэлжлүүлэх"</string> <string name="string_more_options" msgid="7990658711962795124">"Бусад сонголт"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Нэмэлт мэдээлэл авах"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Passkey-тэй байхад илүү аюулгүй"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Passkey-н тусламжтай та нарийн төвөгтэй нууц үг үүсгэх эсвэл санах шаардлагагүй"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Passkey нь таны хурууны хээ, царай эсвэл дэлгэцийн түгжээгээ ашиглан үүсгэсэн шифрлэгдсэн дижитал түлхүүр юм"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Тэдгээрийг нууц үгний менежерт хадгалдаг бөгөөд ингэснээр та бусад төхөөрөмжид нэвтрэх боломжтой"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Passkey-н талаарх дэлгэрэнгүй"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Нууц үггүй технологи"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Passkey нь танд нууц үгэнд найдалгүйгээр нэвтрэх боломжийг олгодог. Та таниулбараа баталгаажуулах болон passkey үүсгэхийн тулд ердөө хурууны хээ, царай танилт, ПИН эсвэл шудрах хээгээ ашиглах шаардлагатай."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Нийтийн түлхүүрийн криптограф"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Холбоодын (Google, Apple, Microsoft ба бусад багтдаг) W3C стандартад тулгуурлан passkey нь криптограф түлхүүрийн хослолыг ашигладаг. Хэрэглэгчийн нэр, бидний нууц үгэнд ашигладаг тэмдэгтийн мөрөөс ялгаатай хувийн-нийтийн түлхүүрийн хослолыг апп эсвэл вебсайтад үүсгэдэг. Хувийн түлхүүрийг таны төхөөрөмж эсвэл нууц үгний менежерт аюулгүй хадгалдаг бөгөөд үүнийг таны таниулбарыг баталгаажуулахад ашигладаг. Нийтийн түлхүүрийг апп эсвэл вебсайтын сервертэй хуваалцдаг. Харгалзах түлхүүрээр та даруй бүртгүүлэх, нэвтрэх боломжтой."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Бүртгэлийн сайжруулсан аюулгүй байдал"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Түлхүүр тус бүрийг тэдгээрийг зориулж үүсгэсэн апп эсвэл вебсайттай нь тусгайлан холбодог бөгөөд ингэснээр та залилан мэхэлсэн апп эсвэл вебсайтад санамсаргүй байдлаар хэзээ ч нэвтрэхгүй. Түүнчлэн зөвхөн нийтийн түлхүүрийг хадгалж буй серверүүдийг хакердахад илүү хэцүү байдаг."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Саадгүй шилжилт"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Бид нууц үггүй ирээдүй рүү урагшлахын хэрээр нууц үг нь passkey-н хамтаар боломжтой хэвээр байх болно."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g>-г хаана хадгалахаа сонгоно уу"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Мэдээллээ хадгалж, дараагийн удаа илүү хурдан нэвтрэхийн тулд нууц үгний менежерийг сонгоно уу"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>-д passkey үүсгэх үү?"</string> diff --git a/packages/CredentialManager/res/values-mr/strings.xml b/packages/CredentialManager/res/values-mr/strings.xml index fffcf00b531d..8626790f6d29 100644 --- a/packages/CredentialManager/res/values-mr/strings.xml +++ b/packages/CredentialManager/res/values-mr/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"रद्द करा"</string> <string name="string_continue" msgid="1346732695941131882">"पुढे सुरू ठेवा"</string> <string name="string_more_options" msgid="7990658711962795124">"आणखी पर्याय"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"अधिक जाणून घ्या"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"पासकीसह आणखी सुरक्षित"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"पासकीसोबत, तुम्हाला क्लिष्ट पासवर्ड तयार करण्याची किंवा लक्षात ठेवण्याची आवश्यकता नाही"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"पासकी या तुम्ही तुमचे फिंगरप्रिंट, फेस किंवा स्क्रीन लॉक वापरून तयार करता अशा एंक्रिप्ट केलेल्या डिजिटल की आहेत"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"त्या Password Manager मध्ये सेव्ह केलेल्या असतात, जेणेकरून तुम्ही इतर डिव्हाइसवर साइन इन करू शकाल"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"पासकीबद्दल आणखी उपयुक्त माहिती"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"पासवर्ड न वापरणारे तंत्रज्ञान"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"पासवर्डवर अवलंबून न राहता, पासकी तुम्हाला साइन इन करण्याची अनुमती देतात. तुम्हाला तुमची ओळख पडताळणी करण्यासाठी आणि पासकी तयार करण्याकरिता, तुमचे फिंगरप्रिंट, फेस रेकग्निशन, पिन किंवा स्वाइप पॅटर्न वापरणे आवश्यक आहे."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"सार्वजनिक की क्रिप्टोग्राफी"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO अलायन्स (ज्यामध्ये Google, Apple, Microsoft, आणि आणखी बरेच समाविष्ट आहेत) आणि W3C स्टँडर्डवर आधारित, पासकी या क्रिप्टोग्राफिक की पेअर वापरतात. आपण पासवर्डसाठी वापरणारे वापरकर्ता नाव व वर्णांची स्ट्रिंगच्या उलट, खाजगी-सार्वजनिक की पेअर अॅप किंवा वेबसाइटसाठी तयार केली जाते. प्रायव्हेट की सुरक्षितरीत्या तुमच्या डिव्हाइस किंवा Password Manager वर स्टोअर केली जाते व तुमची ओळख पडताळणी करते. सार्वजनिक की ही अॅप किंवा वेबसाइट सर्व्हरसोबत शेअर केली जाते. संबंधित की सह, तुम्ही त्वरित नोंदणी व साइन इन करू शकता."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"सुधारित खाते सुरक्षा"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"प्रत्येक की ज्यांच्यासाठी बनवली आहे फक्त त्या अॅप किंवा वेबसाइटसोबत लिंक केलेली असते, ज्यमुळे तुम्ही कधीच कपटपूर्ण अॅप किंवा वेबसाइटवर चुकूनही साइन इन करणार नाही. तसेच, सर्व्हर फक्त सार्वजनिक की स्टोअर करत असल्यामुळे, हॅक करणे खूप अवघड आहे."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"अखंड संक्रमण"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"पासवर्ड न वापरणाऱ्या भविष्यात पुढे जाताना, पासवर्ड तरीही पासकीच्या बरोबरीने उपलब्ध असतील."</string> <string name="choose_provider_title" msgid="8870795677024868108">"तुमची <xliff:g id="CREATETYPES">%1$s</xliff:g> कुठे सेव्ह करायची ते निवडा"</string> <string name="choose_provider_body" msgid="4967074531845147434">"तुमची माहिती सेव्ह करण्यासाठी आणि पुढच्या वेळी जलद साइन इन करण्याकरिता Password Manager निवडा"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> साठी पासकी तयार करायची का?"</string> diff --git a/packages/CredentialManager/res/values-my/strings.xml b/packages/CredentialManager/res/values-my/strings.xml index d4afb281c20a..047f7380f742 100644 --- a/packages/CredentialManager/res/values-my/strings.xml +++ b/packages/CredentialManager/res/values-my/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"မလုပ်တော့"</string> <string name="string_continue" msgid="1346732695941131882">"ရှေ့ဆက်ရန်"</string> <string name="string_more_options" msgid="7990658711962795124">"နောက်ထပ်ရွေးစရာများ"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"ပိုမိုလေ့လာရန်"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"လျှို့ဝှက်ကီးများဖြင့် ပိုလုံခြုံသည်"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"လျှို့ဝှက်ကီးများဖြင့် ရှုပ်ထွေးသောစကားဝှက်များကို ပြုလုပ်ရန် (သို့) မှတ်မိရန် မလိုပါ"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"လျှို့ဝှက်ကီးများမှာ သင်၏လက်ဗွေ၊ မျက်နှာ (သို့) ဖန်သားပြင်လော့ခ်သုံး၍ ပြုလုပ်ထားသော အသွင်ဝှက်ထားသည့် ဒစ်ဂျစ်တယ်ကီးများ ဖြစ်သည်"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"၎င်းတို့ကို စကားဝှက်မန်နေဂျာတွင် သိမ်းသဖြင့် အခြားစက်များတွင် လက်မှတ်ထိုးဝင်နိုင်ပါသည်"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"လျှို့ဝှက်ကီးများအကြောင်း ပိုပြရန်"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"စကားဝှက်မသုံးခြင်း နည်းပညာ"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"လျှို့ဝှက်ကီးများဖြင့် သင်သည် စကားဝှက်အပေါ် အမှီမပြုဘဲ လက်မှတ်ထိုးဝင်နိုင်သည်။ သင့်အထောက်အထားကို အတည်ပြုပြီး လျှို့ဝှက်ကီးလုပ်ရန် သင်၏ လက်ဗွေ၊ မျက်နှာသိရှိမှု၊ ပင်နံပါတ် (သို့) ပွတ်ဆွဲပုံဖော်ခြင်းကို အသုံးပြုရန်သာ လိုသည်။"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"အများသုံးကီး ကုဒ်ထည့်သွင်းခြင်း"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"လျှို့ဝှက်ကီးများသည် FIDO Alliance (Google၊ Apple၊ Microsoft စသည်) နှင့် W3C စံညွှန်းများပေါ် အခြေခံ၍ ကုဒ်ထည့်သွင်းသည့် ကီးအတွဲများသုံးသည်။ အသုံးပြုသူအမည်၊ စကားဝှက်အတွက် အက္ခရာတွဲများနှင့်မတူသည်မှာ အက်ပ် (သို့) ဝဘ်ဆိုက်တစ်ခုအတွက် သီးသန့်-အများသုံး ကီးအတွဲ ပြုလုပ်ခြင်းဖြစ်သည်။ သီးသန့်ကီးကို သင့်စက် (သို့) စကားဝှက်မန်နေဂျာတွင် လုံခြုံစွာသိမ်းပြီး ၎င်းက သင့်အထောက်အထားကို အတည်ပြုသည်။ အများသုံးကီးကို အက်ပ် (သို့) ဝဘ်ဆိုက်ဆာဗာနှင့် မျှဝေသည်။ သက်ဆိုင်ရာကီးများသုံး၍ ချက်ချင်းမှတ်ပုံတင်ပြီး ဝင်နိုင်သည်။"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"ပိုကောင်းသော အကောင့်လုံခြုံရေး"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"ကီးတစ်ခုစီကို ၎င်းအတွက် ပြုလုပ်ထားသော အက်ပ် (သို့) ဝဘ်ဆိုက်နှင့် သီးသန့်လင့်ခ်ချိတ်ထားသဖြင့် လိမ်လည်သော အက်ပ် (သို့) ဝဘ်ဆိုက်သို့ မည်သည့်အခါတွင်မှ မှားယွင်း၍ လက်မှတ်ထိုးဝင်နိုင်မည်မဟုတ်ပါ။ ထို့အပြင် ဆာဗာသီးသန့် သိမ်းထားသော အများသုံးကီးများကို ဟက်လုပ်ရန် ပိုခက်ခဲသည်။"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"အလိုအလျောက် ကူးပြောင်းခြင်း"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"စကားဝှက်မသုံးခြင်း အနာဂတ်ဆီသို့ ရှေ့ဆက်ရာတွင် လျှို့ဝှက်ကီးများနှင့်အတူ စကားဝှက်များကို ဆက်လက်အသုံးပြုနိုင်ပါမည်။"</string> <string name="choose_provider_title" msgid="8870795677024868108">"သင်၏ <xliff:g id="CREATETYPES">%1$s</xliff:g> သိမ်းရန်နေရာ ရွေးခြင်း"</string> <string name="choose_provider_body" msgid="4967074531845147434">"သင့်အချက်အလက်သိမ်းပြီး နောက်တစ်ကြိမ်၌ ပိုမိုမြန်ဆန်စွာ လက်မှတ်ထိုးဝင်ရန် စကားဝှက်မန်နေဂျာကို ရွေးပါ"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> အတွက် လျှို့ဝှက်ကီးပြုလုပ်မလား။"</string> diff --git a/packages/CredentialManager/res/values-nb/strings.xml b/packages/CredentialManager/res/values-nb/strings.xml index 86270308c4e5..bee211e0157c 100644 --- a/packages/CredentialManager/res/values-nb/strings.xml +++ b/packages/CredentialManager/res/values-nb/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Avbryt"</string> <string name="string_continue" msgid="1346732695941131882">"Fortsett"</string> <string name="string_more_options" msgid="7990658711962795124">"Flere alternativer"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Finn ut mer"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Tryggere med tilgangsnøkler"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Med tilgangsnøkler trenger du ikke å lage eller huske kompliserte passord"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Tilgangsnøkler er krypterte digitale nøkler du oppretter med fingeravtrykket, ansiktet eller skjermlåsen"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"De lagres i et verktøy for passordlagring, slik at du kan logge på andre enheter"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Mer om tilgangsnøkler"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Passordfri teknologi"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Med tilgangsnøkler kan du logge på uten å bruke passord. Du trenger bare å bruke et fingeravtrykk, ansiktsgjenkjenning, en PIN-kode eller et sveipemønster for å bekrefte hvem du er, og lage en tilgangsnøkkel."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kryptografi for offentlige nøkler"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Tilgangsnøkler er basert på FIDO Alliance (med bl.a. Google, Apple og Microsoft) og W3C-standardene og bruker kryptografiske nøkkelpar. I stedet for brukernavn og strenger med tegn som brukes som passord, opprettes det et privat-offentlig nøkkelpar per app eller nettsted. Den private nøkkelen lagres trygt på enheten eller i passordlagringen og bekrefter hvem du er. Den offentlige nøkkelen deles med app- eller nettstedstjeneren. Med korresponderende nøkler kan du raskt registrere deg og logge på."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Forbedret kontosikkerhet"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Hver nøkkel er eksklusivt tilknyttet appen eller nettstedet den er laget for. Dermed kan du aldri logge på falske apper eller nettsteder ved et uhell. Og siden tjenerne bare har offentlige nøkler, blir det mye vanskeligere å hacke deg."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Sømløs overgang"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Vi går mot en fremtid uten passord, men passord fortsetter å være tilgjengelige ved siden av tilgangsnøkler."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Velg hvor du vil lagre <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Velg et verktøy for passordlagring for å lagre informasjonen din og logge på raskere neste gang"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vil du opprette en tilgangsnøkkel for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-ne/strings.xml b/packages/CredentialManager/res/values-ne/strings.xml index b8d63e138239..ce338221dca4 100644 --- a/packages/CredentialManager/res/values-ne/strings.xml +++ b/packages/CredentialManager/res/values-ne/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"रद्द गर्नुहोस्"</string> <string name="string_continue" msgid="1346732695941131882">"जारी राख्नुहोस्"</string> <string name="string_more_options" msgid="7990658711962795124">"थप विकल्पहरू"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"थप जान्नुहोस्"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"पासकीका सहायताले सुरक्षित रहनुहोस्"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"तपाईंले पासकी बनाउनुभयो भने तपाईंले जटिल पासवर्ड बनाउनु वा तिनलाई याद गरिराख्नु पर्दैन"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"पासकी भनेको तपाईंले आफ्नो फिंगरप्रिन्ट, अनुहार वा स्क्रिन लक प्रयोग गरेर बनाएको इन्क्रिप्ट गरिएको डिजिटल की हो"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"तपाईं अन्य डिभाइसहरूमा साइन इन गर्न सक्नुहोस् भन्नाका लागि तिनलाई पासवर्ड म्यानेजरमा सेभ गरिन्छन्"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"पासकीहरूका बारेमा थप जानकारी"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"पासवर्डरहित प्रविधि"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"तपाईं पासकीका सहायताले पासवर्ड नहालिकन साइन इन गर्न सक्नुहुन्छ। तपाईंले आफ्नो फिंगरप्रिन्ट, अनुहार पहिचान गर्ने सुविधा, PIN वा स्वाइप प्याटर्न प्रयोग गरी आफ्नो पहिचान पुष्टि गरेर एउटा पासकी बनाए पुग्छ।"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"सार्वजनिक कीको क्रिप्टोग्राफी"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (जसमा Google, Apple, Microsoft र अन्य कम्पनी सामेल छन्) र W3C ले तोकेका मापदण्डहरूका आधारमा पासकीमा क्रिप्टोग्राफिक जोडी की प्रयोग गरिएको छ। निजी-सार्वजनिक जोडी की कुनै एप वा वेबसाइटका लागि बनाइन्छ। यो जोडी की युजरनेम र हामीले पासवर्डमा प्रयोग गर्ने वर्णहरूको स्ट्रिङभन्दा फरक हुन्छ। निजी की तपाईंको डिभाइस वा पासवर्ड म्यानेजरमा सुरक्षित रूपमा राखिन्छ र यसले तपाईंको पहिचान पुष्टि गर्छ। सार्वजनिक की चाहिँ एप वा वेबसाइटको सर्भरसँग सेयर गरिन्छ। तपाईं यी की प्रयोग गरी तुरुन्तै दर्ता वा साइन इन गर्न सक्नुहुन्छ।"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"खाताको सुदृढ सुरक्षा"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"तपाईं कहिले पनि गल्तीले कुनै कपटपूर्ण एप वा वेबसाइटमा लग इन गर्न नसक्नुहोस् भन्नाका लागि हरेक की जुन एप वा वेबसाइटको लागि बनाइएको थियो त्यसलाई खास गरी सोही एप वा वेबसाइटसँग लिंक गरिन्छ। यसका साथै, सर्भरहरूले सार्वजनिक की मात्र राखिराख्ने भएकाले ह्याक गर्न झनै कठिन भएको छ।"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"निर्बाध ट्रान्जिसन"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"हामी पासवर्डरहित भविष्यतर्फ बढ्दै गर्दा पासकीका साथसाथै पासवर्ड पनि उपलब्ध हुने छ।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"तपाईं आफ्ना <xliff:g id="CREATETYPES">%1$s</xliff:g> कहाँ सेभ गर्न चाहनुहुन्छ भन्ने कुरा छनौट गर्नुहोस्"</string> <string name="choose_provider_body" msgid="4967074531845147434">"कुनै पासवर्ड म्यानेजरमा आफ्नो जानकारी सेभ गरी अर्को टपक अझ छिटो साइन एन गर्नुहोस्"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> को पासकी बनाउने हो?"</string> diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml index 6d8af5f00ab7..7e6d10af966a 100644 --- a/packages/CredentialManager/res/values-or/strings.xml +++ b/packages/CredentialManager/res/values-or/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"ବାତିଲ କରନ୍ତୁ"</string> <string name="string_continue" msgid="1346732695941131882">"ଜାରି ରଖନ୍ତୁ"</string> <string name="string_more_options" msgid="7990658711962795124">"ଅଧିକ ବିକଳ୍ପ"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"ଅଧିକ ଜାଣନ୍ତୁ"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"ପାସକୀ ସହ ଅଧିକ ସୁରକ୍ଷିତ"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"ପାସକୀଗୁଡ଼ିକ ସହ ଆପଣଙ୍କୁ ଜଟିଳ ପାସୱାର୍ଡଗୁଡ଼ିକ ତିଆରି କରିବା କିମ୍ବା ମନେରଖିବାର ଆବଶ୍ୟକତା ନାହିଁ"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"ପାସକୀଗୁଡ଼ିକ ହେଉଛି ଆପଣ ଆପଣଙ୍କ ଟିପଚିହ୍ନ, ଫେସ କିମ୍ବା ସ୍କ୍ରିନ ଲକ ବ୍ୟବହାର କରି ତିଆରି କରୁଥିବା ଏକକ୍ରିପ୍ଟ କରାଯାଇଥିବା ଡିଜିଟାଲ କୀ"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"ସେଗୁଡ଼ିକୁ ଏକ Password Managerରେ ସେଭ କରାଯାଏ, ଯାହା ଫଳରେ ଆପଣ ଅନ୍ୟ ଡିଭାଇସଗୁଡ଼ିକରେ ସାଇନ ଇନ କରିପାରିବେ"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"ପାସକୀଗୁଡ଼ିକ ବିଷୟରେ ଅଧିକ"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"ପାସୱାର୍ଡ ବିହୀନ ଟେକ୍ନୋଲୋଜି"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"ପାସକୀଗୁଡ଼ିକ, ପାସୱାର୍ଡ ଉପରେ ନିର୍ଭର ନକରି ସାଇନ ଇନ କରିବାକୁ ଆପଣଙ୍କୁ ଅନୁମତି ଦେଇଥାଏ। ଆପଣଙ୍କ ପରିଚୟ ଯାଞ୍ଚ କରି ଏକ ପାସକୀ ତିଆରି କରିବାକୁ ଆପଣଙ୍କୁ କେବଳ ଆପଣଙ୍କ ଟିପଚିହ୍ନ, ଫେସ ଚିହ୍ନଟକରଣ, PIN କିମ୍ବା ସ୍ୱାଇପ ପାଟର୍ନ ବ୍ୟବହାର କରିବାକୁ ହେବ।"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"ସାର୍ବଜନୀନ କୀ କ୍ରିପ୍ଟୋଗ୍ରାଫି"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (Google, Apple, Microsoft ଓ ଆହୁରି ଅନେକ କିଛି ଅନ୍ତର୍ଭୁକ୍ତ) ଓ W3C ଷ୍ଟାଣ୍ଡାର୍ଡ ଆଧାରରେ ପାସକୀଗୁଡ଼ିକ କ୍ରିପ୍ଟୋଗ୍ରାଫିକ କୀ ପେୟାର ବ୍ୟବହାର କରେ। ପାସୱାର୍ଡ ପାଇଁ ଆମେ ବ୍ୟବହାର କରୁଥିବା ୟୁଜରନେମ ଓ କେରେକ୍ଟରର ଷ୍ଟ୍ରିଂ ପରି ଏକ ଆପ ବା ୱେବସାଇଟ ପାଇଁ ଏକ ବ୍ୟକ୍ତିଗତ-ସାର୍ବଜନୀନ କୀ ପେୟାର ତିଆରି କରାଯାଇଛି। ପ୍ରାଇଭେଟ କୀ ଆପଣଙ୍କ ଡିଭାଇସ ବା ପାସୱାର୍ଡ ମେନେଜରରେ ସୁରକ୍ଷିତ ଭାବରେ ଷ୍ଟୋର କରାଯାଏ ଓ ଏହା ଆପଣଙ୍କ ପରିଚୟ ସୁନିଶ୍ଚିତ କରେ। ସାର୍ବଜନୀନ କୀ ଆପ ବା ୱେବସାଇଟ ସର୍ଭର ସହ ସେୟାର କରାଯାଏ। ସମ୍ବନ୍ଧିତ କୀ ସହ ଆପଣ ତୁରନ୍ତ ପଞ୍ଜିକରଣ କରି ସାଇନ ଇନ କରିପାରିବେ।"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"ଉନ୍ନତ ଆକାଉଣ୍ଟ ସୁରକ୍ଷା"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"ପ୍ରତ୍ୟେକ କୀ\'କୁ ସେହି ଆପ କିମ୍ବା ୱେବସାଇଟ ସହ ଏକ୍ସକ୍ଲୁସିଭ ଭାବେ ଲିଙ୍କ କରାଯାଏ ଯେଉଁଥିପାଇଁ ଏହାକୁ ତିଆରି କରାଯାଇଛି, ଫଳରେ ଆପଣ ଭୁଲବଶତଃ କୌଣସି ପ୍ରତାରଣାମୂଳକ ଆପ କିମ୍ବା ୱେବସାଇଟରେ କେବେ ବି ସାଇନ ଇନ କରିପାରିବେ ନାହିଁ। ଏହା ସହ, କେବଳ ସର୍ଭରଗୁଡ଼ିକ ସାର୍ବଜନୀନ କୀ ରଖୁଥିବା ଯୋଗୁଁ ଏହାକୁ ହେକ କରିବା ବହୁତ କଷ୍ଟକର।"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"ବାଧାରହିତ ଟ୍ରାଞ୍ଜିସନ"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"ଆମେ ଏକ ପାସୱାର୍ଡ ବିହୀନ ଭବିଷ୍ୟତ ଆଡ଼କୁ ମୁଭ କରୁଥିବା ଯୋଗୁଁ ଏବେ ବି ପାସକୀଗୁଡ଼ିକ ସହିତ ପାସୱାର୍ଡ ଉପଲବ୍ଧ ହେବ।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"ଆପଣଙ୍କ <xliff:g id="CREATETYPES">%1$s</xliff:g>କୁ କେଉଁଠାରେ ସେଭ କରିବେ ତାହା ବାଛନ୍ତୁ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ଆପଣଙ୍କ ସୂଚନା ସେଭ କରି ପରବର୍ତ୍ତୀ ସମୟରେ ଶୀଘ୍ର ସାଇନ ଇନ କରିବା ପାଇଁ ଏକ Password Manager ଚୟନ କରନ୍ତୁ"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> ପାଇଁ ପାସକୀ ତିଆରି କରିବେ?"</string> diff --git a/packages/CredentialManager/res/values-pa/strings.xml b/packages/CredentialManager/res/values-pa/strings.xml index c77130c2ba04..cbf199eec71c 100644 --- a/packages/CredentialManager/res/values-pa/strings.xml +++ b/packages/CredentialManager/res/values-pa/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"ਰੱਦ ਕਰੋ"</string> <string name="string_continue" msgid="1346732695941131882">"ਜਾਰੀ ਰੱਖੋ"</string> <string name="string_more_options" msgid="7990658711962795124">"ਹੋਰ ਵਿਕਲਪ"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"ਹੋਰ ਜਾਣੋ"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"ਪਾਸਕੀਆਂ ਨਾਲ ਸੁਰੱਖਿਅਤ"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"ਪਾਸਕੀਆਂ ਨਾਲ, ਤੁਹਾਨੂੰ ਜਟਿਲ ਪਾਸਵਰਡ ਬਣਾਉਣ ਜਾਂ ਯਾਦ ਰੱਖਣ ਦੀ ਲੋੜ ਨਹੀਂ ਹੁੰਦੀ"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"ਪਾਸਕੀਆਂ ਇਨਕ੍ਰਿਪਟਡ ਡਿਜੀਟਲ ਕੁੰਜੀਆਂ ਹੁੰਦੀਆਂ ਹਨ ਜੋ ਤੁਹਾਡੇ ਵੱਲੋਂ ਤੁਹਾਡੇ ਫਿੰਗਰਪ੍ਰਿੰਟ, ਚਿਹਰੇ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਬਣਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"ਉਨ੍ਹਾਂ ਨੂੰ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ \'ਤੇ ਰੱਖਿਅਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਤਾਂ ਜੋ ਤੁਸੀਂ ਹੋਰ ਡੀਵਾਈਸਾਂ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰ ਸਕੋ"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"ਪਾਸਕੀਆਂ ਬਾਰੇ ਹੋਰ ਜਾਣੋ"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"ਪਾਸਵਰਡ ਰਹਿਤ ਤਕਨਾਲੋਜੀ"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"ਪਾਸਕੀਆਂ ਤੁਹਾਨੂੰ ਪਾਸਵਰਡਾਂ \'ਤੇ ਭਰੋਸਾ ਕੀਤੇ ਬਿਨਾਂ ਸਾਈਨ-ਇਨ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀਆਂ ਹਨ। ਤੁਹਾਨੂੰ ਆਪਣੀ ਪਛਾਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਅਤੇ ਪਾਸਕੀ ਬਣਾਉਣ ਲਈ ਸਿਰਫ਼ ਆਪਣੇ ਫਿੰਗਰਪ੍ਰਿੰਟ, ਚਿਹਰਾ ਪਛਾਣ, ਪਿੰਨ ਜਾਂ ਸਵਾਈਪ ਪੈਟਰਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"ਜਨਤਕ ਕੁੰਜੀ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫ਼ੀ"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO ਗਠਜੋੜ (ਜਿਸ ਵਿੱਚ Google, Apple, Microsoft ਅਤੇ ਹੋਰ ਸ਼ਾਮਲ ਹਨ) ਅਤੇ W3C ਮਿਆਰਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਪਾਸਕੀਆਂ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫ਼ਿਕ ਕੁੰਜੀਆਂ ਦੇ ਜੋੜੇ ਵਰਤਦੀਆਂ ਹਨ। ਪਾਸਵਰਡ ਲਈ ਵਰਤੇ ਜਾਂਦੇ ਵਰਤੋਂਕਾਰ ਨਾਮ ਅਤੇ ਅੱਖਰ-ਚਿੰਨ੍ਹਾਂ ਦੀ ਸਤਰ ਤੋਂ ਅਲੱਗ, ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਲਈ ਨਿੱਜੀ-ਜਨਤਕ ਕੁੰਜੀ ਜੋੜਾ ਬਣਾਇਆ ਜਾਂਦਾ ਹੈ। ਨਿੱਜੀ ਕੁੰਜੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਜਾਂ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ \'ਤੇ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਸਟੋਰ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਅਤੇ ਇਹ ਤੁਹਾਡੀ ਪਛਾਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰਦੀ ਹੈ। ਜਨਤਕ ਕੁੰਜੀ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਸਰਵਰ ਨਾਲ ਸਾਂਝੀ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਸੰਬੰਧਿਤ ਕੁੰਜੀਆਂ ਨਾਲ, ਤੁਸੀਂ ਤੁਰੰਤ ਰਜਿਸਟਰ ਅਤੇ ਸਾਈਨ-ਇਨ ਕਰ ਸਕਦੇ ਹੋ।"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"ਬਿਹਤਰ ਖਾਤਾ ਸੁਰੱਖਿਆ"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"ਹਰੇਕ ਕੁੰਜੀ ਖਾਸ ਤੌਰ \'ਤੇ ਉਸ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਨਾਲ ਲਿੰਕ ਹੁੰਦੀ ਹੈ ਜਿਸ ਲਈ ਉਹ ਬਣਾਈ ਗਈ ਸੀ, ਇਸ ਲਈ ਤੁਸੀਂ ਕਦੇ ਵੀ ਗਲਤੀ ਨਾਲ ਕਿਸੇ ਧੋਖਾਧੜੀ ਵਾਲੀ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ \'ਤੇ ਸਾਈਨ-ਇਨ ਨਹੀਂ ਕਰ ਸਕਦੇ। ਇਸ ਤੋਂ ਇਲਾਵਾ, ਸਿਰਫ਼ ਜਨਤਕ ਕੁੰਜੀਆਂ ਵਾਲੇ ਸਰਵਰਾਂ \'ਤੇ, ਹੈਕਿੰਗ ਕਰਨਾ ਬਹੁਤ ਔਖਾ ਹੁੰਦਾ ਹੈ।"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"ਸਹਿਜ ਪਰਿਵਰਤਨ"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"ਜਦੋਂ ਕਿ ਅਸੀਂ ਪਾਸਵਰਡ ਰਹਿਤ ਭਵਿੱਖ ਵੱਲ ਵਧ ਰਹੇ ਹਾਂ, ਪਰ ਪਾਸਕੀਆਂ ਦੇ ਨਾਲ ਪਾਸਵਰਡ ਹਾਲੇ ਵੀ ਉਪਲਬਧ ਹੋਣਗੇ।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"ਚੁਣੋ ਕਿ ਆਪਣੇ <xliff:g id="CREATETYPES">%1$s</xliff:g> ਨੂੰ ਕਿੱਥੇ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ਆਪਣੀ ਜਾਣਕਾਰੀ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਅਤੇ ਅਗਲੀ ਵਾਰ ਤੇਜ਼ੀ ਨਾਲ ਸਾਈਨ-ਇਨ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ ਚੁਣੋ"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"ਕੀ <xliff:g id="APPNAME">%1$s</xliff:g> ਲਈ ਪਾਸਕੀ ਬਣਾਉਣੀ ਹੈ?"</string> diff --git a/packages/CredentialManager/res/values-pl/strings.xml b/packages/CredentialManager/res/values-pl/strings.xml index 9f857d1fea42..bf7a09e20f42 100644 --- a/packages/CredentialManager/res/values-pl/strings.xml +++ b/packages/CredentialManager/res/values-pl/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Anuluj"</string> <string name="string_continue" msgid="1346732695941131882">"Dalej"</string> <string name="string_more_options" msgid="7990658711962795124">"Więcej opcji"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Więcej informacji"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Klucze zwiększają Twoje bezpieczeństwo"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Dzięki kluczom nie musisz tworzyć ani zapamiętywać skomplikowanych haseł"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Klucze są szyfrowanymi kluczami cyfrowymi, które tworzysz za pomocą funkcji rozpoznawania odcisku palca lub twarzy bądź blokady ekranu"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Klucze są zapisane w menedżerze haseł, dzięki czemu możesz logować się na innych urządzeniach"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Więcej informacji o kluczach"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Technologia niewymagająca haseł"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Klucze umożliwiają logowanie się bez konieczności stosowania haseł. Wystarczy użyć odcisku palca, rozpoznawania twarzy, kodu PIN lub wzoru, aby potwierdzić tożsamość i utworzyć klucz."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kryptografia klucza publicznego"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Zgodnie z zasadami FIDO Alliance (stowarzyszenia zrzeszającego m.in. Google, Apple i Microsoft) oraz standardami W3C klucze opierają się kluczach kryptograficznych. W odróżnieniu od nazw użytkownika i ciągów znaków stanowiących hasła pary kluczy prywatnych i publicznych są tworzone dla konkretnych aplikacji i stron. Klucz prywatny jest bezpiecznie przechowywany na urządzeniu lub w menedżerze haseł i potwierdza Twoją tożsamość. Klucz publiczny jest udostępniany serwerowi aplikacji lub strony. Mając odpowiednie klucze, od razu się zarejestrujesz i zalogujesz."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Zwiększone bezpieczeństwo konta"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Każdy klucz jest połączony wyłącznie z aplikacją lub stroną, dla której został utworzony, więc nie zalogujesz się przypadkowo w fałszywej aplikacji ani na fałszywej stronie. Ponadto na serwerach są przechowywane wyłącznie klucze publiczne, co znacznie utrudnia hakowanie."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Płynne przechodzenie"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"W czasie przechodzenia na technologie niewymagające haseł możliwość stosowania haseł – niezależnie od kluczy – wciąż będzie dostępna."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Wybierz, gdzie zapisywać <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Wybierz menedżera haseł, aby zapisywać informacje i logować się szybciej"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Utworzyć klucz dla aplikacji <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-pt-rBR/strings.xml b/packages/CredentialManager/res/values-pt-rBR/strings.xml index 7deefbb06244..7a8e50a006f9 100644 --- a/packages/CredentialManager/res/values-pt-rBR/strings.xml +++ b/packages/CredentialManager/res/values-pt-rBR/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Cancelar"</string> <string name="string_continue" msgid="1346732695941131882">"Continuar"</string> <string name="string_more_options" msgid="7990658711962795124">"Mais opções"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Saiba mais"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mais segurança com as chaves de acesso"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Com as chaves de acesso, você não precisa criar nem se lembrar de senhas complexas"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As chaves de acesso são chaves digitais criptografadas que você cria usando a impressão digital, o rosto ou o bloqueio de tela"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Elas são salvas em um gerenciador de senhas para que você possa fazer login em outros dispositivos"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Saiba mais sobre chaves de acesso"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Tecnologia sem senha"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"As chaves de acesso permitem fazer login sem depender de senhas. Basta usar as tecnologias de impressão digital, reconhecimento facial, PIN ou padrão para confirmar sua identidade e criar uma chave de acesso."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Criptografia de chave pública"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Com base nos padrões do W3C e da FIDO Alliance (que inclui o Google, a Apple, a Microsoft e outros), as chaves de acesso usam pares de chaves criptográficas. Ao contrário do nome de usuário e da string de caracteres que usamos para criar senhas, um par de chaves pública/privada é criado especificamente para um app ou site. A chave privada confirma sua identidade e fica armazenada em segurança no seu dispositivo ou gerenciador de senhas. A pública é compartilhada com o servidor do site ou app. Use as chaves correspondentes para se registrar e fazer login de forma instantânea."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Mais segurança para sua conta"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Cada chave está vinculada exclusivamente ao app ou site para a qual foi criada. Isso impede que você faça login em um app ou site fraudulento por engano. Além disso, os servidores mantêm apenas chaves públicas, dificultando qualquer invasão."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Transição simplificada"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Estamos avançando em direção a um futuro sem senhas, mas elas ainda vão estar disponíveis junto às chaves de acesso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Escolha onde salvar suas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecione um gerenciador de senhas para salvar suas informações e fazer login mais rapidamente na próxima vez"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Criar uma chave de acesso para o app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-pt/strings.xml b/packages/CredentialManager/res/values-pt/strings.xml index 7deefbb06244..7a8e50a006f9 100644 --- a/packages/CredentialManager/res/values-pt/strings.xml +++ b/packages/CredentialManager/res/values-pt/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Cancelar"</string> <string name="string_continue" msgid="1346732695941131882">"Continuar"</string> <string name="string_more_options" msgid="7990658711962795124">"Mais opções"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Saiba mais"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mais segurança com as chaves de acesso"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Com as chaves de acesso, você não precisa criar nem se lembrar de senhas complexas"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As chaves de acesso são chaves digitais criptografadas que você cria usando a impressão digital, o rosto ou o bloqueio de tela"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Elas são salvas em um gerenciador de senhas para que você possa fazer login em outros dispositivos"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Saiba mais sobre chaves de acesso"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Tecnologia sem senha"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"As chaves de acesso permitem fazer login sem depender de senhas. Basta usar as tecnologias de impressão digital, reconhecimento facial, PIN ou padrão para confirmar sua identidade e criar uma chave de acesso."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Criptografia de chave pública"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Com base nos padrões do W3C e da FIDO Alliance (que inclui o Google, a Apple, a Microsoft e outros), as chaves de acesso usam pares de chaves criptográficas. Ao contrário do nome de usuário e da string de caracteres que usamos para criar senhas, um par de chaves pública/privada é criado especificamente para um app ou site. A chave privada confirma sua identidade e fica armazenada em segurança no seu dispositivo ou gerenciador de senhas. A pública é compartilhada com o servidor do site ou app. Use as chaves correspondentes para se registrar e fazer login de forma instantânea."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Mais segurança para sua conta"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Cada chave está vinculada exclusivamente ao app ou site para a qual foi criada. Isso impede que você faça login em um app ou site fraudulento por engano. Além disso, os servidores mantêm apenas chaves públicas, dificultando qualquer invasão."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Transição simplificada"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Estamos avançando em direção a um futuro sem senhas, mas elas ainda vão estar disponíveis junto às chaves de acesso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Escolha onde salvar suas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecione um gerenciador de senhas para salvar suas informações e fazer login mais rapidamente na próxima vez"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Criar uma chave de acesso para o app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-ro/strings.xml b/packages/CredentialManager/res/values-ro/strings.xml index 73bddeaa2c35..b0a008f2e6b5 100644 --- a/packages/CredentialManager/res/values-ro/strings.xml +++ b/packages/CredentialManager/res/values-ro/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Anulează"</string> <string name="string_continue" msgid="1346732695941131882">"Continuă"</string> <string name="string_more_options" msgid="7990658711962795124">"Mai multe opțiuni"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Află mai multe"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mai în siguranță cu chei de acces"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Dacă folosești chei de acces, nu este nevoie să creezi sau să reții parole complexe"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Cheile de acces sunt chei digitale criptate pe care le creezi folosindu-ți amprenta, fața sau blocarea ecranului"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Acestea sunt salvate într-un manager de parole, ca să te poți conecta pe alte dispozitive"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Mai multe despre cheile de acces"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Tehnologie fără parole"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Cu ajutorul cheilor de acces, poți să te conectezi fără să te bazezi pe parole. Pentru a-ți verifica identitatea și a crea o cheie de acces, nu trebuie decât să folosești amprenta, recunoașterea facială, PIN-ul sau modelul."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Criptografia cheilor publice"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Conform standardelor FIDO Alliance (din care fac parte Google, Apple, Microsoft etc.) și W3C, cheile de acces folosesc perechi de chei criptografice. Spre deosebire de numele de utilizator și șirul de caractere pe care le folosim pentru parole, perechea de chei publică/privată este creată pentru o aplicație sau un site. Cheia privată este stocată în siguranță pe dispozitivul sau în managerul tău de parole și îți confirmă identitatea. Cheia publică este trimisă aplicației sau serverului site-ului. Cu ajutorul cheilor corespunzătoare, poți să te înregistrezi și să te conectezi instantaneu."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Securitate îmbunătățită a contului"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Fiecare cheie este conectată în mod exclusiv cu aplicația sau site-ul pentru care a fost creată, prin urmare nu te poți conecta niciodată din greșeală la o aplicație sau un site fraudulos. În plus, întrucât pe servere sunt stocate doar chei publice, hackingul este mult mai dificil."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Tranziție fluidă"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Ne îndreptăm spre un viitor fără parole, în care parolele vor fi disponibile pe lângă cheile de acces."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Alege unde dorești să salvezi <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selectează un manager de parole pentru a salva informațiile și a te conecta mai rapid data viitoare"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Creezi o cheie de acces pentru <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-sl/strings.xml b/packages/CredentialManager/res/values-sl/strings.xml index a8561f458f4c..eeb4a966e8cd 100644 --- a/packages/CredentialManager/res/values-sl/strings.xml +++ b/packages/CredentialManager/res/values-sl/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Prekliči"</string> <string name="string_continue" msgid="1346732695941131882">"Naprej"</string> <string name="string_more_options" msgid="7990658711962795124">"Več možnosti"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Več o tem"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Večja varnost s ključi za dostop"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Po zaslugi ključev za dostop vam ni treba ustvarjati ali si zapomniti zapletenih gesel."</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Ključi za dostop so šifrirani digitalni ključi, ki jih ustvarite s prstnim odtisom, obrazom ali načinom zaklepanja zaslona."</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Shranjeni so v upravitelju gesel, kar pomeni, da se z njimi lahko prijavite tudi v drugih napravah."</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Več o ključih za dostop"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Tehnologija brez uporabe gesel"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Ključi za dostop vam omogočajo prijavo brez uporabe gesel. Za potrditev identitete in ustvarjanje ključa za dostop morate uporabiti le prstni odtis, prepoznavo obraza, kodo PIN ali vzorec za vlečenje s prstom."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kriptografija javnih ključev"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"V skladu s pravili združenja FIDO Alliance (ki vključuje Google, Apple, Microsoft in druge družbe) in standardi W3C so ključi za dostop sestavljeni iz parov kriptografskih ključev. Za razliko od uporabniškega imena in niza znakov, ki ga uporabljamo za geslo, je par zasebnega in javnega ključa ustvarjen za aplikacijo ali spletno mesto. Zasebni ključ je varno shranjen v vaši napravi ali upravitelju gesel in se uporablja za potrditev vaše identitete. Javni ključ se deli s strežnikom aplikacije ali spletnega mesta. Z ustreznima ključema se lahko hitro registrirate in prijavite."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Večja varnost računov"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Vsak ključ je neločljivo povezan z aplikacijo ali spletnim mestom, za katero je bil ustvarjen, zato se nikoli ne morete pomotoma prijaviti v goljufivo aplikacijo ali spletno mesto. Poleg tega so v strežnikih shranjeni le javni ključi, zato je vdiranje v račune precej oteženo."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Prehod brez zapletov"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Na poti v prihodnost brez gesel bodo poleg ključev za dostop še vedno v uporabi tudi gesla."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Izbira mesta za shranjevanje <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Izberite upravitelja gesel za shranjevanje podatkov za prijavo, da se boste naslednjič lahko hitreje prijavili."</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Želite ustvariti ključ za dostop do aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml index 897450e91a65..28e8716501f9 100644 --- a/packages/CredentialManager/res/values-sq/strings.xml +++ b/packages/CredentialManager/res/values-sq/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Anulo"</string> <string name="string_continue" msgid="1346732695941131882">"Vazhdo"</string> <string name="string_more_options" msgid="7990658711962795124">"Opsione të tjera"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Mëso më shumë"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Më e sigurt me çelësat e kalimit"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Me çelësat e kalimit, nuk ka nevojë të krijosh ose të mbash mend fjalëkalime të ndërlikuara"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Çelësat e kalimit kanë çelësa dixhitalë të enkriptuar që ti i krijon duke përdorur gjurmën e gishtit, fytyrën ose kyçjen e ekranit"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Ata ruhen te një menaxher fjalëkalimesh, në mënyrë që mund të identifikohesh në pajisje të tjera"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Më shumë rreth çelësave të kalimit"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Teknologji pa fjalëkalime"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Çelësat e kalimit të lejojnë të identifikohesh pa u mbështetur te fjalëkalimet. Të duhet vetëm të përdorësh gjurmën e gishtit, njohjen e fytyrës, PIN-in ose të rrëshqasësh motivin për të verifikuar identitetin dhe për të krijuar një çelës kalimi."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kriptografia e çelësit publik"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Bazuar në aleancën FIDO (e cila përfshin Google, Apple, Microsoft e të tjera) dhe standardet W3C, çelësat e kalimit përdorin çifte çelësash kriptografikë. Ndryshe nga emri i përdoruesit dhe vargu i karaktereve që përdorim për fjalëkalime, një çift çelësash privat-publik krijohet për aplikacion ose sajtin e uebit. Çelësi privat ruhet i sigurt në pajisjen tënde ose në menaxherin e fjalëkalimeve dhe konfirmon identitetin tënd. Çelësi publik ndahet me aplikacionin ose serverin e sajtit të uebit. Me çelësat përkatës, mund të regjistrohesh dhe të identifikohesh në çast."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Siguri e përmirësuar e llogarisë"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Secili çelës është i lidhur ekskluzivisht me aplikacionin ose sajtin e uebit për të cilin është krijuar, kështu që nuk do të identifikohesh asnjëherë gabimisht në një aplikacion ose sajt uebi mashtrues. Gjithashtu, me serverët që mbajnë vetëm çelësa publikë, pirateria informatike është shumë më e vështirë."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Kalim i thjeshtuar"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Teksa shkojmë drejt një të ardhmeje pa fjalëkalime, këto të fundit do të ofrohen ende së bashku me çelësat e kalimit."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Zgjidh se ku të ruash <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Zgjidh një menaxher fjalëkalimesh për të ruajtur informacionet e tua dhe për t\'u identifikuar më shpejt herën tjetër"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Të krijohet çelësi i kalimit për <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-sr/strings.xml b/packages/CredentialManager/res/values-sr/strings.xml index 375d97dca1bd..0474277fd6d0 100644 --- a/packages/CredentialManager/res/values-sr/strings.xml +++ b/packages/CredentialManager/res/values-sr/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Откажи"</string> <string name="string_continue" msgid="1346732695941131882">"Настави"</string> <string name="string_more_options" msgid="7990658711962795124">"Још опција"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Сазнајте више"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Безбедније уз приступне кодове"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Уз приступне кодове нема потребе да правите или памтите сложене лозинке"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Приступни кодови су шифровани дигитални кодови које правите помоћу отиска прста, лица или закључавања екрана"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Чувају се у менаџеру лозинки да бисте могли да се пријављујете на другим уређајима"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Више о приступним кодовима"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Технологија без лозинке"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Приступни кодови вам омогућавају да се пријавите без ослањања на лозинке. Довољно је само да користите отисак прста, препознавање лица, PIN или шаблон да бисте верификовали идентитет и направили приступни кôд."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Криптографија преко јавног кључа"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"На основу стандарда удружења FIDO (Google, Apple, Microsoft и други) и W3C, приступни кодови користе парове кључева за шифровање. За разлику од корисничког имена и стринга знакова који користимо за лозинке, за апликацију или сајт праве се парови приватних и јавних кључева. Приватни кључ се безбедно чува на уређају или у менаџеру лозинки и потврђује ваш идентитет. Јавни кључ се дели са сервером апликације или веб-сајта. Помоћу одговарајућих кључева можете тренутно да се региструјете и пријавите."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Побољшана безбедност налога"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Сваки кључ је искључиво повезан са апликацијом или веб-сајтом за које је направљен, па никад не можете грешком да се пријавите у апликацију или на веб-сајт који служе за превару. Осим тога, са серверима који чувају само јавне кључеве хаковање је много теже."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Беспрекоран прелаз"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Како се крећемо ка будућности без лозинки, лозинке ће и даље бити доступне уз приступне кодове."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Одаберите где ћете сачувати ставке <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Изаберите менаџера лозинки да бисте сачували податке и брже се пријавили следећи пут"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Желите да направите приступни кôд за: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-sv/strings.xml b/packages/CredentialManager/res/values-sv/strings.xml index d1a043daaa67..fe131249acd3 100644 --- a/packages/CredentialManager/res/values-sv/strings.xml +++ b/packages/CredentialManager/res/values-sv/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Avbryt"</string> <string name="string_continue" msgid="1346732695941131882">"Fortsätt"</string> <string name="string_more_options" msgid="7990658711962795124">"Fler alternativ"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Läs mer"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Säkrare med nycklar"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Med nycklar behöver du inte skapa eller komma ihop invecklade lösenord"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Nycklar är krypterade digitala nycklar som du skapar med ditt fingeravtryck, ansikte eller skärmlås"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"De sparas i lösenordshanteraren så att du kan logga in på andra enheter"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Mer om nycklar"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Lösenordslös teknik"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Nycklar gör det möjligt för dig att logga in utan att förlita dig på lösenord. Du behöver bara använda ditt fingeravtryck, svepmönster, din ansiktsigenkänning eller pinkod för att verifiera din identitet och skapa en nyckel."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kryptering med offentlig nyckel"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Kryptografiska nyckelpar används enligt standarder från FIDO Alliance (som inkluderar Google, Apple, Microsoft m.fl.) och W3C. Ett nyckelpar (en offentlig och en privat) skapas för appen eller webbplatsen, till skillnad från användarnamnet och teckensträngen som används som lösenord. Den privata nyckeln lagras säkert på enheten eller i Lösenordshantering. Den bekräftar din identitet. Den offentliga nyckeln delas med app- eller webbplatsservern. Med motsvarande nycklar kan du snabbt logga in."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Förbättrad kontosäkerhet"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Varje nyckel är exklusivt länkad till appen eller webbplatsen den skapades för, så du kan aldrig logga in i en bedräglig app eller webbplats av misstag. Hackning blir dessutom mycket svårare eftersom servrar bara behåller offentliga nycklar."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"En sömlös övergång"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Medan vi beger oss mot en lösenordslös framtid kommer lösenord fortfarande att vara tillgängliga utöver nycklar."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Välj var du vill spara <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Välj en lösenordshanterare för att spara dina uppgifter och logga in snabbare nästa gång"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vill du skapa en nyckel för <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-sw/strings.xml b/packages/CredentialManager/res/values-sw/strings.xml index 68af50b306dd..3c5015113409 100644 --- a/packages/CredentialManager/res/values-sw/strings.xml +++ b/packages/CredentialManager/res/values-sw/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Ghairi"</string> <string name="string_continue" msgid="1346732695941131882">"Endelea"</string> <string name="string_more_options" msgid="7990658711962795124">"Chaguo zaidi"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Pata maelezo zaidi"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Ni salama ukitumia funguo za siri"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Kwa kutumia funguo za siri, huhitaji kuunda au kukumbuka manenosiri changamano"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Funguo za siri ni funguo dijitali zilizosimbwa kwa njia fiche unazounda kwa kutumia alama yako ya kidole, uso au mbinu ya kufunga skrini"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Vyote huhifadhiwa kwenye kidhibiti cha manenosiri, ili uweze kuingia katika akaunti kwenye vifaa vingine"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Maelezo zaidi kuhusu funguo za siri"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Teknolojia isiyotumia manenosiri"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Funguo za siri zinakuruhusu uingie katika akaunti bila kutegemea manenosiri. Unapaswa tu kutumia alama yako ya kidole, kipengele cha utambuzi wa uso, PIN au mchoro wa kutelezesha ili uthibitishe utambulisho wako na uunde ufunguo wa siri."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kriptographia ya ufunguo wa umma"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Kulingana na Ushirikiano wa FIDO (unaojumuisha Google, Apple, Microsoft na zaidi) na viwango vya W3C, funguo za siri hutumia jozi ya funguo za kriptografia. Tofauti na jina la mtumiaji na mfuatano wa herufi tunazotumia kwa ajili ya manenosiri, jozi ya funguo binafsi na za umma imeundwa kwa ajili ya programu au tovuti. Ufunguo binafsi unatunzwa kwa usalama kwenye kifaa chako au kidhibiti cha manenosiri na huthibitisha utambulisho wako. Ufunguo wa umma unashirikiwa na seva ya programu au tovuti. Kwa funguo zinazolingana, unaweza kujisajili na kuingia katika akaunti papo hapo."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Ulinzi wa akaunti ulioboreshwa"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Kila ufunguo umeunganishwa kwa upekee na programu au tovuti husika, kwa hivyo kamwe huwezi kuingia katika akaunti ya programu au tovuti ya kilaghai kwa bahati mbaya. Pia, kwa kuwa seva huhifadhi tu funguo za umma, udukuzi si rahisi."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Mabadiliko rahisi"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Tunavyoelekea katika enzi isiyo ya manenosiri, manenosiri yataendelea kupatikana pamoja na funguo za siri."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Chagua ambako unahifadhi <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Chagua kidhibiti cha manenosiri ili uhifadhi taarifa zako na uingie kwenye akaunti kwa urahisi wakati mwingine"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Ungependa kuunda ufunguo wa siri kwa ajili ya <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-ta/strings.xml b/packages/CredentialManager/res/values-ta/strings.xml index 9857215137b3..77beb85f800f 100644 --- a/packages/CredentialManager/res/values-ta/strings.xml +++ b/packages/CredentialManager/res/values-ta/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"ரத்துசெய்"</string> <string name="string_continue" msgid="1346732695941131882">"தொடர்க"</string> <string name="string_more_options" msgid="7990658711962795124">"கூடுதல் விருப்பங்கள்"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"மேலும் அறிக"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"கடவுச்சாவிகள் மூலம் பாதுகாப்பாக வைத்திருங்கள்"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"கடவுச்சாவிகளைப் பயன்படுத்துவதன் மூலம் கடினமான கடவுச்சொற்களை உருவாக்கவோ நினைவில்கொள்ளவோ தேவையில்லை"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"கடவுச்சாவிகள் என்பவை உங்கள் கைரேகை, முகம் அல்லது திரைப் பூட்டு மூலம் உருவாக்கப்படும் என்க்ரிப்ஷன் செய்யப்பட்ட டிஜிட்டல் சாவிகள் ஆகும்"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"அவை Password Managerரில் சேமிக்கப்பட்டுள்ளதால் நீங்கள் பிற சாதனங்களிலிருந்து உள்நுழையலாம்"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"கடவுச்சாவிகள் குறித்த கூடுதல் விவரங்கள்"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"கடவுச்சொல்லற்ற தொழில்நுட்பம்"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"கடவுச்சாவிகள் மூலம், கடவுச்சொற்களை உள்ளிடாமலேயே நீங்கள் உள்நுழைய முடியும். உங்கள் அடையாளத்தை உறுதிப்படுத்தி கடவுச்சாவியை உருவாக்க உங்கள் கைரேகை, முகம் அறிதல், பின் அல்லது ஸ்வைப் பேட்டர்னைப் பயன்படுத்தினாலே போதும்."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"பொதுக் குறியீட்டுக் கிரிப்டோகிராஃபி"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (Google, Apple, Microsoft மற்றும் பல நிறுவனங்கள்) & W3C தரநிலைகளின் அடிப்படையில் கடவுச்சாவிகள் கிரிப்டோகிராஃபிக் இரட்டைக் குறியீடுகளைப் பயன்படுத்துகின்றன. பயனர்பெயர் & கடவுச்சொல் போல் இல்லாமல், ஓர் ஆப்ஸ்/தளத்திற்கென இரட்டைக் குறியீடு உருவாக்கப்படும். சாதனம்/கடவுச்சொல் நிர்வாகியில் பாதுகாப்பாகச் சேமிக்கப்படும் தனிப்பட்ட குறியீடு உங்கள் அடையாளத்தை உறுதிசெய்யும். பொதுக் குறியீடு ஆப்ஸ்/இணையதள சர்வருடன் பகிரப்படும். தொடர்புடைய குறியீடுகள் மூலம் உடனடியாகப் பதிவுசெய்யலாம் உள்நுழையலாம்."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"மேம்படுத்தப்பட்ட கணக்குப் பாதுகாப்பு"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"ஒவ்வொரு குறியீடும் எந்த ஆப்ஸ்/இணையதளத்திற்காக உருவாக்கப்பட்டதோ அதனுடன் மட்டுமே இணைக்கப்பட்டிருக்கும். இது மோசடியான ஆப்ஸ்/இணையதளத்தில் நீங்கள் தவறுதலாக உள்நுழைவதைத் தடுக்கும். அத்துடன், சேவையகங்களில் பொதுக் குறியீடுகள் மட்டுமே சேமிக்கப்படுவதால் கணக்கை ஹேக் செய்வது மிகக் கடினமாகும்."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"தடையற்ற டிரான்ஸிஷன்"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"கடவுச்சொல்லற்ற எதிர்காலத்தை நோக்கி நாம் பயணிக்கிறோம். கடவுச்சாவிகளைப் பயன்படுத்தும் இதே வேளையில் கடவுச்சொற்களையும் பயன்படுத்த முடியும்."</string> <string name="choose_provider_title" msgid="8870795677024868108">"உங்கள் <xliff:g id="CREATETYPES">%1$s</xliff:g> எங்கே சேமிக்கப்பட வேண்டும் என்பதைத் தேர்வுசெய்யுங்கள்"</string> <string name="choose_provider_body" msgid="4967074531845147434">"உங்கள் தகவல்களைச் சேமித்து அடுத்த முறை விரைவாக உள்நுழைய ஒரு கடவுச்சொல் நிர்வாகியைத் தேர்வுசெய்யுங்கள்"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸுக்கான கடவுச்சாவியை உருவாக்கவா?"</string> diff --git a/packages/CredentialManager/res/values-tl/strings.xml b/packages/CredentialManager/res/values-tl/strings.xml index 1c78fb8c5841..d75ac574e9f4 100644 --- a/packages/CredentialManager/res/values-tl/strings.xml +++ b/packages/CredentialManager/res/values-tl/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Kanselahin"</string> <string name="string_continue" msgid="1346732695941131882">"Magpatuloy"</string> <string name="string_more_options" msgid="7990658711962795124">"Higit pang opsyon"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Matuto pa"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mas ligtas gamit ang mga passkey"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Gamit ang mga passkey, hindi mo na kailangang gumawa o tumanda ng mga komplikadong password"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Ang mga passkey ay mga naka-encrypt na digital na susi na ginagawa mo gamit ang iyong fingerprint, mukha, o lock ng screen"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Sine-save ang mga ito sa isang password manager para makapag-sign in ka sa iba pang device"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Higit pa tungkol sa mga passkey"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Teknolohiyang hindi gumagamit ng password"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Sa pamamagitan ng mga passkey, makakapag-sign in ka nang hindi umaasa sa mga password. Kailangan mo lang gamitin ang iyong fingerprint, pagkilala ng mukha, PIN, o swipe pattern para i-verify ang pagkakakilanlan mo at gumawa ng passkey."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Cryptography ng pampublikong key"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Batay sa FIDO Alliance (na kinabibilangan ng Google, Apple, Microsoft, atbp) at W3C standards, gumagamit ang passkeys ng cryptographic key pairs. Hindi tulad ng username at string ng characters na ginagamit sa password, para sa app o website ginagawa ang private-public key pair. Ligtas na naka-store sa device o password manager ang private key at kinukumpirma nito ang identity. Naka-share sa app o website server ang public key. Gamit ang key, instant kang makakapag-register at makakapag-sign in."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Pinahusay na seguridad sa account"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Eksklusibong naka-link sa app o website kung para saan ginawa ang bawat key, kaya hindi ka makakapag-sign in sa isang mapanlokong app o website nang hindi sinasadya. Bukod pa rito, dahil mga pampublikong key lang ang itinatabi ng mga server, lubos na mas mahirap ang pag-hack."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Madaling transition"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Habang lumalayo tayo sa mga password, magiging available pa rin ang mga password kasama ng mga passkey."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Piliin kung saan mo ise-save ang iyong <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Pumili ng password manger para ma-save ang iyong impormasyon at makapag-sign in nang mas mabilis sa susunod na pagkakataon"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Gumawa ng passkey para sa <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-tr/strings.xml b/packages/CredentialManager/res/values-tr/strings.xml index 5a3bcba29ebf..4ee0b51cdbd3 100644 --- a/packages/CredentialManager/res/values-tr/strings.xml +++ b/packages/CredentialManager/res/values-tr/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"İptal"</string> <string name="string_continue" msgid="1346732695941131882">"Devam"</string> <string name="string_more_options" msgid="7990658711962795124">"Diğer seçenekler"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Daha fazla bilgi"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Şifre anahtarlarıyla daha yüksek güvenlik"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Şifre anahtarı kullandığınızda karmaşık şifreler oluşturmanız veya bunları hatırlamanız gerekmez"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Şifre anahtarları; parmak iziniz, yüzünüz veya ekran kilidinizi kullanarak oluşturduğunuz şifrelenmiş dijital anahtarlardır"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Diğer cihazlarda oturum açabilmeniz için şifre anahtarları bir şifre yöneticisine kaydedilir"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Şifre anahtarları hakkında daha fazla bilgi"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Şifresiz teknoloji"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Şifre anahtarları, şifre kullanmadan oturum açmanıza olanak tanır. Kimliğinizi doğrulayıp şifre anahtarı oluşturmak için parmak iziniz, yüz tanıma özelliği, PIN veya kaydırma deseni kullanmanız yeterlidir."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Ortak anahtar kriptografisi"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Şifre anahtarları, FIDO Alliance (Google, Apple, Microsoft ve daha pek çok şirket yer alır) ve W3C standartları uyarınca şifreleme anahtarı çiftleri kullanır. Şifrelerde kullandığımız kullanıcı adı ve karakter dizisinden farklı olarak bir uygulama veya web sitesi için özel-ortak anahtar çifti oluşturulur. Özel anahtar, cihazınızda ya da şifre yöneticinizde güvenle saklanır ve kimliğinizi doğrular. Ortak anahtar, uygulama veya web sitesi sunucusuyla paylaşılır. İlgili anahtarları kullanarak anında kaydolabilir ve oturum açabilirsiniz."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Daha iyi hesap güvenliği"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Her anahtar, oluşturulduğu uygulama veya web sitesiyle özel olarak bağlantılı olduğu için sahte bir uygulamaya veya web sitesine hiçbir zaman yanlışlıkla giriş yapamazsınız. Ayrıca, sunucularda yalnızca ortak anahtarlar saklandığı için saldırıya uğramak daha zordur."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Sorunsuz geçiş"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Şifresiz bir geleceğe doğru ilerlerken şifreler, şifre anahtarlarıyla birlikte kullanılmaya devam edecektir."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> bilgilerinizin kaydedileceği yeri seçin"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Bilgilerinizi kaydedip bir dahaki sefere daha hızlı oturum açmak için bir şifre yöneticisi seçin"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> için şifre anahtarı oluşturulsun mu?"</string> diff --git a/packages/CredentialManager/res/values-uk/strings.xml b/packages/CredentialManager/res/values-uk/strings.xml index 46e764928466..bd10f429c0bf 100644 --- a/packages/CredentialManager/res/values-uk/strings.xml +++ b/packages/CredentialManager/res/values-uk/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Скасувати"</string> <string name="string_continue" msgid="1346732695941131882">"Продовжити"</string> <string name="string_more_options" msgid="7990658711962795124">"Інші опції"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Докладніше"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Ключі доступу покращують безпеку"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Маючи ключі доступу, не потрібно створювати чи запам’ятовувати складні паролі"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Ключі доступу – це зашифровані цифрові ключі, які ви створюєте за допомогою відбитка пальця, фейс-контролю чи засобу розблокування екрана"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Вони зберігаються в менеджері паролів, тож ви можете входити на інших пристроях"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Докладніше про ключі доступу"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Технологія безпарольної автентифікації"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Ключі доступу дають змогу входити в облікові записи, не покладаючись на паролі. Щоб підтвердити свою особу та створити ключ доступу, потрібно лише скористатися відбитком пальця, PIN-кодом або ключем розблокування чи пройти розпізнавання обличчя."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Криптографія з відкритим ключем"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Згідно зі стандартами FIDO Alliance (куди входять компанії Google, Apple, Microsoft тощо) і W3C, у ключах доступу використовуються пари криптографічних ключів. На відміну від імені користувача й рядка символів у паролі, для додатка чи сайту створюється пара із секретного і відкритого ключів. Перший надійно зберігається на пристрої або в менеджері паролів і підтверджує вашу особу. Другий надсилається на сервер додатка чи сайту. Маючи відповідні ключі, можна миттєво реєструватися та входити в систему."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Підвищена безпека облікового запису"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Кожен ключ зв’язано виключно з додатком або веб-сайтом, для якого його створено, тому ви ніколи не зможете помилково ввійти в шахрайський додаток чи на шахрайський веб-сайт. Крім того, коли на серверах зберігаються лише відкриті ключі, зламати захист набагато складніше."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Плавний перехід"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"На шляху до безпарольного майбутнього паролі й надалі будуть використовуватися паралельно з ключами."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Виберіть, де зберігати <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Виберіть менеджер паролів, щоб зберігати свої дані й надалі входити в облікові записи швидше"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Створити ключ доступу для додатка <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-uz/strings.xml b/packages/CredentialManager/res/values-uz/strings.xml index f815f6724d97..43ece9a629d2 100644 --- a/packages/CredentialManager/res/values-uz/strings.xml +++ b/packages/CredentialManager/res/values-uz/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Bekor qilish"</string> <string name="string_continue" msgid="1346732695941131882">"Davom etish"</string> <string name="string_more_options" msgid="7990658711962795124">"Boshqa parametrlar"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Batafsil"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Kalitlar orqali qulay"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Kodlar yordami tufayli murakkab parollarni yaratish va eslab qolish shart emas"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Kodlar – bu barmoq izi, yuz yoki ekran qulfi yordamida yaratilgan shifrlangan raqamli identifikator."</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Ular parollar menejerida saqlanadi va ulardan boshqa qurilmalarda hisobga kirib foydalanish mumkin"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Kodlar haqida batafsil"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Parolsiz texnologiya"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Kodlar parollarga tayanmasdan tizimga kirish imkonini beradi. Shaxsingizni tasdiqlash va kod yaratish uchun barmoq izi, yuzni tanish, PIN kod yoki grafik kalitni surishdan foydalanishingiz kifoya."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Ochiq kalit kriptografiyasi"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (Google, Apple, Microsoft va boshqalar) va W3C standartlari asosida kodlar kriptografik kalitlar juftligidan foydalanadi. Parollarda ishlatiladigan foydalanuvchi nomi va belgilardan farqli ravishda, ilova yoki veb-sayt uchun maxfiy ochiq kalitlar juftligi yaratiladi. Maxfiy kalit qurilmangizda yoki parollar menejerida xavfsiz saqlanadi va u shaxsingizni tasdiqlaydi. Ochiq kalit ilova yoki veb-sayt serveriga ulashiladi. Mos kalitlar bilan darhol registratsiya va tizimga kirish mumkin."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Hisob xavfsizligi yaxshilandi"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Har bir kalit faqat ular uchun yaratilgan ilova yoki veb-sayt bilan ulangan, shuning uchun siz hech qachon xatolik bilan soxta ilova yoki veb-saytga kira olmaysiz. Shuningdek, serverlar bilan faqat ochiq kalitlarni saqlagan holda, buzib kirish ancha qiyinroq boʻladi."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Uzluksiz oʻtish"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsiz kelajak sari borayotganimizda, parollar kodlar bilan birga ishlatilishda davom etadi."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> qayerga saqlanishini tanlang"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Maʼlumotlaringizni saqlash va keyingi safar tez kirish uchun parollar menejerini tanlang"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> uchun kod yaratilsinmi?"</string> diff --git a/packages/CredentialManager/res/values-vi/strings.xml b/packages/CredentialManager/res/values-vi/strings.xml index 0fe35b1b5f8e..f2b94761c6b1 100644 --- a/packages/CredentialManager/res/values-vi/strings.xml +++ b/packages/CredentialManager/res/values-vi/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Huỷ"</string> <string name="string_continue" msgid="1346732695941131882">"Tiếp tục"</string> <string name="string_more_options" msgid="7990658711962795124">"Tuỳ chọn khác"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Tìm hiểu thêm"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"An toàn hơn nhờ mã xác thực"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Mã xác thực giúp bạn tránh được việc phải tạo và ghi nhớ mật khẩu phức tạp"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Mã xác thực là các khoá kỹ thuật số được mã hoá mà bạn tạo bằng cách dùng vân tay, khuôn mặt hoặc phương thức khoá màn hình của mình"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Thông tin này được lưu vào trình quản lý mật khẩu nên bạn có thể đăng nhập trên các thiết bị khác"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Xem thêm thông tin về mã xác thực"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Công nghệ không dùng mật khẩu"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Mã xác thực cho phép bạn đăng nhập mà không cần dựa vào mật khẩu. Bạn chỉ cần dùng vân tay, tính năng nhận dạng khuôn mặt, mã PIN hoặc hình mở khoá để xác minh danh tính và tạo mã xác thực."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"Mật mã của khoá công khai"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Dựa trên Liên minh FIDO (bao gồm Google, Apple, Microsoft, v.v.) và tiêu chuẩn W3C, mã xác thực sử dụng cặp khoá mã hoá. Khác với tên người dùng và chuỗi ký tự chúng tôi dùng cho mật khẩu, một cặp khoá riêng tư – công khai được tạo cho một ứng dụng hoặc trang web. Khoá riêng tư được lưu trữ an toàn trên thiết bị hoặc trình quản lý mật khẩu và xác nhận danh tính của bạn. Khoá công khai được chia sẻ với máy chủ ứng dụng hoặc trang web. Với khoá tương ứng, bạn có thể đăng ký và đăng nhập tức thì."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Cải thiện tính bảo mật của tài khoản"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Mỗi khoá được liên kết riêng với ứng dụng hoặc trang web mà khoá đó được tạo. Vì vậy, bạn sẽ không bao giờ đăng nhập nhầm vào một ứng dụng hoặc trang web lừa đảo. Ngoài ra, với các máy chủ chỉ lưu giữ khoá công khai, việc xâm nhập càng khó hơn nhiều."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Chuyển đổi liền mạch"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Trong quá trình chúng tôi hướng đến tương lai không dùng mật khẩu, bạn vẫn sẽ dùng được mật khẩu cùng với mã xác thực."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Chọn vị trí lưu <xliff:g id="CREATETYPES">%1$s</xliff:g> của bạn"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Hãy chọn một trình quản lý mật khẩu để lưu thông tin của bạn và đăng nhập nhanh hơn trong lần tới"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Tạo mã xác thực cho <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/CredentialManager/res/values-zh-rCN/strings.xml b/packages/CredentialManager/res/values-zh-rCN/strings.xml index 78a3d2294d1a..daffaca3c24b 100644 --- a/packages/CredentialManager/res/values-zh-rCN/strings.xml +++ b/packages/CredentialManager/res/values-zh-rCN/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"取消"</string> <string name="string_continue" msgid="1346732695941131882">"继续"</string> <string name="string_more_options" msgid="7990658711962795124">"更多选项"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"了解详情"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"通行密钥可提高安全性"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"借助通行密钥,您无需创建或记住复杂的密码"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"通行密钥是指您使用您的指纹、面孔或屏锁方式创建的加密数字钥匙"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"系统会将通行密钥保存到密码管理工具中,以便您在其他设备上登录"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"详细了解通行密钥"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"无密码技术"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"借助通行密钥,您不必依赖密码就能登录。您只需使用指纹、人脸识别功能、PIN 码或滑动图案便可验证您的身份并创建通行密钥。"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"公钥加密"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"根据 FIDO 联盟(成员包括 Google、Apple、Microsoft 等)和 W3C 的标准,通行密钥使用加密密钥对。不同于用户名及可在密码中使用的一系列字符,系统会为应用或网站创建一个私钥-公钥对。私钥会安全地存储在您的设备上或密码管理工具中,用于证实您的身份。公钥会被共享给应用或网站服务器。您只要使用相应密钥,就能瞬间注册并登录。"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"提升了帐号安全性"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"每个密钥都是专为特定应用或网站创建的,且仅与各自对应的网站或应用关联,因此您绝不会错误地登录任何欺诈性应用或网站。另外,由于服务器只保留公钥,黑客入侵的难度会大大增加。"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"无缝转换"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"在我们向无密码未来迈进的过程中,密码仍会与通行密钥并存供用。"</string> <string name="choose_provider_title" msgid="8870795677024868108">"选择保存<xliff:g id="CREATETYPES">%1$s</xliff:g>的位置"</string> <string name="choose_provider_body" msgid="4967074531845147434">"请选择一款密码管理工具来保存您的信息,以便下次更快地登录"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"要为“<xliff:g id="APPNAME">%1$s</xliff:g>”创建通行密钥吗?"</string> diff --git a/packages/CredentialManager/res/values-zh-rHK/strings.xml b/packages/CredentialManager/res/values-zh-rHK/strings.xml index 54fe97ce7a12..5255b929890e 100644 --- a/packages/CredentialManager/res/values-zh-rHK/strings.xml +++ b/packages/CredentialManager/res/values-zh-rHK/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"取消"</string> <string name="string_continue" msgid="1346732695941131882">"繼續"</string> <string name="string_more_options" msgid="7990658711962795124">"更多選項"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"瞭解詳情"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"使用密鑰確保帳戶安全"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"有了密鑰,您便無需建立或記住複雜的密碼"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"密鑰是您使用指紋、面孔或螢幕鎖定時建立的加密數碼鑰匙"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"密鑰已儲存至密碼管理工具,方便您在其他裝置上登入"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"進一步瞭解密鑰"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"無密碼技術"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"只要有密鑰,就無需使用密碼登入。使用指紋、面孔識別、PIN 或滑動畫出圖案,便可驗證身分並建立密鑰。"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"公開金鑰加密技術"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"密鑰根據 FIDO 聯盟 (包括 Google、Apple、Microsoft 等) 及 W3C 標準,使用加密配對金鑰技術。私密 - 公開金鑰組專為應用程式或網站建立,與建立密碼時使用的使用者名稱和作為密碼的字元字串不同。私密金鑰會安全地儲存在裝置或密碼管理工具上,用來確認您的身分。公開金鑰會與應用程式或網站伺服器共用。只要有對應的金鑰,就能立即註冊和登入。"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"提升帳戶安全性"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"系統會為應用程式或網站建立專用的對應金鑰,因此您不會錯誤登入欺詐的應用程式或網站。此外,伺服器上只會保留公開金鑰,因此可大幅降低駭客入侵的風險。"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"流暢轉換"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"我們將會改用無密碼技術,而密碼仍可與密鑰並行使用。"</string> <string name="choose_provider_title" msgid="8870795677024868108">"選擇儲存<xliff:g id="CREATETYPES">%1$s</xliff:g>的位置"</string> <string name="choose_provider_body" msgid="4967074531845147434">"選取密碼管理工具即可儲存自己的資料,縮短下次登入的時間"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"要為「<xliff:g id="APPNAME">%1$s</xliff:g>」建立密鑰嗎?"</string> diff --git a/packages/CredentialManager/res/values-zh-rTW/strings.xml b/packages/CredentialManager/res/values-zh-rTW/strings.xml index 0be95d29ead4..274ed21c7e06 100644 --- a/packages/CredentialManager/res/values-zh-rTW/strings.xml +++ b/packages/CredentialManager/res/values-zh-rTW/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"取消"</string> <string name="string_continue" msgid="1346732695941131882">"繼續"</string> <string name="string_more_options" msgid="7990658711962795124">"更多選項"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"瞭解詳情"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"使用密碼金鑰確保帳戶安全"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"有了密碼金鑰,就不必建立或記住複雜的密碼"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"密碼金鑰是你利用指紋、臉孔或螢幕鎖定功能建立的加密數位金鑰"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"密碼金鑰會儲存到密碼管理工具,方便你在其他裝置上登入"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"進一步瞭解密碼金鑰"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"無密碼技術"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"只要有密碼金鑰,就不必使用密碼登入。使用指紋、臉部辨識、PIN 碼或滑動畫出解鎖圖案,就能驗證身分並建立密碼金鑰。"</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"公開金鑰密碼編譯"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"密碼金鑰根據 FIDO 聯盟 (包括 Google、Apple、Microsoft 等) 及 W3C 標準,使用加密編譯金鑰技術。私密 - 公開金鑰組專為應用程式或網站建立,有別於建立密碼時使用的使用者名稱和做為密碼的字元字串。私密金鑰會安全地儲存在裝置或 Google 密碼管理工具中,並用來確認你的身分。公開金鑰會提供給應用程式或網站伺服器。只要有相對應的金鑰,就能立即註冊和登入。"</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"提升帳戶安全性"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"系統會為應用程式或網站建立專屬的對應金鑰,因此你不會意外登入詐欺性的應用程式或網站。此外,伺服器上只存放公開金鑰,因此可大幅降低駭客入侵的風險。"</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"流暢轉換"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"我們日後將改採無密碼技術,密碼仍可與密碼金鑰並行使用。"</string> <string name="choose_provider_title" msgid="8870795677024868108">"選擇要將<xliff:g id="CREATETYPES">%1$s</xliff:g>存在哪裡"</string> <string name="choose_provider_body" msgid="4967074531845147434">"選取密碼管理工具並儲存資訊,下次就能更快登入"</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"要為「<xliff:g id="APPNAME">%1$s</xliff:g>」建立密碼金鑰嗎?"</string> diff --git a/packages/CredentialManager/res/values-zu/strings.xml b/packages/CredentialManager/res/values-zu/strings.xml index f281c0dc2875..d6624f0e3f79 100644 --- a/packages/CredentialManager/res/values-zu/strings.xml +++ b/packages/CredentialManager/res/values-zu/strings.xml @@ -5,30 +5,20 @@ <string name="string_cancel" msgid="6369133483981306063">"Khansela"</string> <string name="string_continue" msgid="1346732695941131882">"Qhubeka"</string> <string name="string_more_options" msgid="7990658711962795124">"Okunye okungakukhethwa kukho"</string> - <!-- no translation found for string_learn_more (4541600451688392447) --> - <skip /> + <string name="string_learn_more" msgid="4541600451688392447">"Funda kabanzi"</string> <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Iphephe ngokhiye bokudlula"</string> <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Ngokhiye wokudlula, awudingi ukusungula noma ukukhumbula amaphasiwedi ayinkimbinkimbi"</string> <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Okhiye bokungena bangokhiye bedijithali ababethelwe obasungula usebenzisa isigxivizo somunwe sakho, ubuso, noma ukukhiya isikrini"</string> <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Okhiye bokudlula balondolozwa kusiphathi sephasiwedi, ukuze ukwazi ukungena ngemvume kwamanye amadivayisi"</string> - <!-- no translation found for more_about_passkeys_title (7797903098728837795) --> - <skip /> - <!-- no translation found for passwordless_technology_title (2497513482056606668) --> - <skip /> - <!-- no translation found for passwordless_technology_detail (6853928846532955882) --> - <skip /> - <!-- no translation found for public_key_cryptography_title (6751970819265298039) --> - <skip /> - <!-- no translation found for public_key_cryptography_detail (6937631710280562213) --> - <skip /> - <!-- no translation found for improved_account_security_title (1069841917893513424) --> - <skip /> - <!-- no translation found for improved_account_security_detail (9123750251551844860) --> - <skip /> - <!-- no translation found for seamless_transition_title (5335622196351371961) --> - <skip /> - <!-- no translation found for seamless_transition_detail (4475509237171739843) --> - <skip /> + <string name="more_about_passkeys_title" msgid="7797903098728837795">"Okuningi mayelana nokhiye bokudlula"</string> + <string name="passwordless_technology_title" msgid="2497513482056606668">"Ubuchwepheshe obungenaphasiwedi"</string> + <string name="passwordless_technology_detail" msgid="6853928846532955882">"Okhiye bokudlula bakuvumela ukuthi ungene ngemvume ngaphandle kokuthembela kumaphasiwedi. Udinga nje ukusebenzisa izigxivizo zakho zominwe, ukubona ubuso, Iphinikhodi, noma iphethini yokuswayipha ukuze uqinisekise ubuwena futhi usungule ukhiye wokudlula."</string> + <string name="public_key_cryptography_title" msgid="6751970819265298039">"I-cryptography yokhiye osesidlangalaleni"</string> + <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Ngokusekelwe ku-FIDO Alliance (ehlanganisa i-Google, i-Apple, i-Microsoft, nokwengeziwe) namazinga e-W3C, okhiye bokudlula basebenzisa amapheya okhiye be-cryptographic. Ngokungafani negama lomsebenzisi nezinhlamvu esizisebenzisela amaphasiwedi, ukhiye ogodliwe wasesidlangalaleni usungulelwe i-app noma iwebhusayithi. Ukhiye ogodliwe ugcinwe ngokuphephile kudivayisi yakho noma kumphathi wephasiwedi futhi uqinisekisa ubuwena. Ukhiye osesidlangalaleni wabiwe ne-app noma iseva yewebhusayithi. Ngokhiye abahambisanayo, ungabhalisa ngokushesha futhi ungene ngemvume."</string> + <string name="improved_account_security_title" msgid="1069841917893513424">"Ukuvikeleka kwe-akhawunti okuthuthukisiwe"</string> + <string name="improved_account_security_detail" msgid="9123750251551844860">"Ukhiye ngamunye olinkwe ngokukhethekile ne-app noma iwebhusayithi usungulelwe yona, ngakho awukwazi ukungena ngemvume ku-app noma kuwebhusayithi yomgunyathi ngephutha. Futhi, ngamaseva agcina okhiye basesidlangalaleni kuphela, ukugebengu be-inthanethi bunzima kakhulu."</string> + <string name="seamless_transition_title" msgid="5335622196351371961">"Ushintsho olulula"</string> + <string name="seamless_transition_detail" msgid="4475509237171739843">"Njengoba sibhekela kwikusasa elingenaphasiwedi, amagama ayimfihlo asazotholakala eceleni kokhiye bokudlula."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Khetha lapho ongagcina khona i-<xliff:g id="CREATETYPES">%1$s</xliff:g> yakho"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Khetha isiphathi sephasiwedi ukuze ulondoloze ulwazi lwakho futhi ungene ngemvume ngokushesha ngesikhathi esizayo."</string> <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Sungula ukhiye wokudlula we-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string> diff --git a/packages/PackageInstaller/res/values-af/strings.xml b/packages/PackageInstaller/res/values-af/strings.xml index bc3a9c857dd6..fd2aeb13ec7b 100644 --- a/packages/PackageInstaller/res/values-af/strings.xml +++ b/packages/PackageInstaller/res/values-af/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Deïnstalleer tans <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string> <string name="uninstall_done" msgid="439354138387969269">"Deïnstallering is klaar."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Het <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> gedeïnstalleer"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Deïnstallering onsuksesvol."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Kon nie <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deïnstalleer nie."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Vee tans <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-kloon uit …"</string> diff --git a/packages/PackageInstaller/res/values-am/strings.xml b/packages/PackageInstaller/res/values-am/strings.xml index de53a5e548dc..4ebcd335bae9 100644 --- a/packages/PackageInstaller/res/values-am/strings.xml +++ b/packages/PackageInstaller/res/values-am/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን በማራገፍ ላይ…"</string> <string name="uninstall_done" msgid="439354138387969269">"ማራግፍ ተጠናቅቋል።"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ተራግፏል"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"ማራገፍ አልተሳካም።"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን ማራገፍ ስኬታማ አልነበረም።"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"የተባዛ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን በመሰረዝ ላይ…"</string> diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml index f41115ba1ec4..88fd1a5b4feb 100644 --- a/packages/PackageInstaller/res/values-ar/strings.xml +++ b/packages/PackageInstaller/res/values-ar/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"جارٍ إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"تمّ إلغاء تثبيت التطبيق."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"تم إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"تعذّر إلغاء تثبيت التطبيق."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"لم يتم إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> بنجاح."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"جارٍ حذف النسخة الطبق الأصل عن \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string> diff --git a/packages/PackageInstaller/res/values-as/strings.xml b/packages/PackageInstaller/res/values-as/strings.xml index 08758a1b9cff..401ffdb4b4c6 100644 --- a/packages/PackageInstaller/res/values-as/strings.xml +++ b/packages/PackageInstaller/res/values-as/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰি থকা হৈছে…"</string> <string name="uninstall_done" msgid="439354138387969269">"আনইনষ্টল কৰা হ’ল।"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰা হ’ল"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"আনইনষ্টল কৰিব পৰা নগ\'ল।"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰিব পৰা নগ\'ল।"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ৰ ক্ল’ন মচি থকা হৈছে…"</string> diff --git a/packages/PackageInstaller/res/values-az/strings.xml b/packages/PackageInstaller/res/values-az/strings.xml index d6e117ffd881..7d46f9dfdd1f 100644 --- a/packages/PackageInstaller/res/values-az/strings.xml +++ b/packages/PackageInstaller/res/values-az/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silinir…"</string> <string name="uninstall_done" msgid="439354138387969269">"Sistemdən silindi."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silindi"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Sistemdən silinmədi."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silinmədi."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kopya silinir…"</string> diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml index 13bd74b52b11..9837d1512127 100644 --- a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml +++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se deinstalira…"</string> <string name="uninstall_done" msgid="439354138387969269">"Deinstaliranje je završeno."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je deinstalirana"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Deinstaliranje nije uspelo."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspelo."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Briše se klon aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-be/strings.xml b/packages/PackageInstaller/res/values-be/strings.xml index 9e7a0af288ec..052750f2c6cf 100644 --- a/packages/PackageInstaller/res/values-be/strings.xml +++ b/packages/PackageInstaller/res/values-be/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> выдаляецца…"</string> <string name="uninstall_done" msgid="439354138387969269">"Выдаленне завершана."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Выдалена: <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Не выдалена."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Не ўдалося выдаліць <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Выдаленне клона \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string> diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml index 140cd2fca8fb..abbd499fa492 100644 --- a/packages/PackageInstaller/res/values-bg/strings.xml +++ b/packages/PackageInstaller/res/values-bg/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string> <string name="uninstall_done" msgid="439354138387969269">"Деинсталирането завърши."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Деинсталирахте <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Деинсталирането не бе успешно."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Деинсталирането на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> не бе успешно."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Копието на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се изтрива…"</string> diff --git a/packages/PackageInstaller/res/values-bn/strings.xml b/packages/PackageInstaller/res/values-bn/strings.xml index ec64f9b43222..610412119844 100644 --- a/packages/PackageInstaller/res/values-bn/strings.xml +++ b/packages/PackageInstaller/res/values-bn/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা হচ্ছে…"</string> <string name="uninstall_done" msgid="439354138387969269">"আনইনস্টল করা শেষ হয়েছে।"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা হয়ে গেছে"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"আনইনস্টল করা যায়নি।"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা যায়নি।"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ক্লোন মুছে ফেলা হচ্ছে…"</string> diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml index 2f849a212741..2f03d027fcd3 100644 --- a/packages/PackageInstaller/res/values-bs/strings.xml +++ b/packages/PackageInstaller/res/values-bs/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Deinstaliranje je završeno."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Deinstalirana je aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Izbrisan je klon paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> <string name="uninstall_failed" msgid="1847750968168364332">"Deinstaliranje nije uspjelo."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspješno deinstaliran."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Brisanje klona aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml index 9b75fe3580d2..369c33b59426 100644 --- a/packages/PackageInstaller/res/values-ca/strings.xml +++ b/packages/PackageInstaller/res/values-ca/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"S\'està desinstal·lant <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"La desinstal·lació ha finalitzat."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"S\'ha desinstal·lat <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"No s\'ha pogut desinstal·lar."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"No s\'ha pogut desinstal·lar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"S\'està suprimint el clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml index c55695246a1e..85fcfbec18f8 100644 --- a/packages/PackageInstaller/res/values-cs/strings.xml +++ b/packages/PackageInstaller/res/values-cs/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Odinstalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Odinstalace byla dokončena."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Balíček <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> byl odinstalován"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Odinstalace se nezdařila."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Odinstalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se nezdařila."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Mazání klonu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-da/strings.xml b/packages/PackageInstaller/res/values-da/strings.xml index 7f47029608ea..b2219a783163 100644 --- a/packages/PackageInstaller/res/values-da/strings.xml +++ b/packages/PackageInstaller/res/values-da/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Afinstallerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Afinstallationen er gennemført."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> blev afinstalleret"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Appen blev ikke afinstalleret."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kunne ikke afinstalleres."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Sletter klonen af <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml index dea95e8bca12..0e595297cd6b 100644 --- a/packages/PackageInstaller/res/values-de/strings.xml +++ b/packages/PackageInstaller/res/values-de/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> wird deinstalliert…"</string> <string name="uninstall_done" msgid="439354138387969269">"Deinstallation abgeschlossen."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deinstalliert"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Deinstallation fehlgeschlagen."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Deinstallation von <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> fehlgeschlagen."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-Klon wird gelöscht…"</string> diff --git a/packages/PackageInstaller/res/values-el/strings.xml b/packages/PackageInstaller/res/values-el/strings.xml index 3c3eae8852fe..11cd8f47f2db 100644 --- a/packages/PackageInstaller/res/values-el/strings.xml +++ b/packages/PackageInstaller/res/values-el/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Απεγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Η απεγκατάσταση ολοκληρώθηκε."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Απεγκαταστάθηκε το πακέτο <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Μη επιτυχής απεγκατάσταση."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Μη επιτυχής απεγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Διαγραφή διπλότυπου εφαρμογής <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-en-rAU/strings.xml b/packages/PackageInstaller/res/values-en-rAU/strings.xml index beec7c75f43c..7bcc90fb881a 100644 --- a/packages/PackageInstaller/res/values-en-rAU/strings.xml +++ b/packages/PackageInstaller/res/values-en-rAU/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Uninstallation finished."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Deleted <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> clone"</string> <string name="uninstall_failed" msgid="1847750968168364332">"Uninstallation unsuccessful."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Deleting <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> clone…"</string> diff --git a/packages/PackageInstaller/res/values-en-rCA/strings.xml b/packages/PackageInstaller/res/values-en-rCA/strings.xml index 054506c4b560..1c3197dbb6e4 100644 --- a/packages/PackageInstaller/res/values-en-rCA/strings.xml +++ b/packages/PackageInstaller/res/values-en-rCA/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Uninstall finished."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Deleted <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> clone"</string> <string name="uninstall_failed" msgid="1847750968168364332">"Uninstall unsuccessful."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Deleting <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> clone…"</string> diff --git a/packages/PackageInstaller/res/values-en-rGB/strings.xml b/packages/PackageInstaller/res/values-en-rGB/strings.xml index beec7c75f43c..7bcc90fb881a 100644 --- a/packages/PackageInstaller/res/values-en-rGB/strings.xml +++ b/packages/PackageInstaller/res/values-en-rGB/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Uninstallation finished."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Deleted <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> clone"</string> <string name="uninstall_failed" msgid="1847750968168364332">"Uninstallation unsuccessful."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Deleting <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> clone…"</string> diff --git a/packages/PackageInstaller/res/values-en-rIN/strings.xml b/packages/PackageInstaller/res/values-en-rIN/strings.xml index beec7c75f43c..7bcc90fb881a 100644 --- a/packages/PackageInstaller/res/values-en-rIN/strings.xml +++ b/packages/PackageInstaller/res/values-en-rIN/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Uninstallation finished."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Deleted <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> clone"</string> <string name="uninstall_failed" msgid="1847750968168364332">"Uninstallation unsuccessful."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Deleting <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> clone…"</string> diff --git a/packages/PackageInstaller/res/values-en-rXC/strings.xml b/packages/PackageInstaller/res/values-en-rXC/strings.xml index d8df53235a7d..a0aaabb6ddde 100644 --- a/packages/PackageInstaller/res/values-en-rXC/strings.xml +++ b/packages/PackageInstaller/res/values-en-rXC/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Uninstall finished."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Deleted <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> clone"</string> <string name="uninstall_failed" msgid="1847750968168364332">"Uninstall unsuccessful."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Deleting <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> clone…"</string> diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml index 9d44fcc95307..9808e2a5a97d 100644 --- a/packages/PackageInstaller/res/values-es-rUS/strings.xml +++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Se completó la desinstalación."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Se desinstaló <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"No se pudo completar la desinstalación."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"No se pudo desinstalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Borrando la clonación de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml index bedb822d5009..de337d3faba0 100644 --- a/packages/PackageInstaller/res/values-es/strings.xml +++ b/packages/PackageInstaller/res/values-es/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Se ha completado la desinstalación."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Se ha desinstalado <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"No se ha podido completar la desinstalación."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"No se ha podido desinstalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Eliminando clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-et/strings.xml b/packages/PackageInstaller/res/values-et/strings.xml index 38a6fbf8de7f..555c8bfe28e7 100644 --- a/packages/PackageInstaller/res/values-et/strings.xml +++ b/packages/PackageInstaller/res/values-et/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Paketi <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine …"</string> <string name="uninstall_done" msgid="439354138387969269">"Desinstallimine on lõpetatud."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on desinstallitud"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Desinstallimine ebaõnnestus."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine ebaõnnestus."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klooni kustutamine …"</string> diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml index ad2a5be2d2e7..1a50a26835d7 100644 --- a/packages/PackageInstaller/res/values-eu/strings.xml +++ b/packages/PackageInstaller/res/values-eu/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalatzen…"</string> <string name="uninstall_done" msgid="439354138387969269">"Desinstalatu da."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Desinstalatu da <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Ezin izan da desinstalatu."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Ezin izan da desinstalatu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> aplikazioaren klona ezabatzen…"</string> diff --git a/packages/PackageInstaller/res/values-fa/strings.xml b/packages/PackageInstaller/res/values-fa/strings.xml index 2725afae6fd5..1c636c724bbc 100644 --- a/packages/PackageInstaller/res/values-fa/strings.xml +++ b/packages/PackageInstaller/res/values-fa/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"درحال حذف نصب <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"حذف نصب انجام شد."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> را حذف نصب کرد"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"حذف نصب انجام نشد."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> باموفقیت حذف نصب شد."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"درحال حذف همسانه <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-fi/strings.xml b/packages/PackageInstaller/res/values-fi/strings.xml index 0a7486db232b..e117dfb47469 100644 --- a/packages/PackageInstaller/res/values-fi/strings.xml +++ b/packages/PackageInstaller/res/values-fi/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Poistetaan pakettia <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Poisto valmis"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> poistettu"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Poisto epäonnistui."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on poistettu."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Poistetaan kloonia (<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>)…"</string> diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml index 1377f256c941..8e196905445c 100644 --- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml +++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> en cours…"</string> <string name="uninstall_done" msgid="439354138387969269">"Désinstallation terminée."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"L\'application <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a bien été désinstallée"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Échec de la désinstallation."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"La désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> n\'a pas réussi."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Suppression du clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml index 5eaea19df745..b3e76f9f61b6 100644 --- a/packages/PackageInstaller/res/values-fr/strings.xml +++ b/packages/PackageInstaller/res/values-fr/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Désinstallation terminée."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a été désinstallé"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Échec de la désinstallation."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Échec de la désinstallation du package <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Suppression du clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-gl/strings.xml b/packages/PackageInstaller/res/values-gl/strings.xml index 205cb26dd0fc..b3d9973c5d94 100644 --- a/packages/PackageInstaller/res/values-gl/strings.xml +++ b/packages/PackageInstaller/res/values-gl/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Finalizou a desinstalación."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Desinstalouse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Produciuse un erro na desinstalación."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"A desinstalación de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> non se realizou correctamente."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Eliminando clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-gu/strings.xml b/packages/PackageInstaller/res/values-gu/strings.xml index ab752e6f24df..08312709148e 100644 --- a/packages/PackageInstaller/res/values-gu/strings.xml +++ b/packages/PackageInstaller/res/values-gu/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ને અનઇન્સ્ટૉલ કરી રહ્યાં છીએ…"</string> <string name="uninstall_done" msgid="439354138387969269">"અનઇન્સ્ટૉલ કરવાનું સમાપ્ત થયું."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> અનઇન્સ્ટૉલ કર્યું"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"અનઇન્સ્ટૉલ કરવું નિષ્ફળ રહ્યું."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ને અનઇન્સ્ટૉલ કરવું અસફળ રહ્યું."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ની ક્લોન ડિલીટ કરી રહ્યાં છીએ…"</string> diff --git a/packages/PackageInstaller/res/values-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml index 3bb636dfd880..43e6e4d533bc 100644 --- a/packages/PackageInstaller/res/values-hi/strings.xml +++ b/packages/PackageInstaller/res/values-hi/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल किया जा रहा है…"</string> <string name="uninstall_done" msgid="439354138387969269">"अनइंस्टॉल हो गया."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल किया गया"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"अनइंस्टॉल नहीं किया जा सका."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को अनइंस्टॉल नहीं किया जा सका."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> का क्लोन मिटाया जा रहा है…"</string> diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml index 2eb343489f96..8e7f6feeab68 100644 --- a/packages/PackageInstaller/res/values-hr/strings.xml +++ b/packages/PackageInstaller/res/values-hr/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Deinstalacija je završena."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deinstalirana"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Izbrisan je klon paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> <string name="uninstall_failed" msgid="1847750968168364332">"Deinstalacija nije uspjela."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspjelo."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Brisanje klona za <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-hu/strings.xml b/packages/PackageInstaller/res/values-hu/strings.xml index fc2d34b09e4b..79b1f3d772f9 100644 --- a/packages/PackageInstaller/res/values-hu/strings.xml +++ b/packages/PackageInstaller/res/values-hu/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása folyamatban van…"</string> <string name="uninstall_done" msgid="439354138387969269">"Az eltávolítás befejeződött."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása befejeződött"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Az eltávolítás sikertelen."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása nem sikerült."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Klónozott <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> törlése…"</string> diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml index 8a6f3af8fa81..4b0b5490d8bf 100644 --- a/packages/PackageInstaller/res/values-hy/strings.xml +++ b/packages/PackageInstaller/res/values-hy/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածն ապատեղադրվում է…"</string> <string name="uninstall_done" msgid="439354138387969269">"Ապատեղադրվեց:"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածն ապատեղադրվեց"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Չհաջողվեց ապատեղադրել:"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Չհաջողվեց ապատեղադրել <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածը:"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ի կրկնօրինակը ջնջվում է…"</string> diff --git a/packages/PackageInstaller/res/values-in/strings.xml b/packages/PackageInstaller/res/values-in/strings.xml index 56b47ad83693..a50bf0cd9961 100644 --- a/packages/PackageInstaller/res/values-in/strings.xml +++ b/packages/PackageInstaller/res/values-in/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Meng-uninstal <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Uninstal selesai."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> di-uninstal"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Uninstal gagal."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Gagal meng-uninstal <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Menghapus clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string> diff --git a/packages/PackageInstaller/res/values-is/strings.xml b/packages/PackageInstaller/res/values-is/strings.xml index 08fa6a00bc64..7bfaff48a24c 100644 --- a/packages/PackageInstaller/res/values-is/strings.xml +++ b/packages/PackageInstaller/res/values-is/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Fjarlægir <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Forritið hefur verið fjarlægt."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Fjarlægði <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Ekki tókst að fjarlægja forritið."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Ekki tókst að fjarlægja <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Eyðir afriti af <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml index 939b1f46104c..b3eb19b80310 100644 --- a/packages/PackageInstaller/res/values-it/strings.xml +++ b/packages/PackageInstaller/res/values-it/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Disinstallazione di <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Disinstallazione completata."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"App <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> disinstallata"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Clone di <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eliminato"</string> <string name="uninstall_failed" msgid="1847750968168364332">"Disinstallazione non riuscita."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Impossibile disinstallare <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Eliminazione del clone di <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> in corso…"</string> diff --git a/packages/PackageInstaller/res/values-iw/strings.xml b/packages/PackageInstaller/res/values-iw/strings.xml index 906043f52285..2542f0eeabb2 100644 --- a/packages/PackageInstaller/res/values-iw/strings.xml +++ b/packages/PackageInstaller/res/values-iw/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"המערכת מסירה את ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"הסרת ההתקנה הסתיימה."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> הוסרה"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"לא ניתן היה להסיר את ההתקנה."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"לא ניתן היה להסיר את ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"מחיקת השכפול של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> מתבצעת…"</string> diff --git a/packages/PackageInstaller/res/values-ja/strings.xml b/packages/PackageInstaller/res/values-ja/strings.xml index d114bb294651..cacd02257e9a 100644 --- a/packages/PackageInstaller/res/values-ja/strings.xml +++ b/packages/PackageInstaller/res/values-ja/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールしています…"</string> <string name="uninstall_done" msgid="439354138387969269">"アンインストールが完了しました。"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールしました"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"削除された <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> のクローン"</string> <string name="uninstall_failed" msgid="1847750968168364332">"アンインストールできませんでした。"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールできませんでした。"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> のクローンを削除しています…"</string> diff --git a/packages/PackageInstaller/res/values-ka/strings.xml b/packages/PackageInstaller/res/values-ka/strings.xml index 82ca5a71ba13..c10074001a45 100644 --- a/packages/PackageInstaller/res/values-ka/strings.xml +++ b/packages/PackageInstaller/res/values-ka/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"მიმდინარეობს <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის დეინსტალაცია…"</string> <string name="uninstall_done" msgid="439354138387969269">"დეინსტალაცია დასრულდა."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> დეინსტალირებულია"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"დეინსტალაცია ვერ მოხერხდა."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის დეინსტალაცია ვერ მოხერხდა."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"მიმდინარეობს <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> კლონის წაშლა…"</string> diff --git a/packages/PackageInstaller/res/values-kk/strings.xml b/packages/PackageInstaller/res/values-kk/strings.xml index 562898dc7f87..b973362c97c4 100644 --- a/packages/PackageInstaller/res/values-kk/strings.xml +++ b/packages/PackageInstaller/res/values-kk/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жойылуда…"</string> <string name="uninstall_done" msgid="439354138387969269">"Жою аяқталды."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жойылды"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Жою мүмкін болмады."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жою сәтсіз аяқталды."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клоны жойылып жатыр…"</string> diff --git a/packages/PackageInstaller/res/values-km/strings.xml b/packages/PackageInstaller/res/values-km/strings.xml index 938aa3be6200..7b65679be429 100644 --- a/packages/PackageInstaller/res/values-km/strings.xml +++ b/packages/PackageInstaller/res/values-km/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"កំពុងលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"បានបញ្ចប់ការលុប។"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"បានលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"មិនអាចលុបបានទេ។"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"មិនអាចលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> បានទេ។"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"កំពុងលុបក្លូន <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml index e70d75d5f4b5..ab00502859d3 100644 --- a/packages/PackageInstaller/res/values-kn/strings.xml +++ b/packages/PackageInstaller/res/values-kn/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅನ್ನು ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string> <string name="uninstall_done" msgid="439354138387969269">"ಅನ್ಇನ್ಸ್ಟಾಲ್ ಪೂರ್ಣಗೊಂಡಿದೆ."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿದೆ"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"ಅನ್ಇನ್ಸ್ಟಾಲ್ ವಿಫಲವಾಗಿದೆ."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡುವಿಕೆ ಯಶಸ್ವಿಯಾಗಿಲ್ಲ."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಕ್ಲೋನ್ ಅನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ…"</string> diff --git a/packages/PackageInstaller/res/values-ko/strings.xml b/packages/PackageInstaller/res/values-ko/strings.xml index b5adf3fd7b82..c4014306fb32 100644 --- a/packages/PackageInstaller/res/values-ko/strings.xml +++ b/packages/PackageInstaller/res/values-ko/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 제거 중…"</string> <string name="uninstall_done" msgid="439354138387969269">"제거를 완료했습니다."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>를 제거했습니다."</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"제거하지 못했습니다."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>을(를) 제거하지 못했습니다."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 클론 삭제 중…"</string> diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml index 34c6293ee9d9..d3d82c3117b4 100644 --- a/packages/PackageInstaller/res/values-ky/strings.xml +++ b/packages/PackageInstaller/res/values-ky/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> чыгарылууда…"</string> <string name="uninstall_done" msgid="439354138387969269">"Чыгарылып салынды."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> чыгарылып салынды"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Чыгарылып салынган жок."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> чыгарылып салынган жок."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клону өчүрүлүүдө…"</string> diff --git a/packages/PackageInstaller/res/values-lo/strings.xml b/packages/PackageInstaller/res/values-lo/strings.xml index 45cd47a7e4bd..7ab33a9d3521 100644 --- a/packages/PackageInstaller/res/values-lo/strings.xml +++ b/packages/PackageInstaller/res/values-lo/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"ກຳລັງຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"ຖອນການຕິດຕັ້ງສຳເລັດແລ້ວ."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"ຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ແລ້ວ"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"ຖອນການຕິດຕັ້ງບໍ່ສຳເລັດ."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"ຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ບໍ່ສຳເລັດ."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"ກຳລັງລຶບ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ໂຄລນ…"</string> diff --git a/packages/PackageInstaller/res/values-lt/strings.xml b/packages/PackageInstaller/res/values-lt/strings.xml index a58fc8e17d3c..9ffa09cd971f 100644 --- a/packages/PackageInstaller/res/values-lt/strings.xml +++ b/packages/PackageInstaller/res/values-lt/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Pašalinamas paketas „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“…"</string> <string name="uninstall_done" msgid="439354138387969269">"Pašalinimas baigtas."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Paketas „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ pašalintas"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Ištrinta „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ kopija"</string> <string name="uninstall_failed" msgid="1847750968168364332">"Nepavyko pašalinti."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Paketo „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ pašalinimo veiksmas nesėkmingas."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Ištrinama „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ kopija…"</string> diff --git a/packages/PackageInstaller/res/values-lv/strings.xml b/packages/PackageInstaller/res/values-lv/strings.xml index b802fa20902f..c3e1a88c7eaf 100644 --- a/packages/PackageInstaller/res/values-lv/strings.xml +++ b/packages/PackageInstaller/res/values-lv/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Notiek lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> atinstalēšana…"</string> <string name="uninstall_done" msgid="439354138387969269">"Atinstalēšana ir pabeigta."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Lietotne <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ir atinstalēta"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Atinstalēšana neizdevās."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> atinstalēšana nebija sekmīga."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Notiek lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klona dzēšana…"</string> diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml index c038506bda51..e10025733790 100644 --- a/packages/PackageInstaller/res/values-mk/strings.xml +++ b/packages/PackageInstaller/res/values-mk/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Се деинсталира <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Деинсталирањето заврши."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталираше"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Избришан е клон на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> <string name="uninstall_failed" msgid="1847750968168364332">"Деинсталирањето е неуспешно."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Деинсталирањето на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> е неуспешно."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Се брише клонот на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-ml/strings.xml b/packages/PackageInstaller/res/values-ml/strings.xml index 68bb819fd3e4..ca1ae385c76f 100644 --- a/packages/PackageInstaller/res/values-ml/strings.xml +++ b/packages/PackageInstaller/res/values-ml/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺ ഇൻസ്റ്റാൾ ചെയ്യുന്നു…"</string> <string name="uninstall_done" msgid="439354138387969269">"അൺ ഇൻസ്റ്റാൾ ചെയ്യൽ പൂർത്തിയായി."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺ ഇൻസ്റ്റാൾ ചെയ്തു"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"അൺ ഇൻസ്റ്റാൾ ചെയ്യാനായില്ല."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺ ഇൻസ്റ്റാൾ ചെയ്യാനായില്ല."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ക്ലോൺ ചെയ്യൽ ഇല്ലാതാക്കുന്നു…"</string> diff --git a/packages/PackageInstaller/res/values-mn/strings.xml b/packages/PackageInstaller/res/values-mn/strings.xml index 6a95f5490fae..3be98b574030 100644 --- a/packages/PackageInstaller/res/values-mn/strings.xml +++ b/packages/PackageInstaller/res/values-mn/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгаж байна…"</string> <string name="uninstall_done" msgid="439354138387969269">"Устгаж дууслаа."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгасан"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Устгах амжилтгүй боллоо."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгах амжилтгүй боллоо."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клоныг устгаж байна…"</string> diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml index fb271b39d4bf..ffd6610e44f3 100644 --- a/packages/PackageInstaller/res/values-mr/strings.xml +++ b/packages/PackageInstaller/res/values-mr/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल करत आहे…"</string> <string name="uninstall_done" msgid="439354138387969269">"अनइंस्टॉल पूर्ण झाले."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल केले"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"अनइंस्टॉल करता आले नाही."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल करता आले नाही."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"क्लोन <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> हटवत आहे…"</string> diff --git a/packages/PackageInstaller/res/values-ms/strings.xml b/packages/PackageInstaller/res/values-ms/strings.xml index 4e9daa76b334..1c369bc3236f 100644 --- a/packages/PackageInstaller/res/values-ms/strings.xml +++ b/packages/PackageInstaller/res/values-ms/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Menyahpasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Nyahpasang selesai."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> dinyahpasang"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Penyahpasangan tidak berjaya."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Tidak berjaya menyahpasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Memadamkan klon <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-my/strings.xml b/packages/PackageInstaller/res/values-my/strings.xml index 35e82fe85ee8..08135d202b9b 100644 --- a/packages/PackageInstaller/res/values-my/strings.xml +++ b/packages/PackageInstaller/res/values-my/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှားနေပါသည်…"</string> <string name="uninstall_done" msgid="439354138387969269">"ဖယ်ရှားပြီးပါပြီ။"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှားလိုက်ပါပြီ"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"ဖယ်ရှား၍ မရပါ။"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှား၍မရပါ။"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ပုံတူပွားကို ဖျက်နေသည်…"</string> diff --git a/packages/PackageInstaller/res/values-nb/strings.xml b/packages/PackageInstaller/res/values-nb/strings.xml index 3b145d1d665d..ad49d5253cce 100644 --- a/packages/PackageInstaller/res/values-nb/strings.xml +++ b/packages/PackageInstaller/res/values-nb/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Avinstallerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string> <string name="uninstall_done" msgid="439354138387969269">"Avinstalleringen er fullført."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Avinstallerte <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Avinstalleringen mislyktes."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Kunne ikke avinstallere <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Sletter <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-klonen …"</string> diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml index 4efd35a207bd..034c6f6617e2 100644 --- a/packages/PackageInstaller/res/values-ne/strings.xml +++ b/packages/PackageInstaller/res/values-ne/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गर्दै…"</string> <string name="uninstall_done" msgid="439354138387969269">"स्थापना रद्द गर्ने काम सम्पन्न भयो।"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइन्स्टल गरियो"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"स्थापना रद्द गर्न सकिएन।"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गर्ने कार्य असफल भयो।"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> क्लोन मेटाइँदै छ…"</string> diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml index 3e859717ea54..1a732823073c 100644 --- a/packages/PackageInstaller/res/values-nl/strings.xml +++ b/packages/PackageInstaller/res/values-nl/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> verwijderen…"</string> <string name="uninstall_done" msgid="439354138387969269">"Verwijdering voltooid."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> verwijderd"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Verwijdering mislukt."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kan niet worden verwijderd."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-kloon verwijderen…"</string> diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml index f457a2da146b..95ad47055093 100644 --- a/packages/PackageInstaller/res/values-or/strings.xml +++ b/packages/PackageInstaller/res/values-or/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍ କରାଯାଉଛି…"</string> <string name="uninstall_done" msgid="439354138387969269">"ଅନଇନଷ୍ଟଲ୍ ହୋଇଗଲା।"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>କୁ ଅନଇନଷ୍ଟଲ୍ କରାଗଲା"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"ଅନଇନଷ୍ଟଲ୍ କରିହେଲା ନାହିଁ।"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍ କରିବା ସଫଳ ହେଲାନାହିଁ।"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> କ୍ଲୋନକୁ ଡିଲିଟ କରାଯାଉଛି…"</string> diff --git a/packages/PackageInstaller/res/values-pa/strings.xml b/packages/PackageInstaller/res/values-pa/strings.xml index e8977d10fca1..9e6b9b82cc58 100644 --- a/packages/PackageInstaller/res/values-pa/strings.xml +++ b/packages/PackageInstaller/res/values-pa/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string> <string name="uninstall_done" msgid="439354138387969269">"ਅਣਸਥਾਪਤ ਕਰਨਾ ਮੁਕੰਮਲ ਹੋਇਆ।"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕੀਤਾ ਗਿਆ"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"ਅਣਸਥਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ।"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ।"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਦੇ ਕਲੋਨ ਨੂੰ ਮਿਟਾਇਆ ਜਾ ਰਿਹਾ ਹੈ…"</string> diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml index e06dea679c72..678432558d03 100644 --- a/packages/PackageInstaller/res/values-pl/strings.xml +++ b/packages/PackageInstaller/res/values-pl/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Odinstalowuję <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Odinstalowywanie zakończone."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Odinstalowano aplikację <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Nie udało się odinstalować."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Nie udało się odinstalować pakietu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Usuwam klona aplikacji <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-pt-rBR/strings.xml b/packages/PackageInstaller/res/values-pt-rBR/strings.xml index 98a75cfaa5e0..8514aebabe50 100644 --- a/packages/PackageInstaller/res/values-pt-rBR/strings.xml +++ b/packages/PackageInstaller/res/values-pt-rBR/strings.xml @@ -55,7 +55,7 @@ <string name="uninstall_application_title" msgid="4045420072401428123">"Desinstalar app"</string> <string name="uninstall_update_title" msgid="824411791011583031">"Desinstalar atualização"</string> <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> é parte do seguinte app:"</string> - <string name="uninstall_application_text" msgid="3816830743706143980">"Quer desinstalar este app?"</string> + <string name="uninstall_application_text" msgid="3816830743706143980">"Você quer desinstalar este app?"</string> <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Quer desinstalar este app para "<b>"todos"</b>" os usuários? O aplicativo e os dados dele serão removidos para "<b>"todos"</b>" os usuários do dispositivo."</string> <string name="uninstall_application_text_user" msgid="498072714173920526">"Quer desinstalar este app para o usuário <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Você quer desinstalar esse app do seu perfil de trabalho?"</string> @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Desinstalação concluída."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalado"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Falha na desinstalação."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Falha na desinstalação de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Excluindo o clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml index 07bd2de2f4da..248c3668cd52 100644 --- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml +++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"A desinstalar a app <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Desinstalação concluída."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"A app <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> foi desinstalada"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Desinstalação sem êxito."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Falha ao desinstalar a app <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"A apagar o clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-pt/strings.xml b/packages/PackageInstaller/res/values-pt/strings.xml index 98a75cfaa5e0..8514aebabe50 100644 --- a/packages/PackageInstaller/res/values-pt/strings.xml +++ b/packages/PackageInstaller/res/values-pt/strings.xml @@ -55,7 +55,7 @@ <string name="uninstall_application_title" msgid="4045420072401428123">"Desinstalar app"</string> <string name="uninstall_update_title" msgid="824411791011583031">"Desinstalar atualização"</string> <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> é parte do seguinte app:"</string> - <string name="uninstall_application_text" msgid="3816830743706143980">"Quer desinstalar este app?"</string> + <string name="uninstall_application_text" msgid="3816830743706143980">"Você quer desinstalar este app?"</string> <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Quer desinstalar este app para "<b>"todos"</b>" os usuários? O aplicativo e os dados dele serão removidos para "<b>"todos"</b>" os usuários do dispositivo."</string> <string name="uninstall_application_text_user" msgid="498072714173920526">"Quer desinstalar este app para o usuário <xliff:g id="USERNAME">%1$s</xliff:g>?"</string> <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Você quer desinstalar esse app do seu perfil de trabalho?"</string> @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Desinstalação concluída."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalado"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Falha na desinstalação."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Falha na desinstalação de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Excluindo o clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-ro/strings.xml b/packages/PackageInstaller/res/values-ro/strings.xml index 7a18b2af40e0..2dc2b0c43831 100644 --- a/packages/PackageInstaller/res/values-ro/strings.xml +++ b/packages/PackageInstaller/res/values-ro/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Se dezinstalează <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Dezinstalare finalizată."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> s-a dezinstalat"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Dezinstalare nefinalizată."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nu s-a putut dezinstala."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Se șterge clona <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-ru/strings.xml b/packages/PackageInstaller/res/values-ru/strings.xml index 3bc40c3ce7ce..e811b4e34544 100644 --- a/packages/PackageInstaller/res/values-ru/strings.xml +++ b/packages/PackageInstaller/res/values-ru/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Удаление приложения \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string> <string name="uninstall_done" msgid="439354138387969269">"Удаление завершено."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Приложение \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\" удалено."</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"При удалении произошла ошибка."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Не удалось удалить приложение \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Удаление клона пакета \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string> diff --git a/packages/PackageInstaller/res/values-si/strings.xml b/packages/PackageInstaller/res/values-si/strings.xml index 9d400ef59d3d..dfd88ef7f05e 100644 --- a/packages/PackageInstaller/res/values-si/strings.xml +++ b/packages/PackageInstaller/res/values-si/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කරමින්…"</string> <string name="uninstall_done" msgid="439354138387969269">"අස්ථාපනය කිරීම අවසානයි."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කරන ලදී"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"අස්ථාපනය කිරිම අසාර්ථක විය."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කිරීම සාර්ථකයි."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ක්ලෝනය මකමින්…"</string> diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml index cb3cdaec42ca..8620d60338ac 100644 --- a/packages/PackageInstaller/res/values-sk/strings.xml +++ b/packages/PackageInstaller/res/values-sk/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Prebieha odinštalovanie balíka <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Odinštalovanie bolo dokončené."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Balík <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> bol odinštalovaný"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Nepodarilo sa odinštalovať."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Balík <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sa nepodarilo odinštalovať."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Klon <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sa odstraňuje…"</string> diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml index 654fba1b3490..f083ec264f5a 100644 --- a/packages/PackageInstaller/res/values-sl/strings.xml +++ b/packages/PackageInstaller/res/values-sl/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Odmeščanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string> <string name="uninstall_done" msgid="439354138387969269">"Odstranitev je končana."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je bila odstranjena."</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Odstranitev ni uspela."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Odmeščanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ni uspelo."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Brisanje kloniranega paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string> diff --git a/packages/PackageInstaller/res/values-sq/strings.xml b/packages/PackageInstaller/res/values-sq/strings.xml index b967259e1fc9..271a7b30128f 100644 --- a/packages/PackageInstaller/res/values-sq/strings.xml +++ b/packages/PackageInstaller/res/values-sq/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> po çinstalohet…"</string> <string name="uninstall_done" msgid="439354138387969269">"Çinstalimi përfundoi."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> u çinstalua"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Çinstalimi nuk pati sukses."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Çinstalimi i <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nuk u krye me sukses."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Po fshihet kloni i <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-sr/strings.xml b/packages/PackageInstaller/res/values-sr/strings.xml index 8858ef5e8d65..3ac1995481a0 100644 --- a/packages/PackageInstaller/res/values-sr/strings.xml +++ b/packages/PackageInstaller/res/values-sr/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string> <string name="uninstall_done" msgid="439354138387969269">"Деинсталирање је завршено."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Апликација <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> је деинсталирана"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Деинсталирање није успело."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Деинсталирање апликације <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> није успело."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Брише се клон апликације <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-sv/strings.xml b/packages/PackageInstaller/res/values-sv/strings.xml index 43f3d4c8a9b1..86813922df0d 100644 --- a/packages/PackageInstaller/res/values-sv/strings.xml +++ b/packages/PackageInstaller/res/values-sv/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> avinstalleras …"</string> <string name="uninstall_done" msgid="439354138387969269">"Avinstallationen har slutförts."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> har avinstallerats"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Det gick inte att avinstallera."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Det gick inte att avinstallera <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Raderar klonen av <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string> diff --git a/packages/PackageInstaller/res/values-sw/strings.xml b/packages/PackageInstaller/res/values-sw/strings.xml index 978f6676d1e8..849a0424bd67 100644 --- a/packages/PackageInstaller/res/values-sw/strings.xml +++ b/packages/PackageInstaller/res/values-sw/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Inaondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Imeondolewa."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Imeondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Imeshindwa kuondoa."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Imeshindwa kuondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Inafuta nakala ya <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-ta/strings.xml b/packages/PackageInstaller/res/values-ta/strings.xml index eaa8711ab966..564606a7edbf 100644 --- a/packages/PackageInstaller/res/values-ta/strings.xml +++ b/packages/PackageInstaller/res/values-ta/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவல் நீக்குகிறது…"</string> <string name="uninstall_done" msgid="439354138387969269">"நிறுவல் நீக்கம் முடிந்தது."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> நிறுவல் நீக்கப்பட்டது"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"நிறுவல் நீக்க இயலவில்லை."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவல் நீக்குவதில் தோல்வி."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> குளோனை நீக்குகிறது…"</string> diff --git a/packages/PackageInstaller/res/values-te/strings.xml b/packages/PackageInstaller/res/values-te/strings.xml index a6cd3e7b4423..b1662eb084f5 100644 --- a/packages/PackageInstaller/res/values-te/strings.xml +++ b/packages/PackageInstaller/res/values-te/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ని అన్ఇన్స్టాల్ చేస్తోంది…"</string> <string name="uninstall_done" msgid="439354138387969269">"అన్ఇన్స్టాల్ చేయడం ముగిసింది."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> అన్ఇన్స్టాల్ చేయబడింది"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"అన్ఇన్స్టాల్ చేయడం విజయవంతం కాలేదు."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> అన్ఇన్స్టాల్ చేయడంలో విఫలమైంది."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> క్లోన్ను తొలగిస్తోంది…"</string> diff --git a/packages/PackageInstaller/res/values-th/strings.xml b/packages/PackageInstaller/res/values-th/strings.xml index fd1af0b1add7..c0fe2ed1bde2 100644 --- a/packages/PackageInstaller/res/values-th/strings.xml +++ b/packages/PackageInstaller/res/values-th/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"กำลังถอนการติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"ถอนการติดตั้งเสร็จแล้ว"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"ถอนการติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> แล้ว"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"ลบโคลนของ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> แล้ว"</string> <string name="uninstall_failed" msgid="1847750968168364332">"ถอนการติดตั้งไม่สำเร็จ"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"ถอนการติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ไม่สำเร็จ"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"กำลังลบโคลนของ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-tl/strings.xml b/packages/PackageInstaller/res/values-tl/strings.xml index f46be7fe9f6f..f194e86fb03d 100644 --- a/packages/PackageInstaller/res/values-tl/strings.xml +++ b/packages/PackageInstaller/res/values-tl/strings.xml @@ -70,6 +70,7 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Ina-uninstall ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Tapos na ang pag-uninstall."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Na-uninstall ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Na-delete na ang clone ng <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> <string name="uninstall_failed" msgid="1847750968168364332">"Hindi matagumpay ang pag-uninstall."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Hindi matagumpay ang pag-uninstall sa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Dine-delete ang clone ng <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-tr/strings.xml b/packages/PackageInstaller/res/values-tr/strings.xml index 7548c5da0345..fb64517cc707 100644 --- a/packages/PackageInstaller/res/values-tr/strings.xml +++ b/packages/PackageInstaller/res/values-tr/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırılıyor…"</string> <string name="uninstall_done" msgid="439354138387969269">"Yüklemeyi kaldırma işlemi tamamlandı."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırıldı"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Yükleme kaldırılamadı."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırılamadı."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klonu siliniyor…"</string> diff --git a/packages/PackageInstaller/res/values-uk/strings.xml b/packages/PackageInstaller/res/values-uk/strings.xml index 48ff5544d25d..1b805d3047f4 100644 --- a/packages/PackageInstaller/res/values-uk/strings.xml +++ b/packages/PackageInstaller/res/values-uk/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Видалення додатка <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Видалено."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Додаток <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> видалено"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Не видалено."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Не вдалося видалити додаток <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Видалення копії додатка <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-ur/strings.xml b/packages/PackageInstaller/res/values-ur/strings.xml index 1327d481f500..03ee46a52e41 100644 --- a/packages/PackageInstaller/res/values-ur/strings.xml +++ b/packages/PackageInstaller/res/values-ur/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ان انسٹال ہو رہا ہے…"</string> <string name="uninstall_done" msgid="439354138387969269">"اَن انسٹال مکمل ہو گیا۔"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> اَن انسٹال ہو گیا"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"اَن انسٹال ناکام ہو گیا۔"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کو ان انسٹال کرنا ناکام ہو گیا۔"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کلون کو حذف کیا جا رہا ہے…"</string> diff --git a/packages/PackageInstaller/res/values-uz/strings.xml b/packages/PackageInstaller/res/values-uz/strings.xml index ef8f6b3b364b..aeb00cc6d624 100644 --- a/packages/PackageInstaller/res/values-uz/strings.xml +++ b/packages/PackageInstaller/res/values-uz/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘chirilmoqda…"</string> <string name="uninstall_done" msgid="439354138387969269">"O‘chirib tashlandi."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘chirib tashlandi"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"O‘chirib tashlanmadi."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ilovasini o‘chirib bo‘lmadi."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nusxasi oʻchirilmoqda…"</string> diff --git a/packages/PackageInstaller/res/values-vi/strings.xml b/packages/PackageInstaller/res/values-vi/strings.xml index 2d49c9b8983f..7fbc74cd50ed 100644 --- a/packages/PackageInstaller/res/values-vi/strings.xml +++ b/packages/PackageInstaller/res/values-vi/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Đang gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Đã gỡ cài đặt xong."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Đã gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Gỡ cài đặt không thành công."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> không thành công."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Đang xoá bản sao của <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> diff --git a/packages/PackageInstaller/res/values-zh-rCN/strings.xml b/packages/PackageInstaller/res/values-zh-rCN/strings.xml index eb1332170aa0..b5f3cba5801b 100644 --- a/packages/PackageInstaller/res/values-zh-rCN/strings.xml +++ b/packages/PackageInstaller/res/values-zh-rCN/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"正在卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"卸载完成。"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"已卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"卸载失败。"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>失败。"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"正在删除 <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 克隆应用…"</string> diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml index d7fb07e32194..74e8bea236a5 100644 --- a/packages/PackageInstaller/res/values-zh-rHK/strings.xml +++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"正在解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string> <string name="uninstall_done" msgid="439354138387969269">"完成解除安裝。"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"已解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"解除安裝失敗。"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」失敗。"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"正在刪除「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」複製本…"</string> diff --git a/packages/PackageInstaller/res/values-zh-rTW/strings.xml b/packages/PackageInstaller/res/values-zh-rTW/strings.xml index a825d20aa35b..a3380158f42f 100644 --- a/packages/PackageInstaller/res/values-zh-rTW/strings.xml +++ b/packages/PackageInstaller/res/values-zh-rTW/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"正在解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string> <string name="uninstall_done" msgid="439354138387969269">"已順利解除安裝。"</string> <string name="uninstall_done_app" msgid="4588850984473605768">"已解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"無法解除安裝。"</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"無法解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」。"</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"正在刪除「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」副本…"</string> diff --git a/packages/PackageInstaller/res/values-zu/strings.xml b/packages/PackageInstaller/res/values-zu/strings.xml index 62c8a9a0c4d9..9298cbd783e1 100644 --- a/packages/PackageInstaller/res/values-zu/strings.xml +++ b/packages/PackageInstaller/res/values-zu/strings.xml @@ -70,6 +70,8 @@ <string name="uninstalling_app" msgid="8866082646836981397">"Ikhipha i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string> <string name="uninstall_done" msgid="439354138387969269">"Ukukhipha kuqedile."</string> <string name="uninstall_done_app" msgid="4588850984473605768">"Kukhishwe i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for uninstall_done_clone_app (5578308154544195413) --> + <skip /> <string name="uninstall_failed" msgid="1847750968168364332">"Ukukhipha akuphumelelanga."</string> <string name="uninstall_failed_app" msgid="5506028705017601412">"Ukukhipha i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> akuphumelele."</string> <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Isula <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> i-clone…"</string> diff --git a/packages/SettingsLib/Spa/build.gradle b/packages/SettingsLib/Spa/build.gradle index ded62516bb68..9117524a3e88 100644 --- a/packages/SettingsLib/Spa/build.gradle +++ b/packages/SettingsLib/Spa/build.gradle @@ -19,12 +19,12 @@ buildscript { BUILD_TOOLS_VERSION = "30.0.3" MIN_SDK = 21 TARGET_SDK = 33 - jetpack_compose_version = '1.4.0-alpha03' - jetpack_compose_compiler_version = '1.3.2' + jetpack_compose_version = '1.4.0-alpha05' + jetpack_compose_compiler_version = '1.4.0' } } plugins { id 'com.android.application' version '7.3.1' apply false id 'com.android.library' version '7.3.1' apply false - id 'org.jetbrains.kotlin.android' version '1.7.20' apply false + id 'org.jetbrains.kotlin.android' version '1.8.0' apply false } diff --git a/packages/SettingsLib/Spa/spa/build.gradle b/packages/SettingsLib/Spa/spa/build.gradle index bf4ad758e465..e03561566402 100644 --- a/packages/SettingsLib/Spa/spa/build.gradle +++ b/packages/SettingsLib/Spa/spa/build.gradle @@ -75,9 +75,9 @@ dependencies { api "androidx.slice:slice-builders:1.1.0-alpha02" api "androidx.slice:slice-core:1.1.0-alpha02" api "androidx.slice:slice-view:1.1.0-alpha02" - api "androidx.compose.material3:material3:1.1.0-alpha03" + api "androidx.compose.material3:material3:1.1.0-alpha05" api "androidx.compose.material:material-icons-extended:$jetpack_compose_version" - api "androidx.compose.runtime:runtime-livedata:$jetpack_compose_version" + api "androidx.compose.runtime:runtime-livedata:1.4.0-alpha04" api "androidx.compose.ui:ui-tooling-preview:$jetpack_compose_version" api "androidx.lifecycle:lifecycle-livedata-ktx:$jetpack_lifecycle_version" api "androidx.lifecycle:lifecycle-runtime-compose:$jetpack_lifecycle_version" diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugActivity.kt index f7cbdae6909f..72f662ff7d08 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugActivity.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugActivity.kt @@ -62,7 +62,7 @@ private const val PARAM_NAME_ENTRY_ID = "eid" /** * The Debug Activity to display all Spa Pages & Entries. * One can open the debug activity by: - * $ adb shell am start -n <Package>/com.android.settingslib.spa.framework.debug.DebugActivity + * $ adb shell am start -n <Package>/com.android.settingslib.spa.debug.DebugActivity * For gallery, Package = com.android.settingslib.spa.gallery */ class DebugActivity : ComponentActivity() { diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt index ae88ed7c99b9..e8b5b19daad0 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt @@ -50,6 +50,8 @@ import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.SideEffect import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -61,6 +63,7 @@ import androidx.compose.ui.layout.AlignmentLine import androidx.compose.ui.layout.LastBaseline import androidx.compose.ui.layout.Layout import androidx.compose.ui.layout.layoutId +import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.text.TextStyle @@ -116,7 +119,7 @@ internal fun CustomizedLargeTopAppBar( actions = actions, colors = topAppBarColors(), windowInsets = TopAppBarDefaults.windowInsets, - maxHeight = 176.dp, + maxHeightWithoutTitle = 120.dp, pinnedHeight = ContainerHeight, scrollBehavior = scrollBehavior, ) @@ -258,8 +261,8 @@ private fun SingleRowTopAppBar( * A two-rows top app bar that is designed to be called by the Large and Medium top app bar * composables. * - * @throws [IllegalArgumentException] if the given [maxHeight] is equal or smaller than the - * [pinnedHeight] + * @throws [IllegalArgumentException] if the given [maxHeightWithoutTitle] is equal or smaller than + * the [pinnedHeight] */ @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -274,29 +277,31 @@ private fun TwoRowsTopAppBar( actions: @Composable RowScope.() -> Unit, windowInsets: WindowInsets, colors: TopAppBarColors, - maxHeight: Dp, + maxHeightWithoutTitle: Dp, pinnedHeight: Dp, scrollBehavior: TopAppBarScrollBehavior? ) { - if (maxHeight <= pinnedHeight) { + if (maxHeightWithoutTitle <= pinnedHeight) { throw IllegalArgumentException( "A TwoRowsTopAppBar max height should be greater than its pinned height" ) } val pinnedHeightPx: Float - val maxHeightPx: Float + val density = LocalDensity.current + val maxHeightPx = density.run { + remember { mutableStateOf((maxHeightWithoutTitle + pinnedHeight).toPx()) } + } val titleBottomPaddingPx: Int - LocalDensity.current.run { + density.run { pinnedHeightPx = pinnedHeight.toPx() - maxHeightPx = maxHeight.toPx() titleBottomPaddingPx = titleBottomPadding.roundToPx() } // Sets the app bar's height offset limit to hide just the bottom title area and keep top title // visible when collapsed. SideEffect { - if (scrollBehavior?.state?.heightOffsetLimit != pinnedHeightPx - maxHeightPx) { - scrollBehavior?.state?.heightOffsetLimit = pinnedHeightPx - maxHeightPx + if (scrollBehavior?.state?.heightOffsetLimit != pinnedHeightPx - maxHeightPx.value) { + scrollBehavior?.state?.heightOffsetLimit = pinnedHeightPx - maxHeightPx.value } } @@ -366,12 +371,19 @@ private fun TwoRowsTopAppBar( ) TopAppBarLayout( modifier = Modifier.clipToBounds(), - heightPx = maxHeightPx - pinnedHeightPx + (scrollBehavior?.state?.heightOffset - ?: 0f), + heightPx = maxHeightPx.value - pinnedHeightPx + + (scrollBehavior?.state?.heightOffset ?: 0f), navigationIconContentColor = colors.navigationIconContentColor, titleContentColor = colors.titleContentColor, actionIconContentColor = colors.actionIconContentColor, - title = title, + title = { + Box(modifier = Modifier.onGloballyPositioned { coordinates -> + density.run { + maxHeightPx.value = + maxHeightWithoutTitle.toPx() + coordinates.size.height.toFloat() + } + }) { title() } + }, titleTextStyle = titleTextStyle, titleAlpha = bottomTitleAlpha, titleVerticalArrangement = Arrangement.Bottom, diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java index 7c75bc42dbfc..c9d840a77b80 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java @@ -92,6 +92,10 @@ public class SystemSettings { Settings.System.CLOCKWORK_BLUETOOTH_SETTINGS_PREF, Settings.System.UNREAD_NOTIFICATION_DOT_INDICATOR, Settings.System.AUTO_LAUNCH_MEDIA_CONTROLS, - Settings.System.LOCALE_PREFERENCES + Settings.System.LOCALE_PREFERENCES, + Settings.System.TOUCHPAD_POINTER_SPEED, + Settings.System.TOUCHPAD_NATURAL_SCROLLING, + Settings.System.TOUCHPAD_TAP_TO_CLICK, + Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, }; } diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java index bd43606f1678..c2a3ada53591 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java @@ -186,6 +186,10 @@ public class SystemSettingsValidators { VALIDATORS.put(System.SIP_ADDRESS_ONLY, BOOLEAN_VALIDATOR); VALIDATORS.put(System.SIP_ASK_ME_EACH_TIME, BOOLEAN_VALIDATOR); VALIDATORS.put(System.POINTER_SPEED, new InclusiveFloatRangeValidator(-7, 7)); + VALIDATORS.put(System.TOUCHPAD_POINTER_SPEED, new InclusiveIntegerRangeValidator(-7, 7)); + VALIDATORS.put(System.TOUCHPAD_NATURAL_SCROLLING, BOOLEAN_VALIDATOR); + VALIDATORS.put(System.TOUCHPAD_TAP_TO_CLICK, BOOLEAN_VALIDATOR); + VALIDATORS.put(System.TOUCHPAD_RIGHT_CLICK_ZONE, BOOLEAN_VALIDATOR); VALIDATORS.put(System.LOCK_TO_APP_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put( System.EGG_MODE, diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index 75d28d551e6b..25b990694646 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -2913,6 +2913,22 @@ class SettingsProtoDumpUtil { dumpSetting(s, p, Settings.System.TIME_12_24, SystemSettingsProto.TIME_12_24); + + final long touchpadToken = p.start(SystemSettingsProto.TOUCHPAD); + dumpSetting(s, p, + Settings.System.TOUCHPAD_NATURAL_SCROLLING, + SystemSettingsProto.Touchpad.NATURAL_SCROLLING); + dumpSetting(s, p, + Settings.System.TOUCHPAD_POINTER_SPEED, + SystemSettingsProto.Touchpad.POINTER_SPEED); + dumpSetting(s, p, + Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, + SystemSettingsProto.Touchpad.RIGHT_CLICK_ZONE); + dumpSetting(s, p, + Settings.System.TOUCHPAD_TAP_TO_CLICK, + SystemSettingsProto.Touchpad.TAP_TO_CLICK); + p.end(touchpadToken); + dumpSetting(s, p, Settings.System.TTY_MODE, SystemSettingsProto.TTY_MODE); diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 2779fa282836..0664061401f3 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -49,6 +49,7 @@ <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" /> <uses-permission android:name="android.permission.RECEIVE_MMS" /> <uses-permission android:name="android.permission.READ_CELL_BROADCASTS" /> + <uses-permission android:name="android.permission.SATELLITE_COMMUNICATION" /> <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" /> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" /> diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt index c729b09628af..17a94b8639d0 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt @@ -41,6 +41,7 @@ import androidx.annotation.BinderThread import androidx.annotation.UiThread import com.android.internal.annotations.VisibleForTesting import com.android.internal.policy.ScreenDecorationsUtils +import java.lang.IllegalArgumentException import kotlin.math.roundToInt private const val TAG = "ActivityLaunchAnimator" @@ -338,13 +339,24 @@ class ActivityLaunchAnimator( * Return a [Controller] that will animate and expand [view] into the opening window. * * Important: The view must be attached to a [ViewGroup] when calling this function and - * during the animation. For safety, this method will return null when it is not. + * during the animation. For safety, this method will return null when it is not. The + * view must also implement [LaunchableView], otherwise this method will throw. * * Note: The background of [view] should be a (rounded) rectangle so that it can be * properly animated. */ @JvmStatic fun fromView(view: View, cujType: Int? = null): Controller? { + // Make sure the View we launch from implements LaunchableView to avoid visibility + // issues. + if (view !is LaunchableView) { + throw IllegalArgumentException( + "An ActivityLaunchAnimator.Controller was created from a View that does " + + "not implement LaunchableView. This can lead to subtle bugs where the" + + " visibility of the View we are launching from is not what we expected." + ) + } + if (view.parent !is ViewGroup) { Log.e( TAG, diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt index e91a6710ace5..b8d78fb208f4 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt @@ -40,6 +40,7 @@ import com.android.systemui.animation.back.BackAnimationSpec import com.android.systemui.animation.back.applyTo import com.android.systemui.animation.back.floatingSystemSurfacesForSysUi import com.android.systemui.animation.back.onBackAnimationCallbackFrom +import java.lang.IllegalArgumentException import kotlin.math.roundToInt private const val TAG = "DialogLaunchAnimator" @@ -157,12 +158,23 @@ constructor( * Create a [Controller] that can animate [source] to and from a dialog. * * Important: The view must be attached to a [ViewGroup] when calling this function and - * during the animation. For safety, this method will return null when it is not. + * during the animation. For safety, this method will return null when it is not. The + * view must also implement [LaunchableView], otherwise this method will throw. * * Note: The background of [view] should be a (rounded) rectangle so that it can be * properly animated. */ fun fromView(source: View, cuj: DialogCuj? = null): Controller? { + // Make sure the View we launch from implements LaunchableView to avoid visibility + // issues. + if (source !is LaunchableView) { + throw IllegalArgumentException( + "A DialogLaunchAnimator.Controller was created from a View that does not " + + "implement LaunchableView. This can lead to subtle bugs where the " + + "visibility of the View we are launching from is not what we expected." + ) + } + if (source.parent !is ViewGroup) { Log.e( TAG, @@ -249,23 +261,6 @@ constructor( } ?: controller - if ( - animatedParent == null && - controller is ViewDialogLaunchAnimatorController && - controller.source !is LaunchableView - ) { - // Make sure the View we launch from implements LaunchableView to avoid visibility - // issues. Given that we don't own dialog decorViews so we can't enforce it for launches - // from a dialog. - // TODO(b/243636422): Throw instead of logging to enforce this. - Log.w( - TAG, - "A dialog was launched from a View that does not implement LaunchableView. This " + - "can lead to subtle bugs where the visibility of the View we are " + - "launching from is not what we expected." - ) - } - // Make sure we don't run the launch animation from the same source twice at the same time. if (openedDialogs.any { it.controller.sourceIdentity == controller.sourceIdentity }) { Log.e( @@ -613,10 +608,16 @@ private class AnimatedDialog( } // Animate that view with the background. Throw if we didn't find one, because - // otherwise - // it's not clear what we should animate. + // otherwise it's not clear what we should animate. + if (viewGroupWithBackground == null) { + error("Unable to find ViewGroup with background") + } + + if (viewGroupWithBackground !is LaunchableView) { + error("The animated ViewGroup with background must implement LaunchableView") + } + viewGroupWithBackground - ?: throw IllegalStateException("Unable to find ViewGroup with background") } else { // We will make the dialog window (and therefore its DecorView) fullscreen to make // it possible to animate outside its bounds. @@ -639,7 +640,7 @@ private class AnimatedDialog( FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) ) - val dialogContentWithBackground = FrameLayout(dialog.context) + val dialogContentWithBackground = LaunchableFrameLayout(dialog.context) dialogContentWithBackground.background = decorView.background // Make the window background transparent. Note that setting the window (or @@ -720,7 +721,10 @@ private class AnimatedDialog( // Make the background view invisible until we start the animation. We use the transition // visibility like GhostView does so that we don't mess up with the accessibility tree (see - // b/204944038#comment17). + // b/204944038#comment17). Given that this background implements LaunchableView, we call + // setShouldBlockVisibilityChanges() early so that the current visibility (VISIBLE) is + // restored at the end of the animation. + dialogContentWithBackground.setShouldBlockVisibilityChanges(true) dialogContentWithBackground.setTransitionVisibility(View.INVISIBLE) // Make sure the dialog is visible instantly and does not do any window animation. diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt index 26aa0e85cbd2..23e3a01c2686 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt @@ -34,6 +34,7 @@ import android.view.ViewGroup import android.view.ViewGroupOverlay import android.widget.FrameLayout import com.android.internal.jank.InteractionJankMonitor +import java.lang.IllegalArgumentException import java.util.LinkedList import kotlin.math.min import kotlin.math.roundToInt @@ -46,7 +47,8 @@ private const val TAG = "GhostedViewLaunchAnimatorController" * of the ghosted view. * * Important: [ghostedView] must be attached to a [ViewGroup] when calling this function and during - * the animation. + * the animation. It must also implement [LaunchableView], otherwise an exception will be thrown + * during this controller instantiation. * * Note: Avoid instantiating this directly and call [ActivityLaunchAnimator.Controller.fromView] * whenever possible instead. @@ -101,6 +103,15 @@ constructor( private val background: Drawable? init { + // Make sure the View we launch from implements LaunchableView to avoid visibility issues. + if (ghostedView !is LaunchableView) { + throw IllegalArgumentException( + "A GhostedViewLaunchAnimatorController was created from a View that does not " + + "implement LaunchableView. This can lead to subtle bugs where the visibility " + + "of the View we are launching from is not what we expected." + ) + } + /** Find the first view with a background in [view] and its children. */ fun findBackground(view: View): Drawable? { if (view.background != null) { diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableFrameLayout.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableFrameLayout.kt new file mode 100644 index 000000000000..2eb503b43cc5 --- /dev/null +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableFrameLayout.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.animation + +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout + +/** A [FrameLayout] that also implements [LaunchableView]. */ +open class LaunchableFrameLayout : FrameLayout, LaunchableView { + private val delegate = + LaunchableViewDelegate( + this, + superSetVisibility = { super.setVisibility(it) }, + ) + + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int + ) : super(context, attrs, defStyleAttr) + + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int + ) : super(context, attrs, defStyleAttr, defStyleRes) + + override fun setShouldBlockVisibilityChanges(block: Boolean) { + delegate.setShouldBlockVisibilityChanges(block) + } + + override fun setVisibility(visibility: Int) { + delegate.setVisibility(visibility) + } +} diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt index 9257f99efe96..46d5a5c0af8c 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt @@ -25,7 +25,7 @@ import com.android.internal.jank.InteractionJankMonitor /** A [DialogLaunchAnimator.Controller] that can animate a [View] from/to a dialog. */ class ViewDialogLaunchAnimatorController internal constructor( - internal val source: View, + private val source: View, override val cuj: DialogCuj?, ) : DialogLaunchAnimator.Controller { override val viewRoot: ViewRootImpl? diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt index fd9355d6a77d..e4f6db57f689 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt @@ -30,8 +30,8 @@ object ViewRootSync { val syncGroup = SurfaceSyncGroup("SysUIAnimation") syncGroup.addSyncCompleteCallback(view.context.mainExecutor) { then() } - syncGroup.addToSync(view.rootSurfaceControl) - syncGroup.addToSync(otherView.rootSurfaceControl) + syncGroup.add(view.rootSurfaceControl, null /* runnable */) + syncGroup.add(otherView.rootSurfaceControl, null /* runnable */) syncGroup.markSyncReady() } diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt index 0e3d41c40c97..7897934fa264 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt @@ -48,7 +48,7 @@ class RippleAnimation(private val config: RippleAnimationConfig) { animator.addUpdateListener { updateListener -> val now = updateListener.currentPlayTime val progress = updateListener.animatedValue as Float - rippleShader.progress = progress + rippleShader.rawProgress = progress rippleShader.distortionStrength = if (config.shouldDistort) 1 - progress else 0f rippleShader.time = now.toFloat() } diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt index 90585109643a..4322d53bcab9 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt @@ -18,6 +18,7 @@ package com.android.systemui.surfaceeffects.ripple import android.graphics.PointF import android.graphics.RuntimeShader import android.util.MathUtils +import com.android.systemui.animation.Interpolators import com.android.systemui.surfaceeffects.shaderutil.SdfShaderLibrary import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary @@ -47,7 +48,6 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) : """ uniform vec2 in_center; uniform vec2 in_size; - uniform float in_progress; uniform float in_cornerRadius; uniform float in_thickness; uniform float in_time; @@ -162,21 +162,15 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) : maxSize.y = height } - /** Progress of the ripple. Float value between [0, 1]. */ - var progress: Float = 0.0f + /** + * Linear progress of the ripple. Float value between [0, 1]. + * + * <p>Note that the progress here is expected to be linear without any curve applied. + */ + var rawProgress: Float = 0.0f set(value) { field = value - setFloatUniform("in_progress", value) - val curvedProg = 1 - (1 - value) * (1 - value) * (1 - value) - - currentWidth = maxSize.x * curvedProg - currentHeight = maxSize.y * curvedProg - setFloatUniform("in_size", /* width= */ currentWidth, /* height= */ currentHeight) - setFloatUniform("in_thickness", maxSize.y * curvedProg * 0.5f) - // radius should not exceed width and height values. - setFloatUniform("in_cornerRadius", Math.min(maxSize.x, maxSize.y) * curvedProg) - - setFloatUniform("in_blur", MathUtils.lerp(1.25f, 0.5f, value)) + progress = Interpolators.STANDARD.getInterpolation(value) val fadeIn = subProgress(0f, 0.1f, value) val fadeOutNoise = subProgress(0.4f, 1f, value) @@ -191,6 +185,20 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) : setFloatUniform("in_fadeRing", Math.min(fadeIn, 1 - fadeOutRipple)) } + /** Progress with Standard easing curve applied. */ + private var progress: Float = 0.0f + set(value) { + currentWidth = maxSize.x * value + currentHeight = maxSize.y * value + setFloatUniform("in_size", currentWidth, currentHeight) + + setFloatUniform("in_thickness", maxSize.y * value * 0.5f) + // radius should not exceed width and height values. + setFloatUniform("in_cornerRadius", Math.min(maxSize.x, maxSize.y) * value) + + setFloatUniform("in_blur", MathUtils.lerp(1.25f, 0.5f, value)) + } + /** Play time since the start of the effect. */ var time: Float = 0.0f set(value) { @@ -220,7 +228,7 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) : var distortionStrength: Float = 0.0f set(value) { field = value - setFloatUniform("in_distort_radial", 75 * progress * value) + setFloatUniform("in_distort_radial", 75 * rawProgress * value) setFloatUniform("in_distort_xy", 75 * value) } diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt index b37c73417119..bc4796aff042 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt @@ -77,7 +77,7 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a rippleShader = RippleShader(rippleShape) rippleShader.color = RippleAnimationConfig.RIPPLE_DEFAULT_COLOR - rippleShader.progress = 0f + rippleShader.rawProgress = 0f rippleShader.sparkleStrength = RippleAnimationConfig.RIPPLE_SPARKLE_STRENGTH rippleShader.pixelDensity = resources.displayMetrics.density @@ -93,7 +93,7 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a animator.addUpdateListener { updateListener -> val now = updateListener.currentPlayTime val progress = updateListener.animatedValue as Float - rippleShader.progress = progress + rippleShader.rawProgress = progress rippleShader.distortionStrength = 1 - progress rippleShader.time = now.toFloat() invalidate() @@ -142,25 +142,13 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a } // To reduce overdraw, we mask the effect to a circle or a rectangle that's bigger than the // active effect area. Values here should be kept in sync with the animation implementation - // in the ripple shader. + // in the ripple shader. (Twice bigger) if (rippleShape == RippleShape.CIRCLE) { - val maskRadius = - (1 - - (1 - rippleShader.progress) * - (1 - rippleShader.progress) * - (1 - rippleShader.progress)) * maxWidth + val maskRadius = rippleShader.currentWidth canvas.drawCircle(centerX, centerY, maskRadius, ripplePaint) } else { - val maskWidth = - (1 - - (1 - rippleShader.progress) * - (1 - rippleShader.progress) * - (1 - rippleShader.progress)) * maxWidth * 2 - val maskHeight = - (1 - - (1 - rippleShader.progress) * - (1 - rippleShader.progress) * - (1 - rippleShader.progress)) * maxHeight * 2 + val maskWidth = rippleShader.currentWidth * 2 + val maskHeight = rippleShader.currentHeight * 2 canvas.drawRect( /* left= */ centerX - maskWidth, /* top= */ centerY - maskHeight, diff --git a/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml b/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml index de96e9765668..446bb0122630 100644 --- a/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml +++ b/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml @@ -20,7 +20,7 @@ android:layout_width="wrap_content" android:paddingVertical="@dimen/dream_overlay_complication_home_controls_padding"> - <ImageView + <com.android.systemui.common.ui.view.LaunchableImageView android:id="@+id/home_controls_chip" android:layout_height="@dimen/keyguard_affordance_fixed_height" android:layout_width="@dimen/keyguard_affordance_fixed_width" diff --git a/packages/SystemUI/res/layout/global_actions_grid_lite.xml b/packages/SystemUI/res/layout/global_actions_grid_lite.xml index 5588fd391681..a64c9aebec3e 100644 --- a/packages/SystemUI/res/layout/global_actions_grid_lite.xml +++ b/packages/SystemUI/res/layout/global_actions_grid_lite.xml @@ -33,7 +33,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_weight="1"> - <androidx.constraintlayout.widget.ConstraintLayout + <com.android.systemui.common.ui.view.LaunchableConstraintLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@android:id/list" @@ -55,6 +55,6 @@ app:flow_horizontalGap="@dimen/global_actions_lite_padding" app:flow_verticalGap="@dimen/global_actions_lite_padding" app:flow_horizontalStyle="packed"/> - </androidx.constraintlayout.widget.ConstraintLayout> + </com.android.systemui.common.ui.view.LaunchableConstraintLayout> </com.android.systemui.globalactions.GlobalActionsLayoutLite> </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/packages/SystemUI/res/layout/keyguard_qs_user_switch.xml b/packages/SystemUI/res/layout/keyguard_qs_user_switch.xml index 6f3362308484..07c428b5dd7a 100644 --- a/packages/SystemUI/res/layout/keyguard_qs_user_switch.xml +++ b/packages/SystemUI/res/layout/keyguard_qs_user_switch.xml @@ -24,7 +24,7 @@ android:layout_gravity="end"> <!-- We add a background behind the UserAvatarView with the same color and with a circular shape so that this view can be expanded into a Dialog or an Activity. --> - <FrameLayout + <com.android.systemui.animation.LaunchableFrameLayout android:id="@+id/kg_multi_user_avatar_with_background" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -42,5 +42,5 @@ systemui:framePadding="0dp" systemui:frameWidth="0dp"> </com.android.systemui.statusbar.phone.UserAvatarView> - </FrameLayout> + </com.android.systemui.animation.LaunchableFrameLayout> </FrameLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/media_recommendation_view.xml b/packages/SystemUI/res/layout/media_recommendation_view.xml new file mode 100644 index 000000000000..101fad97beb5 --- /dev/null +++ b/packages/SystemUI/res/layout/media_recommendation_view.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<!-- Layout for media recommendation item inside QSPanel carousel --> +<merge xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- Album cover --> + <ImageView + android:id="@+id/media_cover" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:translationZ="0dp" + android:scaleType="centerCrop" + android:adjustViewBounds="true" + android:clipToOutline="true" + android:background="@drawable/bg_smartspace_media_item"/> + + <!-- App icon --> + <com.android.internal.widget.CachingIconView + android:id="@+id/media_rec_app_icon" + android:layout_width="@dimen/qs_media_rec_icon_top_margin" + android:layout_height="@dimen/qs_media_rec_icon_top_margin" + android:layout_marginStart="@dimen/qs_media_info_spacing" + android:layout_marginTop="@dimen/qs_media_info_spacing"/> + + <!-- Artist name --> + <TextView + android:id="@+id/media_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/qs_media_info_spacing" + android:layout_marginEnd="@dimen/qs_media_info_spacing" + android:layout_marginBottom="@dimen/qs_media_rec_album_title_bottom_margin" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" + android:singleLine="true" + android:textSize="12sp" + android:gravity="top" + android:layout_gravity="bottom"/> + + <!-- Album name --> + <TextView + android:id="@+id/media_subtitle" + android:layout_width="match_parent" + android:layout_height="@dimen/qs_media_rec_album_subtitle_height" + android:layout_marginEnd="@dimen/qs_media_info_spacing" + android:layout_marginStart="@dimen/qs_media_info_spacing" + android:layout_marginBottom="@dimen/qs_media_info_spacing" + android:fontFamily="@*android:string/config_headlineFontFamily" + android:singleLine="true" + android:textSize="11sp" + android:gravity="center_vertical" + android:layout_gravity="bottom"/> +</merge>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/media_recommendations.xml b/packages/SystemUI/res/layout/media_recommendations.xml new file mode 100644 index 000000000000..65fc19c5b2a4 --- /dev/null +++ b/packages/SystemUI/res/layout/media_recommendations.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> + +<!-- Layout for media recommendations inside QSPanel carousel --> +<com.android.systemui.util.animation.TransitionLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/media_recommendations_updated" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:clipChildren="false" + android:clipToPadding="false" + android:forceHasOverlappingRendering="false" + android:background="@drawable/qs_media_background" + android:theme="@style/MediaPlayer"> + + <!-- This view just ensures the full media player is a certain height. --> + <View + android:id="@+id/sizing_view" + android:layout_width="match_parent" + android:layout_height="@dimen/qs_media_session_height_expanded" /> + + <TextView + android:id="@+id/media_rec_title" + style="@style/MediaPlayer.Recommendation.Header" + android:text="@string/controls_media_smartspace_rec_header"/> + + <FrameLayout + android:id="@+id/media_cover1_container" + style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated" + > + + <include + layout="@layout/media_recommendation_view"/> + + </FrameLayout> + + + <FrameLayout + android:id="@+id/media_cover2_container" + style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated" + > + + <include + layout="@layout/media_recommendation_view"/> + + </FrameLayout> + + <FrameLayout + android:id="@+id/media_cover3_container" + style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated" + > + + <include + layout="@layout/media_recommendation_view"/> + + </FrameLayout> + + <include + layout="@layout/media_long_press_menu" /> + +</com.android.systemui.util.animation.TransitionLayout> diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml index abc83379950a..f2e114b511bc 100644 --- a/packages/SystemUI/res/layout/media_session_view.xml +++ b/packages/SystemUI/res/layout/media_session_view.xml @@ -106,7 +106,7 @@ app:layout_constrainedWidth="true" app:layout_constraintWidth_min="@dimen/min_clickable_item_size" app:layout_constraintHeight_min="@dimen/min_clickable_item_size"> - <LinearLayout + <com.android.systemui.common.ui.view.LaunchableLinearLayout android:id="@+id/media_seamless_button" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -135,7 +135,7 @@ android:textDirection="locale" android:textSize="12sp" android:lineHeight="16sp" /> - </LinearLayout> + </com.android.systemui.common.ui.view.LaunchableLinearLayout> </LinearLayout> <!-- Song name --> diff --git a/packages/SystemUI/res/layout/ongoing_call_chip.xml b/packages/SystemUI/res/layout/ongoing_call_chip.xml index c949ba0db171..18d231c5d32f 100644 --- a/packages/SystemUI/res/layout/ongoing_call_chip.xml +++ b/packages/SystemUI/res/layout/ongoing_call_chip.xml @@ -23,7 +23,7 @@ android:layout_gravity="center_vertical|start" android:layout_marginStart="5dp" > - <LinearLayout + <com.android.systemui.common.ui.view.LaunchableLinearLayout android:id="@+id/ongoing_call_chip_background" android:layout_width="wrap_content" android:layout_height="@dimen/ongoing_appops_chip_height" @@ -55,5 +55,5 @@ android:textColor="?android:attr/colorPrimary" /> - </LinearLayout> + </com.android.systemui.common.ui.view.LaunchableLinearLayout> </FrameLayout> diff --git a/packages/SystemUI/res/layout/screenshot_static.xml b/packages/SystemUI/res/layout/screenshot_static.xml index 496eb6e6130e..7e8bc2c1577e 100644 --- a/packages/SystemUI/res/layout/screenshot_static.xml +++ b/packages/SystemUI/res/layout/screenshot_static.xml @@ -31,7 +31,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/actions_container" app:layout_constraintEnd_toEndOf="@+id/actions_container" - app:layout_constraintBottom_toTopOf="@id/screenshot_message_container"/> + app:layout_constraintBottom_toTopOf="@id/guideline"/> <HorizontalScrollView android:id="@+id/actions_container" android:layout_width="0dp" @@ -127,57 +127,28 @@ app:layout_constraintTop_toTopOf="@id/screenshot_preview" android:elevation="7dp"/> + <androidx.constraintlayout.widget.Guideline + android:id="@+id/guideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintGuide_end="0dp" /> + <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/screenshot_message_container" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginHorizontal="@dimen/overlay_action_container_margin_horizontal" - android:layout_marginVertical="4dp" + android:layout_marginTop="4dp" + android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom" android:paddingHorizontal="@dimen/overlay_action_container_padding_end" android:paddingVertical="@dimen/overlay_action_container_padding_vertical" android:elevation="4dp" android:background="@drawable/action_chip_container_background" - android:visibility="gone" + android:visibility="invisible" + app:layout_constraintTop_toBottomOf="@id/guideline" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintBottom_toBottomOf="parent"> - - <ImageView - android:id="@+id/screenshot_message_icon" - android:layout_width="48dp" - android:layout_height="48dp" - android:paddingEnd="4dp" - android:src="@drawable/ic_work_app_badge" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintEnd_toStartOf="@id/screenshot_message_content" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent"/> - - <TextView - android:id="@+id/screenshot_message_content" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_gravity="start" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/screenshot_message_icon" - app:layout_constraintEnd_toStartOf="@id/message_dismiss_button"/> - - <FrameLayout - android:id="@+id/message_dismiss_button" - android:layout_width="@dimen/overlay_dismiss_button_tappable_size" - android:layout_height="@dimen/overlay_dismiss_button_tappable_size" - app:layout_constraintStart_toEndOf="@id/screenshot_message_content" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" - android:contentDescription="@string/screenshot_dismiss_work_profile"> - <ImageView - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_margin="@dimen/overlay_dismiss_button_margin" - android:src="@drawable/overlay_cancel"/> - </FrameLayout> - + > </androidx.constraintlayout.widget.ConstraintLayout> </com.android.systemui.screenshot.DraggableConstraintLayout> diff --git a/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml b/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml new file mode 100644 index 000000000000..c794d91c02be --- /dev/null +++ b/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<merge + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <ImageView + android:id="@+id/screenshot_message_icon" + android:layout_width="48dp" + android:layout_height="48dp" + android:paddingEnd="4dp" + android:src="@drawable/ic_work_app_badge" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toStartOf="@id/screenshot_message_content" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + + <TextView + android:id="@+id/screenshot_message_content" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_gravity="start" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/screenshot_message_icon" + app:layout_constraintEnd_toStartOf="@id/message_dismiss_button"/> + + <FrameLayout + android:id="@+id/message_dismiss_button" + android:layout_width="@dimen/overlay_dismiss_button_tappable_size" + android:layout_height="@dimen/overlay_dismiss_button_tappable_size" + app:layout_constraintStart_toEndOf="@id/screenshot_message_content" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + android:contentDescription="@string/screenshot_dismiss_work_profile"> + <ImageView + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_margin="@dimen/overlay_dismiss_button_margin" + android:src="@drawable/overlay_cancel"/> + </FrameLayout> +</merge> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 7f12066166b5..6bb51bbb055a 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Outomaties"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Geen klank of vibrasie nie"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Geen klank of vibrasie nie en verskyn laer in gespreksafdeling"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Kan lui of vibreer op grond van toestelinstellings"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Kan lui of vibreer op grond van toestelinstellings. Gesprekke van <xliff:g id="APP_NAME">%1$s</xliff:g> af verskyn by verstek in ’n borrel."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Laat die stelsel bepaal of hierdie kennisgewing \'n klank moet maak of vibreer"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> Bevorder na Verstek"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> Gedegradeer na Stil"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Kies program om kontroles by te voeg"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrole bygevoeg.}other{# kontroles bygevoeg.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Verwyder"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"As gunsteling gemerk"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"As gunsteling gemerk; posisie <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"As gunsteling ontmerk"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Fout, probeer weer"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Voeg kontroles by"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Wysig kontroles"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Voeg uitvoere by"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Groep"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 toestel gekies"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Luidsprekers en skerms"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Voorgestelde toestelle"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Vereis premiumrekening"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitsaai werk"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Saai uit"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mense in jou omtrek met versoenbare Bluetooth-toestelle kan na die media luister wat jy uitsaai"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batterykrag oor"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Koppel jou stilus aan ’n laaier"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Stilus se battery is amper pap"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Kan nie van hierdie profiel af bel nie"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Jou werkbeleid laat jou toe om slegs van die werkprofiel af foonoproepe te maak"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skakel oor na werkprofiel"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Maak toe"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 822f156a597c..45e83c0c91ed 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"ራስ-ሰር"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"ምንም ድምፅ ወይም ንዝረት የለም"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ምንም ድምፅ ወይም ንዝረት የለም እና በውይይት ክፍል ላይ አይታይም"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"በመሣሪያ ቅንብሮች መሰረት ሊጮህ ወይም ሊነዝር ይችላል"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"በስልክ ቅንብሮች መሰረት ሊጮህ ወይም ሊነዝር ይችላል። የ<xliff:g id="APP_NAME">%1$s</xliff:g> ውይይቶች በነባሪነት አረፋ ይሆናሉ።"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ይህ ማሳወቂያ ድምፅ ወይም ንዝረት መደረግ ካለበት ስርዓቱ እንዲወሰን ያድርጉት"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>ሁኔታ:</b> ለነባሪ ከፍ ተዋውቋል።"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>ሁኔታ:</b> ወደ ዝምታ ዝቅ ተደርጓል"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"መቆጣጠሪያዎችን ለማከል መተግበሪያ ይምረጡ"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ቁጥጥር ታክሏል።}one{# ቁጥጥር ታክሏል።}other{# ቁጥጥሮች ታክለዋል።}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ተወግዷል"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ተወዳጅ የተደረገ"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ተወዳጅ ተደርጓል፣ አቋም <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ተወዳጅ አልተደረገም"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"ስህተት፣ እንደገና ይሞክሩ"</string> <string name="controls_menu_add" msgid="4447246119229920050">"መቆጣጠሪያዎችን አክል"</string> <string name="controls_menu_edit" msgid="890623986951347062">"መቆጣጠሪያዎችን ያርትዑ"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ውጽዓቶችን ያክሉ"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ቡድን"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 መሣሪያ ተመርጧል"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ድምጽ ማውጫዎች እና ማሳያዎች"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"የተጠቆሙ መሣሪያዎች"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ፕሪሚየም መለያ ይጠይቃል"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ማሰራጨት እንዴት እንደሚሠራ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ስርጭት"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ተኳሃኝ የብሉቱዝ መሣሪያዎች ያላቸው በአቅራቢያዎ ያሉ ሰዎች እርስዎ እያሰራጩት ያሉትን ሚዲያ ማዳመጥ ይችላሉ"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ባትሪ ይቀራል"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ብሮስፌዎን ከኃይል መሙያ ጋር ያገናኙ"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"የብሮስፌ ባትሪ ዝቅተኛ ነው"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"የቪድዮ ካሜራ"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"ከዚህ መገለጫ መደወል አይቻልም"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"የሥራ መመሪያዎ እርስዎ ከሥራ መገለጫው ብቻ ጥሪ እንዲያደርጉ ይፈቅድልዎታል"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"ወደ የሥራ መገለጫ ቀይር"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"ዝጋ"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 3daba4146c5d..eeaf5d70d75f 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"تلقائي"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"بدون صوت أو اهتزاز"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"بدون صوت أو اهتزاز وتظهر في أسفل قسم المحادثات"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"يمكن إصدار رنين أو اهتزاز بناءً على إعدادات الجهاز"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"يمكن إصدار رنين أو اهتزاز بناءً على إعدادات الجهاز. تظهر المحادثات من \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" كفقاعات تلقائيًا."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"السماح للنظام بتحديد ما إذا يجب اهتزاز الجهاز أو إصدار رنين عند تلقّي هذا الإشعار"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>الحالة:</b> تمت الترقية إلى الإعداد التلقائي"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>الحالة:</b> تم خفض الترتيب إلى الوضع صامت"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"متوسط"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"صغير"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"كبير"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"تم"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"تعديل"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"إعدادات نافذة مكبّر الشاشة"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"انقر لفتح ميزات تسهيل الاستخدام. يمكنك تخصيص هذا الزر أو استبداله من الإعدادات.\n\n"<annotation id="link">"عرض الإعدادات"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"اختيار تطبيق لإضافة عناصر التحكّم"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{تمت إضافة عنصر تحكّم واحد.}zero{تمت إضافة # عنصر تحكّم.}two{تمت إضافة عنصرَي تحكّم.}few{تمت إضافة # عناصر تحكّم.}many{تمت إضافة # عنصر تحكّم.}other{تمت إضافة # عنصر تحكّم.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"تمت الإزالة"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"تمت الإضافة إلى المفضّلة"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"تمت الإضافة إلى المفضّلة، الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"تمت الإزالة من المفضّلة"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"حدث خطأ، يُرجى إعادة المحاولة."</string> <string name="controls_menu_add" msgid="4447246119229920050">"إضافة عناصر تحكّم"</string> <string name="controls_menu_edit" msgid="890623986951347062">"تعديل عناصر التحكّم"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"إضافة مخرجات"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"مجموعة"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"تم اختيار جهاز واحد."</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"مكبّرات الصوت والشاشات"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"الأجهزة المقترَحة"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"يجب استخدام حساب مدفوع."</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"كيفية عمل البث"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"البث"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"يمكن للأشخاص القريبين منك الذين لديهم أجهزة متوافقة تتضمّن بلوتوث الاستماع إلى الوسائط التي تبثها."</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"النسبة المئوية المتبقية من شحن البطارية: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"عليك توصيل قلم الشاشة بشاحن."</string> <string name="stylus_battery_low" msgid="7134370101603167096">"بطارية قلم الشاشة منخفضة"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"كاميرا فيديو"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"لا يمكن الاتصال باستخدام هذا الملف الشخصي."</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"تسمح لك سياسة العمل بإجراء المكالمات الهاتفية من الملف الشخصي للعمل فقط."</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"التبديل إلى الملف الشخصي للعمل"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"إغلاق"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 16c9935c7622..56f7e8e0b4d0 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"স্বয়ংক্ৰিয়"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"কোনো ধ্বনি অথবা কম্পন নাই"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"কোনো ধ্বনি অথবা কম্পন নাই আৰু বাৰ্তালাপ শাখাটোৰ তলৰ অংশত দেখা পোৱা যায়"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"ডিভাইচৰ ছেটিঙৰ ওপৰত নিৰ্ভৰ কৰি ৰিং কৰিব অথবা কম্পন হ’ব পাৰে"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ডিভাইচৰ ছেটিঙৰ ওপৰত নিৰ্ভৰ কৰি ৰিং কৰিব অথবা কম্পন হ’ব পাৰে। <xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাৰ্তালাপ ডিফ’ল্টভাৱে বাবল হিচাপে প্ৰদৰ্শিত হয়।"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"এই জাননীটোৱে ধ্বনি নে কম্পন সৃষ্টি কৰিব সেয়া ছিষ্টেমটোক নিৰ্ধাৰণ কৰিবলৈ দিয়ক"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>স্থিতি:</b> ডিফ’ল্টলৈ বৃদ্ধি কৰা হৈছে"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>স্থিতি:</b> নীৰৱলৈ হ্ৰাস কৰা হৈছে"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"মধ্যমীয়া"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"সৰু"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"ডাঙৰ"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"কৰা হ’ল"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"সম্পাদনা কৰক"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"বিবৰ্ধকৰ ৱিণ্ড’ৰ ছেটিং"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"সাধ্য সুবিধাসমূহ খুলিবলৈ টিপক। ছেটিঙত এই বুটামটো কাষ্টমাইজ অথবা সলনি কৰক।\n\n"<annotation id="link">"ছেটিং চাওক"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"নিয়ন্ত্ৰণসমূহ যোগ কৰিবলৈ এপ্ বাছনি কৰক"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}one{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}other{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}}"</string> <string name="controls_removed" msgid="3731789252222856959">"আঁতৰোৱা হ’ল"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল, স্থান <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"অপ্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"আসোঁৱাহ হৈছে, আকৌ চেষ্টা কৰক"</string> <string name="controls_menu_add" msgid="4447246119229920050">"নিয়ন্ত্ৰণসমূহ যোগ দিয়ক"</string> <string name="controls_menu_edit" msgid="890623986951347062">"নিয়ন্ত্ৰণসমূহ সম্পাদনা কৰক"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"আউটপুটসমূহ যোগ দিয়ক"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"গোট"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"১ টা ডিভাইচ বাছনি কৰা হৈছে"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"স্পীকাৰ আৰু ডিছপ্লে’"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"পৰামৰ্শ হিচাপে পোৱা ডিভাইচ"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium একাউণ্টৰ আৱশ্যক"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"সম্প্ৰচাৰ কৰাটোৱে কেনেকৈ কাম কৰে"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"সম্প্ৰচাৰ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"সমিল ব্লুটুথ ডিভাইচৰ সৈতে আপোনাৰ নিকটৱৰ্তী স্থানত থকা লোকসকলে আপুনি সম্প্ৰচাৰ কৰা মিডিয়াটো শুনিব পাৰে"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> বেটাৰী বাকী আছে"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"আপোনাৰ ষ্টাইলাছ এটা চাৰ্জাৰৰ সৈতে সংযোগ কৰক"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"ষ্টাইলাছৰ বেটাৰী কম আছে"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"ভিডিঅ’ কেমেৰা"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"এই প্ৰ’ফাইলৰ পৰা কল কৰিব নোৱাৰি"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"আপোনাৰ কৰ্মস্থানৰ নীতিয়ে আপোনাক কেৱল কৰ্মস্থানৰ প্ৰ’ফাইলৰ পৰা ফ’ন কল কৰিবলৈ দিয়ে"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"কৰ্মস্থানৰ প্ৰ’ফাইললৈ সলনি কৰক"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"বন্ধ কৰক"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 06466971d04f..6b5ad2acbdb7 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Avtomatik"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Səs və ya vibrasiya yoxdur"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Söhbət siyahısının aşağısında səssiz və vibrasiyasız görünür"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Cihaz ayarlarına əsasən zəng çala və ya vibrasiya edə bilər"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Cihaz ayarlarına əsasən zəng çala və ya vibrasiya edə bilər. <xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqindən söhbətlərdə defolt olaraq qabarcıq çıxır."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Bu bildirişin səs çıxarması və ya vibrasiya etməsi sistem tərəfindən təyin edilsin"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> Defolt ayara keçirilib"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> Səssiz rejimə keçirilib"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Kontrol əlavə etmək üçün tətbiq seçin"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# nizamlayıcı əlavə edilib.}other{# nizamlayıcı əlavə edilib.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Silinib"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Sevimlilərə əlavə edilib"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Sevimlilərə əlavə edilib, sıra: <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Sevimlilərdən silinib"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Xəta, yenidən cəhd edin"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Vidcet əlavə edin"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Vidcetlərə düzəliş edin"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Nəticələri əlavə edin"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Qrup"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 cihaz seçilib"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Dinamiklər & Displeylər"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Təklif olunan Cihazlar"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium hesab tələb edilir"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayım necə işləyir"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Yayım"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Uyğun Bluetooth cihazları olan yaxınlığınızdakı insanlar yayımladığınız medianı dinləyə bilər"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> enerji qalıb"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Qələmi adapterə qoşun"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Qələm enerjisi azdır"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Bu profildən zəng etmək mümkün deyil"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"İş siyasətiniz yalnız iş profilindən telefon zəngləri etməyə imkan verir"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"İş profilinə keçin"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bağlayın"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 9b8bbec6f359..3f9f3ec94a8e 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatska"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez zvuka i vibriranja"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Bez zvuka i vibriranja i prikazuje se u nastavku odeljka za konverzacije"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Može da zvoni ili vibrira u zavisnosti od podešavanja uređaja"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Može da zvoni ili vibrira u zavisnosti od podešavanja uređaja. Konverzacije iz aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> podrazumevano se prikazuju u oblačićima."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Neka sistem utvrdi da li ovo obaveštenje treba da emituje zvuk ili da vibrira"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> Unapređeno u Podrazumevano"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> Degradirano u Nečujno"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Odaberite aplikaciju za dodavanje kontrola"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrola je dodata.}one{# kontrola je dodata.}few{# kontrole su dodate.}other{# kontrola je dodato.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Označeno je kao omiljeno"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Označeno je kao omiljeno, <xliff:g id="NUMBER">%d</xliff:g>. pozicija"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Uklonjeno je iz omiljenih"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Greška. Probajte ponovo"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Dodaj kontrole"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Izmeni kontrole"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodajte izlaze"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Izabran je 1 uređaj"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvučnici i ekrani"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Zahteva premijum nalog"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako funkcioniše emitovanje"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Emitovanje"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ljudi u blizini sa kompatibilnim Bluetooth uređajima mogu da slušaju medijski sadržaj koji emitujete"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostalo je još<xliff:g id="PERCENTAGE">%s</xliff:g> baterije"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Povežite pisaljku sa punjačem"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Nizak nivo baterije pisaljke"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Video kamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Ne možete da upućujete pozive sa ovog profila"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Smernice za posao vam omogućavaju da telefonirate samo sa poslovnog profila"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređi na poslovni profil"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 3a476f44f075..d4dc17b3f822 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Аўтаматычна"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без гуку ці вібрацыі"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Паказваецца без гуку ці вібрацыі ў раздзеле размоў"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"У залежнасці ад налад прылады магчымы званок або вібрацыя"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"У залежнасці ад налад прылады магчымы званок або вібрацыя. Размовы ў праграме \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" стандартна паяўляюцца ў выглядзе ўсплывальных апавяшчэнняў."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Сістэма сама будзе вызначаць, ці трэба для гэтага апавяшчэння ўключаць гук або вібрацыю"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Стан:</b> Пазначана як стандартнае"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Стан:</b> Пераведзена ў рэжым \"Без гуку\""</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Выберыце праграму для дадавання элементаў кіравання"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Дададзены # элемент кіравання.}one{Дададзена # элемента кіравання.}few{Дададзена # элементы кіравання.}many{Дададзена # элементаў кіравання.}other{Дададзена # элемента кіравання.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Выдалена"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Дададзена ў абранае"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Дададзена ў абранае, пазіцыя <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Выдалена з абранага"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Памылка, паўтарыце спробу"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Дадаць элементы кіравання"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Змяніць элементы кіравання"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Дадайце прылады вываду"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Выбрана 1 прылада"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Дынамікі і дысплэі"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Прылады, якія падтрымліваюцца"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Патрабуецца платны ўліковы запіс"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як адбываецца трансляцыя"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляцыя"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Людзі паблізу, у якіх ёсць прылады з Bluetooth, змогуць праслухваць мультымедыйнае змесціва, якое вы трансліруеце"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Засталося зараду: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Падключыце пяро да зараднай прылады"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Нізкі ўзровень зараду пяра"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Відэакамера"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Не ўдалося зрабіць выклік з гэтага профілю"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Згодна з палітыкай вашай арганізацыі, рабіць тэлефонныя выклікі дазволена толькі з працоўнага профілю"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пераключыцца на працоўны профіль"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыць"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index de24b946a2b3..2141a47e9a27 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматично"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звук или вибриране"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звук или вибриране и се показва по-долу в секцията с разговори"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Може да звъни или да вибрира въз основа на настройките на устройството"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Може да звъни или да вибрира въз основа на настройките на устройството. Разговорите от <xliff:g id="APP_NAME">%1$s</xliff:g> се показват като балончета по подразбиране."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Нека системата да определя дали дадено известие да се придружава от звук, или вибриране"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Състояние:</b> Повишено до основно"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Състояние:</b> Понижено до беззвучно"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Среден"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Малък"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Голям"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Готово"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Редактиране"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Настройки за инструмента за увеличаване на прозорци"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Докоснете, за да отворите функциите за достъпност. Персон./заменете бутона от настройките.\n\n"<annotation id="link">"Преглед на настройките"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Изберете приложение, за да добавите контроли"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Добавена е # контрола.}other{Добавени са # контроли.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Премахнато"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено като любимо"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено като любимо – позиция <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Не е означено като любимо"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Грешка. Опитайте отново"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Добавяне на контроли"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Редактиране на контролите"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Добавяне на изходящи устройства"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 избрано устройство"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Високоговорители и екрани"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени устройства"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Необходим е платен профил"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Как работи предаването"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Предаване"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Хората в близост със съвместими устройства с Bluetooth могат да слушат мултимедията, която предавате"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Оставаща батерия: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Свържете писалката към зарядно устройство"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Батерията на писалката е изтощена"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Видеокамера"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Не може да се извърши обаждане от този потребителски профил"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Служебните правила ви дават възможност да извършвате телефонни обаждания само от служебния потребителски профил"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Превключване към служебния потребителски профил"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затваряне"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index a72733c0be45..691293c62032 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"অটোমেটিক"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"আওয়াজ করবে না বা ভাইব্রেট হবে না"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"আওয়াজ করবে না বা ভাইব্রেট হবে না এবং কথোপকথন বিভাগের নিচের দিকে দেখা যাবে"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"ডিভাইসের সেটিংস অনুযায়ী রিং বা ভাইব্রেট হতে পারে"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ডিভাইসের সেটিংস অনুযায়ী রিং বা ভাইব্রেট হতে পারে। <xliff:g id="APP_NAME">%1$s</xliff:g>-এর কথোপকথন সাধারণত বাবলের মতো দেখাবে।"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"এই বিজ্ঞপ্তি এলে ডিভাইস আওয়াজ করবে না ভাইব্রেট করবে তা সিস্টেমকে সেট করতে দিন"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>স্ট্যাটাস:</b> লেভেল বাড়িয়ে ডিফল্ট করা হয়েছে"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>স্ট্যাটাস:</b> লেভেল কমিয়ে সাইলেন্ করা হয়েছে"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"মাঝারি"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"ছোট"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"বড়"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"হয়ে গেছে"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"এডিট করুন"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"\'ম্যাগনিফায়ার উইন্ডো\' সেটিংস"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"অ্যাক্সেসিবিলিটি ফিচার খুলতে ট্যাপ করুন। কাস্টমাইজ করুন বা সেটিংসে এই বোতামটি সরিয়ে দিন।\n\n"<annotation id="link">"সেটিংস দেখুন"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"কন্ট্রোল যোগ করতে অ্যাপ বেছে নিন"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#টি কন্ট্রোল যোগ করা হয়েছে।}one{#টি কন্ট্রোল যোগ করা হয়েছে।}other{#টি কন্ট্রোল যোগ করা হয়েছে।}}"</string> <string name="controls_removed" msgid="3731789252222856959">"সরানো হয়েছে"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"পছন্দসই হিসেবে চিহ্নিত করেছেন"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"পছন্দসই হিসেবে চিহ্নিত করেছেন, অবস্থান <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"পছন্দসই থেকে সরিয়ে দিয়েছেন"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"সমস্যা হয়েছে, আবার চেষ্টা করুন"</string> <string name="controls_menu_add" msgid="4447246119229920050">"কন্ট্রোল যোগ করুন"</string> <string name="controls_menu_edit" msgid="890623986951347062">"কন্ট্রোল এডিট করুন"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"আউটপুট যোগ করুন"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"গ্রুপ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"১টি ডিভাইস বেছে নেওয়া হয়েছে"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"স্পিকার & ডিসপ্লে"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"সাজেস্ট করা ডিভাইস"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"প্রিমিয়াম অ্যাকাউন্ট প্রয়োজন"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ব্রডকাস্ট কীভাবে কাজ করে"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"সম্প্রচার করুন"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"আশপাশে লোকজন যাদের মানানসই ব্লুটুথ ডিভাইস আছে, তারা আপনার ব্রডকাস্ট করা মিডিয়া শুনতে পারবেন"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ব্যাটারির চার্জ বাকি আছে"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"কোনও চার্জারের সাথে আপনার স্টাইলাস কানেক্ট করুন"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"স্টাইলাস ব্যাটারিতে চার্জ কম আছে"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"ভিডিও ক্যামেরা"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"এই প্রোফাইল থেকে কল করা যাচ্ছে না"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"কাজ সংক্রান্ত নীতি, আপনাকে শুধুমাত্র অফিস প্রোফাইল থেকে কল করার অনুমতি দেয়"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"অফিস প্রোফাইলে পাল্টে নিন"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"বন্ধ করুন"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index d82e269f8aa0..57c0a23b8625 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -543,8 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatski"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez zvuka ili vibracije"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Bez zvuka ili vibracije i pojavljuje se pri dnu odjeljka razgovora"</string> - <string name="notification_channel_summary_default" msgid="777294388712200605">"Možda će zvoniti ili vibrirati, ovisno o postavkama uređaja"</string> - <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Možda će zvoniti ili vibrirati, ovisno o postavkama uređaja. Razgovori iz aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> prikazuju se u oblačiću prema zadanim postavkama."</string> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Može zvoniti ili vibrirati na osnovu postavki uređaja"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Može zvoniti ili vibrirati na osnovu postavki uređaja. Razgovori iz aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> prikazuju se u oblačićima prema zadanim postavkama."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Neka sistem odluči treba li se ovo obavještenje oglasiti zvukom ili vibracijom"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> je unaprijeđen u Zadano"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> je unazađen u Nečujno"</string> @@ -832,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Odaberite aplikaciju da dodate kontrole"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodana je # kontrola.}one{Dodana je # kontrola.}few{Dodane su # kontrole.}other{Dodano je # kontrola.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite li dodati aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Kada dodate aplikaciju <xliff:g id="APPNAME">%s</xliff:g>, može dodati kontrole i sadržaj na ovu ploču. U nekim aplikacijama možete odabrati koje se kontrole prikazuju ovdje."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano u omiljeno"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano u omiljeno, pozicija <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Uklonjeno iz omiljenog"</string> @@ -898,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Greška, pokušajte ponovo"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Dodaj kontrole"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Uredi kontrole"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Dodavanje aplikacije"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodajte izlaze"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Odabran je 1 uređaj"</string> @@ -913,7 +916,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvučnici i ekrani"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string> - <string name="media_output_status_require_premium" msgid="5691200962588753380">"Zahtijeva račun s naplatom"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Zahtijeva premijum račun"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako funkcionira emitiranje"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Emitirajte"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osobe u vašoj blizini s kompatibilnim Bluetooth uređajima mogu slušati medijske sadržaje koje emitirate"</string> @@ -1058,9 +1061,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostalo baterije: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Priključite pisaljku na punjač"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Baterija pisaljke je slaba"</string> - <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> - <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nije moguće uspostavljati pozive s ovog profila"</string> - <string name="call_from_work_profile_text" msgid="3458704745640229638">"Vaša pravila za poslovne uređaje omogućuju vam upućivanje poziva samo s poslovnog profila"</string> - <string name="call_from_work_profile_action" msgid="2937701298133010724">"Prijeđite na poslovni profil"</string> + <string name="video_camera" msgid="7654002575156149298">"Video kamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nije moguće pozvati s ovog profila"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Radna pravila vam dozvoljavaju upućivanje telefonskih poziva samo s radnog profila"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređite na radni profil"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 308ea11dff84..e5563c089f94 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automàtic"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sense so ni vibració"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sense so ni vibració i es mostra més avall a la secció de converses"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Pot sonar o vibrar en funció de la configuració del dispositiu"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Pot sonar o vibrar en funció de la configuració del dispositiu. Les converses de l\'aplicació <xliff:g id="APP_NAME">%1$s</xliff:g> es mostren com a bombolles de manera predeterminada."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Fes que el sistema determini si aquesta notificació ha d\'emetre un so o una vibració"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Estat</b>: s\'ha augmentat a Predeterminat"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Estat</b>: s\'ha disminuït a Silenci"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Normal"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Petit"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Gran"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Fet"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Edita"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Configuració de la finestra de la lupa"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Toca per obrir funcions d\'accessibilitat. Personalitza o substitueix el botó a Configuració.\n\n"<annotation id="link">"Mostra"</annotation>"."</string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Selecciona l\'aplicació per afegir controls"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S\'ha afegit # control.}many{# controls added.}other{S\'han afegit # controls.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Suprimit"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Afegit als preferits"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Afegit als preferits, posició <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Suprimit dels preferits"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error; torna-ho a provar"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Afegeix controls"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edita els controls"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Afegeix sortides"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositiu seleccionat"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altaveus i pantalles"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositius suggerits"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requereix un compte prèmium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Com funciona l\'emissió"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Emet"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les persones properes amb dispositius Bluetooth compatibles poden escoltar el contingut multimèdia que emets"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> de bateria"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connecta el llapis òptic a un carregador"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria del llapis òptic baixa"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Càmera de vídeo"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"No es pot trucar des d\'aquest perfil"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"La teva política de treball et permet fer trucades només des del perfil de treball"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Canvia al perfil de treball"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tanca"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 2a013186607a..c099f66122d0 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Vyberte aplikaci, pro kterou chcete přidat ovládací prvky"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Byl přidán # ovládací prvek.}few{Byly přidány # ovládací prvky.}many{Bylo přidáno # ovládacího prvku.}other{Bylo přidáno # ovládacích prvků.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Odstraněno"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Přidáno do oblíbených"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Přidáno do oblíbených na pozici <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Odebráno z oblíbených"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Chyba, zkuste to znovu"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Přidat ovládací prvky"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Upravit ovládací prvky"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Přidání výstupů"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Skupina"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Je vybráno 1 zařízení"</string> @@ -1063,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Vaše pracovní zásady vám umožňují telefonovat pouze z pracovního profilu"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Přepnout na pracovní profil"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zavřít"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index d7467b002cc2..c50202d43b1f 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisk"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ingen lyd eller vibration"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ingen lyd eller vibration, og den vises længere nede i samtalesektionen"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Kan ringe eller vibrere baseret på enhedens indstillinger"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Kan ringe eller vibrere baseret på enhedens indstillinger. Samtaler fra <xliff:g id="APP_NAME">%1$s</xliff:g> vises som standard i bobler."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Få systemet til at afgøre, om denne notifikation skal vibrere eller afspille en lyd"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> Angivet som Standard"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> Angivet som Lydløs"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Mellem"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Lille"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Stor"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Udfør"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Rediger"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Indstillinger for lupvindue"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Tryk for at åbne hjælpefunktioner. Tilpas eller erstat denne knap i Indstillinger.\n\n"<annotation id="link">"Se indstillingerne"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Vælg en app for at tilføje styring"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# styringselement er tilføjet.}one{# styringselement er tilføjet.}other{# styringselementer er tilføjet.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Angivet som favorit"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Angivet som favorit. Position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjernet fra favoritter"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Der opstod en fejl. Prøv igen"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Tilføj styring"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Rediger styring"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Tilføj medieudgange"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Gruppe"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Der er valgt 1 enhed"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Højttalere og skærme"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Foreslåede enheder"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Kræver Premium-konto"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Sådan fungerer udsendelser"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Udsendelse"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personer i nærheden, som har kompatible Bluetooth-enheder, kan lytte til det medie, du udsender"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteri tilbage"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Slut din styluspen til en oplader"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Lavt batteriniveau på styluspen"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Du kan ikke ringe fra denne profil"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Din arbejdspolitik tillader kun, at du kan foretage telefonopkald fra arbejdsprofilen"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skift til arbejdsprofil"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Luk"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 0b01f15fb47a..0ac3f4bc3ca8 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisch"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Kein Ton und keine Vibration"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Kein Ton und keine Vibration, erscheint weiter unten im Bereich „Unterhaltungen“"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Kann je nach Geräteeinstellungen klingeln oder vibrieren"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Kann je nach Geräteeinstellungen klingeln oder vibrieren. Unterhaltungen von <xliff:g id="APP_NAME">%1$s</xliff:g> werden standardmäßig als Bubble angezeigt."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Das System entscheiden lassen, ob bei dieser Benachrichtigung ein Ton oder eine Vibration ausgegeben wird"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status</b>: auf „Standard“ hochgestuft"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status</b>: auf „Lautlos“ herabgestuft"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Mittel"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Klein"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Groß"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Fertig"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Bearbeiten"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Einstellungen für das Vergrößerungsfenster"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Tippe, um die Bedienungshilfen aufzurufen. Du kannst diese Schaltfläche in den Einstellungen anpassen oder ersetzen.\n\n"<annotation id="link">"Zu den Einstellungen"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"App zum Hinzufügen von Steuerelementen auswählen"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# Steuerelement hinzugefügt.}other{# Steuerelemente hinzugefügt.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Entfernt"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Zu Favoriten hinzugefügt"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Zu Favoriten hinzugefügt, Position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Aus Favoriten entfernt"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Fehler – versuch es noch mal"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Steuerelemente hinzufügen"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Steuerelemente bearbeiten"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ausgabegeräte hinzufügen"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Gruppe"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Ein Gerät ausgewählt"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Lautsprecher & Displays"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Vorgeschlagene Geräte"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium-Konto erforderlich"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Funktionsweise von Nachrichten an alle"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Nachricht an alle"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personen, die in der Nähe sind und kompatible Bluetooth-Geräten haben, können sich die Medien anhören, die du per Nachricht an alle sendest"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akku bei <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Schließe deinen Eingabestift an ein Ladegerät an"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus-Akkustand niedrig"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Keine Anrufe über dieses Profil möglich"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Gemäß den Arbeitsrichtlinien darfst du nur über dein Arbeitsprofil telefonieren"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Zum Arbeitsprofil wechseln"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Schließen"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 0db8cfb441d6..eb0abeac7f36 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Αυτόματο"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Χωρίς ήχο ή δόνηση"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Χωρίς ήχο ή δόνηση και εμφανίζεται χαμηλά στην ενότητα συζητήσεων"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Ενδέχεται να κουδουνίζει ή να δονείται βάσει των ρυθμίσεων συσκευής"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Ενδέχεται να κουδουνίζει ή να δονείται βάσει των ρυθμίσεων συσκευής. Οι συζητήσεις από την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> εμφανίζονται σε συννεφάκι από προεπιλογή."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Επιτρέψτε στο σύστημα να αποφασίσει αν αυτή η ειδοποίηση θα αναπαράγει έναν ήχο ή θα ενεργοποιήσει τη δόνηση της συσκευής"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Κατάσταση:</b> Προάχθηκε σε Προεπιλογή"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Κατάσταση:</b> Υποβιβάστηκε σε Αθόρυβη"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Μέτριο"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Μικρό"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Μεγάλο"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Τέλος"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Επεξεργασία"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Ρυθμίσεις παραθύρου μεγεθυντικού φακού"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Πατήστε για άνοιγμα των λειτουργιών προσβασιμότητας. Προσαρμόστε ή αντικαταστήστε το κουμπί στις Ρυθμίσεις.\n\n"<annotation id="link">"Προβολή ρυθμίσεων"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Επιλογή εφαρμογής για προσθήκη στοιχείων ελέγχου"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Προστέθηκε # στοιχείο ελέγχου.}other{Προστέθηκαν # στοιχεία ελέγχου.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Καταργήθηκε"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Προστέθηκε στα αγαπημένα"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Προστέθηκε στα αγαπημένα, στη θέση <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Αφαιρέθηκε από τα αγαπημένα"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Σφάλμα, προσπαθήστε ξανά."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Προσθήκη στοιχείων ελέγχου"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Επεξεργασία στοιχείων ελέγχου"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Προσθήκη εξόδων"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Ομάδα"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Επιλέχτηκε 1 συσκευή"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Ηχεία και οθόνες"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Προτεινόμενες συσκευές"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Απαιτεί λογαριασμό premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Πώς λειτουργεί η μετάδοση"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Μετάδοση"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Οι άνθρωποι με συμβατές συσκευές Bluetooth που βρίσκονται κοντά σας μπορούν να ακούσουν το μέσο που μεταδίδετε."</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Απομένει το <xliff:g id="PERCENTAGE">%s</xliff:g> της μπαταρίας"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Συνδέστε τη γραφίδα σε έναν φορτιστή"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Χαμηλή στάθμη μπαταρίας γραφίδας"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Βιντεοκάμερα"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Δεν είναι δυνατή η κλήση από αυτό το προφίλ"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Η πολιτική εργασίας σάς επιτρέπει να πραγματοποιείτε τηλεφωνικές κλήσεις μόνο από το προφίλ εργασίας σας."</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Εναλλαγή σε προφίλ εργασίας"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Κλείσιμο"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 8f6b9b959b69..cad3b47328b9 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -832,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Choose app to add controls"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Removed"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"When you add <xliff:g id="APPNAME">%s</xliff:g>, it can add controls and content to this panel. In some apps, you can choose which controls show up here."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavourited"</string> @@ -898,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error, try again"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Add controls"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edit controls"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Add app"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Add outputs"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Group"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"One device selected"</string> @@ -1063,4 +1066,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Your work policy allows you to make phone calls only from the work profile"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 8c4e66c08ec2..c41a1641f4e0 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -832,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Choose app to add controls"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Removed"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"When you add <xliff:g id="APPNAME">%s</xliff:g>, it can add controls and content to this panel. In some apps, you can choose which controls show up here."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favorited"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorited, position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavorited"</string> @@ -898,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error, try again"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Add controls"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edit controls"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Add app"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Add outputs"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Group"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 device selected"</string> @@ -1063,4 +1066,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Your work policy allows you to make phone calls only from the work profile"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 8f6b9b959b69..cad3b47328b9 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -832,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Choose app to add controls"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Removed"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"When you add <xliff:g id="APPNAME">%s</xliff:g>, it can add controls and content to this panel. In some apps, you can choose which controls show up here."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavourited"</string> @@ -898,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error, try again"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Add controls"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edit controls"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Add app"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Add outputs"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Group"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"One device selected"</string> @@ -1063,4 +1066,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Your work policy allows you to make phone calls only from the work profile"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 8f6b9b959b69..cad3b47328b9 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -832,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Choose app to add controls"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Removed"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"When you add <xliff:g id="APPNAME">%s</xliff:g>, it can add controls and content to this panel. In some apps, you can choose which controls show up here."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavourited"</string> @@ -898,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error, try again"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Add controls"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edit controls"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Add app"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Add outputs"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Group"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"One device selected"</string> @@ -1063,4 +1066,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Your work policy allows you to make phone calls only from the work profile"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 34bf569ba3bd..059a5fa248e5 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -832,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Choose app to add controls"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Removed"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"When you add <xliff:g id="APPNAME">%s</xliff:g>, it can add controls and content to this panel. In some apps, you can choose which controls show up here."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favorited"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorited, position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavorited"</string> @@ -898,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error, try again"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Add controls"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edit controls"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Add app"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Add outputs"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Group"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 device selected"</string> @@ -1063,4 +1066,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Your work policy allows you to make phone calls only from the work profile"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index d4bbb3fe54fb..706248b4b518 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sin sonido ni vibración"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No suena ni vibra, y aparece en la parte inferior de la sección de conversaciones."</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Puede sonar o vibrar según la configuración del dispositivo"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Puede sonar o vibrar según la configuración del dispositivo. Conversaciones de la burbuja de <xliff:g id="APP_NAME">%1$s</xliff:g> de forma predeterminada."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Dejar que el sistema determine si esta notificación debe emitir un sonido o una vibración"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Estado:</b> Se promovió a Predeterminada"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Estado:</b> Descendió de nivel a Silenciada"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Elige la app para agregar los controles"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Se agregó # control.}many{Se agregaron # controles.}other{Se agregaron # controles.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Quitados"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Está en favoritos"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Está en favoritos en la posición <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"No está en favoritos"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error. Vuelve a intentarlo."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Agregar controles"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Editar controles"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Agregar salidas"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Se seleccionó 1 dispositivo"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Bocinas y pantallas"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requiere una cuenta premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la transmisión"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmisión"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que transmites"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de batería restante"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecta tu pluma stylus a un cargador"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"La pluma stylus tiene poca batería"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videocámara"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"No se puede llamar desde este perfil"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Tu política del trabajo te permite hacer llamadas telefónicas solo desde el perfil de trabajo"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index db0b4b0dd82a..458cd38698d0 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sin sonido ni vibración"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sin sonido ni vibración, y se muestra más abajo en la sección de conversaciones"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Puede sonar o vibrar según los ajustes del dispositivo"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Puede sonar o vibrar según los ajustes del dispositivo. Las conversaciones de <xliff:g id="APP_NAME">%1$s</xliff:g> aparecen como burbujas de forma predeterminada."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Haz que el sistema determine si con esta notificación el dispositivo debe sonar o vibrar"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Estado:</b> cambio a Predeterminado"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Estado:</b> cambio a Silencio"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Elige una aplicación para añadir controles"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control añadido.}many{# controles añadidos.}other{# controles añadidos.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Quitado"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Añadido a favoritos"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Añadido a favoritos (posición <xliff:g id="NUMBER">%d</xliff:g>)"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Quitado de favoritos"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error: Vuelve a intentarlo"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Añadir controles"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Editar controles"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Añadir dispositivos de salida"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo seleccionado"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altavoces y pantallas"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Sugerencias de dispositivos"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requiere una cuenta premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la emisión"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Emisión"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que emites"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batería restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecta tu lápiz óptico a un cargador"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Batería del lápiz óptico baja"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videocámara"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"No se puede llamar desde este perfil"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Tu política del trabajo solo te permite hacer llamadas telefónicas desde el perfil de trabajo"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 8171ddd9fcbb..82bb4813d740 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automaatne"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ilma heli ja vibreerimiseta"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ilma heli ja vibreerimiseta, kuvatakse vestluste jaotises allpool"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Võib seadme seadete põhjal heliseda või vibreerida"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Võib seadme seadete põhjal heliseda või vibreerida. Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> vestlused kuvatakse vaikimisi mullis."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Laske süsteemil määrata, kas selle märguande puhul peaks esitama heli või vibreerima"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Olek:</b> määrati prioriteet Vaikimisi"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Olek:</b> määrati prioriteet Vaikne"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Keskmine"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Väike"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Suur"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Valmis"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Muuda"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Luubi akna seaded"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Puudutage juurdepääsufunktsioonide avamiseks. Kohandage nuppu või asendage see seadetes.\n\n"<annotation id="link">"Kuva seaded"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Valige juhtelementide lisamiseks rakendus"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Lisati # juhtnupp.}other{Lisati # juhtnuppu.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Eemaldatud"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisatud lemmikuks"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Lisatud lemmikuks, positsioon <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Eemaldatud lemmikute hulgast"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Ilmnes viga, proovige uuesti"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Lisa juhtelemente"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Muuda juhtelemente"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Väljundite lisamine"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupp"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 seade on valitud"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Kõlarid ja ekraanid"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Soovitatud seadmed"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Vajalik on tasuline konto"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kuidas ülekandmine toimib?"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Ülekanne"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Teie läheduses olevad inimesed, kellel on ühilduvad Bluetooth-seadmed, saavad kuulata teie ülekantavat meediat"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akutase on <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ühendage elektronpliiats laadijaga"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Elektronpliiatsi akutase on madal"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokaamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Sellelt profiililt ei saa helistada"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Teie töökoha eeskirjad lubavad teil helistada ainult tööprofiililt"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Lülitu tööprofiilile"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sule"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 6f49d0639a8a..ebbc8db7db39 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatikoa"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ez du tonurik jotzen edo dar-dar egiten"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ez du tonurik jotzen edo dar-dar egiten, eta elkarrizketen atalaren behealdean agertzen da"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Baliteke tonua jotzea edo dardara egitea, gailuaren ezarpenen arabera"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Baliteke tonua jotzea edo dardara egitea, gailuaren ezarpenen arabera. Modu lehenetsian, <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioko elkarrizketak burbuila gisa agertzen dira."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Ezarri sistemak zehaztu dezala jakinarazpen honek soinua edo dardara egin behar duen ala ez"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"Lehenetsi gisa ezarri da <b>egoera:</b>"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"Soinurik gabeko modura aldatu da <b>egoera:</b>"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Ertaina"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Txikia"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Handia"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Eginda"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Editatu"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Luparen leihoaren ezarpenak"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Erabilerraztasun-eginbideak irekitzeko, sakatu hau. Ezarpenetan pertsonalizatu edo ordez dezakezu botoia.\n\n"<annotation id="link">"Ikusi ezarpenak"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Aukeratu aplikazio bat kontrolatzeko aukerak gehitzeko"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Kontrolatzeko # aukera gehitu da.}other{Kontrolatzeko # aukera gehitu dira.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Kenduta"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Gogokoetan dago"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>. gogokoa da"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Ez dago gogokoetan"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Errorea. Saiatu berriro."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Gehitu aukerak"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Editatu aukerak"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Gehitu irteerak"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Taldea"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 gailu hautatu da"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%% <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Bozgorailuak eta pantailak"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Iradokitako gailuak"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium kontu bat behar da"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Nola funtzionatzen dute iragarpenek?"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Iragarri"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth bidezko gailu bateragarriak dituzten inguruko pertsonek iragartzen ari zaren multimedia-edukia entzun dezakete"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateriaren <xliff:g id="PERCENTAGE">%s</xliff:g> geratzen da"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Konektatu arkatza kargagailu batera"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Arkatzak bateria gutxi du"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Bideokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Ezin duzu deitu profil honetatik"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Deiak laneko profiletik soilik egiteko baimena ematen dizute laneko gidalerroek"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Aldatu laneko profilera"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Itxi"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index f46d67b920da..ab78224c5056 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -812,15 +812,14 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"متوسط"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"کوچک"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"بزرگ"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"تمام"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"ویرایش"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"تنظیمات پنجره ذرهبین"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"برای باز کردن ویژگیهای دسترسپذیری ضربه بزنید. در تنظیمات این دکمه را سفارشی یا جایگزین کنید\n\n"<annotation id="link">"تنظیمات"</annotation></string> <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"برای پنهان کردن موقتی دکمه، آن را به لبه ببرید"</string> <string name="accessibility_floating_button_undo" msgid="511112888715708241">"واگرد"</string> - <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"<xliff:g id="FEATURE_NAME">%s</xliff:g> میانبر برداشته شد"</string> - <string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{# میانبر برداشته شد}one{# میانبر برداشته شد}other{# میانبر برداشته شد}}"</string> + <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"میانبر «<xliff:g id="FEATURE_NAME">%s</xliff:g>» برداشته شد"</string> + <string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{میانبر # برداشته شد}one{میانبر # برداشته شد}other{میانبر # برداشته شد}}"</string> <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"انتقال به بالا سمت راست"</string> <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"انتقال به بالا سمت چپ"</string> <string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"انتقال به پایین سمت راست"</string> @@ -833,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"انتخاب برنامه برای افزودن کنترلها"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# کنترل اضافه شد.}one{# کنترل اضافه شد.}other{# کنترل اضافه شد.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"حذف شد"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"به موارد دلخواه اضافه شد"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"اضافهشده به موارد دلخواه، جایگاه <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"حذفشده از موارد دلخواه"</string> @@ -899,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"خطا، دوباره امتحان کنید"</string> <string name="controls_menu_add" msgid="4447246119229920050">"افزودن کنترلها"</string> <string name="controls_menu_edit" msgid="890623986951347062">"ویرایش کنترلها"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"افزودن خروجی"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"گروه"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"۱ دستگاه انتخاب شد"</string> @@ -1064,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"خطمشی کاری شما فقط به برقراری تماس ازطریق نمایه کاری اجازه میدهد"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"رفتن به نمایه کاری"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"بستن"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index ffb420de2488..b84ca4f3621d 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automaattinen"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ei ääntä tai värinää"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ei ääntä tai värinää ja näkyy alempana keskusteluosiossa"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Voi soida tai väristä laitteen asetuksista riippuen"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Voi soida tai väristä laitteen asetuksista riippuen. Keskusteluista (<xliff:g id="APP_NAME">%1$s</xliff:g>) luodaan oletuksena kuplia."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Järjestelmä valitsee, kuuluuko tästä ilmoituksesta ääntä tai väriseekö se"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Tila:</b> valittu oletusarvoiseksi"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Tila:</b> hiljennetty"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Keskitaso"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Pieni"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Suuri"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Valmis"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Muokkaa"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Ikkunan suurennuksen asetukset"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Avaa esteettömyysominaisuudet napauttamalla. Yksilöi tai vaihda painike asetuksista.\n\n"<annotation id="link">"Avaa asetukset"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Valitse sovellus lisätäksesi säätimiä"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# säädin lisätty.}other{# säädintä lisätty.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Poistettu"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisätty suosikkeihin"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Lisätty suosikkeihin sijalle <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Poistettu suosikeista"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Virhe, yritä uudelleen"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Lisää säätimiä"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Muokkaa säätimiä"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Lisää toistotapoja"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Ryhmä"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 laite valittu"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Kaiuttimet ja näytöt"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Ehdotetut laitteet"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Edellyttää premium-tiliä"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Miten lähetys toimii"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Lähetys"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Lähistöllä olevat ihmiset, joilla on yhteensopiva Bluetooth-laite, voivat kuunnella lähettämääsi mediaa"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akkua jäljellä <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Yhdistä näyttökynä laturiin"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Näyttökynän akku vähissä"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Tästä profiilista ei voi soittaa"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Työkäytäntö sallii sinun soittaa puheluita vain työprofiilista"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Vaihda työprofiiliin"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sulje"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 006cce8f91dc..a60d961275e4 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatique"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Aucun son ni vibration"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Aucun son ni vibration, et s\'affiche plus bas dans la section des conversations"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Peut sonner ou vibrer, selon les paramètres de l\'appareil"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Peut sonner ou vibrer, selon les paramètres de l\'appareil. Conversations des bulles de <xliff:g id="APP_NAME">%1$s</xliff:g> par défaut."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Faire en sorte que le système détermine si cette notification devrait émettre un son ou vibrer"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>État :</b> élevé à la catégorie Par défaut"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>État :</b> abaissé à la catégorie Silencieux"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Moyenne"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Petite"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Grande"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"OK"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Modifier"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Paramètres de la fenêtre de loupe"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Touchez pour ouvrir fonction. d\'access. Personnalisez ou remplacez bouton dans Param.\n\n"<annotation id="link">"Afficher param."</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'application pour laquelle ajouter des commandes"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}many{# de commandes ajoutées.}other{# commandes ajoutées.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ajouté aux favoris, en position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Supprimé des favoris"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Erreur. Veuillez réessayer."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Ajouter des commandes"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Modifier des commandes"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ajouter des sorties"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Groupe"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Un appareil sélectionné"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Haut-parleurs et écrans"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Appareils suggérés"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nécessite un compte payant"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement de la diffusion"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Diffusion"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité disposant d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Charge restante de la pile : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connectez votre stylet à un chargeur"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Pile du stylet faible"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Mode vidéo"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Impossible de passer un appel à partir de ce profil"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Votre politique de l\'entreprise vous autorise à passer des appels téléphoniques uniquement à partir de votre profil professionnel"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fermer"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index d9267c905263..1a37657c2c3b 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatique"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ni son, ni vibreur"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ni son, ni vibreur ; s\'affiche plus bas dans la section des conversations"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Peut sonner ou vibrer en fonction des paramètres de l\'appareil"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Peut sonner ou vibrer en fonction des paramètres de l\'appareil. Les conversations provenant de <xliff:g id="APP_NAME">%1$s</xliff:g> s\'affichent sous forme de bulles par défaut."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Laisser le système déterminer si cette notification doit être accompagnée d\'un son ou d\'une vibration"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>État :</b> Élevée à la catégorie \"Par défaut\""</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>État :</b> Abaissée à la catégorie \"Silencieux\""</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Moyen"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Petit"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Grand"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"OK"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Modifier"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Paramètres de la fenêtre d\'agrandissement"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Appuyez pour ouvrir fonctionnalités d\'accessibilité. Personnalisez ou remplacez bouton dans paramètres.\n\n"<annotation id="link">"Voir paramètres"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'appli pour laquelle ajouter des commandes"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}many{# commandes ajoutées.}other{# commandes ajoutées.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ajouté aux favoris, en position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Supprimé des favoris"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Erreur. Veuillez réessayer."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Ajouter des commandes"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Modifier des commandes"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ajouter des sorties"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Groupe"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 appareil sélectionné"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Enceintes et écrans"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Appareils suggérés"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nécessite un compte premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement des annonces"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Annonce"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité équipées d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de batterie restante"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connectez votre stylet à un chargeur"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"La batterie du stylet est faible"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Caméra vidéo"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Impossible d\'appeler depuis ce profil"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Votre règle professionnelle ne vous permet de passer des appels que depuis le profil professionnel"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fermer"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index a06ddd7f817c..cb1a8cbf7525 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -814,8 +814,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Mediano"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Pequeno"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Grande"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Feito"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Editar"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Configuración da ventá da lupa"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Toca para abrir as funcións de accesibilidade. Cambia este botón en Configuración.\n\n"<annotation id="link">"Ver configuración"</annotation></string> @@ -835,6 +834,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Escolle unha aplicación para engadir controis"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Engadiuse # control.}other{Engadíronse # controis.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Quitouse"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Está entre os controis favoritos"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Está entre os controis favoritos (posición: <xliff:g id="NUMBER">%d</xliff:g>)"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Non está entre os controis favoritos"</string> @@ -901,6 +904,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Erro. Téntao de novo"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Engadir controis"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Editar controis"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Engadir saídas"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Seleccionouse 1 dispositivo"</string> @@ -1072,4 +1077,6 @@ <skip /> <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> <skip /> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 687d1af5484a..78aa0f5f24db 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"નિયંત્રણો ઉમેરવા માટે ઍપ પસંદ કરો"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# નિયંત્રણ ઉમેર્યું.}one{# નિયંત્રણ ઉમેર્યું.}other{# નિયંત્રણ ઉમેર્યા.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"કાઢી નાખ્યું"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"મનપસંદમાં ઉમેર્યું"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"મનપસંદમાં ઉમેર્યું, સ્થાન <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"મનપસંદમાંથી કાઢી નાખ્યું"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"ભૂલ, ફરીથી પ્રયાસ કરો"</string> <string name="controls_menu_add" msgid="4447246119229920050">"નિયંત્રણો ઉમેરો"</string> <string name="controls_menu_edit" msgid="890623986951347062">"નિયંત્રણોમાં ફેરફાર કરો"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"આઉટપુટ ઉમેરો"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ગ્રૂપ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 ડિવાઇસ પસંદ કર્યું"</string> @@ -1063,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"તમારી ઑફિસની પૉલિસી તમને માત્ર ઑફિસની પ્રોફાઇલ પરથી જ ફોન કૉલ કરવાની મંજૂરી આપે છે"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"ઑફિસની પ્રોફાઇલ પર સ્વિચ કરો"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"બંધ કરો"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 555b3d786004..c0d89f908c6e 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"अपने-आप"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"किसी तरह की आवाज़ या वाइब्रेशन न हो"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"इससे किसी तरह की आवाज़ या वाइब्रेशन नहीं होता और बातचीत, सेक्शन में सबसे नीचे दिखती है"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"डिवाइस की सेटिंग के आधार पर, सूचना आने पर घंटी बज सकती है या वाइब्रेशन हो सकता है"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"डिवाइस की सेटिंग के आधार पर, सूचना आने पर घंटी बज सकती है या वाइब्रेशन हो सकता है. <xliff:g id="APP_NAME">%1$s</xliff:g> पर होने वाली बातचीत, डिफ़ॉल्ट रूप से बबल के तौर पर दिखती है."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"सिस्टम को यह तय करने की अनुमति दें कि इस सूचना के मिलने पर आवाज़ हो या वाइब्रेशन हो"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>स्थिति:</b> लेवल बढ़ाकर, डिफ़ॉल्ट के तौर पर सेट किया गया"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>स्थिति:</b> लेवल घटाकर, साइलेंट पर सेट किया गया"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"कंट्रोल जोड़ने के लिए ऐप्लिकेशन चुनें"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कंट्रोल जोड़ा गया.}one{# कंट्रोल जोड़ा गया.}other{# कंट्रोल जोड़े गए.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"हटाया गया"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"पसंदीदा बनाया गया"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"पसंदीदा बनाया गया, क्रम संख्या <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"पसंदीदा से हटाया गया"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"गड़बड़ी हुई, फिर से कोशिश करें"</string> <string name="controls_menu_add" msgid="4447246119229920050">"कंट्राेल जोड़ें"</string> <string name="controls_menu_edit" msgid="890623986951347062">"कंट्रोल में बदलाव करें"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"आउटपुट जोड़ें"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ग्रुप"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"एक डिवाइस चुना गया"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"स्पीकर और डिसप्ले"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"सुझाए गए डिवाइस"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"प्रीमियम खाता होना ज़रूरी है"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ब्रॉडकास्ट करने की सुविधा कैसे काम करती है"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ब्रॉडकास्ट करें"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"आपके आस-पास मौजूद लोग, ब्रॉडकास्ट किए जा रहे मीडिया को सुन सकते हैं. हालांकि, इसके लिए उनके पास ऐसे ब्लूटूथ डिवाइस होने चाहिए जिन पर मीडिया चलाया जा सके"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> बैटरी बची है"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"अपने स्टाइलस को चार्ज करें"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"स्टाइलस की बैटरी कम है"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"वीडियो कैमरा"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"यह प्रोफ़ाइल होने पर कॉल नहीं की जा सकती"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"ऑफ़िस की नीति के तहत, वर्क प्रोफ़ाइल होने पर ही फ़ोन कॉल किए जा सकते हैं"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"वर्क प्रोफ़ाइल पर स्विच करें"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"बंद करें"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 7e0ba0043b77..cdf6e579234d 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -832,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Odabir aplikacije za dodavanje kontrola"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodana je # kontrola.}one{Dodana je # kontrola.}few{Dodane su # kontrole.}other{Dodano je # kontrola.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite li dodati aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Kada dodate aplikaciju <xliff:g id="APPNAME">%s</xliff:g>, može dodati kontrole i sadržaj na ovu ploču. U nekim aplikacijama možete odabrati koje se kontrole prikazuju ovdje."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano u favorite"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano u favorite, položaj <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Uklonjeno iz favorita"</string> @@ -898,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Pogreška, pokušajte ponovo"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Dodaj kontrole"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Uredi kontrole"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Dodavanje aplikacije"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodavanje izlaza"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Odabran je jedan uređaj"</string> @@ -1063,4 +1066,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Vaša pravila za poslovne uređaje omogućuju vam upućivanje poziva samo s poslovnog profila"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Prijeđite na poslovni profil"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 4c8c988569dd..c411a0a7997f 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatikus"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Nincs hang és rezgés"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Nincs hang és rezgés, továbbá lejjebb jelenik meg a beszélgetések szakaszában"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Az eszközbeállítások alapján csöröghet és rezeghet"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Az eszközbeállítások alapján csöröghet és rezeghet. A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazásban lévő beszélgetések alapértelmezés szerint buborékban jelennek meg."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"A rendszer határozza meg, hogy ez az értesítés adjon-e ki hangot, illetve rezegjen-e"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Állapot:</b> alapértelmezettre állítva"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Állapot:</b> némára állítva"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Közepes"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Kicsi"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Nagy"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Kész"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Szerkesztés"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Nagyítóablak beállításai"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Koppintson a kisegítő lehetőségek megnyitásához. A gombot a Beállításokban módosíthatja.\n\n"<annotation id="link">"Beállítások"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Válasszon alkalmazást a vezérlők hozzáadásához"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# vezérlő hozzáadva.}other{# vezérlő hozzáadva.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Eltávolítva"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Hozzáadva a kedvencekhez"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Hozzáadva a kedvencekhez <xliff:g id="NUMBER">%d</xliff:g>. helyen"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Eltávolítva a kedvencek közül"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Hiba történt. Próbálja újra."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Vezérlők hozzáadása"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Vezérlők szerkesztése"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Kimenetek hozzáadása"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Csoport"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 eszköz kiválasztva"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Hangfalak és kijelzők"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Javasolt eszközök"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Prémiumfiók szükséges"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"A közvetítés működése"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Közvetítés"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"A közelben tartózkodó, kompatibilis Bluetooth-eszközzel rendelkező személyek meghallgathatják az Ön közvetített médiatartalmait"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akkumulátor töltöttségi szintje: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Tegye töltőre az érintőceruzát"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Az érintőceruza töltöttsége alacsony"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nem lehet hívást kezdeményezni ebből a profilból"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"A munkahelyi házirend csak munkaprofilból kezdeményezett telefonhívásokat engedélyez"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Váltás munkaprofilra"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bezárás"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 370ce8233f45..9186f121e6f2 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Ավտոմատ"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Առանց ձայնի կամ թրթռոցի"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Առանց ձայնի և թրթռոցի, հայտնվում է զրույցների ցանկի ներքևում"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Կարող է զնգալ կամ թրթռալ՝ կախված սարքի կարգավորումներից"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Կարող է զնգալ կամ թրթռալ՝ կախված սարքի կարգավորումներից։ <xliff:g id="APP_NAME">%1$s</xliff:g>-ի զրույցներն ըստ կանխադրման հայտնվում են ամպիկների տեսքով։"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Թող համակարգն ավտոմատ որոշի՝ արդյոք այս ծանուցումը ձայնով, թե թրթռոցով է պետք մատուցել"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Կարգավիճակը․</b> բարձրացվել է և դարձել կանխադրված"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Կարգավիճակը․</b> իջեցվել է և դարձել անձայն"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Ընտրեք հավելված` կառավարման տարրեր ավելացնելու համար"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Ավելացվեց կառավարման # տարր։}one{Ավելացվեց կառավարման # տարր։}other{Ավելացվեց կառավարման # տարր։}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Հեռացված է"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ավելացված է ընտրանիում"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ավելացված է ընտրանիում, դիրքը՝ <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Հեռացված է ընտրանուց"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Սխալ առաջացավ։ Նորից փորձեք։"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Ավելացնել կառավարման տարրեր"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Փոփոխել կառավարման տարրերը"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ավելացրեք մուտքագրման սարքեր"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Խումբ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Ընտրված է 1 սարք"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Բարձրախոսներ և էկրաններ"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Առաջարկվող սարքեր"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Պահանջվում է պրեմիում հաշիվ"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Ինչպես է աշխատում հեռարձակումը"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Հեռարձակում"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ձեր մոտակայքում գտնվող՝ համատեղելի Bluetooth սարքերով մարդիկ կարող են լսել մեդիա ֆայլերը, որոնք դուք հեռարձակում եք։"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Մարտկոցի լիցքը՝ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ձեր ստիլուսը միացրեք լիցքավորիչի"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Ստիլուսի մարտկոցի լիցքի ցածր մակարդակ"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Տեսախցիկ"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Հնարավոր չէ զանգել այս պրոֆիլից"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Ձեր աշխատանքային կանոնների համաձայն՝ դուք կարող եք զանգեր կատարել աշխատանքային պրոֆիլից"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Անցնել աշխատանքային պրոֆիլ"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Փակել"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index bd1f48b7a65b..1d0d3d64e892 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatis"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Tidak ada suara atau getaran"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Tidak ada suara atau getaran dan ditampilkan lebih rendah di bagian percakapan"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Dapat berdering atau bergetar berdasarkan setelan perangkat"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Dapat berdering atau bergetar berdasarkan setelan perangkat. Percakapan <xliff:g id="APP_NAME">%1$s</xliff:g> ditampilkan sebagai balon secara default."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Biarkan sistem menentukan apakah notifikasi ini akan berbunyi atau bergetar"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> Dipromosikan menjadi Default"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> Didemosikan menjadi Senyap"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Sedang"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Kecil"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Besar"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Selesai"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Edit"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Setelan jendela kaca pembesar"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Ketuk untuk membuka fitur aksesibilitas. Sesuaikan atau ganti tombol ini di Setelan.\n\n"<annotation id="link">"Lihat setelan"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Pilih aplikasi untuk menambahkan kontrol"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrol ditambahkan.}other{# kontrol ditambahkan.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Dihapus"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Difavoritkan"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Difavoritkan, posisi <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Batal difavoritkan"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Error, coba lagi"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Tambahkan kontrol"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edit kontrol"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Tambahkan output"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 perangkat dipilih"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speaker & Layar"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Perangkat yang Disarankan"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Memerlukan akun premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cara kerja siaran"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Siaran"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Orang di dekat Anda dengan perangkat Bluetooth yang kompatibel dapat mendengarkan media yang sedang Anda siarkan"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Baterai tersisa <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Hubungkan stilus ke pengisi daya"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Baterai stilus lemah"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Kamera video"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Tidak dapat melakukan panggilan dari profil ini"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Kebijakan kantor mengizinkan Anda melakukan panggilan telepon hanya dari profil kerja"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Beralih ke profil kerja"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index cd924f23acf7..aabae2f18127 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Sjálfvirk"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ekkert hljóð eða titringur"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ekkert hljóð eða titringur og birtist neðar í samtalshluta"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Gæti hringt eða titrað en það fer eftir stillingum tækisins"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Gæti hringt eða titrað en það fer eftir stillingum tækisins. Samtöl frá <xliff:g id="APP_NAME">%1$s</xliff:g> birtast sjálfkrafa í blöðru."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Láta kerfið ákvarða hvort hljóð eða titringur fylgir þessari tilkynningu"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Staða:</b> gerð sjálfgefin"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Staða:</b> var gerð þögul"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Miðlungs"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Lítið"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Stórt"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Lokið"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Breyta"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Stillingar stækkunarglugga"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Ýttu til að opna aðgengiseiginleika. Sérsníddu eða skiptu hnappinum út í stillingum.\n\n"<annotation id="link">"Skoða stillingar"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Veldu forrit til að bæta við stýringum"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# stýringu bætt við.}one{# stýringu bætt við.}other{# stýringum bætt við.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Fjarlægt"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Eftirlæti"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Eftirlæti, staða <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjarlægt úr eftirlæti"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Villa, reyndu aftur"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Bæta við stýringum"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Breyta stýringum"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Bæta við úttaki"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Hópur"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 tæki valið"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Hátalarar og skjáir"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Tillögur að tækjum"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Krefst úrvalsreiknings"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Svona virkar útsending"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Útsending"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Fólk nálægt þér með samhæf Bluetooth-tæki getur hlustað á efnið sem þú sendir út"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> hleðsla eftir á rafhlöðu"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Tengdu pennann við hleðslutæki"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Rafhlaða pennans er að tæmast"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Kvikmyndatökuvél"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Ekki er hægt að hringja úr þessu sniði"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Vinnureglur gera þér aðeins kleift að hringja símtöl úr vinnusniði"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skipta yfir í vinnusnið"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Loka"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 531ac207d2fa..ced316fac499 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -832,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Scegli un\'app per aggiungere controlli"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controllo aggiunto.}many{# controlli aggiunti.}other{# controlli aggiunti.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Rimosso"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Vuoi aggiungere <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Se la aggiungi, l\'app <xliff:g id="APPNAME">%s</xliff:g> può aggiungere controlli e contenuti a questo riquadro. In alcune app puoi scegliere quali controlli visualizzare qui."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Aggiunto ai preferiti"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Preferito, posizione <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Rimosso dai preferiti"</string> @@ -898,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Errore, riprova"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Aggiungi controlli"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Modifica controlli"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Aggiungi app"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Aggiungi uscite"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Gruppo"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo selezionato"</string> @@ -1063,4 +1066,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Le norme di lavoro ti consentono di fare telefonate soltanto dal profilo di lavoro"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passa a profilo di lavoro"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Chiudi"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 926e2aad196d..dba7c4e95538 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"באופן אוטומטי"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"ללא צליל או רטט"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ללא צליל או רטט ומופיעה למטה בקטע התראות השיחה"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"ייתכן שיופעל צלצול או רטט בהתאם להגדרות במכשיר"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ייתכן שיופעל צלצול או רטט בהתאם להגדרות במכשיר. שיחות מהאפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מופיעות בבועות כברירת מחדל."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"אפשר לתת למערכת לקבוע אם ההתראה הזאת צריכה להיות מלווה בצליל או ברטט"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>הסטטוס:</b> הועלה בדרגה ל\'ברירת מחדל\'"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>הסטטוס:</b> הורד בדרגה ל\'שקט\'"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"יש לבחור אפליקציה כדי להוסיף פקדים"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{נוסף אמצעי בקרה אחד (#).}one{נוספו # אמצעי בקרה.}two{נוספו # אמצעי בקרה.}other{נוספו # אמצעי בקרה.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"הוסר"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"סומן כמועדף"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"סומן כמועדף, במיקום <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"הוסר מהמועדפים"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"שגיאה, יש לנסות שוב"</string> <string name="controls_menu_add" msgid="4447246119229920050">"הוספת פקדים"</string> <string name="controls_menu_edit" msgid="890623986951347062">"עריכת פקדים"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"הוספת מכשירי פלט"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"קבוצה"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"נבחר מכשיר אחד"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"רמקולים ומסכים"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"הצעות למכשירים"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"נדרש חשבון פרימיום"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"הסבר על שידורים"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"שידור"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"אנשים בקרבת מקום עם מכשירי Bluetooth תואמים יכולים להאזין למדיה שמשודרת על ידך"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"רמת הטעינה שנותרה בסוללה: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"כדאי לחבר את הסטיילוס למטען"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"הסוללה של הסטיילוס חלשה"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"מצלמת וידאו"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"אי אפשר להתקשר מהפרופיל הזה"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"המדיניות של מקום העבודה מאפשרת לך לבצע שיחות טלפון רק מפרופיל העבודה"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"מעבר לפרופיל עבודה"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"סגירה"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 8cd79df3a6d4..f88eb8be6fa9 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -832,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"コントロールを追加するアプリの選択"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# 件のコントロールを追加しました。}other{# 件のコントロールを追加しました。}}"</string> <string name="controls_removed" msgid="3731789252222856959">"削除済み"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> を追加しますか?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> を追加することで、コントロールやコンテンツをこのパネルに追加できます。一部のアプリでは、ここに表示されるコントロールを選択できます。"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"お気に入りに追加済み"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"お気に入りに追加済み、位置: <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"お気に入りから削除済み"</string> @@ -898,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"エラー: もう一度お試しください"</string> <string name="controls_menu_add" msgid="4447246119229920050">"コントロールを追加"</string> <string name="controls_menu_edit" msgid="890623986951347062">"コントロールを編集"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"アプリを追加"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"出力の追加"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"グループ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"選択したデバイス: 1 台"</string> @@ -1063,4 +1066,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"仕事用ポリシーでは、通話の発信を仕事用プロファイルからのみに制限できます"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"仕事用プロファイルに切り替える"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"閉じる"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index fe0a8a0690a2..dd4f03dc4161 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"აირჩიეთ აპი მართვის საშუალებების დასამატებლად"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{დაემატა მართვის # საშუალება.}other{დაემატა მართვის # საშუალება.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ამოიშალა"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"რჩეულებშია"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"რჩეულებშია, პოზიციაზე <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"რჩეულებიდან ამოღებულია"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"შეცდომა, ისევ ცადეთ"</string> <string name="controls_menu_add" msgid="4447246119229920050">"მართვის საშუალებების დამატება"</string> <string name="controls_menu_edit" msgid="890623986951347062">"მართვის საშუალებათა რედაქტირება"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"მედია-გამოსავლების დამატება"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ჯგუფი"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"არჩეულია 1 მოწყობილობა"</string> @@ -1063,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"თქვენი სამსახურის წესები საშუალებას გაძლევთ, სატელეფონო ზარები განახორციელოთ მხოლოდ სამსახურის პროფილიდან"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"სამსახურის პროფილზე გადართვა"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"დახურვა"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index b2274c85b46a..f4575f009e8d 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматты"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Дыбыс не діріл болмайды."</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Дыбыс не діріл болмайды, әңгімелер бөлімінің төмен жағында тұрады."</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Құрылғы параметрлеріне байланысты шырылдауы не дірілдеуі мүмкін"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Құрылғы параметрлеріне байланысты шырылдауы не дірілдеуі мүмкін. <xliff:g id="APP_NAME">%1$s</xliff:g> чаттары әдепкісінше қалқымалы етіп көрсетіледі."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Хабарландыру дыбысының немесе дірілдің қосылуын жүйе анықтайтын болады"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Күйі:</b> \"Әдепкі\" санатына көтерілген"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Күйі:</b> \"Үнсіз\" санатына төмендетілген"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Орташа"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Кішi"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Үлкен"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Дайын"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Өзгерту"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Ұлғайтқыш терезесінің параметрлері"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Арнайы мүмкіндікті ашу үшін түртіңіз. Түймені параметрден реттеңіз не ауыстырыңыз.\n\n"<annotation id="link">"Параметрді көру"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Басқару элементтері қосылатын қолданбаны таңдаңыз"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# басқару элементі қосылды.}other{# басқару элементі қосылды.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Өшірілді"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Таңдаулыларға қосылды"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Таңдаулыларға қосылды, <xliff:g id="NUMBER">%d</xliff:g>-позиция"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Таңдаулылардан алып тасталды"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Қате шықты. Қайталап көріңіз."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Басқару элементтерін қосу"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Басқару элементтерін өзгерту"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Шығыс сигналдарды қосу"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Топ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 құрылғы таңдалды."</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Динамиктер мен дисплейлер"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Ұсынылған құрылғылар"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Премиум аккаунт қажет"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Тарату қалай жүзеге асады"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Тарату"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Үйлесімді Bluetooth құрылғылары бар маңайдағы адамдар сіз таратып жатқан медиамазмұнды тыңдай алады."</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Қалған батарея заряды: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Стилусты зарядтағышқа жалғаңыз."</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Стилус батареясының заряды аз"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Бейнекамера"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Бұл профильден қоңырау шалу мүмкін емес"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Жұмыс саясатыңызға сәйкес тек жұмыс профилінен қоңырау шалуға болады."</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жұмыс профиліне ауысу"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабу"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index d33b439141f8..d5e31aa61c9c 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"ស្វ័យប្រវត្តិ"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"គ្មានសំឡេង ឬការញ័រទេ"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"គ្មានសំឡេងឬការញ័រ និងបង្ហាញទាបជាងនៅក្នុងផ្នែកសន្ទនា"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"អាចរោទ៍ ឬញ័រ ដោយផ្អែកលើការកំណត់ឧបករណ៍"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"អាចរោទ៍ ឬញ័រ ដោយផ្អែកលើការកំណត់ឧបករណ៍។ ការសន្ទនាពីផ្ទាំងអណ្ដែត <xliff:g id="APP_NAME">%1$s</xliff:g> តាមលំនាំដើម។"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ឱ្យប្រព័ន្ធកំណត់ថាតើការជូនដំណឹងនេះគួរតែបន្លឺសំឡេង ឬញ័រ"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>ស្ថានភាព៖</b> បានដំឡើងទៅលំនាំដើម"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>ស្ថានភាព៖</b> បានបញ្ចុះទៅស្ងាត់"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"មធ្យម"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"តូច"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"ធំ"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"រួចរាល់"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"កែ"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"ការកំណត់វិនដូកម្មវិធីពង្រីក"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"ចុចដើម្បីបើកមុខងារភាពងាយស្រួល។ ប្ដូរ ឬប្ដូរប៊ូតុងនេះតាមបំណងនៅក្នុងការកំណត់។\n\n"<annotation id="link">"មើលការកំណត់"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"ជ្រើសរើសកម្មវិធីដែលត្រូវបញ្ចូលផ្ទាំងគ្រប់គ្រង"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{បានបញ្ចូលការគ្រប់គ្រង #។}other{បានបញ្ចូលការគ្រប់គ្រង #។}}"</string> <string name="controls_removed" msgid="3731789252222856959">"បានដកចេញ"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"បានដាក់ជាសំណព្វ"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"បានដាក់ជាសំណព្វ ទីតាំងទី <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"បានដកចេញពីសំណព្វ"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"មានបញ្ហា សូមព្យាយាមម្តងទៀត"</string> <string name="controls_menu_add" msgid="4447246119229920050">"បញ្ចូលផ្ទាំងគ្រប់គ្រង"</string> <string name="controls_menu_edit" msgid="890623986951347062">"កែផ្ទាំងគ្រប់គ្រង"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"បញ្ចូលឧបករណ៍មេឌៀ"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ក្រុម"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"បានជ្រើសរើសឧបករណ៍ 1"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ឧបករណ៍បំពងសំឡេង និងផ្ទាំងអេក្រង់"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ឧបករណ៍ដែលបានណែនាំ"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ត្រូវការគណនីលំដាប់ខ្ពស់"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"របៀបដែលការផ្សាយដំណើរការ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ការផ្សាយ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"មនុស្សនៅជិតអ្នកដែលមានឧបករណ៍ប៊្លូធូសត្រូវគ្នាអាចស្តាប់មេឌៀដែលអ្នកកំពុងផ្សាយបាន"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"ថ្មនៅសល់ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ភ្ជាប់ប៊ិករបស់អ្នកជាមួយឆ្នាំងសាក"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"ថ្មប៊ិកនៅសល់តិច"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"កាមេរ៉ាវីដេអូ"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"មិនអាចហៅទូរសព្ទពីកម្រងព័ត៌មាននេះបានទេ"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"គោលការណ៍ការងាររបស់អ្នកអនុញ្ញាតឱ្យអ្នកធ្វើការហៅទូរសព្ទបានតែពីកម្រងព័ត៌មានការងារប៉ុណ្ណោះ"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"ប្ដូរទៅកម្រងព័ត៌មានការងារ"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"បិទ"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index e9dc76960e50..687fa2811501 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲು ಆ್ಯಪ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ನಿಯಂತ್ರಣವನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}one{# ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}other{# ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ಮೆಚ್ಚಲಾಗಿರುವುದು"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ಮೆಚ್ಚಲಾಗಿರುವುದು, ಸ್ಥಾನ <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ಮೆಚ್ಚಿನದಲ್ಲದ್ದು"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"ದೋಷ, ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string> <string name="controls_menu_add" msgid="4447246119229920050">"ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಿ"</string> <string name="controls_menu_edit" msgid="890623986951347062">"ನಿಯಂತ್ರಣಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ಔಟ್ಪುಟ್ಗಳನ್ನು ಸೇರಿಸಿ"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ಗುಂಪು"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 ಸಾಧನವನ್ನು ಆಯ್ಕೆ ಮಾಡಲಾಗಿದೆ"</string> @@ -1063,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"ನಿಮ್ಮ ಕೆಲಸದ ನೀತಿಯು ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ನಿಂದ ಮಾತ್ರ ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ಗೆ ಬದಲಿಸಿ"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"ಮುಚ್ಚಿರಿ"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index c9d70a15ffda..3631973d32d8 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"자동"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"소리 또는 진동 없음"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"소리나 진동이 울리지 않으며 대화 섹션 하단에 표시됨"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"기기 설정에 따라 벨소리나 진동이 울릴 수 있음"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"기기 설정에 따라 벨소리나 진동이 울릴 수 있습니다. 기본적으로 <xliff:g id="APP_NAME">%1$s</xliff:g>의 대화는 대화창으로 표시됩니다."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"시스템에서 알림 시 소리 또는 진동을 사용할지 결정하도록 허용합니다."</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>상태:</b> 기본으로 높임"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>상태:</b> 무음으로 낮춤"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"컨트롤을 추가할 앱을 선택하세요"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{설정이 #개 추가되었습니다.}other{설정이 #개 추가되었습니다.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"삭제됨"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"즐겨찾기에 추가됨"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"즐겨찾기에 추가됨, 위치 <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"즐겨찾기에서 삭제됨"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"오류. 다시 시도하세요."</string> <string name="controls_menu_add" msgid="4447246119229920050">"컨트롤 추가"</string> <string name="controls_menu_edit" msgid="890623986951347062">"컨트롤 수정"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"출력 추가"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"그룹"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"기기 1대 선택됨"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"스피커 및 디스플레이"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"추천 기기"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"프리미엄 계정 필요"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"브로드캐스팅 작동 원리"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"브로드캐스트"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"호환되는 블루투스 기기를 가진 근처의 사용자가 내가 브로드캐스트 중인 미디어를 수신 대기할 수 있습니다."</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"배터리 <xliff:g id="PERCENTAGE">%s</xliff:g> 남음"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"스타일러스를 충전기에 연결하세요"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"스타일러스 배터리 부족"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"비디오 카메라"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"이 프로필에서 전화를 걸 수 없음"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"직장 정책이 직장 프로필에서만 전화를 걸도록 허용합니다."</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"직장 프로필로 전환"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"닫기"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 54a073e249a1..f5b4a26f82d8 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматтык"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Үнү чыкпайт жана дирилдебейт"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Үнү чыкпайт же дирилдебейт жана сүйлөшүүлөр тизмесинин ылдый жагында көрүнөт"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Түзмөктүн параметрлерине жараша шыңгырап же дирилдеши мүмкүн"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Түзмөктүн параметрлерине жараша шыңгырап же дирилдеши мүмкүн. <xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосундагы сүйлөшүүлөр демейки шартта калкып чыкма билдирмелер болуп көрүнөт."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Билдирменин үнүн чыгартууну же басууну тутумга тапшырыңыз"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Абалы:</b> Демейкиге өзгөрдү"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Абалы:</b> Үнсүз абалга төмөндөдү"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Башкаруу элементтери кошула турган колдонмону тандоо"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# көзөмөл кошулду.}other{# көзөмөл кошулду.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Өчүрүлдү"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Сүйүктүүлөргө кошулду"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Сүйүктүүлөргө <xliff:g id="NUMBER">%d</xliff:g>-позицияга кошулду"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Сүйүктүүлөрдөн чыгарылды"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Ката, кайталап көрүңүз"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Башкаруу элементтерин кошуу"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Башкаруу элементтерин түзөтүү"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Медиа түзмөктөрдү кошуу"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Топ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 түзмөк тандалды"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Динамиктер жана дисплейлер"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Сунушталган түзмөктөр"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Премиум аккаунт талап кылынат"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Кабарлоо кантип иштейт"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Кабарлоо"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Шайкеш Bluetooth түзмөктөрү болгон жакын жердеги кишилер кабарлап жаткан медиаңызды уга алышат"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Батареянын кубаты: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Стилусту кубаттаңыз"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Стилустун батареясы отурайын деп калды"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Видео камера"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Бул профилден чала албайсыз"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Жумуш саясатыңызга ылайык, жумуш профилинен гана чалууларды аткара аласыз"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жумуш профилине которулуу"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабуу"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index fc386d69bf28..8754166dfb7b 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"ອັດຕະໂນມັດ"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"ບໍ່ມີສຽງ ຫຼື ການສັ່ນເຕືອນ"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ບໍ່ມີສຽງ ຫຼື ການສັ່ນເຕືອນ ແລະ ປາກົດຢູ່ທາງລຸ່ມຂອງພາກສ່ວນການສົນທະນາ"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"ອາດສົ່ງສຽງ ຫຼື ສັ່ນເຕືອນໂດຍອ້າງອີງຈາກການຕັ້ງຄ່າອຸປະກອນ"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ອາດສົ່ງສຽງ ຫຼື ສັ່ນເຕືອນໂດຍອ້າງອີງຈາກການຕັ້ງຄ່າອຸປະກອນ. ການສົນທະນາຈາກ <xliff:g id="APP_NAME">%1$s</xliff:g> ຈະເປັນ bubble ຕາມຄ່າເລີ່ມຕົ້ນ."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ໃຫ້ລະບົບກຳນົດວ່າການແຈ້ງເຕືອນນິ້ຄວນມີສຽງ ຫຼື ສັ່ນເຕືອນຫຼືບໍ່"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>ສະຖານະ:</b> ເລື່ອນລະດັບເປັນຄ່າເລີ່ມຕົ້ນແລ້ວ"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>ສະຖານະ:</b> ຫຼຸດລະດັບເປັນປິດສຽງແລ້ວ"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"ເລືອກແອັບເພື່ອເພີ່ມການຄວບຄຸມ"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ເພີ່ມ # ການຄວບຄຸມແລ້ວ.}other{ເພີ່ມ # ການຄວບຄຸມແລ້ວ.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ລຶບອອກແລ້ວ"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ເພີ່ມລາຍການທີ່ມັກແລ້ວ"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ເພີ່ມລາຍການທີ່ມັກແລ້ວ, ຕຳແໜ່ງ <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ຍົກເລີກລາຍການທີ່ມັກແລ້ວ"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"ຜິດພາດ, ກະລຸນາລອງໃໝ່"</string> <string name="controls_menu_add" msgid="4447246119229920050">"ເພີ່ມການຄວບຄຸມ"</string> <string name="controls_menu_edit" msgid="890623986951347062">"ແກ້ໄຂການຄວບຄຸມ"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ເພີ່ມເອົ້າພຸດ"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ກຸ່ມ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"ເລືອກ 1 ອຸປະກອນແລ້ວ"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ລຳໂພງ ແລະ ຈໍສະແດງຜົນ"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ອຸປະກອນທີ່ແນະນຳ"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ຕ້ອງໃຊ້ບັນຊີພຣີມຽມ"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ການອອກອາກາດເຮັດວຽກແນວໃດ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ອອກອາກາດ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ຄົນທີ່ຢູ່ໃກ້ທ່ານທີ່ມີອຸປະກອນ Bluetooth ທີ່ເຂົ້າກັນໄດ້ຈະສາມາດຟັງມີເດຍທີ່ທ່ານກຳລັງອອກອາກາດຢູ່ໄດ້"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"ແບັດເຕີຣີເຫຼືອ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ເຊື່ອມຕໍ່ປາກກາຂອງທ່ານກັບສາຍສາກ"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"ແບັດເຕີຣີປາກກາເຫຼືອໜ້ອຍ"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"ກ້ອງວິດີໂອ"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"ບໍ່ສາມາດໂທຈາກໂປຣໄຟລ໌ນີ້ໄດ້"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"ນະໂຍບາຍບ່ອນເຮັດວຽກຂອງທ່ານອະນຸຍາດໃຫ້ທ່ານໂທລະສັບໄດ້ຈາກໂປຣໄຟລ໌ບ່ອນເຮັດວຽກເທົ່ານັ້ນ"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"ສະຫຼັບໄປໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"ປິດ"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 753b8b748c18..d42fc7a487f4 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -832,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Pasirinkite programą, kad pridėtumėte valdiklių"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Pridėtas # valdiklis.}one{Pridėtas # valdiklis.}few{Pridėti # valdikliai.}many{Pridėta # valdiklio.}other{Pridėta # valdiklių.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Pašalinta"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Pridėti „<xliff:g id="APPNAME">%s</xliff:g>“?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Pridėjus programą „<xliff:g id="APPNAME">%s</xliff:g>“, ji gali pridėti valdiklių ir turinio prie šio skydelio. Kai kuriose programose galite pasirinkti, kurie valdikliai čia rodomi."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Įtraukta į mėgstamiausius"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Įtraukta į mėgstamiausius, padėtis: <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Pašalinta iš mėgstamiausių"</string> @@ -898,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Klaida, bandykite dar kartą"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Pridėti valdiklių"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Redaguoti valdiklius"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Pridėti programą"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Išvesčių pridėjimas"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupė"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Pasirinktas 1 įrenginys"</string> @@ -1063,4 +1066,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Pagal jūsų darbo politiką galite skambinti telefonu tik iš darbo profilio"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Perjungti į darbo profilį"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Uždaryti"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index f2af1c1e4f84..d01cab9fa2c0 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automātiski"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Nav skaņas signāla vai vibrācijas"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Nav skaņas signāla vai vibrācijas, kā arī atrodas tālāk sarunu sadaļā"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Atkarībā no iestatījumiem var zvanīt vai vibrēt"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Atkarībā no ierīces iestatījumiem var zvanīt vai vibrēt. Sarunas no lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> pēc noklusējuma tiek parādītas burbulī."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Iestatiet, lai sistēma noteiktu, vai šim paziņojumam būs skaņa vai vibrācija"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Statuss:</b> svarīgums paaugstināts līdz noklusējumam"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Statuss:</b> svarīgums pazemināts, un paziņojums tiks rādīts bez skaņas"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Vidējs"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Mazs"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Liels"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Gatavs"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Rediģēt"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Lupas loga iestatījumi"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Atveriet pieejamības funkcijas. Pielāgojiet vai aizstājiet šo pogu iestatījumos.\n\n"<annotation id="link">"Skatīt iestatījumus"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Izvēlieties lietotni, lai pievienotu vadīklas"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Pievienota # vadīkla.}zero{Pievienotas # vadīklas.}one{Pievienota # vadīkla.}other{Pievienotas # vadīklas.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Noņemta"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Pievienota izlasei"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Pievienota izlasei, <xliff:g id="NUMBER">%d</xliff:g>. pozīcija"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Noņemta no izlases"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Radās kļūda. Mēģiniet vēlreiz."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Pievienot vadīklas"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Rediģēt vadīklas"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Izejas ierīču pievienošana"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Atlasīta viena ierīce"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Skaļruņi un displeji"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Ieteiktās ierīces"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nepieciešams maksas konts"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kā darbojas apraide"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Apraide"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Tuvumā esošās personas ar saderīgām Bluetooth ierīcēm var klausīties jūsu apraidīto multivides saturu."</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Atlikušais uzlādes līmenis: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Pievienojiet skārienekrāna pildspalvu lādētājam"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Zems skārienekrāna pildspalvas akumulatora līmenis"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nevar zvanīt no šī profila"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Saskaņā ar jūsu darba politiku tālruņa zvanus drīkst veikt tikai no darba profila"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pārslēgties uz darba profilu"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Aizvērt"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 1517c23da7bd..f8e0151c6160 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматски"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звук или вибрации"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звук или вибрации и се појавува подолу во делот со разговори"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Може да ѕвони или вибрира во зависност од поставките на уредот"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Може да ѕвони или вибрира во зависност од поставките на уредот. Стандардно, разговорите од <xliff:g id="APP_NAME">%1$s</xliff:g> се во балончиња."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Дозволете системот да определи дали известувањево треба да испушти звук или да вибрира"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Статус:</b> поставено на „Стандардно“"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Статус:</b> намалено на „Тивко“"</string> @@ -834,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Изберете апликација за да додадете контроли"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Додадена е # контрола.}one{Додадени се # контрола.}other{Додадени се # контроли.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Отстранета"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Да се додаде <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Кога ќе ја додадете <xliff:g id="APPNAME">%s</xliff:g>, таа ќе може да додава контроли и содржини на таблава. Кај некои апликации, може да изберете кои контроли ќе се прикажуваат тука."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Омилена"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Омилена, позиција <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Неомилена"</string> @@ -900,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Грешка, обидете се повторно"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Додајте контроли"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Изменете ги контролите"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Додајте апликација"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Додајте излези"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Избран е 1 уред"</string> @@ -915,8 +916,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Звучници и екрани"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени уреди"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Потребна е премиум сметка"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Како функционира емитувањето"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Емитување"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Луѓето во ваша близина со компатибилни уреди со Bluetooth може да ги слушаат аудиозаписите што ги емитувате"</string> @@ -1061,14 +1061,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Преостаната батерија: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Поврзете го пенкалото со полнач"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Слаба батерија на пенкало"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Видеокамера"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Не можете да се јавите од профилов"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Вашето работно правило ви дозволува да упатувате повици само од работниот профил"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Префрли се на работен профил"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 365e66098908..96ebfd037ad5 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"നിയന്ത്രണങ്ങൾ ചേർക്കാൻ ആപ്പ് തിരഞ്ഞെടുക്കുക"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# നിയന്ത്രണം ചേർത്തു.}other{# നിയന്ത്രണങ്ങൾ ചേർത്തു.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"നീക്കം ചെയ്തു"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"പ്രിയപ്പെട്ടതാക്കി"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"പ്രിയപ്പെട്ടതാക്കി, സ്ഥാനം <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"പ്രിയപ്പെട്ടതല്ലാതാക്കി"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"പിശക്, വീണ്ടും ശ്രമിക്കുക"</string> <string name="controls_menu_add" msgid="4447246119229920050">"നിയന്ത്രണങ്ങൾ ചേർക്കുക"</string> <string name="controls_menu_edit" msgid="890623986951347062">"നിയന്ത്രണങ്ങൾ എഡിറ്റ് ചെയ്യുക"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ഔട്ട്പുട്ടുകൾ ചേർക്കുക"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ഗ്രൂപ്പ്"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"ഒരു ഉപകരണം തിരഞ്ഞെടുത്തു"</string> @@ -1063,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"ഔദ്യോഗിക പ്രൊഫൈലിൽ നിന്ന് മാത്രം ഫോൺ കോളുകൾ ചെയ്യാനാണ് നിങ്ങളുടെ ഔദ്യോഗിക നയം അനുവദിക്കുന്നത്"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"ഔദ്യോഗിക പ്രൊഫൈലിലേക്ക് മാറുക"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"അടയ്ക്കുക"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index a6194c928b3a..5a552ad1aaa8 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Автомат"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Дуу эсвэл чичиргээ байхгүй"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Дуу эсвэл чичиргээ байхгүй бөгөөд харилцан ярианы хэсгийн доод талд харагдана"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Төхөөрөмжийн тохиргоонд тулгуурлан хонх дуугаргах эсвэл чичиргэж болзошгүй"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Төхөөрөмжийн тохиргоонд тулгуурлан хонх дуугаргах эсвэл чичиргэж болзошгүй. <xliff:g id="APP_NAME">%1$s</xliff:g>-н харилцан яриаг өгөгдмөлөөр бөмбөлөг болгоно."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Энэ мэдэгдэл дуу гаргах эсвэл чичрэх эсэхийг системээр тодорхойлуулаарай"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Төлөв:</b> Өгөгдмөл болгож дэвшүүлсэн"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Төлөв:</b> Чимээгүй болгож зэрэглэлийг нь бууруулсан"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Хяналтууд нэмэхийн тулд аппыг сонгоно уу"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# хяналт нэмсэн.}other{# хяналт нэмсэн.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Хассан"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Дуртай гэж тэмдэглэсэн"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>-р байршилд дуртай гэж тэмдэглэсэн"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Дургүй гэж тэмдэглэсэн"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Алдаа гарав, дахин оролдоно уу"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Хяналт нэмэх"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Хяналтыг өөрчлөх"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Гаралт нэмэх"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Бүлэг"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 төхөөрөмж сонгосон"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Чанга яригч ба дэлгэц"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Санал болгосон төхөөрөмжүүд"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Тусгай бүртгэл шаарддаг"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Нэвтрүүлэлт хэрхэн ажилладаг вэ?"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Нэвтрүүлэлт"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Тохиромжтой Bluetooth төхөөрөмжүүдтэй таны ойролцоох хүмүүс таны нэвтрүүлж буй медиаг сонсох боломжтой"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> батарей үлдлээ"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Мэдрэгч үзгээ цэнэглэгчтэй холбоорой"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Мэдрэгч үзэгний батарей бага байна"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Видео камер"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Энэ профайлаас залгах боломжгүй"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Таны ажлын бодлого танд зөвхөн ажлын профайлаас утасны дуудлага хийхийг зөвшөөрдөг"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Ажлын профайл руу сэлгэх"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Хаах"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index bbcd7204dc44..a9e57f7d04d3 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"ऑटोमॅटिक"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"आवाज किंवा व्हायब्रेशन नाही"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"आवाज किंवा व्हायब्रेशन नाही आणि संभाषण विभागात सर्वात तळाशी दिसते"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"डिव्हाइस सेटिंग्जनुसार रिंग किंवा व्हायब्रेट होऊ शकतो"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"डिव्हाइस सेटिंग्जनुसार रिंग किंवा व्हायब्रेट होऊ शकतो. <xliff:g id="APP_NAME">%1$s</xliff:g> मधील संभाषणे बाय डीफॉल्ट बबल होतात."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ही सूचना मिळाल्यावर आवाज व्हावा की व्हायब्रेशन व्हावे ते सिस्टममध्ये नमूद करा"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>स्थिती</b> ही डीफॉल्ट म्हणून प्रमोट केली गेली"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>स्थिती</b> ला सायलंट म्हणून डीमोट केले गेले"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"मध्यम"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"लहान"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"मोठा"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"पूर्ण झाले"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"संपादित करा"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"मॅग्निफायर विंडो सेटिंग्ज"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"अॅक्सेसिबिलिटी वैशिष्ट्ये उघडण्यासाठी, टॅप करा. सेटिंग्जमध्ये हे बटण कस्टमाइझ करा किंवा बदला.\n\n"<annotation id="link">"सेटिंग्ज पहा"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"नियंत्रणे जोडण्यासाठी ॲप निवडा"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# नियंत्रण जोडले आहे.}other{# नियंत्रणे जोडली आहेत.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"काढून टाकले"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"आवडले"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"आवडले, स्थान <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"नावडले"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"एरर, पुन्हा प्रयत्न करा"</string> <string name="controls_menu_add" msgid="4447246119229920050">"नियंत्रणे जोडा"</string> <string name="controls_menu_edit" msgid="890623986951347062">"नियंत्रणे संपादित करा"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"आउटपुट जोडा"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"गट"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"एक डिव्हाइस निवडले"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"स्पीकर आणि डिस्प्ले"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"सुचवलेली डिव्हाइस"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"प्रीमियम खाते आवश्यक आहे"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ब्रॉडकास्टिंग कसे काम करते"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ब्रॉडकास्ट करा"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"कंपॅटिबल ब्लूटूथ डिव्हाइस असलेले तुमच्या जवळपासचे लोक हे तुम्ही ब्रॉडकास्ट करत असलेला मीडिया ऐकू शकतात"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> बॅटरी शिल्लक आहे"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"तुमचे स्टायलस चार्जरशी कनेक्ट करा"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"स्टायलस बॅटरी कमी आहे"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"व्हिडिओ कॅमेरा"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"या प्रोफाइलवरून कॉल करू शकत नाही"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"तुमचे कामाशी संबंधित धोरण तुम्हाला फक्त कार्य प्रोफाइलवरून फोन कॉल करन्याची अनुमती देते"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइलवर स्विच करा"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"बंद करा"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 9b9e72c195a8..9ffe8237cc93 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Pilih apl untuk menambahkan kawalan"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kawalan ditambah.}other{# kawalan ditambah.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Dialih keluar"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Digemari"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Digemari, kedudukan <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Dinyahgemari"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Ralat, cuba lagi"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Tambah kawalan"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edit kawalan"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Tambah output"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Kumpulan"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 peranti dipilih"</string> @@ -1063,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Dasar kerja anda membenarkan anda membuat panggilan telefon hanya daripada profil kerja"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Tukar kepada profil kerja"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 21ebda963875..3ccac95a1cdf 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"အလိုအလျောက်"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"အသံ သို့မဟုတ် တုန်ခါမှုမရှိပါ"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"အသံ သို့မဟုတ် တုန်ခါမှုမရှိပါ၊ စကားဝိုင်းကဏ္ဍ၏ အောက်ပိုင်းတွင် မြင်ရသည်"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"စက်ပစ္စည်း ဆက်တင်များပေါ် အခြေခံပြီး အသံမြည်နိုင်သည် (သို့) တုန်ခါနိုင်သည်"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"စက်ပစ္စည်းဆက်တင်များပေါ် အခြေခံပြီး အသံမြည်နိုင်သည် (သို့) တုန်ခါနိုင်သည်။ မူရင်းသတ်မှတ်ချက်အဖြစ် <xliff:g id="APP_NAME">%1$s</xliff:g> မှ စကားဝိုင်းများကို ပူဖောင်းကွက်ဖြင့် ပြသည်။"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ဤအကြောင်းကြားချက်က အသံ သို့မဟုတ် တုန်ခါမှု ပေးရန် သင့်/မသင့်ကို စနစ်က ဆုံးဖြတ်ပါစေ"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>အခြေအနေ-</b> မူရင်းသို့ ချိန်ညှိထားသည်"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>အခြေအနေ-</b> အသံတိတ်ခြင်းသို့ ပြန်ချိန်ညှိထားသည်"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"ထိန်းချုပ်မှုများထည့်ရန် အက်ပ်ရွေးခြင်း"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}other{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ဖယ်ရှားထားသည်"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်၊ အဆင့် <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"အကြိုက်ဆုံးမှ ဖယ်ရှားထားသည်"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"မှားသွားသည်၊ ပြန်စမ်းကြည့်ပါ"</string> <string name="controls_menu_add" msgid="4447246119229920050">"ထိန်းချုပ်မှုများ ထည့်ရန်"</string> <string name="controls_menu_edit" msgid="890623986951347062">"ထိန်းချုပ်မှုများ ပြင်ရန်"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"မီဒီယာအထွက်များ ထည့်ရန်"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"အုပ်စု"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"စက်ပစ္စည်း ၁ ခုကို ရွေးချယ်ထားသည်"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"စပီကာနှင့် ဖန်သားပြင်များ"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"အကြံပြုထားသော စက်ပစ္စည်းများ"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ပရီမီယံအကောင့် လိုအပ်သည်"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ထုတ်လွှင့်မှုဆောင်ရွက်ပုံ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ထုတ်လွှင့်ခြင်း"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"အနီးရှိတွဲသုံးနိုင်သော ဘလူးတုသ်သုံးစက် အသုံးပြုသူများက သင်ထုတ်လွှင့်နေသော မီဒီယာကို နားဆင်နိုင်သည်"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"ဘက်ထရီ <xliff:g id="PERCENTAGE">%s</xliff:g> ကျန်သေးသည်"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"စတိုင်လပ်စ်ကို အားသွင်းကိရိယာနှင့် ချိတ်ဆက်ခြင်း"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"စတိုင်လပ်စ် ဘက်ထရီ အားနည်းနေသည်"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"ဗီဒီယိုကင်မရာ"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"ဤပရိုဖိုင်မှ ခေါ်ဆို၍ မရပါ"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"သင့်အလုပ်မူဝါဒသည် သင့်အား အလုပ်ပရိုဖိုင်မှသာ ဖုန်းခေါ်ဆိုခွင့် ပြုသည်"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"အလုပ်ပရိုဖိုင်သို့ ပြောင်းရန်"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"ပိတ်ရန်"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 30fa917ccbd2..44d97aa0d880 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisk"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ingen lyd eller vibrering"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ingen lyd eller vibrering, og vises lavere i samtaledelen"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Kan ringe eller vibrere basert på enhetsinnstillingene"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Kan ringe eller vibrere basert på enhetsinnstillingene. Samtaler fra <xliff:g id="APP_NAME">%1$s</xliff:g> vises som standard som bobler."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"La systemet velge om dette varselet skal lage lyd eller vibrere"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> Oppgradert til standard"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> Nedgradert til lydløst"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Velg en app for å legge til kontroller"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontroll er lagt til.}other{# kontroller er lagt til.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoritt"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favoritt, posisjon <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjernet som favoritt"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"En feil oppsto. Prøv på nytt"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Legg til kontroller"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Endre kontroller"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Legg til utenheter"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Gruppe"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 enhet er valgt"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Høyttalere og skjermer"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Foreslåtte enheter"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Krever en premium-konto"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Slik fungerer kringkasting"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Kringkasting"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Folk i nærheten med kompatible Bluetooth-enheter kan lytte til mediene du kringkaster"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteri gjenstår"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Koble pekepennen til en lader"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Det er lite batteri i pekepennen"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Kan ikke ringe fra denne profilen"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Som følge av jobbreglene dine kan du bare starte telefonanrop fra jobbprofilen."</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Bytt til jobbprofilen"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Lukk"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 4cc7c2f88bb6..b5ffc212a920 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"स्वचालित"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"बज्दैन पनि, भाइब्रेट पनि हुँदैन"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"बज्दैन पनि, भाइब्रेट पनि हुँदैन र वार्तालाप खण्डको तलतिर देखा पर्छ"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"डिभाइसको सेटिङका आधारमा घन्टी बज्न वा भाइब्रेट हुन सक्छ"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"डिभाइसको सेटिङका आधारमा घन्टी बज्न वा कम्पन हुन सक्छ। <xliff:g id="APP_NAME">%1$s</xliff:g> मार्फत गरिएका वार्तालापहरू स्वतः बबलमा देखिन्छन्।"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"सिस्टमलाई यो सूचना आउँदा ध्वनि बज्नु पर्छ वा कम्पन हुनु पर्छ भन्ने कुराको निधो गर्न दिनुहोस्"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>स्थिति:</b> सूचनालाई महत्त्वपूर्ण ठानी डिफल्ट मोडमा सेट गरिएको छ"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>स्थिति:</b> सूचनालाई कम महत्त्वपूर्ण ठानी साइलेन्ट मोडमा सेट गरिएको छ"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"कन्ट्रोल थप्नु पर्ने एप छान्नुहोस्"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कन्ट्रोल हालियो।}other{# वटा कन्ट्रोल हालियो।}}"</string> <string name="controls_removed" msgid="3731789252222856959">"हटाइएको"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"मनपराइएको"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"मन पराइएका कुराहरूको <xliff:g id="NUMBER">%d</xliff:g> औँ स्थानमा"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"मन पर्ने कुराहरूको सूचीमा नराखिएको"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"त्रुटि भयो, फेरि प्रयास गर्नु…"</string> <string name="controls_menu_add" msgid="4447246119229920050">"कन्ट्रोल थप्नुहोस्"</string> <string name="controls_menu_edit" msgid="890623986951347062">"कन्ट्रोल सम्पादन गर्नुहोस्"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"आउटपुट यन्त्रहरू थप्नुहोस्"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"समूह"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"१ यन्त्र चयन गरियो"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"स्पिकर तथा डिस्प्लेहरू"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"सिफारिस गरिएका डिभाइसहरू"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"प्रिमियम खाता चाहिन्छ"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"प्रसारण गर्ने सुविधाले कसरी काम गर्छ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"प्रसारण"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"कम्प्याटिबल ब्लुटुथ डिभाइस भएका नजिकैका मान्छेहरू तपाईंले प्रसारण गरिरहनुभएको मिडिया सुन्न सक्छन्"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ब्याट्री बाँकी छ"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"आफ्नो स्टाइलस चार्जरमा कनेक्ट गर्नुहोस्"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"स्टाइलसको ब्याट्री लो छ"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"भिडियो क्यामेरा"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"यो प्रोफाइलबाट कल गर्न सकिँदैन"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"तपाईंको कामसम्बन्धी नीतिअनुसार कार्य प्रोफाइलबाट मात्र फोन कल गर्न सकिन्छ"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइल प्रयोग गर्नुहोस्"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"बन्द गर्नुहोस्"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 8f0d864a3f43..221a9d84eb62 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -812,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Normaal"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Klein"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Groot"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Klaar"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Bewerken"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Instellingen voor vergrotingsvenster"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Tik voor toegankelijkheidsfuncties. Wijzig of vervang deze knop via Instellingen.\n\n"<annotation id="link">"Naar Instellingen"</annotation></string> @@ -833,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Kies de app waaraan je bedieningselementen wilt toevoegen"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# bedieningselement toegevoegd.}other{# bedieningselementen toegevoegd.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Verwijderd"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Gemarkeerd als favoriet"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Gemarkeerd als favoriet, positie <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Verwijderd als favoriet"</string> @@ -899,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Fout, probeer het opnieuw"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Bedieningselementen toevoegen"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Bedieningselementen bewerken"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Uitvoer toevoegen"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Groep"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Eén apparaat geselecteerd"</string> @@ -1064,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Op basis van je werkbeleid kun je alleen bellen vanuit het werkprofiel"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Overschakelen naar werkprofiel"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sluiten"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index b179bc5207a7..e3314b326a59 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"ସ୍ୱଚାଳିତ"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"କୌଣସି ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ ନାହିଁ"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"କୌଣସି ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ ନାହିଁ ଏବଂ ବାର୍ତ୍ତାଳାପ ବିଭାଗର ନିମ୍ନରେ ଦେଖାଯାଏ"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"ଡିଭାଇସ ସେଟିଂସ ଆଧାରରେ ରିଂ କିମ୍ବା ଭାଇବ୍ରେଟ ହୋଇପାରେ"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ଡିଭାଇସ ସେଟିଂସ ଆଧାରରେ ରିଂ କିମ୍ବା ଭାଇବ୍ରେଟ ହୋଇପାରେ। ଡିଫଲ୍ଟ ଭାବରେ <xliff:g id="APP_NAME">%1$s</xliff:g>ରୁ ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ ବବଲ ଭାବେ ଦେଖାଯାଏ।"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ଏହି ବିଜ୍ଞପ୍ତି ପ୍ରାପ୍ତ ହେବା ସମୟରେ ସାଉଣ୍ଡ ହେବା ଉଚିତ ନା ଭାଇବ୍ରେସନ୍ ତାହା ସିଷ୍ଟମକୁ ସ୍ଥିର କରିବାକୁ ଦିଅନ୍ତୁ"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>ସ୍ଥିତି:</b> ଡିଫଲ୍ଟକୁ ପ୍ରମୋଟ୍ କରାଯାଇଛି"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>ସ୍ଥିତି:</b> ନୀରବକୁ ଡିମୋଟ୍ କରାଯାଇଛି"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"ମଧ୍ୟମ"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"ଛୋଟ"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"ବଡ଼"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"ହୋଇଗଲା"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"ଏଡିଟ କରନ୍ତୁ"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"ମ୍ୟାଗ୍ନିଫାୟର ୱିଣ୍ଡୋର ସେଟିଂସ"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"ଆକ୍ସେସିବିଲିଟୀ ଫିଚର ଖୋଲିବାକୁ ଟାପ କରନ୍ତୁ। ସେଟିଂସରେ ଏହି ବଟନକୁ କଷ୍ଟମାଇଜ କର କିମ୍ବା ବଦଳାଅ।\n\n"<annotation id="link">"ସେଟିଂସ ଦେଖନ୍ତୁ"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଯୋଗ କରିବାକୁ ଆପ୍ ବାଛନ୍ତୁ"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}other{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}}"</string> <string name="controls_removed" msgid="3731789252222856959">"କାଢ଼ି ଦିଆଯାଇଛି"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ପସନ୍ଦ କରାଯାଇଛି"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ପସନ୍ଦ କରାଯାଇଛି, ସ୍ଥିତି <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ନାପସନ୍ଦ କରାଯାଇଛି"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"ତ୍ରୁଟି ହୋଇଛି, ପୁଣି ଚେଷ୍ଟା କର"</string> <string name="controls_menu_add" msgid="4447246119229920050">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଯୋଗ କରନ୍ତୁ"</string> <string name="controls_menu_edit" msgid="890623986951347062">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଏଡିଟ କରନ୍ତୁ"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ଆଉଟପୁଟ୍ ଯୋଗ କରନ୍ତୁ"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ଗୋଷ୍ଠୀ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1ଟି ଡିଭାଇସ୍ ଚୟନ କରାଯାଇଛି"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ସ୍ପିକର ଏବଂ ଡିସପ୍ଲେଗୁଡ଼ିକ"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ପ୍ରସ୍ତାବିତ ଡିଭାଇସଗୁଡ଼ିକ"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ପ୍ରିମିୟମ ଆକାଉଣ୍ଟ ଆବଶ୍ୟକ"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ବ୍ରଡକାଷ୍ଟିଂ କିପରି କାମ କରେ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ବ୍ରଡକାଷ୍ଟ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ଆପଣଙ୍କ ଆଖପାଖର କମ୍ପାଟିବଲ ବ୍ଲୁଟୁଥ ଡିଭାଇସ ଥିବା ଲୋକମାନେ ଆପଣ ବ୍ରଡକାଷ୍ଟ କରୁଥିବା ମିଡିଆ ଶୁଣିପାରିବେ"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ବେଟେରୀ ଚାର୍ଜ ବାକି ଅଛି"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ଏକ ଚାର୍ଜର ସହ ଆପଣଙ୍କ ଷ୍ଟାଇଲସକୁ କନେକ୍ଟ କରନ୍ତୁ"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"ଷ୍ଟାଇଲସ ବେଟେରୀର ଚାର୍ଜ କମ ଅଛି"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"ଭିଡିଓ କେମେରା"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"ଏହି ପ୍ରୋଫାଇଲରୁ କଲ କରାଯାଇପାରିବ ନାହିଁ"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"ଆପଣଙ୍କ ୱାର୍କ ନୀତି ଆପଣଙ୍କୁ କେବଳ ୱାର୍କ ପ୍ରୋଫାଇଲରୁ ଫୋନ କଲ କରିବାକୁ ଅନୁମତି ଦିଏ"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"ୱାର୍କ ପ୍ରୋଫାଇଲକୁ ସ୍ୱିଚ କରନ୍ତୁ"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"ବନ୍ଦ କରନ୍ତୁ"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index d8ffabffc85b..be4e1490c83c 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"ਸਵੈਚਲਿਤ"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"ਕੋਈ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਹੀਂ"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ਕੋਈ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਹੀਂ ਅਤੇ ਸੂਚਨਾਵਾਂ ਗੱਲਬਾਤ ਸੈਕਸ਼ਨ ਵਿੱਚ ਹੇਠਲੇ ਪਾਸੇ ਦਿਸਦੀਆਂ ਹਨ"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"ਡੀਵਾਈਸ ਸੈਟਿੰਗਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਘੰਟੀ ਵੱਜ ਸਕਦੀ ਹੈ ਜਾਂ ਥਰਥਰਾਹਟ ਹੋ ਸਕਦੀ ਹੈ"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"ਡੀਵਾਈਸ ਸੈਟਿੰਗਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਘੰਟੀ ਵੱਜ ਸਕਦੀ ਹੈ ਜਾਂ ਥਰਥਰਾਹਟ ਹੋ ਸਕਦੀ ਹੈ। ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਤੌਰ \'ਤੇ <xliff:g id="APP_NAME">%1$s</xliff:g> ਬਬਲ ਤੋਂ ਗੱਲਾਂਬਾਤਾਂ।"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ਸਿਸਟਮ ਨੂੰ ਨਿਰਧਾਰਤ ਕਰਨ ਦਿਓ ਕਿ ਇਸ ਸੂਚਨਾ ਲਈ ਕੋਈ ਧੁਨੀ ਵਜਾਉਣੀ ਚਾਹੀਦੀ ਹੈ ਜਾਂ ਥਰਥਰਾਹਟ ਕਰਨੀ ਚਾਹੀਦੀ ਹੈ"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>ਸਥਿਤੀ:</b> ਦਰਜਾ ਵਧਾ ਕੇ ਪੂਰਵ-ਨਿਰਧਾਰਤ \'ਤੇ ਸੈੱਟ ਕੀਤਾ ਗਿਆ"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>ਸਥਿਤੀ:</b> ਦਰਜਾ ਘਟਾ ਕੇ ਸ਼ਾਂਤ \'ਤੇ ਸੈੱਟ ਕੀਤਾ ਗਿਆ"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"ਦਰਮਿਆਨਾ"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"ਛੋਟਾ"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"ਵੱਡਾ"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"ਹੋ ਗਿਆ"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"ਸੰਪਾਦਨ ਕਰੋ"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"ਵੱਡਦਰਸ਼ੀ ਵਿੰਡੋ ਸੈਟਿੰਗਾਂ"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ। ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਇਹ ਬਟਨ ਵਿਉਂਤਬੱਧ ਕਰੋ ਜਾਂ ਬਦਲੋ।\n\n"<annotation id="link">"ਸੈਟਿੰਗਾਂ ਦੇਖੋ"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਐਪ ਚੁਣੋ"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।}one{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।}other{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤੇ ਗਏ।}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ਹਟਾਇਆ ਗਿਆ"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ, ਸਥਾਨ <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ਮਨਪਸੰਦ ਵਿੱਚੋਂ ਹਟਾਇਆ ਗਿਆ"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"ਗੜਬੜ, ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string> <string name="controls_menu_add" msgid="4447246119229920050">"ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="controls_menu_edit" msgid="890623986951347062">"ਕੰਟਰੋਲਾਂ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ਆਊਟਪੁੱਟ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ਗਰੁੱਪ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 ਡੀਵਾਈਸ ਨੂੰ ਚੁਣਿਆ ਗਿਆ"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ਸਪੀਕਰ ਅਤੇ ਡਿਸਪਲੇਆਂ"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ਸੁਝਾਏ ਗਏ ਡੀਵਾਈਸ"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"ਪ੍ਰੀਮੀਅਮ ਖਾਤੇ ਦੀ ਲੋੜ ਹੈ"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ਪ੍ਰਸਾਰਨ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"ਪ੍ਰਸਾਰਨ"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ਅਨੁਰੂਪ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਨਜ਼ਦੀਕੀ ਲੋਕ ਤੁਹਾਡੇ ਵੱਲੋਂ ਪ੍ਰਸਾਰਨ ਕੀਤੇ ਜਾ ਰਹੇ ਮੀਡੀਆ ਨੂੰ ਸੁਣ ਸਕਦੇ ਹਨ"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ਬੈਟਰੀ ਬਾਕੀ"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ਆਪਣੇ ਸਟਾਈਲਸ ਨੂੰ ਚਾਰਜਰ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"ਸਟਾਈਲਸ ਦੀ ਬੈਟਰੀ ਘੱਟ ਹੈ"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"ਵੀਡੀਓ ਕੈਮਰਾ"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"ਇਸ ਪ੍ਰੋਫਾਈਲ ਤੋਂ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"ਤੁਹਾਡੀ ਕਾਰਜ ਨੀਤੀ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਤੋਂ ਹੀ ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ \'ਤੇ ਜਾਓ"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"ਬੰਦ ਕਰੋ"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index f25f1a61584b..b9c3fa6ddf06 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatycznie"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez dźwięku i wibracji"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Brak dźwięku i wibracji, wyświetla się niżej w sekcji rozmów"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Może włączać dzwonek lub wibracje w zależności od ustawień urządzenia"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Może włączyć dzwonek lub wibracje w zależności od ustawień urządzenia. Rozmowy z aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> są domyślnie wyświetlane jako dymki."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Pozwól systemowi decydować, czy o powiadomieniu powinien informować dźwięk czy wibracja"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Stan:</b> zmieniony na Domyślny"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Stan:</b> zmieniono na Ciche"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Średni"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Mały"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Duży"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Gotowe"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Edytuj"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Ustawienia okna powiększania"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Kliknij, aby otworzyć ułatwienia dostępu. Dostosuj lub zmień ten przycisk w Ustawieniach.\n\n"<annotation id="link">"Wyświetl ustawienia"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Wybierz aplikację, do której chcesz dodać elementy sterujące"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodano # element sterujący.}few{Dodano # elementy sterujące.}many{Dodano # elementów sterujących.}other{Dodano # elementu sterującego.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Usunięto"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano do ulubionych"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano do ulubionych, pozycja <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Usunięto z ulubionych"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Błąd, spróbuj ponownie"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Dodaj elementy sterujące"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Edytuj elementy sterujące"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodaj urządzenia wyjściowe"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Wybrano 1 urządzenie"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Głośniki i wyświetlacze"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Proponowane urządzenia"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Wymagane konto premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jak działa transmitowanie"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmisja"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osoby w pobliżu ze zgodnymi urządzeniami Bluetooth mogą słuchać transmitowanych przez Ciebie multimediów"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Pozostało <xliff:g id="PERCENTAGE">%s</xliff:g> baterii"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Podłącz rysik do ładowarki"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Słaba bateria w rysiku"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Kamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nie można nawiązać połączenia z tego profilu"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Zasady obowiązujące w firmie zezwalają na nawiązywanie połączeń telefonicznych tylko w profilu służbowym"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Przełącz na profil służbowy"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zamknij"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index fd5328f6d238..8bb3e7d21f3e 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Som e vibração desativados"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"O som e a vibração estão desativados, e o balão aparece na parte inferior da seção de conversa"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Pode vibrar ou tocar com base nas configurações do dispositivo"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Pode vibrar ou tocar com base nas configurações do dispositivo. As conversas do app <xliff:g id="APP_NAME">%1$s</xliff:g> aparecem em balões por padrão."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Faça com que o sistema determine se a notificação resultará em som ou vibração"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> promovida a Padrão"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> rebaixada a Silenciosa"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Removido"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Removido dos favoritos"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Erro. Tente novamente"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Adicionar controles"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Editar controles"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Adicionar saídas"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo selecionado"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Alto-falantes e telas"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requer uma conta premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmitir"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas a você com dispositivos Bluetooth compatíveis podem ouvir a mídia que você está transmitindo"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateria restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecte sua stylus a um carregador"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria da stylus fraca"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Filmadora"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Não é possível fazer uma ligação por este perfil"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Sua política de trabalho só permite fazer ligações pelo perfil de trabalho"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Alternar para o perfil de trabalho"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 5efafc75a3bc..19e919466784 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Escolha uma app para adicionar controlos"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controlo adicionado.}many{# controlos adicionados.}other{# controlos adicionados.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Removido"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado aos favoritos"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionados aos favoritos, posição <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Removido dos favoritos"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Erro. Tente novamente."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Adicionar controlos"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Editar controlos"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Adicione saídas"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo selecionado"</string> @@ -1063,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"A sua Política de Trabalho só lhe permite fazer chamadas telefónicas a partir do perfil de trabalho"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Mudar para perfil de trabalho"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index fd5328f6d238..8bb3e7d21f3e 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Som e vibração desativados"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"O som e a vibração estão desativados, e o balão aparece na parte inferior da seção de conversa"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Pode vibrar ou tocar com base nas configurações do dispositivo"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Pode vibrar ou tocar com base nas configurações do dispositivo. As conversas do app <xliff:g id="APP_NAME">%1$s</xliff:g> aparecem em balões por padrão."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Faça com que o sistema determine se a notificação resultará em som ou vibração"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> promovida a Padrão"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> rebaixada a Silenciosa"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Removido"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Removido dos favoritos"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Erro. Tente novamente"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Adicionar controles"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Editar controles"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Adicionar saídas"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo selecionado"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Alto-falantes e telas"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requer uma conta premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmitir"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas a você com dispositivos Bluetooth compatíveis podem ouvir a mídia que você está transmitindo"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateria restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecte sua stylus a um carregador"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria da stylus fraca"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Filmadora"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Não é possível fazer uma ligação por este perfil"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Sua política de trabalho só permite fazer ligações pelo perfil de trabalho"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Alternar para o perfil de trabalho"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index c23098a7b840..247315336914 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automat"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Fără sunet sau vibrații"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Fără sunet sau vibrații și apare în partea de jos a secțiunii de conversație"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Poate să sune sau să vibreze, în funcție de setările dispozitivului"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Poate să sune sau să vibreze, în funcție de setările dispozitivului. Conversațiile din balonul <xliff:g id="APP_NAME">%1$s</xliff:g> în mod prestabilit."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Solicită-i sistemului să stabilească dacă această notificare e sonoră sau cu vibrații."</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Stare:</b> promovată la prestabilită"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Stare:</b> setată ca Silențioasă"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Alege aplicația pentru a adăuga comenzi"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S-a adăugat # comandă.}few{S-au adăugat # comenzi.}other{S-au adăugat # de comenzi.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Eliminată"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Marcată ca preferată"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Marcată ca preferată, poziția <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"S-a anulat marcarea ca preferată"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Eroare, încearcă din nou"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Adaugă comenzi"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Editează comenzile"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Adaugă ieșiri"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"S-a selectat un dispozitiv"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Difuzoare și afișaje"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispozitive sugerate"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Necesită un cont premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cum funcționează transmisia"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmite"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Persoanele din apropiere cu dispozitive Bluetooth compatibile pot asculta conținutul pe care îl transmiți"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> baterie rămasă"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conectează-ți creionul la un încărcător"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Nivelul bateriei creionului este scăzut"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Cameră video"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nu poți iniția apeluri din acest profil"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Politica privind activitatea îți permite să efectuezi apeluri telefonice numai din profilul de serviciu"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Comută la profilul de serviciu"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Închide"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 0f1b8951bfce..830b0c18bf67 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Чтобы добавить виджеты управления, выберите приложение"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Добавлен # элемент управления.}one{Добавлен # элемент управления.}few{Добавлено # элемента управления.}many{Добавлено # элементов управления.}other{Добавлено # элемента управления.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Удалено"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Добавлено в избранное"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Добавлено в избранное на позицию <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Не добавлено в избранное"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Ошибка. Повторите попытку."</string> <string name="controls_menu_add" msgid="4447246119229920050">"Добавить виджеты"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Изменить виджеты"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Добавление устройств вывода"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Группа"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Выбрано 1 устройство"</string> @@ -1063,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Согласно правилам вашей организации вы можете совершать телефонные звонки только из рабочего профиля."</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в рабочий профиль"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыть"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 9ad90af63a8e..bee211a52a15 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -812,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"මධ්යම"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"කුඩා"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"විශාල"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"නිමයි"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"සංස්කරණය කරන්න"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"විශාලන කවුළු සැකසීම්"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"ප්රවේශ්යතා විශේෂාංග විවෘත කිරීමට තට්ටු කරන්න. සැකසීම් තුළ මෙම බොත්තම අභිරුචිකරණය හෝ ප්රතිස්ථාපනය කරන්න.\n\n"<annotation id="link">"සැකසීම් බලන්න"</annotation></string> @@ -833,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"පාලන එක් කිරීමට යෙදුම තෝරා ගන්න"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# පාලනයක් එක් කර ඇත.}one{පාලන #ක් එක් කර ඇත.}other{පාලන #ක් එක් කර ඇත.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ඉවත් කළා"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ප්රියතම කළා"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ප්රියතම කළා, තත්ත්ව <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ප්රියතම වෙතින් ඉවත් කළා"</string> @@ -899,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"දෝෂයකි, නැවත උත්සාහ කරන්න"</string> <string name="controls_menu_add" msgid="4447246119229920050">"පාලන එක් කරන්න"</string> <string name="controls_menu_edit" msgid="890623986951347062">"පාලන සංස්කරණය කරන්න"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ප්රතිදාන එක් කරන්න"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"සමූහය"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"උපාංග 1ක් තෝරන ලදී"</string> @@ -1064,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"ඔබේ වැඩ ප්රතිපත්තිය ඔබට කාර්යාල පැතිකඩෙන් පමණක් දුරකථන ඇමතුම් ලබා ගැනීමට ඉඩ සලසයි"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"කාර්යාල පැතිකඩ වෙත මාරු වන්න"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"වසන්න"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index a646e5b34508..beb0ee0788c3 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -812,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Stredný"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Malý"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Veľký"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Hotovo"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Upraviť"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Nastavenia okna lupy"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Funkcie dostupnosti otvoríte klepnutím. Tlačidlo prispôsobte alebo nahraďte v Nastav.\n\n"<annotation id="link">"Zobraz. nast."</annotation></string> @@ -833,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Vyberte aplikáciu, ktorej ovládače si chcete pridať"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Bol pridaný # ovládací prvok.}few{Boli pridané # ovládacie prvky.}many{# controls added.}other{Bolo pridaných # ovládacích prvkov.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Odstránené"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Pridané medzi obľúbené"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Pridané medzi obľúbené, pozícia <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Odstránené z obľúbených"</string> @@ -899,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Chyba, skúste to znova"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Pridať ovládače"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Upraviť ovládače"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Pridanie výstupov"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Skupina"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 vybrané zariadenie"</string> @@ -1064,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"Pracovné pravidlá vám umožňujú telefonovať iba v pracovnom profile"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"Prepnúť na pracovný profil"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zavrieť"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 48c4a666cf48..72eddd3cb76e 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Samodejno"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Brez zvočnega opozarjanja ali vibriranja."</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Brez zvočnega opozarjanja ali vibriranja, prikaz nižje v razdelku Pogovor."</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Zvonjenje ali vibriranje je omogočeno na podlagi nastavitev naprave."</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Zvonjenje ali vibriranje je omogočeno na podlagi nastavitev naprave. Pogovori v aplikaciji <xliff:g id="APP_NAME">%1$s</xliff:g> so privzeto prikazani v oblačkih."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Naj sistem določi, ali ob prejemu tega obvestila naprava predvaja zvok ali zavibrira"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Stanje:</b> Uvrščeno med privzeta obvestila"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Stanje:</b> Uvrščeno med obvestila brez zvoka"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Izberite aplikacijo za dodajanje kontrolnikov"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrolnik je dodan.}one{# kontrolnik je dodan.}two{# kontrolnika sta dodana.}few{# kontrolniki so dodani.}other{# kontrolnikov je dodanih.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Odstranjeno"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano med priljubljene"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano med priljubljene, položaj <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Odstranjeno iz priljubljenih"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Napaka, poskusite znova"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Dodajte kontrolnike"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Uredite kontrolnike"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodajanje izhodov"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Skupina"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Izbrana je ena naprava"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvočniki in zasloni"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predlagane naprave"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Obvezen je plačljivi račun"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako deluje oddajanje"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Oddajanje"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osebe v bližini z združljivo napravo Bluetooth lahko poslušajo predstavnost, ki jo oddajate."</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostanek energije baterije: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Povežite pisalo s polnilnikom."</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Skoraj prazna baterija pisala"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Ni mogoče klicati iz tega profila"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Službeni pravilnik dovoljuje opravljanje telefonskih klicev le iz delovnega profila."</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Preklopi na delovni profil"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zapri"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 0713019dde5c..0cbd9cdeee05 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatike"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Asnjë tingull ose dridhje"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Asnjë tingull ose dridhje dhe shfaqet më poshtë në seksionin e bisedave"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Mund të bjerë zilja ose të dridhet në bazë të cilësimeve të pajisjes"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Mund të bjerë zilja ose të dridhet në bazë të cilësimeve të pajisjes. Bisedat nga flluska e <xliff:g id="APP_NAME">%1$s</xliff:g> si parazgjedhje."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Kërkoji sistemit të përcaktojë nëse ky njoftim duhet të lëshojë tingull apo dridhje"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Statusi:</b> Promovuar si parazgjedhje"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Statusi:</b> Ulur në nivel si në heshtje"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Mesatar"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"I vogël"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"I madh"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"U krye"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Modifiko"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Cilësimet e dritares së zmadhimit"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Trokit dhe hap veçoritë e qasshmërisë. Modifiko ose ndërro butonin te \"Cilësimet\".\n\n"<annotation id="link">"Shih cilësimet"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Zgjidh aplikacionin për të shtuar kontrollet"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{U shtua # kontroll.}other{U shtuan # kontrolle.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"E hequr"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"E shtuar te të preferuarat"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"E shtuar te të preferuarat, pozicioni <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"E hequr nga të preferuarat"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Gabim, provo sërish"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Shto kontrollet"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Modifiko kontrollet"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Shto daljet"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupi"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 pajisje e zgjedhur"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altoparlantët dhe ekranet"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Pajisjet e sugjeruara"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Kërkon llogari premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Si funksionon transmetimi"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Transmetimi"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personat në afërsi me ty me pajisje të përputhshme me Bluetooth mund të dëgjojnë median që ti po transmeton"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Përqindja e mbetur e baterisë: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Lidhe stilolapsin me një karikues"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria e stilolapsit në nivel të ulët"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nuk mund të telefonosh nga ky profil"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Politika jote e punës të lejon të bësh telefonata vetëm nga profili i punës"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Kalo te profili i punës"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Mbyll"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 864b86128c6f..4c685a9c9fed 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Аутоматска"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звука и вибрирања"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звука и вибрирања и приказује се у наставку одељка за конверзације"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Може да звони или вибрира у зависности од подешавања уређаја"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Може да звони или вибрира у зависности од подешавања уређаја. Конверзације из апликације <xliff:g id="APP_NAME">%1$s</xliff:g> подразумевано се приказују у облачићима."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Нека систем утврди да ли ово обавештење треба да емитује звук или да вибрира"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Статус:</b> Унапређено у Подразумевано"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Статус:</b> Деградирано у Нечујно"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Одаберите апликацију за додавање контрола"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# контрола је додата.}one{# контрола је додата.}few{# контроле су додате.}other{# контрола је додато.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Уклоњено"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено је као омиљено"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено је као омиљено, <xliff:g id="NUMBER">%d</xliff:g>. позиција"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Уклоњено је из омиљених"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Грешка. Пробајте поново"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Додај контроле"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Измени контроле"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Додајте излазе"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Изабран је 1 уређај"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Звучници и екрани"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени уређаји"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Захтева премијум налог"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Како функционише емитовање"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Емитовање"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Људи у близини са компатибилним Bluetooth уређајима могу да слушају медијски садржај који емитујете"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Преостало је још<xliff:g id="PERCENTAGE">%s</xliff:g> батерије"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Повежите писаљку са пуњачем"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Низак ниво батерије писаљке"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Видео камера"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Не можете да упућујете позиве са овог профила"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Смернице за посао вам омогућавају да телефонирате само са пословног профила"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пређи на пословни профил"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 24c939cf9528..94cd420843a4 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatiskt"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Inga ljud eller vibrationer"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Inga ljud eller vibrationer och visas längre ned bland konversationerna"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Kan ringa eller vibrera beroende på inställningarna på enheten"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Kan ringa eller vibrera beroende på inställningarna på enheten. Konversationer från <xliff:g id="APP_NAME">%1$s</xliff:g> visas i bubblor som standard."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Låt systemet avgöra om den här aviseringen ska låta eller vibrera"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> Ändrad till Standard"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> Ändrad till Tyst"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Medel"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Liten"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Stor"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Klar"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Redigera"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Inställningar för förstoringsfönster"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Tryck för att öppna tillgänglighetsfunktioner. Anpassa/ersätt knappen i Inställningar.\n\n"<annotation id="link">"Inställningar"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Välj en app om du vill lägga till snabbkontroller"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontroll har lagts till.}other{# kontroller har lagts till.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Har tagits bort"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Har lagts till som favorit"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Har lagts till som favorit, plats <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Har tagits bort från favoriter"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Fel, försök igen"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Lägg till snabbkontroller"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Redigera snabbkontroller"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Lägg till utgångar"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupp"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 enhet har valts"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Högtalare och skärmar"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Förslag på enheter"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premiumkonto krävs"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Så fungerar utsändning"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Utsändning"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personer i närheten med kompatibla Bluetooth-enheter kan lyssna på medieinnehåll som du sänder ut"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> av batteriet återstår"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Anslut e-pennan till en laddare"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"E-pennans batterinivå är låg"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Det går inte att ringa från den här profilen"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Jobbprincipen tillåter endast att du ringer telefonsamtal från jobbprofilen"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Byt till jobbprofilen"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Stäng"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 1c1d71e0e533..9fbaf9297d91 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatiki"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Hakuna sauti wala mtetemo"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Hakuna sauti wala mtetemo na huonekana upande wa chini katika sehemu ya mazungumzo"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Huenda ikalia au kutetema kulingana na mipangilio ya kifaa"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Huenda ikalia au kutetema kulingana na mipangilio ya kifaa. Mazungumzo kutoka kiputo cha <xliff:g id="APP_NAME">%1$s</xliff:g> kwa chaguomsingi."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Ruhusu mfumo ubainishe iwapo arifa hii inapaswa kutoa sauti au mtetemo"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Hali:</b> Imepandishwa Hadhi Kuwa Chaguomsingi"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> Imeshushwa Hadhi Kuwa Kimya"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Wastani"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Ndogo"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Kubwa"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Nimemaliza"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Badilisha"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Mipangilio ya dirisha la kikuzaji"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Gusa ili ufungue vipengele vya ufikivu. Weka mapendeleo au ubadilishe kitufe katika Mipangilio.\n\n"<annotation id="link">"Angalia mipangilio"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Chagua programu ili uweke vidhibiti"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Umeweka kidhibiti #.}other{Umeweka vidhibiti #.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Kimeondolewa"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Kimewekwa kwenye vipendwa"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Kimewekwa kwenye vipendwa, nafasi ya <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Kimeondolewa kwenye vipendwa"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Hitilafu, jaribu tena"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Weka vidhibiti"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Badilisha vidhibiti"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Weka vifaa vya kutoa sauti"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Kikundi"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Umechagua kifaa 1"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Spika na Skrini"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Vifaa Vilivyopendekezwa"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Inahitaji akaunti ya kulipia"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jinsi utangazaji unavyofanya kazi"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Tangaza"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Watu walio karibu nawe wenye vifaa oanifu vya Bluetooth wanaweza kusikiliza maudhui unayoyatangaza"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Chaji ya betri imesalia <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Unganisha stylus yako kwenye chaja"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Chaji ya betri ya Stylus imepungua"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Kamera ya kuchukulia video"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Huwezi kupiga simu kutoka kwenye wasifu huu"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Sera ya mahali pako pa kazi inakuruhusu upige simu kutoka kwenye wasifu wa kazini pekee"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Tumia wasifu wa kazini"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Funga"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 07f90ba5b4a2..dd9959461e3b 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"தானியங்கு"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"ஒலி / அதிர்வு இல்லை"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ஒலி / அதிர்வு இல்லாமல் உரையாடல் பிரிவின் கீழ்ப் பகுதியில் தோன்றும்"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"சாதன அமைப்புகளைப் பொறுத்து ஒலிக்கக்கூடும் அல்லது அதிர்வடையக்கூடும்"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"சாதன அமைப்புகளைப் பொறுத்து ஒலிக்கக்கூடும் அல்லது அதிர்வடையக்கூடும். இயல்பாக, <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸில் பெறப்படும் உரையாடல் அறிவிப்புகள் குமிழ்களாகத் தோன்றும்."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"இந்த அறிவிப்பு ஒலி எழுப்ப வேண்டுமா அதிர வேண்டுமா என்பதை சிஸ்டம் தீர்மானிக்கும்"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>நிலை:</b> இயல்புநிலைக்கு உயர்த்தி அமைக்கப்பட்டது"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>நிலை:</b> சைலன்ட் நிலைக்குக் குறைத்து அமைக்கப்பட்டது"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"நடுத்தரமானது"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"சிறியது"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"பெரியது"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"முடிந்தது"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"மாற்று"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"சாளரத்தைப் பெரிதாக்கும் கருவிக்கான அமைப்புகள்"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"அணுகல்தன்மை அம்சத்தை திறக்க தட்டவும். அமைப்பில் பட்டனை பிரத்தியேகமாக்கலாம்/மாற்றலாம்.\n\n"<annotation id="link">"அமைப்பில் காண்க"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"கட்டுப்பாடுகளைச் சேர்க்க வேண்டிய ஆப்ஸைத் தேர்ந்தெடுங்கள்"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# கட்டுப்பாடு சேர்க்கப்பட்டது.}other{# கட்டுப்பாடுகள் சேர்க்கப்பட்டன.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"அகற்றப்பட்டது"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"பிடித்தவற்றில் சேர்க்கப்பட்டது"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"பிடித்தவற்றில் சேர்க்கப்பட்டது, நிலை <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"பிடித்தவற்றிலிருந்து நீக்கப்பட்டது"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"பிழை, மீண்டும் முயலவும்"</string> <string name="controls_menu_add" msgid="4447246119229920050">"கட்டுப்பாடுகளைச் சேர்த்தல்"</string> <string name="controls_menu_edit" msgid="890623986951347062">"கட்டுப்பாடுகளை மாற்றுதல்"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"அவுட்புட்களைச் சேர்த்தல்"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"குழு"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 சாதனம் தேர்ந்தெடுக்கப்பட்டுள்ளது"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ஸ்பீக்கர்கள் & டிஸ்ப்ளேக்கள்"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"பரிந்துரைக்கப்படும் சாதனங்கள்"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"பிரீமியம் கணக்கு தேவை"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"பிராட்காஸ்ட் எவ்வாறு செயல்படுகிறது?"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"பிராட்காஸ்ட்"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"நீங்கள் பிராட்காஸ்ட் செய்யும் மீடியாவை அருகிலுள்ளவர்கள் இணக்கமான புளூடூத் சாதனங்கள் மூலம் கேட்கலாம்"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> பேட்டரி மீதமுள்ளது"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"உங்கள் ஸ்டைலஸைச் சார்ஜருடன் இணையுங்கள்"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"ஸ்டைலஸின் பேட்டரி குறைவாக உள்ளது"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"வீடியோ கேமரா"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"இந்தக் கணக்கிலிருந்து அழைக்க முடியாது"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"உங்கள் பணிக் கொள்கையின்படி நீங்கள் பணிக் கணக்கில் இருந்து மட்டுமே ஃபோன் அழைப்புகளைச் செய்ய முடியும்"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"பணிக் கணக்கிற்கு மாறு"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"மூடுக"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 824fd11e3687..655f2f92eba6 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"కంట్రోల్స్ను యాడ్ చేయడానికి యాప్ను ఎంచుకోండి"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# కంట్రోల్ జోడించబడింది.}other{# కంట్రోల్స్ జోడించబడ్డాయి.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"తీసివేయబడింది"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>వ స్థానంలో ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ఇష్టమైనదిగా పెట్టిన గుర్తు తీసివేయబడింది"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"ఎర్రర్, మళ్లీ ప్రయత్నించండి"</string> <string name="controls_menu_add" msgid="4447246119229920050">"కంట్రోల్స్ను జోడించండి"</string> <string name="controls_menu_edit" msgid="890623986951347062">"కంట్రోల్స్ను ఎడిట్ చేయండి"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"అవుట్పుట్లను జోడించండి"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"గ్రూప్"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 పరికరం ఎంచుకోబడింది"</string> @@ -1063,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"మీ వర్క్ పాలసీ, మిమ్మల్ని వర్క్ ప్రొఫైల్ నుండి మాత్రమే ఫోన్ కాల్స్ చేయడానికి అనుమతిస్తుంది"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"వర్క్ ప్రొఫైల్కు మారండి"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"మూసివేయండి"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index ff1bf357f69d..1d6220223822 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -832,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"เลือกแอปเพื่อเพิ่มตัวควบคุม"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{เพิ่มตัวควบคุม # ตัวแล้ว}other{เพิ่มตัวควบคุม # ตัวแล้ว}}"</string> <string name="controls_removed" msgid="3731789252222856959">"นำออกแล้ว"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"เพิ่ม <xliff:g id="APPNAME">%s</xliff:g> ไหม"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"เมื่อเพิ่ม <xliff:g id="APPNAME">%s</xliff:g> คุณจะเพิ่มการควบคุมและเนื้อหาไปยังแผงนี้ได้ ในบางแอป คุณเลือกได้ว่าต้องการให้การควบคุมใดปรากฏขึ้นที่นี่"</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"ตั้งเป็นรายการโปรดแล้ว"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ตั้งเป็นรายการโปรดแล้ว โดยอยู่ลำดับที่ <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"นำออกจากรายการโปรดแล้ว"</string> @@ -898,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"พบข้อผิดพลาด โปรดลองอีกครั้ง"</string> <string name="controls_menu_add" msgid="4447246119229920050">"เพิ่มตัวควบคุม"</string> <string name="controls_menu_edit" msgid="890623986951347062">"แก้ไขตัวควบคุม"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"เพิ่มแอป"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"เพิ่มเอาต์พุต"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"กลุ่ม"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"เลือกอุปกรณ์ไว้ 1 รายการ"</string> @@ -1063,4 +1066,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"นโยบายการทำงานอนุญาตให้คุณโทรออกได้จากโปรไฟล์งานเท่านั้น"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"สลับไปใช้โปรไฟล์งาน"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"ปิด"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index a287d2032c48..e29fc9eacca0 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Awtomatiko"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Walang tunog o pag-vibrate"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Walang tunog o pag-vibrate at lumalabas nang mas mababa sa seksyon ng pag-uusap"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Puwedeng mag-ring o mag-vibrate batay sa mga setting ng device"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Puwedeng mag-ring o mag-vibrate batay sa mga setting ng device. Mga pag-uusap mula sa <xliff:g id="APP_NAME">%1$s</xliff:g> bubble bilang default."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Ipatukoy sa system kung dapat gumawa ng tunog o pag-vibrate ang notification na ito"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Status:</b> Na-promote sa Default"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Status:</b> Na-demote sa Naka-silent"</string> @@ -834,6 +832,8 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Pumili ng app para magdagdag ng mga kontrol"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Nagdagdag ng # kontrol.}one{Nagdagdag ng # kontrol.}other{Nagdagdag ng # na kontrol.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Inalis"</string> + <string name="controls_panel_authorization_title" msgid="267429338785864842">"Idagdag ang <xliff:g id="APPNAME">%s</xliff:g>?"</string> + <string name="controls_panel_authorization" msgid="4540047176861801815">"Kapag idinagdag mo ang <xliff:g id="APPNAME">%s</xliff:g>, puwede itong magdagdag ng mga kontrol at content sa panel na ito. Sa ilang app, puwede mong piliin kung aling mga kontrol ang lalabas dito."</string> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ginawang paborito"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ginawang paborito, posisyon <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Inalis sa paborito"</string> @@ -900,6 +900,7 @@ <string name="controls_error_failed" msgid="960228639198558525">"Nagka-error, subukan ulit"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Magdagdag ng mga kontrol"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Mag-edit ng mga kontrol"</string> + <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Magdagdag ng app"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Magdagdag ng mga output"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 device ang napili"</string> @@ -915,8 +916,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Mga Speaker at Display"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Mga Iminumungkahing Device"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nangangailangan ng premium account"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Paano gumagana ang pag-broadcast"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Makakapakinig ang mga taong malapit sa iyo na may mga compatible na Bluetooth device sa media na bino-broadcast mo"</string> @@ -1061,14 +1061,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> baterya na lang ang natitira"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ikonekta sa charger ang iyong stylus"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Paubos na ang baterya ng stylus"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Video camera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Hindi puwedeng tumawag mula sa profile na ito"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Pinapayagan ka ng iyong patakaran sa trabaho na tumawag lang mula sa profile sa trabaho"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Lumipat sa profile sa trabaho"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Isara"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index de21f2c7c691..d421610d9a4c 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatik"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sessiz veya titreşim yok"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ses veya titreşim yok, görüşme bölümünün altında görünür"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Cihaz ayarlarına bağlı olarak zili çalabilir veya titreyebilir"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Cihaz ayarlarına bağlı olarak zili çalabilir veya titreyebilir <xliff:g id="APP_NAME">%1$s</xliff:g> adlı uygulamadan görüşmeler varsayılan olarak baloncukla gösterilir."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Bu bildirimin ses çıkarması veya titreşmesi gerekip gerekmediğine sistem karar versin"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Durum:</b> Varsayılana yükseltildi"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Durum:</b> Sessize Düşürüldü"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Orta"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Küçük"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Büyük"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Bitti"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Düzenle"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Büyüteç penceresi ayarları"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Erişilebilirlik özelliklerini açmak için dokunun. Bu düğmeyi Ayarlar\'dan özelleştirin veya değiştirin.\n\n"<annotation id="link">"Ayarları göster"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Denetim eklemek için uygulama seçin"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrol eklendi.}other{# kontrol eklendi.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Kaldırıldı"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoriler listesine eklendi"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorilere eklendi, konum: <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Favorilerden kaldırıldı"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Hata, yeniden deneyin"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Denetim ekle"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Denetimleri düzenle"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Çıkışlar ekleyin"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 cihaz seçildi"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Hoparlörler ve Ekranlar"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Önerilen Cihazlar"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium hesap gerekiyor"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayınlamanın işleyiş şekli"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Anons"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Yakınınızda ve uyumlu Bluetooth cihazları olan kişiler yayınladığınız medya içeriğini dinleyebilir"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> pil kaldı"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ekran kaleminizi bir şarj cihazına bağlayın"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Ekran kaleminin pil seviyesi düşük"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Video kamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Bu profilden telefon araması yapılamıyor"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"İşletme politikanız yalnızca iş profilinden telefon araması yapmanıza izin veriyor"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"İş profiline geç"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Kapat"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 61fc89ca65cf..43c212d0b05d 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматично"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звуку чи вібрації"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звуку чи вібрації, з\'являється нижче в розділі розмов"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Дзвінок або вібрація залежно від налаштувань пристрою"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Може дзвонити або вібрувати залежно від налаштувань пристрою. Показує спливаючі розмови з додатка <xliff:g id="APP_NAME">%1$s</xliff:g> за умовчанням."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Дозволити системі визначати, чи має сповіщення супроводжуватися звуком або вібрацією"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Статус</b>: підвищено до \"За умовчанням\""</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Статус</b>: знижено до \"Без звуку\""</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"Звичайна"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"Мала"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"Велика"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"Готово"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Змінити"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Налаштування розміру лупи"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Кнопка спеціальних можливостей. Змініть або замініть її в Налаштуваннях.\n\n"<annotation id="link">"Переглянути налаштування"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Виберіть, для якого додатка налаштувати елементи керування"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Додано # елемент керування.}one{Додано # елемент керування.}few{Додано # елементи керування.}many{Додано # елементів керування.}other{Додано # елемента керування.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Вилучено"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Додано у вибране"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Додано у вибране, позиція <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Видалено з вибраного"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Помилка. Спробуйте знову"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Додати елементи керування"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Змінити елементи керування"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Додати пристрої виводу"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Вибрано 1 пристрій"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Колонки й екрани"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Пропоновані пристрої"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Потрібен платний обліковий запис"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як працює трансляція"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляція"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Люди поблизу, які мають сумісні пристрої з Bluetooth, можуть слухати медіаконтент, який ви транслюєте."</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Заряд акумулятора: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Підключіть стилус до зарядного пристрою"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Низький заряд акумулятора стилуса"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Відеокамера"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Неможливо телефонувати з цього профілю"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Відповідно до правил організації ви можете телефонувати лише з робочого профілю"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в робочий профіль"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрити"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index bec50f1cb6ae..c9e1ee44c92a 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"کنٹرولز شامل کرنے کے لیے ایپ منتخب کریں"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# کنٹرول کو شامل کیا گیا۔}other{# کنٹرولز کو شامل کیا گیا۔}}"</string> <string name="controls_removed" msgid="3731789252222856959">"ہٹا دیا گیا"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"پسند کردہ"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"پسند کردہ، پوزیشن <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ناپسند کردہ"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"خرابی، دوبارہ کوشش کریں"</string> <string name="controls_menu_add" msgid="4447246119229920050">"کنٹرولز شامل کریں"</string> <string name="controls_menu_edit" msgid="890623986951347062">"کنٹرولز میں ترمیم کریں"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"آؤٹ پٹس شامل کریں"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"گروپ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 آلہ منتخب کیا گیا"</string> @@ -1063,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"آپ کے کام سے متعلق پالیسی آپ کو صرف دفتری پروفائل سے فون کالز کرنے کی اجازت دیتی ہے"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"دفتری پروفائل پر سوئچ کریں"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"بند کریں"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 939cb5c2a512..d31f3f8368f8 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Avtomatik"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Tovush yoki tebranishsiz"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Tovush yoki tebranishsiz hamda suhbatlar ruknining pastida chiqadi"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Qurilma sozlamalari asosida jiringlashi yoki tebranishi mumkin"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Qurilma sozlamalari asosida jiringlashi yoki tebranishi mumkin. <xliff:g id="APP_NAME">%1$s</xliff:g> suhbatlari standart holatda bulutcha shaklida chiqadi."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Bu bildirishnoma jiringlashi yoki tebranishini hal qilsin"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Holati:</b> Birlamchi darajaga chiqarildi"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Holati:</b> Sokin darajaga tushirildi"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Boshqaruv elementlarini kiritish uchun ilovani tanlang"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ta boshqaruv elementi kiritildi.}other{# ta boshqaruv elementi kiritildi.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Olib tashlandi"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Saralanganlarga kiritilgan"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Saralanganlarga kiritilgan, <xliff:g id="NUMBER">%d</xliff:g>-joy"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Saralanganlardan olib tashlangan"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Xato, qayta urining"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Element kiritish"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Elementlarni tahrirlash"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Chiquvchi qurilmani kiritish"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Guruh"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 ta qurilma tanlandi"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Karnaylar va displeylar"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Taklif qilingan qurilmalar"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium hisob talab etiladi"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Translatsiya qanday ishlaydi"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Translatsiya"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Atrofingizdagi mos Bluetooth qurilmasiga ega foydalanuvchilar siz translatsiya qilayotgan mediani tinglay olishadi"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batareya quvvati: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Stilusni quvvat manbaiga ulang"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Stilus batareyasi kam"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Bu profildan chaqiruv qilish imkonsiz"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Ishga oid siyosatingiz faqat ish profilidan telefon chaqiruvlarini amalga oshirish imkonini beradi"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Ish profiliga almashish"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Yopish"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 232681372b26..2a4989a1590d 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Tự động"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Không phát âm thanh hoặc rung"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Không phát âm thanh hoặc rung và xuất hiện phía dưới trong phần cuộc trò chuyện"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Có thể đổ chuông hoặc rung tuỳ theo chế độ cài đặt trên thiết bị"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Có thể đổ chuông hoặc rung tuỳ theo chế độ cài đặt trên thiết bị. Theo mặc định, các cuộc trò chuyện từ <xliff:g id="APP_NAME">%1$s</xliff:g> sẽ hiển thị dưới dạng bong bóng."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Cho phép hệ thống quyết định xem thông báo này phát âm thanh hay rung"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Trạng thái:</b> Đã thay đổi thành Mặc định"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Trạng thái:</b> Đã thay đổi thành Im lặng"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Chọn ứng dụng để thêm các tùy chọn điều khiển"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Đã thêm # chế độ điều khiển.}other{Đã thêm # chế độ điều khiển.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Đã xóa"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Được yêu thích"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Được yêu thích, vị trí số <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Không được yêu thích"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Lỗi, hãy thử lại"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Thêm các tùy chọn điều khiển"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Chỉnh sửa tùy chọn điều khiển"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Thêm thiết bị đầu ra"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Nhóm"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Đã chọn 1 thiết bị"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Loa và màn hình"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Thiết bị được đề xuất"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Yêu cầu tài khoản trả phí"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cách tính năng truyền hoạt động"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Truyền"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Những người ở gần có thiết bị Bluetooth tương thích có thể nghe nội dung nghe nhìn bạn đang truyền"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Còn <xliff:g id="PERCENTAGE">%s</xliff:g> pin"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Hãy kết nối bút cảm ứng với bộ sạc"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Bút cảm ứng bị yếu pin"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Máy quay video"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Không thể gọi điện từ hồ sơ này"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Chính sách của nơi làm việc chỉ cho phép bạn gọi điện thoại từ hồ sơ công việc"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Chuyển sang hồ sơ công việc"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Đóng"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index bfc6cc560dcb..431146b43dc1 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"自动"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"不发出提示音,也不振动"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"不发出提示音,也不振动;显示在对话部分的靠下位置"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"可能会响铃或振动,取决于设备设置"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"可能会响铃或振动,取决于设备设置。默认情况下,来自<xliff:g id="APP_NAME">%1$s</xliff:g>的对话会以对话泡的形式显示。"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"让系统决定是否应让设备在收到此通知时发出提示音或振动"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>状态</b>:已提升为“默认”"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>状态</b>:已降低为“静音”"</string> @@ -814,8 +812,7 @@ <string name="accessibility_magnification_medium" msgid="6994632616884562625">"中"</string> <string name="accessibility_magnification_small" msgid="8144502090651099970">"小"</string> <string name="accessibility_magnification_large" msgid="6602944330021308774">"大"</string> - <!-- no translation found for accessibility_magnification_done (263349129937348512) --> - <skip /> + <string name="accessibility_magnification_done" msgid="263349129937348512">"完成"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"修改"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"放大镜窗口设置"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"点按即可打开无障碍功能。您可在“设置”中自定义或更换此按钮。\n\n"<annotation id="link">"查看设置"</annotation></string> @@ -835,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"选择要添加控制器的应用"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已添加 # 个控件。}other{已添加 # 个控件。}}"</string> <string name="controls_removed" msgid="3731789252222856959">"已移除"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"已收藏"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已收藏,位置:<xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"已取消收藏"</string> @@ -901,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"出现错误,请重试"</string> <string name="controls_menu_add" msgid="4447246119229920050">"添加控制器"</string> <string name="controls_menu_edit" msgid="890623986951347062">"修改控制器"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"添加输出设备"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"群组"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"已选择 1 个设备"</string> @@ -916,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"音箱和显示屏"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建议的设备"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"需要使用付费帐号"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"广播的运作方式"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"广播"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近使用兼容蓝牙设备的用户可以收听您广播的媒体内容"</string> @@ -1062,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"电池还剩 <xliff:g id="PERCENTAGE">%s</xliff:g> 的电量"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"请将触控笔连接充电器"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"触控笔电池电量低"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"摄像机"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"无法通过这份资料拨打电话"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"根据您的工作政策,您只能通过工作资料拨打电话"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"切换到工作资料"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"关闭"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 3f14f5efb80a..ac27be26ee0f 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -543,8 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"無音效或震動"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"無音效或震動,並在對話部分的較低位置顯示"</string> - <string name="notification_channel_summary_default" msgid="777294388712200605">"根據裝置的設定響鈴或震動"</string> - <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"根據裝置的設定響鈴或震動。根據預設,來自「<xliff:g id="APP_NAME">%1$s</xliff:g>」的對話會以對話框形式顯示。"</string> + <string name="notification_channel_summary_default" msgid="777294388712200605">"可能會根據裝置設定發出鈴聲或震動"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"可能會根據裝置設定發出鈴聲或震動。根據預設,來自 <xliff:g id="APP_NAME">%1$s</xliff:g> 的對話會以對話氣泡顯示。"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"由系統判斷是否要讓此通知發出音效或震動"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>狀態:</b>已提升為預設"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>狀態:</b>已降低為靜音"</string> @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"選擇要新增控制項的應用程式"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已新增 # 個控制項。}other{已新增 # 個控制項。}}"</string> <string name="controls_removed" msgid="3731789252222856959">"已移除"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"已加入收藏"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已加入至收藏位置 <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"已取消收藏"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"發生錯誤,請重試"</string> <string name="controls_menu_add" msgid="4447246119229920050">"新增控制項"</string> <string name="controls_menu_edit" msgid="890623986951347062">"編輯控制項"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"新增輸出裝置"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"群組"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"已選取 1 部裝置"</string> @@ -913,7 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"喇叭和螢幕"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建議的裝置"</string> - <string name="media_output_status_require_premium" msgid="5691200962588753380">"必須有付費帳戶"</string> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"需要付費帳戶"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播運作方式"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近有兼容藍牙裝置的人可收聽您正在廣播的媒體內容"</string> @@ -1059,8 +1065,10 @@ <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"將觸控筆連接充電器"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"觸控筆電量不足"</string> <string name="video_camera" msgid="7654002575156149298">"攝影機"</string> - <string name="call_from_work_profile_title" msgid="6991157106804289643">"無法透過這個資料夾撥打電話"</string> - <string name="call_from_work_profile_text" msgid="3458704745640229638">"貴公司政策僅允許透過工作資料夾撥打電話"</string> - <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作資料夾"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"無法透過此設定檔撥打電話"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"您的公司政策只允許透過工作設定檔撥打電話"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作設定檔"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"關閉"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index e02597fb1219..56fc01db5700 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -832,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"選擇應用程式以新增控制項"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已新增 # 個控制項。}other{已新增 # 個控制項。}}"</string> <string name="controls_removed" msgid="3731789252222856959">"已移除"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"已加入收藏"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已加入收藏,位置 <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"從收藏中移除"</string> @@ -898,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"發生錯誤,請再試一次"</string> <string name="controls_menu_add" msgid="4447246119229920050">"新增控制項"</string> <string name="controls_menu_edit" msgid="890623986951347062">"編輯控制項"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"新增輸出裝置"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"群組"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"已選取 1 部裝置"</string> @@ -1063,4 +1069,6 @@ <string name="call_from_work_profile_text" msgid="3458704745640229638">"貴公司政策僅允許透過工作資料夾撥打電話"</string> <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作資料夾"</string> <string name="call_from_work_profile_close" msgid="7927067108901068098">"關閉"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index a68b2144d29d..eda75717fc31 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -543,10 +543,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Okuzenzekelayo"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Awukho umsindo noma ukudlidliza"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Awukho umsindo noma ukudlidliza futhi ivela ngezansi esigabeni sengxoxo"</string> - <!-- no translation found for notification_channel_summary_default (777294388712200605) --> - <skip /> - <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) --> - <skip /> + <string name="notification_channel_summary_default" msgid="777294388712200605">"Ingase ikhale noma idlidlize ngokusekelwe kumasethingi edivayisi"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Ingase ikhale noma idlidlize kuya ngamasethingi wedivayisi. Izingxoxo ezivela ku-<xliff:g id="APP_NAME">%1$s</xliff:g> ziba yibhamuza ngokuzenzakalela."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Vumela isistimu inqume uma lesi saziso kufanele senze umsindo noma sidlidlize"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Isimo:</b> Siphromothelwe Kokuzenzakalelayo"</string> <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Isimo:</b> Sehliselwe Kokuthulile"</string> @@ -834,6 +832,10 @@ <string name="controls_providers_title" msgid="6879775889857085056">"Khetha uhlelo lokusebenza ukwengeza izilawuli"</string> <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ulawulo olu-# olwengeziwe.}one{ukulawulwa okungu-# okwengeziwe.}other{ukulawulwa okungu-# okwengeziwe.}}"</string> <string name="controls_removed" msgid="3731789252222856959">"Isusiwe"</string> + <!-- no translation found for controls_panel_authorization_title (267429338785864842) --> + <skip /> + <!-- no translation found for controls_panel_authorization (4540047176861801815) --> + <skip /> <string name="accessibility_control_favorite" msgid="8694362691985545985">"Kwenziwe intandokazi"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Kwenziwe intandokazi, isimo esiyi-<xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Akwenziwanga intandokazi"</string> @@ -900,6 +902,8 @@ <string name="controls_error_failed" msgid="960228639198558525">"Iphutha, zama futhi"</string> <string name="controls_menu_add" msgid="4447246119229920050">"Engeza Izilawuli"</string> <string name="controls_menu_edit" msgid="890623986951347062">"Hlela izilawuli"</string> + <!-- no translation found for controls_menu_add_another_app (8661172304650786705) --> + <skip /> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Engeza okukhiphayo"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"Iqembu"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"idivayisi ekhethiwe e-1"</string> @@ -915,8 +919,7 @@ <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string> <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Izipikha Neziboniso"</string> <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Amadivayisi Aphakanyisiwe"</string> - <!-- no translation found for media_output_status_require_premium (5691200962588753380) --> - <skip /> + <string name="media_output_status_require_premium" msgid="5691200962588753380">"Idinga i-akhawunti ye-premium"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Indlela ukusakaza okusebenza ngayo"</string> <string name="media_output_broadcast" msgid="3555580945878071543">"Sakaza"</string> <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Abantu abaseduze nawe abanamadivayisi e-Bluetooth ahambisanayo bangalalela imidiya oyisakazayo"</string> @@ -1061,14 +1064,11 @@ <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ibhethri elisele"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Xhuma i-stylus yakho kushaja"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Ibhethri le-stylus liphansi"</string> - <!-- no translation found for video_camera (7654002575156149298) --> - <skip /> - <!-- no translation found for call_from_work_profile_title (6991157106804289643) --> - <skip /> - <!-- no translation found for call_from_work_profile_text (3458704745640229638) --> - <skip /> - <!-- no translation found for call_from_work_profile_action (2937701298133010724) --> - <skip /> - <!-- no translation found for call_from_work_profile_close (7927067108901068098) --> + <string name="video_camera" msgid="7654002575156149298">"Ikhamera yevidiyo"</string> + <string name="call_from_work_profile_title" msgid="6991157106804289643">"Ayikwazi ukufonela le phrofayela"</string> + <string name="call_from_work_profile_text" msgid="3458704745640229638">"Inqubomgomo yakho yomsebenzi ikuvumela ukuthi wenze amakholi wefoni kuphela ngephrofayela yomsebenzi"</string> + <string name="call_from_work_profile_action" msgid="2937701298133010724">"Shintshela kuphrofayela yomsebenzi"</string> + <string name="call_from_work_profile_close" msgid="7927067108901068098">"Vala"</string> + <!-- no translation found for lock_screen_settings (9197175446592718435) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index d01bc4adf78d..f5db5eccc2e0 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -831,4 +831,8 @@ <string name="config_wallpaperPickerPackage" translatable="false"> com.android.wallpaper </string> + + <!-- Whether the floating rotation button should be on the left/right in the device's natural + orientation --> + <bool name="floating_rotation_button_position_left">true</bool> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index ade75cb2805f..9e001e006803 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -337,7 +337,7 @@ <!-- Used for both start and bottom margin of the preview, relative to the action container --> <dimen name="overlay_preview_container_margin">8dp</dimen> <dimen name="overlay_action_container_margin_horizontal">8dp</dimen> - <dimen name="overlay_action_container_margin_bottom">4dp</dimen> + <dimen name="overlay_action_container_margin_bottom">6dp</dimen> <dimen name="overlay_bg_protection_height">242dp</dimen> <dimen name="overlay_action_container_corner_radius">18dp</dimen> <dimen name="overlay_action_container_padding_vertical">4dp</dimen> @@ -1068,8 +1068,13 @@ <!-- Size of Smartspace media recommendations cards in the QSPanel carousel --> <dimen name="qs_media_rec_icon_top_margin">16dp</dimen> <dimen name="qs_media_rec_album_size">88dp</dimen> + <dimen name="qs_media_rec_album_width">110dp</dimen> + <dimen name="qs_media_rec_album_height_expanded">108dp</dimen> + <dimen name="qs_media_rec_album_height_collapsed">77dp</dimen> <dimen name="qs_media_rec_album_side_margin">16dp</dimen> <dimen name="qs_media_rec_album_bottom_margin">8dp</dimen> + <dimen name="qs_media_rec_album_title_bottom_margin">22dp</dimen> + <dimen name="qs_media_rec_album_subtitle_height">12dp</dimen> <!-- Media tap-to-transfer chip for sender device --> <dimen name="media_ttt_chip_outer_padding">16dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index d14207a2d104..575dc940ec4d 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2464,6 +2464,8 @@ <string name="controls_media_smartspace_rec_item_description">Play <xliff:g id="song_name" example="Daily mix">%1$s</xliff:g> by <xliff:g id="artist_name" example="Various artists">%2$s</xliff:g> from <xliff:g id="app_label" example="Spotify">%3$s</xliff:g></string> <!-- Description for Smartspace recommendation's media item which doesn't have artist info, including information for the media's title and the source app [CHAR LIMIT=NONE]--> <string name="controls_media_smartspace_rec_item_no_artist_description">Play <xliff:g id="song_name" example="Daily mix">%1$s</xliff:g> from <xliff:g id="app_label" example="Spotify">%2$s</xliff:g></string> + <!-- Header title for Smartspace recommendation card within media controls. [CHAR_LIMIT=30] --> + <string name="controls_media_smartspace_rec_header">For You</string> <!--- ****** Media tap-to-transfer ****** --> <!-- Text for a button to undo the media transfer. [CHAR LIMIT=20] --> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index f8f5e8365165..dd87e914eefe 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -678,6 +678,17 @@ <style name="MediaPlayer.Recommendation"/> + <style name="MediaPlayer.Recommendation.Header"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_marginTop">@dimen/qs_media_padding</item> + <item name="android:layout_marginStart">@dimen/qs_media_padding</item> + <item name="android:fontFamily">=@*android:string/config_headlineFontFamilyMedium</item> + <item name="android:singleLine">true</item> + <item name="android:textSize">14sp</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> + </style> + <style name="MediaPlayer.Recommendation.AlbumContainer"> <item name="android:layout_width">@dimen/qs_media_rec_album_size</item> <item name="android:layout_height">@dimen/qs_media_rec_album_size</item> @@ -686,6 +697,12 @@ <item name="android:layout_marginBottom">@dimen/qs_media_rec_album_bottom_margin</item> </style> + <style name="MediaPlayer.Recommendation.AlbumContainer.Updated"> + <item name="android:layout_width">@dimen/qs_media_rec_album_width</item> + <item name="android:background">@drawable/qs_media_light_source</item> + <item name="android:layout_marginTop">@dimen/qs_media_info_spacing</item> + </style> + <style name="MediaPlayer.Recommendation.Album"> <item name="android:backgroundTint">@color/media_player_album_bg</item> </style> diff --git a/packages/SystemUI/res/xml/media_recommendations_view_collapsed.xml b/packages/SystemUI/res/xml/media_recommendations_view_collapsed.xml new file mode 100644 index 000000000000..d3be3c7de5ad --- /dev/null +++ b/packages/SystemUI/res/xml/media_recommendations_view_collapsed.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<ConstraintSet + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + > + + <Constraint + android:id="@+id/sizing_view" + android:layout_width="match_parent" + android:layout_height="@dimen/qs_media_session_height_collapsed" + /> + + <Constraint + android:id="@+id/media_rec_title" + style="@style/MediaPlayer.Recommendation.Header" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"/> + + <Constraint + android:id="@+id/media_cover1_container" + style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated" + android:layout_height="@dimen/qs_media_rec_album_height_collapsed" + android:layout_marginEnd="@dimen/qs_media_info_spacing" + android:layout_marginStart="@dimen/qs_media_padding" + app:layout_constraintTop_toBottomOf="@+id/media_rec_title" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toStartOf="@id/media_cover2_container"/> + + + <Constraint + android:id="@+id/media_cover2_container" + style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated" + android:layout_height="@dimen/qs_media_rec_album_height_collapsed" + android:layout_marginEnd="@dimen/qs_media_info_spacing" + app:layout_constraintTop_toBottomOf="@+id/media_rec_title" + app:layout_constraintStart_toEndOf="@id/media_cover1_container" + app:layout_constraintEnd_toStartOf="@id/media_cover3_container"/> + + <Constraint + android:id="@+id/media_cover3_container" + style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated" + android:layout_height="@dimen/qs_media_rec_album_height_collapsed" + android:layout_marginEnd="@dimen/qs_media_padding" + app:layout_constraintTop_toBottomOf="@+id/media_rec_title" + app:layout_constraintStart_toEndOf="@id/media_cover2_container" + app:layout_constraintEnd_toEndOf="parent"/> + + +</ConstraintSet> diff --git a/packages/SystemUI/res/xml/media_recommendations_view_expanded.xml b/packages/SystemUI/res/xml/media_recommendations_view_expanded.xml new file mode 100644 index 000000000000..88c70552e9e8 --- /dev/null +++ b/packages/SystemUI/res/xml/media_recommendations_view_expanded.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<ConstraintSet + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + > + + <Constraint + android:id="@+id/sizing_view" + android:layout_width="match_parent" + android:layout_height="@dimen/qs_media_session_height_expanded" + /> + + <Constraint + android:id="@+id/media_rec_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/qs_media_padding" + android:layout_marginStart="@dimen/qs_media_padding" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" + android:singleLine="true" + android:textSize="14sp" + android:textColor="@color/notification_primary_text_color"/> + + <Constraint + android:id="@+id/media_cover1_container" + style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated" + android:layout_height="@dimen/qs_media_rec_album_height_expanded" + android:layout_marginEnd="@dimen/qs_media_info_spacing" + android:layout_marginStart="@dimen/qs_media_padding" + app:layout_constraintTop_toBottomOf="@+id/media_rec_title" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toStartOf="@id/media_cover2_container"/> + + + <Constraint + android:id="@+id/media_cover2_container" + style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated" + android:layout_height="@dimen/qs_media_rec_album_height_expanded" + android:layout_marginEnd="@dimen/qs_media_info_spacing" + app:layout_constraintTop_toBottomOf="@+id/media_rec_title" + app:layout_constraintStart_toEndOf="@id/media_cover1_container" + app:layout_constraintEnd_toStartOf="@id/media_cover3_container"/> + + <Constraint + android:id="@+id/media_cover3_container" + style="@style/MediaPlayer.Recommendation.AlbumContainer.Updated" + android:layout_height="@dimen/qs_media_rec_album_height_expanded" + android:layout_marginEnd="@dimen/qs_media_padding" + app:layout_constraintTop_toBottomOf="@+id/media_rec_title" + app:layout_constraintStart_toEndOf="@id/media_cover2_container" + app:layout_constraintEnd_toEndOf="parent"/> + + +</ConstraintSet> diff --git a/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt b/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt index 196f7f05d20d..c9a25b067b94 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt @@ -47,10 +47,6 @@ interface ResourceFlag<T> : Flag<T> { val resourceId: Int } -interface DeviceConfigFlag<T> : Flag<T> { - val default: T -} - interface SysPropFlag<T> : Flag<T> { val default: T } @@ -80,8 +76,8 @@ abstract class BooleanFlag constructor( private constructor(parcel: Parcel) : this( id = parcel.readInt(), - name = parcel.readString(), - namespace = parcel.readString(), + name = parcel.readString() ?: "", + namespace = parcel.readString() ?: "", default = parcel.readBoolean(), teamfood = parcel.readBoolean(), overridden = parcel.readBoolean() @@ -137,21 +133,6 @@ data class ResourceBooleanFlag constructor( ) : ResourceFlag<Boolean> /** - * A Flag that can reads its overrides from DeviceConfig. - * - * This is generally useful for flags that come from or are used _outside_ of SystemUI. - * - * Prefer [UnreleasedFlag] and [ReleasedFlag]. - */ -data class DeviceConfigBooleanFlag constructor( - override val id: Int, - override val name: String, - override val namespace: String, - override val default: Boolean = false, - override val teamfood: Boolean = false -) : DeviceConfigFlag<Boolean> - -/** * A Flag that can reads its overrides from System Properties. * * This is generally useful for flags that come from or are used _outside_ of SystemUI. @@ -186,8 +167,8 @@ data class StringFlag constructor( private constructor(parcel: Parcel) : this( id = parcel.readInt(), - name = parcel.readString(), - namespace = parcel.readString(), + name = parcel.readString() ?: "", + namespace = parcel.readString() ?: "", default = parcel.readString() ?: "" ) @@ -226,8 +207,8 @@ data class IntFlag constructor( private constructor(parcel: Parcel) : this( id = parcel.readInt(), - name = parcel.readString(), - namespace = parcel.readString(), + name = parcel.readString() ?: "", + namespace = parcel.readString() ?: "", default = parcel.readInt() ) @@ -266,8 +247,8 @@ data class LongFlag constructor( private constructor(parcel: Parcel) : this( id = parcel.readInt(), - name = parcel.readString(), - namespace = parcel.readString(), + name = parcel.readString() ?: "", + namespace = parcel.readString() ?: "", default = parcel.readLong() ) @@ -298,8 +279,8 @@ data class FloatFlag constructor( private constructor(parcel: Parcel) : this( id = parcel.readInt(), - name = parcel.readString(), - namespace = parcel.readString(), + name = parcel.readString() ?: "", + namespace = parcel.readString() ?: "", default = parcel.readFloat() ) @@ -338,8 +319,8 @@ data class DoubleFlag constructor( private constructor(parcel: Parcel) : this( id = parcel.readInt(), - name = parcel.readString(), - namespace = parcel.readString(), + name = parcel.readString() ?: "", + namespace = parcel.readString() ?: "", default = parcel.readDouble() ) diff --git a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagListenable.kt b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagListenable.kt index 195ba46515cd..72a4fabf1f0d 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagListenable.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagListenable.kt @@ -34,7 +34,7 @@ interface FlagListenable { /** An event representing the change */ interface FlagEvent { /** the id of the flag which changed */ - val flagId: Int + val flagName: String /** if all listeners alerted invoke this method, the restart will be skipped */ fun requestNoRestart() } diff --git a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt index d85292a90d63..da1641c326de 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt @@ -39,7 +39,7 @@ class FlagManager constructor( const val ACTION_GET_FLAGS = "com.android.systemui.action.GET_FLAGS" const val FLAGS_PERMISSION = "com.android.systemui.permission.FLAGS" const val ACTION_SYSUI_STARTED = "com.android.systemui.STARTED" - const val EXTRA_ID = "id" + const val EXTRA_NAME = "name" const val EXTRA_VALUE = "value" const val EXTRA_FLAGS = "flags" private const val SETTINGS_PREFIX = "systemui/flags" @@ -56,7 +56,7 @@ class FlagManager constructor( * that the restart be suppressed */ var onSettingsChangedAction: Consumer<Boolean>? = null - var clearCacheAction: Consumer<Int>? = null + var clearCacheAction: Consumer<String>? = null private val listeners: MutableSet<PerFlagListener> = mutableSetOf() private val settingsObserver: ContentObserver = SettingsObserver() @@ -96,35 +96,42 @@ class FlagManager constructor( * Returns the stored value or null if not set. * This API is used by TheFlippinApp. */ - fun isEnabled(id: Int): Boolean? = readFlagValue(id, BooleanFlagSerializer) + fun isEnabled(name: String): Boolean? = readFlagValue(name, BooleanFlagSerializer) /** * Sets the value of a boolean flag. * This API is used by TheFlippinApp. */ - fun setFlagValue(id: Int, enabled: Boolean) { - val intent = createIntent(id) + fun setFlagValue(name: String, enabled: Boolean) { + val intent = createIntent(name) intent.putExtra(EXTRA_VALUE, enabled) context.sendBroadcast(intent) } - fun eraseFlag(id: Int) { - val intent = createIntent(id) + fun eraseFlag(name: String) { + val intent = createIntent(name) context.sendBroadcast(intent) } /** Returns the stored value or null if not set. */ + // TODO(b/265188950): Remove method this once ids are fully deprecated. fun <T> readFlagValue(id: Int, serializer: FlagSerializer<T>): T? { - val data = settings.getString(idToSettingsKey(id)) + val data = settings.getStringFromSecure(idToSettingsKey(id)) + return serializer.fromSettingsData(data) + } + + /** Returns the stored value or null if not set. */ + fun <T> readFlagValue(name: String, serializer: FlagSerializer<T>): T? { + val data = settings.getString(nameToSettingsKey(name)) return serializer.fromSettingsData(data) } override fun addListener(flag: Flag<*>, listener: FlagListenable.Listener) { synchronized(listeners) { val registerNeeded = listeners.isEmpty() - listeners.add(PerFlagListener(flag.id, listener)) + listeners.add(PerFlagListener(flag.name, listener)) if (registerNeeded) { settings.registerContentObserver(SETTINGS_PREFIX, true, settingsObserver) } @@ -143,38 +150,38 @@ class FlagManager constructor( } } - private fun createIntent(id: Int): Intent { + private fun createIntent(name: String): Intent { val intent = Intent(ACTION_SET_FLAG) intent.setPackage(RECEIVING_PACKAGE) - intent.putExtra(EXTRA_ID, id) + intent.putExtra(EXTRA_NAME, name) return intent } + // TODO(b/265188950): Remove method this once ids are fully deprecated. fun idToSettingsKey(id: Int): String { return "$SETTINGS_PREFIX/$id" } + fun nameToSettingsKey(name: String): String { + return "$SETTINGS_PREFIX/$name" + } + inner class SettingsObserver : ContentObserver(handler) { override fun onChange(selfChange: Boolean, uri: Uri?) { if (uri == null) { return } val parts = uri.pathSegments - val idStr = parts[parts.size - 1] - val id = try { - idStr.toInt() - } catch (e: NumberFormatException) { - return - } - clearCacheAction?.accept(id) - dispatchListenersAndMaybeRestart(id, onSettingsChangedAction) + val name = parts[parts.size - 1] + clearCacheAction?.accept(name) + dispatchListenersAndMaybeRestart(name, onSettingsChangedAction) } } - fun dispatchListenersAndMaybeRestart(id: Int, restartAction: Consumer<Boolean>?) { + fun dispatchListenersAndMaybeRestart(name: String, restartAction: Consumer<Boolean>?) { val filteredListeners: List<FlagListenable.Listener> = synchronized(listeners) { - listeners.mapNotNull { if (it.id == id) it.listener else null } + listeners.mapNotNull { if (it.name == name) it.listener else null } } // If there are no listeners, there's nothing to dispatch to, and nothing to suppress it. if (filteredListeners.isEmpty()) { @@ -185,7 +192,7 @@ class FlagManager constructor( val suppressRestartList: List<Boolean> = filteredListeners.map { listener -> var didRequestNoRestart = false val event = object : FlagListenable.FlagEvent { - override val flagId = id + override val flagName = name override fun requestNoRestart() { didRequestNoRestart = true } @@ -198,7 +205,7 @@ class FlagManager constructor( restartAction?.accept(suppressRestart) } - private data class PerFlagListener(val id: Int, val listener: FlagListenable.Listener) + private data class PerFlagListener(val name: String, val listener: FlagListenable.Listener) } class NoFlagResultsException : Exception( diff --git a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagSettingsHelper.kt b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagSettingsHelper.kt index 742bb0b6f954..6beb8518ab67 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagSettingsHelper.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagSettingsHelper.kt @@ -22,7 +22,10 @@ import android.provider.Settings class FlagSettingsHelper(private val contentResolver: ContentResolver) { - fun getString(key: String): String? = Settings.Secure.getString(contentResolver, key) + // TODO(b/265188950): Remove method this once ids are fully deprecated. + fun getStringFromSecure(key: String): String? = Settings.Secure.getString(contentResolver, key) + + fun getString(key: String): String? = Settings.Global.getString(contentResolver, key) fun registerContentObserver( name: String, diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java index 857cc4620ebd..5d036fbe5e52 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java @@ -35,6 +35,7 @@ import android.view.WindowManager.LayoutParams; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.FrameLayout; +import androidx.annotation.BoolRes; import androidx.core.view.OneShotPreDrawListener; import com.android.systemui.shared.rotation.FloatingRotationButtonPositionCalculator.Position; @@ -65,6 +66,8 @@ public class FloatingRotationButton implements RotationButton { private final int mTaskbarBottomMarginResource; @DimenRes private final int mButtonDiameterResource; + @BoolRes + private final int mFloatingRotationBtnPositionLeftResource; private AnimatedVectorDrawable mAnimatedDrawable; private boolean mIsShowing; @@ -84,7 +87,7 @@ public class FloatingRotationButton implements RotationButton { @LayoutRes int layout, @IdRes int keyButtonId, @DimenRes int minMargin, @DimenRes int roundedContentPadding, @DimenRes int taskbarLeftMargin, @DimenRes int taskbarBottomMargin, @DimenRes int buttonDiameter, - @DimenRes int rippleMaxWidth) { + @DimenRes int rippleMaxWidth, @BoolRes int floatingRotationBtnPositionLeftResource) { mWindowManager = context.getSystemService(WindowManager.class); mKeyButtonContainer = (ViewGroup) LayoutInflater.from(context).inflate(layout, null); mKeyButtonView = mKeyButtonContainer.findViewById(keyButtonId); @@ -100,6 +103,7 @@ public class FloatingRotationButton implements RotationButton { mTaskbarLeftMarginResource = taskbarLeftMargin; mTaskbarBottomMarginResource = taskbarBottomMargin; mButtonDiameterResource = buttonDiameter; + mFloatingRotationBtnPositionLeftResource = floatingRotationBtnPositionLeftResource; updateDimensionResources(); } @@ -116,8 +120,11 @@ public class FloatingRotationButton implements RotationButton { int taskbarMarginBottom = res.getDimensionPixelSize(mTaskbarBottomMarginResource); + boolean floatingRotationButtonPositionLeft = + res.getBoolean(mFloatingRotationBtnPositionLeftResource); + mPositionCalculator = new FloatingRotationButtonPositionCalculator(defaultMargin, - taskbarMarginLeft, taskbarMarginBottom); + taskbarMarginLeft, taskbarMarginBottom, floatingRotationButtonPositionLeft); final int diameter = res.getDimensionPixelSize(mButtonDiameterResource); mContainerSize = diameter + Math.max(defaultMargin, Math.max(taskbarMarginLeft, diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonPositionCalculator.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonPositionCalculator.kt index ec3c073dc68d..40e43a94ab17 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonPositionCalculator.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonPositionCalculator.kt @@ -10,7 +10,8 @@ import android.view.Surface class FloatingRotationButtonPositionCalculator( private val defaultMargin: Int, private val taskbarMarginLeft: Int, - private val taskbarMarginBottom: Int + private val taskbarMarginBottom: Int, + private val floatingRotationButtonPositionLeft: Boolean ) { fun calculatePosition( @@ -18,7 +19,6 @@ class FloatingRotationButtonPositionCalculator( taskbarVisible: Boolean, taskbarStashed: Boolean ): Position { - val isTaskbarSide = currentRotation == Surface.ROTATION_0 || currentRotation == Surface.ROTATION_90 val useTaskbarMargin = isTaskbarSide && taskbarVisible && !taskbarStashed @@ -55,11 +55,21 @@ class FloatingRotationButtonPositionCalculator( ) private fun resolveGravity(rotation: Int): Int = - when (rotation) { - Surface.ROTATION_0 -> Gravity.BOTTOM or Gravity.LEFT - Surface.ROTATION_90 -> Gravity.BOTTOM or Gravity.RIGHT - Surface.ROTATION_180 -> Gravity.TOP or Gravity.RIGHT - Surface.ROTATION_270 -> Gravity.TOP or Gravity.LEFT - else -> throw IllegalArgumentException("Invalid rotation $rotation") + if (floatingRotationButtonPositionLeft) { + when (rotation) { + Surface.ROTATION_0 -> Gravity.BOTTOM or Gravity.LEFT + Surface.ROTATION_90 -> Gravity.BOTTOM or Gravity.RIGHT + Surface.ROTATION_180 -> Gravity.TOP or Gravity.RIGHT + Surface.ROTATION_270 -> Gravity.TOP or Gravity.LEFT + else -> throw IllegalArgumentException("Invalid rotation $rotation") + } + } else { + when (rotation) { + Surface.ROTATION_0 -> Gravity.BOTTOM or Gravity.RIGHT + Surface.ROTATION_90 -> Gravity.TOP or Gravity.RIGHT + Surface.ROTATION_180 -> Gravity.TOP or Gravity.LEFT + Surface.ROTATION_270 -> Gravity.BOTTOM or Gravity.LEFT + else -> throw IllegalArgumentException("Invalid rotation $rotation") + } } } diff --git a/packages/SystemUI/src-debug/com/android/systemui/flags/FlagsFactory.kt b/packages/SystemUI/src-debug/com/android/systemui/flags/FlagsFactory.kt index 05372fec7211..31234cf2ab53 100644 --- a/packages/SystemUI/src-debug/com/android/systemui/flags/FlagsFactory.kt +++ b/packages/SystemUI/src-debug/com/android/systemui/flags/FlagsFactory.kt @@ -35,7 +35,7 @@ object FlagsFactory { teamfood: Boolean = false ): UnreleasedFlag { val flag = UnreleasedFlag(id = id, name = name, namespace = namespace, teamfood = teamfood) - FlagsFactory.checkForDupesAndAdd(flag) + checkForDupesAndAdd(flag) return flag } @@ -46,7 +46,7 @@ object FlagsFactory { teamfood: Boolean = false ): ReleasedFlag { val flag = ReleasedFlag(id = id, name = name, namespace = namespace, teamfood = teamfood) - FlagsFactory.checkForDupesAndAdd(flag) + checkForDupesAndAdd(flag) return flag } @@ -65,7 +65,7 @@ object FlagsFactory { resourceId = resourceId, teamfood = teamfood ) - FlagsFactory.checkForDupesAndAdd(flag) + checkForDupesAndAdd(flag) return flag } @@ -77,18 +77,13 @@ object FlagsFactory { ): SysPropBooleanFlag { val flag = SysPropBooleanFlag(id = id, name = name, namespace = "systemui", default = default) - FlagsFactory.checkForDupesAndAdd(flag) + checkForDupesAndAdd(flag) return flag } private fun checkForDupesAndAdd(flag: Flag<*>) { if (flagMap.containsKey(flag.name)) { - throw IllegalArgumentException("Name {flag.name} is already registered") - } - flagMap.forEach { - if (it.value.id == flag.id) { - throw IllegalArgumentException("Name {flag.id} is already registered") - } + throw IllegalArgumentException("Name {$flag.name} is already registered") } flagMap[flag.name] = flag } diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt index 1680b477c7cf..3a940e95bd12 100644 --- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt +++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt @@ -54,7 +54,6 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter import kotlinx.coroutines.launch -import java.io.PrintWriter import java.util.Locale import java.util.TimeZone import java.util.concurrent.Executor @@ -309,15 +308,6 @@ open class ClockEventController @Inject constructor( resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()) } - /** - * Dump information for debugging - */ - fun dump(pw: PrintWriter) { - pw.println(this) - clock?.dump(pw) - regionSampler?.dump(pw) - } - @VisibleForTesting internal fun listenForDozeAmount(scope: CoroutineScope): Job { return scope.launch { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java index 7da27b1d6898..baaef1983e9c 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java @@ -103,6 +103,7 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey @Override public void reset() { + super.reset(); // start fresh mDismissing = false; mView.resetPasswordText(false /* animate */, false /* announce */); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java index 6d9c5df8dae7..0685794dae52 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java @@ -45,6 +45,7 @@ import com.android.systemui.plugins.log.LogBuffer; import com.android.systemui.plugins.log.LogLevel; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shared.clocks.ClockRegistry; +import com.android.systemui.shared.regionsampling.RegionSampler; import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.PropertyAnimator; @@ -88,7 +89,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS private final ClockRegistry.ClockChangeListener mClockChangedListener; private ViewGroup mStatusArea; - // If set will replace keyguard_slice_view + + // If the SMARTSPACE flag is set, keyguard_slice_view is replaced by the following views. + private View mWeatherView; private View mSmartspaceView; private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController; @@ -192,10 +195,17 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS if (mSmartspaceController.isEnabled()) { View ksv = mView.findViewById(R.id.keyguard_slice_view); - int ksvIndex = mStatusArea.indexOfChild(ksv); + int viewIndex = mStatusArea.indexOfChild(ksv); ksv.setVisibility(View.GONE); - addSmartspaceView(ksvIndex); + // TODO(b/261757708): add content observer for the Settings toggle and add/remove + // weather according to the Settings. + if (mSmartspaceController.isDateWeatherDecoupled()) { + addWeatherView(viewIndex); + viewIndex += 1; + } + + addSmartspaceView(viewIndex); } mSecureSettings.registerContentObserverForUser( @@ -237,6 +247,18 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } } + private void addWeatherView(int index) { + mWeatherView = mSmartspaceController.buildAndConnectWeatherView(mView); + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + MATCH_PARENT, WRAP_CONTENT); + mStatusArea.addView(mWeatherView, index, lp); + int startPadding = getContext().getResources().getDimensionPixelSize( + R.dimen.below_clock_padding_start); + int endPadding = getContext().getResources().getDimensionPixelSize( + R.dimen.below_clock_padding_end); + mWeatherView.setPaddingRelative(startPadding, 0, endPadding, 0); + } + private void addSmartspaceView(int index) { mSmartspaceView = mSmartspaceController.buildAndConnectView(mView); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( @@ -424,6 +446,10 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS if (clock != null) { clock.dump(pw); } + final RegionSampler regionSampler = mClockEventController.getRegionSampler(); + if (regionSampler != null) { + regionSampler.dump(pw); + } } /** Gets the animations for the current clock. */ diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java index 02776a295359..ec8fa921c6fa 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java @@ -15,8 +15,6 @@ */ package com.android.keyguard; -import static android.view.Display.DEFAULT_DISPLAY; - import android.app.Presentation; import android.content.Context; import android.graphics.Color; @@ -37,9 +35,11 @@ import android.view.WindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.dagger.KeyguardStatusViewComponent; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.navigationbar.NavigationBarController; import com.android.systemui.navigationbar.NavigationBarView; +import com.android.systemui.settings.DisplayTracker; import java.util.concurrent.Executor; @@ -53,6 +53,7 @@ public class KeyguardDisplayManager { private MediaRouter mMediaRouter = null; private final DisplayManager mDisplayService; + private final DisplayTracker mDisplayTracker; private final Lazy<NavigationBarController> mNavigationBarControllerLazy; private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory; private final Context mContext; @@ -62,46 +63,43 @@ public class KeyguardDisplayManager { private final SparseArray<Presentation> mPresentations = new SparseArray<>(); - private final DisplayManager.DisplayListener mDisplayListener = - new DisplayManager.DisplayListener() { - - @Override - public void onDisplayAdded(int displayId) { - Trace.beginSection( - "KeyguardDisplayManager#onDisplayAdded(displayId=" + displayId + ")"); - final Display display = mDisplayService.getDisplay(displayId); - if (mShowing) { - updateNavigationBarVisibility(displayId, false /* navBarVisible */); - showPresentation(display); - } - Trace.endSection(); - } - - @Override - public void onDisplayChanged(int displayId) { - - } + private final DisplayTracker.Callback mDisplayCallback = + new DisplayTracker.Callback() { + @Override + public void onDisplayAdded(int displayId) { + Trace.beginSection( + "KeyguardDisplayManager#onDisplayAdded(displayId=" + displayId + ")"); + final Display display = mDisplayService.getDisplay(displayId); + if (mShowing) { + updateNavigationBarVisibility(displayId, false /* navBarVisible */); + showPresentation(display); + } + Trace.endSection(); + } - @Override - public void onDisplayRemoved(int displayId) { - Trace.beginSection( - "KeyguardDisplayManager#onDisplayRemoved(displayId=" + displayId + ")"); - hidePresentation(displayId); - Trace.endSection(); - } - }; + @Override + public void onDisplayRemoved(int displayId) { + Trace.beginSection( + "KeyguardDisplayManager#onDisplayRemoved(displayId=" + displayId + ")"); + hidePresentation(displayId); + Trace.endSection(); + } + }; @Inject public KeyguardDisplayManager(Context context, Lazy<NavigationBarController> navigationBarControllerLazy, KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory, + DisplayTracker displayTracker, + @Main Executor mainExecutor, @UiBackground Executor uiBgExecutor) { mContext = context; mNavigationBarControllerLazy = navigationBarControllerLazy; mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory; uiBgExecutor.execute(() -> mMediaRouter = mContext.getSystemService(MediaRouter.class)); mDisplayService = mContext.getSystemService(DisplayManager.class); - mDisplayService.registerDisplayListener(mDisplayListener, null /* handler */); + mDisplayTracker = displayTracker; + mDisplayTracker.addDisplayChangeCallback(mDisplayCallback, mainExecutor); } private boolean isKeyguardShowable(Display display) { @@ -109,7 +107,7 @@ public class KeyguardDisplayManager { if (DEBUG) Log.i(TAG, "Cannot show Keyguard on null display"); return false; } - if (display.getDisplayId() == DEFAULT_DISPLAY) { + if (display.getDisplayId() == mDisplayTracker.getDefaultDisplayId()) { if (DEBUG) Log.i(TAG, "Do not show KeyguardPresentation on the default display"); return false; } @@ -224,7 +222,7 @@ public class KeyguardDisplayManager { protected boolean updateDisplays(boolean showing) { boolean changed = false; if (showing) { - final Display[] displays = mDisplayService.getDisplays(); + final Display[] displays = mDisplayTracker.getAllDisplays(); for (Display display : displays) { int displayId = display.getDisplayId(); updateNavigationBarVisibility(displayId, false /* navBarVisible */); @@ -247,7 +245,7 @@ public class KeyguardDisplayManager { // term solution in R. private void updateNavigationBarVisibility(int displayId, boolean navBarVisible) { // Leave this task to {@link StatusBarKeyguardViewManager} - if (displayId == DEFAULT_DISPLAY) return; + if (displayId == mDisplayTracker.getDefaultDisplayId()) return; NavigationBarView navBarView = mNavigationBarControllerLazy.get() .getNavigationBarView(displayId); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java index d1c9a3090860..b143c5b90373 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java @@ -121,6 +121,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView> @Override public void reset() { + mMessageAreaController.setMessage("", false); } @Override diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java index 0b2b1214e599..e3de8c7e5671 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java @@ -17,7 +17,6 @@ package com.android.keyguard; import static android.app.slice.Slice.HINT_LIST_ITEM; -import static android.view.Display.DEFAULT_DISPLAY; import android.app.PendingIntent; import android.net.Uri; @@ -43,6 +42,7 @@ import com.android.systemui.Dumpable; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardSliceProvider; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.tuner.TunerService; import com.android.systemui.util.ViewController; @@ -64,6 +64,7 @@ public class KeyguardSliceViewController extends ViewController<KeyguardSliceVie private final ConfigurationController mConfigurationController; private final TunerService mTunerService; private final DumpManager mDumpManager; + private final DisplayTracker mDisplayTracker; private int mDisplayId; private LiveData<Slice> mLiveData; private Uri mKeyguardSliceUri; @@ -108,12 +109,14 @@ public class KeyguardSliceViewController extends ViewController<KeyguardSliceVie ActivityStarter activityStarter, ConfigurationController configurationController, TunerService tunerService, - DumpManager dumpManager) { + DumpManager dumpManager, + DisplayTracker displayTracker) { super(keyguardSliceView); mActivityStarter = activityStarter; mConfigurationController = configurationController; mTunerService = tunerService; mDumpManager = dumpManager; + mDisplayTracker = displayTracker; } @Override @@ -124,7 +127,7 @@ public class KeyguardSliceViewController extends ViewController<KeyguardSliceVie } mTunerService.addTunable(mTunable, Settings.Secure.KEYGUARD_SLICE_URI); // Make sure we always have the most current slice - if (mDisplayId == DEFAULT_DISPLAY && mLiveData != null) { + if (mDisplayId == mDisplayTracker.getDefaultDisplayId() && mLiveData != null) { mLiveData.observeForever(mObserver); } mConfigurationController.addCallback(mConfigurationListener); @@ -137,7 +140,7 @@ public class KeyguardSliceViewController extends ViewController<KeyguardSliceVie @Override protected void onViewDetached() { // TODO(b/117344873) Remove below work around after this issue be fixed. - if (mDisplayId == DEFAULT_DISPLAY) { + if (mDisplayId == mDisplayTracker.getDefaultDisplayId()) { mLiveData.removeObserver(mObserver); } mTunerService.removeTunable(mTunable); diff --git a/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt b/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt index 9ac45b3c77cc..227f0ace33dd 100644 --- a/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt +++ b/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt @@ -34,7 +34,7 @@ class ChooserSelector @Inject constructor( override fun start() { coroutineScope.launch { val listener = FlagListenable.Listener { event -> - if (event.flagId == Flags.CHOOSER_UNBUNDLED.id) { + if (event.flagName == Flags.CHOOSER_UNBUNDLED.name) { launch { updateUnbundledChooserEnabled() } event.requestNoRestart() } diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index e6f559b3da5f..71f98fa3613a 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -36,10 +36,10 @@ import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.hardware.display.DisplayManager; import android.hardware.graphics.common.AlphaInterpretation; import android.hardware.graphics.common.DisplayDecorationSupport; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.SystemProperties; import android.os.Trace; import android.provider.Settings.Secure; @@ -76,6 +76,7 @@ import com.android.systemui.decor.PrivacyDotDecorProviderFactory; import com.android.systemui.decor.RoundedCornerDecorProviderFactory; import com.android.systemui.decor.RoundedCornerResDelegate; import com.android.systemui.qs.SettingObserver; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.events.PrivacyDotViewController; import com.android.systemui.tuner.TunerService; @@ -120,7 +121,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { R.id.display_cutout_bottom }; - private DisplayManager mDisplayManager; + private DisplayTracker mDisplayTracker; @VisibleForTesting protected boolean mIsRegistered; private final Context mContext; @@ -128,7 +129,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { private final TunerService mTunerService; private final SecureSettings mSecureSettings; @VisibleForTesting - DisplayManager.DisplayListener mDisplayListener; + DisplayTracker.Callback mDisplayListener; private CameraAvailabilityListener mCameraListener; private final UserTracker mUserTracker; private final PrivacyDotViewController mDotViewController; @@ -302,6 +303,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { SecureSettings secureSettings, TunerService tunerService, UserTracker userTracker, + DisplayTracker displayTracker, PrivacyDotViewController dotViewController, ThreadFactory threadFactory, PrivacyDotDecorProviderFactory dotFactory, @@ -311,6 +313,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { mSecureSettings = secureSettings; mTunerService = tunerService; mUserTracker = userTracker; + mDisplayTracker = displayTracker; mDotViewController = dotViewController; mThreadFactory = threadFactory; mDotFactory = dotFactory; @@ -376,7 +379,6 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { private void startOnScreenDecorationsThread() { Trace.beginSection("ScreenDecorations#startOnScreenDecorationsThread"); mWindowManager = mContext.getSystemService(WindowManager.class); - mDisplayManager = mContext.getSystemService(DisplayManager.class); mContext.getDisplay().getDisplayInfo(mDisplayInfo); mRotation = mDisplayInfo.rotation; mDisplayMode = mDisplayInfo.getMode(); @@ -393,17 +395,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { setupDecorations(); setupCameraListener(); - mDisplayListener = new DisplayManager.DisplayListener() { - @Override - public void onDisplayAdded(int displayId) { - // do nothing - } - - @Override - public void onDisplayRemoved(int displayId) { - // do nothing - } - + mDisplayListener = new DisplayTracker.Callback() { @Override public void onDisplayChanged(int displayId) { mContext.getDisplay().getDisplayInfo(mDisplayInfo); @@ -474,8 +466,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { } } }; - - mDisplayManager.registerDisplayListener(mDisplayListener, mHandler); + mDisplayTracker.addDisplayChangeCallback(mDisplayListener, new HandlerExecutor(mHandler)); updateConfiguration(); Trace.endSection(); } diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java index 46cc894c9726..00f5ac2ffa23 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java @@ -36,7 +36,6 @@ import android.os.PowerManager; import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; -import android.view.Display; import android.view.IWindowManager; import android.view.InputDevice; import android.view.KeyCharacterMap; @@ -50,6 +49,7 @@ import com.android.internal.util.ScreenshotHelper; import com.android.systemui.CoreStartable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.recents.Recents; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.ShadeController; import com.android.systemui.statusbar.CommandQueue; @@ -180,6 +180,7 @@ public class SystemActions implements CoreStartable { private final Context mContext; private final UserTracker mUserTracker; private final Optional<Recents> mRecentsOptional; + private final DisplayTracker mDisplayTracker; private Locale mLocale; private final AccessibilityManager mA11yManager; private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy; @@ -194,11 +195,13 @@ public class SystemActions implements CoreStartable { NotificationShadeWindowController notificationShadeController, ShadeController shadeController, Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy, - Optional<Recents> recentsOptional) { + Optional<Recents> recentsOptional, + DisplayTracker displayTracker) { mContext = context; mUserTracker = userTracker; mShadeController = shadeController; mRecentsOptional = recentsOptional; + mDisplayTracker = displayTracker; mReceiver = new SystemActionsBroadcastReceiver(); mLocale = mContext.getResources().getConfiguration().getLocales().get(0); mA11yManager = (AccessibilityManager) mContext.getSystemService( @@ -523,7 +526,7 @@ public class SystemActions implements CoreStartable { private void handleAccessibilityButton() { AccessibilityManager.getInstance(mContext).notifyAccessibilityButtonClicked( - Display.DEFAULT_DISPLAY); + mDisplayTracker.getDefaultDisplayId()); } private void handleAccessibilityButtonChooser() { diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java index 348c2eeb7104..3653bc80e8ad 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java @@ -40,6 +40,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.model.SysUiState; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.util.settings.SecureSettings; @@ -64,6 +65,7 @@ public class WindowMagnification implements CoreStartable, WindowMagnifierCallba private final AccessibilityManager mAccessibilityManager; private final CommandQueue mCommandQueue; private final OverviewProxyService mOverviewProxyService; + private final DisplayTracker mDisplayTracker; private WindowMagnificationConnectionImpl mWindowMagnificationConnectionImpl; private SysUiState mSysUiState; @@ -115,7 +117,7 @@ public class WindowMagnification implements CoreStartable, WindowMagnifierCallba public WindowMagnification(Context context, @Main Handler mainHandler, CommandQueue commandQueue, ModeSwitchesController modeSwitchesController, SysUiState sysUiState, OverviewProxyService overviewProxyService, - SecureSettings secureSettings) { + SecureSettings secureSettings, DisplayTracker displayTracker) { mContext = context; mHandler = mainHandler; mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class); @@ -123,6 +125,7 @@ public class WindowMagnification implements CoreStartable, WindowMagnifierCallba mModeSwitchesController = modeSwitchesController; mSysUiState = sysUiState; mOverviewProxyService = overviewProxyService; + mDisplayTracker = displayTracker; mMagnificationControllerSupplier = new ControllerSupplier(context, mHandler, this, context.getSystemService(DisplayManager.class), sysUiState, secureSettings); @@ -144,14 +147,14 @@ public class WindowMagnification implements CoreStartable, WindowMagnifierCallba private void updateSysUiStateFlag() { //TODO(b/187510533): support multi-display once SysuiState supports it. final WindowMagnificationController controller = - mMagnificationControllerSupplier.valueAt(Display.DEFAULT_DISPLAY); + mMagnificationControllerSupplier.valueAt(mDisplayTracker.getDefaultDisplayId()); if (controller != null) { controller.updateSysUIStateFlag(); } else { // The instance is initialized when there is an IPC request. Considering // self-crash cases, we need to reset the flag in such situation. mSysUiState.setFlag(SYSUI_STATE_MAGNIFICATION_OVERLAP, false) - .commitUpdate(Display.DEFAULT_DISPLAY); + .commitUpdate(mDisplayTracker.getDefaultDisplayId()); } } diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java index 7fedf162d672..2c413a234c59 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java @@ -17,7 +17,6 @@ package com.android.systemui.accessibility.floatingmenu; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static com.android.systemui.flags.Flags.A11Y_FLOATING_MENU_FLING_SPRING_ANIMATIONS; @@ -40,6 +39,7 @@ import com.android.systemui.accessibility.AccessibilityButtonModeObserver.Access import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.util.settings.SecureSettings; import javax.inject.Inject; @@ -61,6 +61,7 @@ public class AccessibilityFloatingMenuController implements private final AccessibilityManager mAccessibilityManager; private final FeatureFlags mFeatureFlags; private final SecureSettings mSecureSettings; + private final DisplayTracker mDisplayTracker; @VisibleForTesting IAccessibilityFloatingMenu mFloatingMenu; private int mBtnMode; @@ -105,7 +106,8 @@ public class AccessibilityFloatingMenuController implements AccessibilityButtonModeObserver accessibilityButtonModeObserver, KeyguardUpdateMonitor keyguardUpdateMonitor, FeatureFlags featureFlags, - SecureSettings secureSettings) { + SecureSettings secureSettings, + DisplayTracker displayTracker) { mContext = context; mWindowManager = windowManager; mDisplayManager = displayManager; @@ -115,6 +117,7 @@ public class AccessibilityFloatingMenuController implements mKeyguardUpdateMonitor = keyguardUpdateMonitor; mFeatureFlags = featureFlags; mSecureSettings = secureSettings; + mDisplayTracker = displayTracker; mIsKeyguardVisible = false; } @@ -185,7 +188,8 @@ public class AccessibilityFloatingMenuController implements private void showFloatingMenu() { if (mFloatingMenu == null) { if (mFeatureFlags.isEnabled(A11Y_FLOATING_MENU_FLING_SPRING_ANIMATIONS)) { - final Display defaultDisplay = mDisplayManager.getDisplay(DEFAULT_DISPLAY); + final Display defaultDisplay = mDisplayManager.getDisplay( + mDisplayTracker.getDefaultDisplayId()); final Context windowContext = mContext.createWindowContext(defaultDisplay, TYPE_NAVIGATION_BAR_PANEL, /* options= */ null); mFloatingMenu = new MenuViewLayerController(windowContext, mWindowManager, diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java index ee09c620ec1d..ecfe4caa5984 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java @@ -100,14 +100,16 @@ public class AccessibilityTargetAdapter extends Adapter<ViewHolder> { @ItemType @Override public int getItemViewType(int position) { - if (position == 0) { - return ItemType.FIRST_ITEM; - } - + // This LAST_ITEM condition should be checked before others to ensure proper padding when + // adding a second target via notifyItemInserted(). if (position == (getItemCount() - 1)) { return ItemType.LAST_ITEM; } + if (position == 0) { + return ItemType.FIRST_ITEM; + } + return ItemType.REGULAR_ITEM; } diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DismissAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DismissAnimationController.java index c2bc1408274f..7f4e78445759 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DismissAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DismissAnimationController.java @@ -33,6 +33,7 @@ import com.android.wm.shell.common.magnetictarget.MagnetizedObject; * {@link MagnetizedObject.MagneticTarget}. */ class DismissAnimationController { + private static final boolean ENABLE_FLING_TO_DISMISS_MENU = false; private static final float COMPLETELY_OPAQUE = 1.0f; private static final float COMPLETELY_TRANSPARENT = 0.0f; private static final float CIRCLE_VIEW_DEFAULT_SCALE = 1.0f; @@ -101,6 +102,7 @@ class DismissAnimationController { final MagnetizedObject.MagneticTarget magneticTarget = new MagnetizedObject.MagneticTarget( dismissView.getCircle(), (int) mMinDismissSize); mMagnetizedObject.addTarget(magneticTarget); + mMagnetizedObject.setFlingToTargetEnabled(ENABLE_FLING_TO_DISMISS_MENU); } void showDismissView(boolean show) { diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java index e2a9d5456a8e..105de16ce66b 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java @@ -403,7 +403,7 @@ class MenuAnimationController { } cancelAndRemoveCallbacksAndMessages(); - mHandler.post(() -> mMenuView.setAlpha(COMPLETELY_OPAQUE)); + mMenuView.setAlpha(COMPLETELY_OPAQUE); } void fadeOutIfEnabled() { diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java index aad708ae4038..0538e7d55bfd 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java @@ -42,6 +42,7 @@ import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; +import android.view.View; import android.view.accessibility.AccessibilityManager; import androidx.annotation.NonNull; @@ -66,6 +67,9 @@ class MenuInfoRepository { private static final float DEFAULT_MENU_POSITION_X_PERCENT = 1.0f; @FloatRange(from = 0.0, to = 1.0) + private static final float DEFAULT_MENU_POSITION_X_PERCENT_RTL = 0.0f; + + @FloatRange(from = 0.0, to = 1.0) private static final float DEFAULT_MENU_POSITION_Y_PERCENT = 0.77f; private static final boolean DEFAULT_MOVE_TO_TUCKED_VALUE = false; private static final boolean DEFAULT_HAS_SEEN_DOCK_TOOLTIP_VALUE = false; @@ -226,8 +230,12 @@ class MenuInfoRepository { final String absolutePositionString = Prefs.getString(mContext, Prefs.Key.ACCESSIBILITY_FLOATING_MENU_POSITION, /* defaultValue= */ null); + final float defaultPositionXPercent = + mConfiguration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL + ? DEFAULT_MENU_POSITION_X_PERCENT_RTL + : DEFAULT_MENU_POSITION_X_PERCENT; return TextUtils.isEmpty(absolutePositionString) - ? new Position(DEFAULT_MENU_POSITION_X_PERCENT, DEFAULT_MENU_POSITION_Y_PERCENT) + ? new Position(defaultPositionXPercent, DEFAULT_MENU_POSITION_Y_PERCENT) : Position.fromString(absolutePositionString); } diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandler.java index 8a31142a0212..d01590f10253 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandler.java @@ -111,6 +111,7 @@ class MenuListViewTouchHandler implements RecyclerView.OnItemTouchListener { return true; } + mMenuAnimationController.fadeOutIfEnabled(); break; default: // Do nothing } diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuTargetsCallback.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuTargetsCallback.java new file mode 100644 index 000000000000..849b79ae18a6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuTargetsCallback.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.accessibility.floatingmenu; + +import android.text.TextUtils; + +import androidx.recyclerview.widget.DiffUtil; + +import com.android.internal.accessibility.dialog.AccessibilityTarget; + +import java.util.ArrayList; +import java.util.List; + +/** + * A {@link DiffUtil.Callback} to calculate the difference between old and new menu target List. + */ +class MenuTargetsCallback extends DiffUtil.Callback { + private final List<AccessibilityTarget> mOldTargets = new ArrayList<>(); + private final List<AccessibilityTarget> mNewTargets = new ArrayList<>(); + + MenuTargetsCallback(List<AccessibilityTarget> oldTargets, + List<AccessibilityTarget> newTargets) { + mOldTargets.addAll(oldTargets); + mNewTargets.addAll(newTargets); + } + + @Override + public int getOldListSize() { + return mOldTargets.size(); + } + + @Override + public int getNewListSize() { + return mNewTargets.size(); + } + + @Override + public boolean areItemsTheSame(int oldIndex, int newIndex) { + return mOldTargets.get(oldIndex).getId().equals(mNewTargets.get(newIndex).getId()); + } + + @Override + public boolean areContentsTheSame(int oldIndex, int newIndex) { + if (!TextUtils.equals(mOldTargets.get(oldIndex).getLabel(), + mNewTargets.get(newIndex).getLabel())) { + return false; + } + + if (!TextUtils.equals(mOldTargets.get(oldIndex).getStateDescription(), + mNewTargets.get(newIndex).getStateDescription())) { + return false; + } + + return true; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java index 28269d943ee3..47770fa28b79 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java @@ -32,6 +32,7 @@ import android.widget.FrameLayout; import androidx.annotation.NonNull; import androidx.core.view.AccessibilityDelegateCompat; import androidx.lifecycle.Observer; +import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate; @@ -222,14 +223,17 @@ class MenuView extends FrameLayout implements } private void onTargetFeaturesChanged(List<AccessibilityTarget> newTargetFeatures) { - // TODO(b/252756133): Should update specific item instead of the whole list mMenuAnimationController.fadeInNowIfEnabled(); + final List<AccessibilityTarget> targetFeatures = + Collections.unmodifiableList(mTargetFeatures.stream().toList()); mTargetFeatures.clear(); mTargetFeatures.addAll(newTargetFeatures); - mMenuViewAppearance.setTargetFeaturesSize(mTargetFeatures.size()); + mMenuViewAppearance.setTargetFeaturesSize(newTargetFeatures.size()); mTargetFeaturesView.setOverScrollMode(mMenuViewAppearance.getMenuScrollMode()); - mAdapter.notifyDataSetChanged(); + DiffUtil.calculateDiff( + new MenuTargetsCallback(targetFeatures, newTargetFeatures)).dispatchUpdatesTo( + mAdapter); onSizeChanged(); onEdgeChanged(); diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 86f0d06afc87..665a398a3c15 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -1,7 +1,5 @@ package com.android.systemui.assist; -import static android.view.Display.DEFAULT_DISPLAY; - import static com.android.systemui.DejankUtils.whitelistIpcs; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED; @@ -35,6 +33,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.model.SysUiState; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -122,6 +121,7 @@ public class AssistManager { protected final Lazy<SysUiState> mSysUiState; protected final AssistLogger mAssistLogger; private final UserTracker mUserTracker; + private final DisplayTracker mDisplayTracker; private final SecureSettings mSecureSettings; private final DeviceProvisionedController mDeviceProvisionedController; @@ -141,6 +141,7 @@ public class AssistManager { AssistLogger assistLogger, @Main Handler uiHandler, UserTracker userTracker, + DisplayTracker displayTracker, SecureSettings secureSettings) { mContext = context; mDeviceProvisionedController = controller; @@ -150,6 +151,7 @@ public class AssistManager { mPhoneStateMonitor = phoneStateMonitor; mAssistLogger = assistLogger; mUserTracker = userTracker; + mDisplayTracker = displayTracker; mSecureSettings = secureSettings; registerVoiceInteractionSessionListener(); @@ -214,7 +216,7 @@ public class AssistManager { .setFlag( SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED, hints.getBoolean(CONSTRAINED_KEY, false)) - .commitUpdate(DEFAULT_DISPLAY); + .commitUpdate(mDisplayTracker.getDefaultDisplayId()); } } }); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index e42f051bf3bb..3e5d16ac007f 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -878,7 +878,7 @@ public class AuthContainerView extends LinearLayout final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL, + WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, windowFlags, PixelFormat.TRANSLUCENT); lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt index 04a26894de71..53ab6d63c62d 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt @@ -86,7 +86,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at init { rippleShader.color = 0xffffffff.toInt() // default color - rippleShader.progress = 0f + rippleShader.rawProgress = 0f rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH ripplePaint.shader = rippleShader @@ -269,7 +269,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at duration = AuthRippleController.RIPPLE_ANIMATION_DURATION addUpdateListener { animator -> val now = animator.currentPlayTime - rippleShader.progress = animator.animatedValue as Float + rippleShader.rawProgress = animator.animatedValue as Float rippleShader.time = now.toFloat() invalidate() @@ -342,7 +342,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at override fun onDraw(canvas: Canvas?) { // To reduce overdraw, we mask the effect to a circle whose radius is big enough to cover // the active effect area. Values here should be kept in sync with the - // animation implementation in the ripple shader. + // animation implementation in the ripple shader. (Twice bigger) if (drawDwell) { val maskRadius = (1 - (1 - dwellShader.progress) * (1 - dwellShader.progress) * (1 - dwellShader.progress)) * dwellRadius * 2f @@ -351,10 +351,8 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at } if (drawRipple) { - val mask = (1 - (1 - rippleShader.progress) * (1 - rippleShader.progress) * - (1 - rippleShader.progress)) * radius * 2f canvas?.drawCircle(origin.x.toFloat(), origin.y.toFloat(), - mask, ripplePaint) + rippleShader.currentWidth, ripplePaint) } } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt index 9bccafbd650b..2d0d52e067ab 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt @@ -33,7 +33,6 @@ import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor -import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.ShadeExpansionListener @@ -83,7 +82,6 @@ constructor( ) { private val useExpandedOverlay: Boolean = featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION) - private val isModernBouncerEnabled: Boolean = featureFlags.isEnabled(Flags.MODERN_BOUNCER) private val isModernAlternateBouncerEnabled: Boolean = featureFlags.isEnabled(Flags.MODERN_ALTERNATE_BOUNCER) private var showingUdfpsBouncer = false @@ -109,12 +107,6 @@ constructor( ) } } - /** - * Hidden amount of input (pin/pattern/password) bouncer. This is used - * [KeyguardBouncerConstants.EXPANSION_VISIBLE] (0f) to - * [KeyguardBouncerConstants.EXPANSION_HIDDEN] (1f). Only used for the non-modernBouncer. - */ - private var inputBouncerHiddenAmount = KeyguardBouncerConstants.EXPANSION_HIDDEN private var inputBouncerExpansion = 0f // only used for modernBouncer private val stateListener: StatusBarStateController.StateListener = @@ -253,15 +245,13 @@ constructor( } init { - if (isModernBouncerEnabled || isModernAlternateBouncerEnabled) { - view.repeatWhenAttached { - // repeatOnLifecycle CREATED (as opposed to STARTED) because the Bouncer expansion - // can make the view not visible; and we still want to listen for events - // that may make the view visible again. - repeatOnLifecycle(Lifecycle.State.CREATED) { - if (isModernBouncerEnabled) listenForBouncerExpansion(this) - if (isModernAlternateBouncerEnabled) listenForAlternateBouncerVisibility(this) - } + view.repeatWhenAttached { + // repeatOnLifecycle CREATED (as opposed to STARTED) because the Bouncer expansion + // can make the view not visible; and we still want to listen for events + // that may make the view visible again. + repeatOnLifecycle(Lifecycle.State.CREATED) { + listenForBouncerExpansion(this) + if (isModernAlternateBouncerEnabled) listenForAlternateBouncerVisibility(this) } } } @@ -333,7 +323,6 @@ constructor( override fun dump(pw: PrintWriter, args: Array<String>) { super.dump(pw, args) - pw.println("isModernBouncerEnabled=$isModernBouncerEnabled") pw.println("isModernAlternateBouncerEnabled=$isModernAlternateBouncerEnabled") pw.println("showingUdfpsAltBouncer=$showingUdfpsBouncer") pw.println( @@ -353,11 +342,7 @@ constructor( pw.println("udfpsRequestedByApp=$udfpsRequested") pw.println("launchTransitionFadingAway=$launchTransitionFadingAway") pw.println("lastDozeAmount=$lastDozeAmount") - if (isModernBouncerEnabled) { - pw.println("inputBouncerExpansion=$inputBouncerExpansion") - } else { - pw.println("inputBouncerHiddenAmount=$inputBouncerHiddenAmount") - } + pw.println("inputBouncerExpansion=$inputBouncerExpansion") view.dump(pw) } @@ -384,7 +369,6 @@ constructor( } else { keyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false) } - updateBouncerHiddenAmount() updateAlpha() updatePauseAuth() return true @@ -425,19 +409,11 @@ constructor( } fun isBouncerExpansionGreaterThan(bouncerExpansionThreshold: Float): Boolean { - return if (isModernBouncerEnabled) { - inputBouncerExpansion >= bouncerExpansionThreshold - } else { - inputBouncerHiddenAmount < bouncerExpansionThreshold - } + return inputBouncerExpansion >= bouncerExpansionThreshold } fun isInputBouncerFullyVisible(): Boolean { - return if (isModernBouncerEnabled) { - inputBouncerExpansion == 1f - } else { - keyguardViewManager.isBouncerShowing && !alternateBouncerInteractor.isVisibleState() - } + return inputBouncerExpansion == 1f } override fun listenForTouchesOutsideView(): Boolean { @@ -489,11 +465,7 @@ constructor( } private fun getInputBouncerHiddenAmt(): Float { - return if (isModernBouncerEnabled) { - 1f - inputBouncerExpansion - } else { - inputBouncerHiddenAmount - } + return 1f - inputBouncerExpansion } /** Update the scale factor based on the device's resolution. */ @@ -501,19 +473,6 @@ constructor( udfpsController.mOverlayParams?.scaleFactor?.let { view.setScaleFactor(it) } } - private fun updateBouncerHiddenAmount() { - if (isModernBouncerEnabled) { - return - } - val altBouncerShowing = alternateBouncerInteractor.isVisibleState() - if (altBouncerShowing || !keyguardViewManager.primaryBouncerIsOrWillBeShowing()) { - inputBouncerHiddenAmount = 1f - } else if (keyguardViewManager.isBouncerShowing) { - // input bouncer is fully showing - inputBouncerHiddenAmount = 0f - } - } - private val legacyAlternateBouncer: LegacyAlternateBouncer = object : LegacyAlternateBouncer { override fun showAlternateBouncer(): Boolean { diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java index f97d6af632b0..8c8ee8a325a0 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java @@ -17,7 +17,6 @@ package com.android.systemui.clipboardoverlay; import static android.content.Intent.ACTION_CLOSE_SYSTEM_DIALOGS; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT; import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_SHOW_ACTIONS; @@ -72,6 +71,7 @@ import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayModule.Overl import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.screenshot.TimeoutHandler; +import com.android.systemui.settings.DisplayTracker; import java.io.IOException; import java.util.Optional; @@ -96,6 +96,7 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv private final ClipboardLogger mClipboardLogger; private final BroadcastDispatcher mBroadcastDispatcher; private final DisplayManager mDisplayManager; + private final DisplayTracker mDisplayTracker; private final ClipboardOverlayWindow mWindow; private final TimeoutHandler mTimeoutHandler; private final ClipboardOverlayUtils mClipboardUtils; @@ -186,9 +187,11 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv FeatureFlags featureFlags, ClipboardOverlayUtils clipboardUtils, @Background Executor bgExecutor, - UiEventLogger uiEventLogger) { + UiEventLogger uiEventLogger, + DisplayTracker displayTracker) { mBroadcastDispatcher = broadcastDispatcher; mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class)); + mDisplayTracker = displayTracker; final Context displayContext = context.createDisplayContext(getDefaultDisplay()); mContext = displayContext.createWindowContext(TYPE_SCREENSHOT, null); @@ -514,7 +517,7 @@ public class ClipboardOverlayController implements ClipboardListener.ClipboardOv } private Display getDefaultDisplay() { - return mDisplayManager.getDisplay(DEFAULT_DISPLAY); + return mDisplayManager.getDisplay(mDisplayTracker.getDefaultDisplayId()); } static class ClipboardLogger { diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java index 22448130f7e5..09b2e44c1be1 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java @@ -16,7 +16,6 @@ package com.android.systemui.clipboardoverlay.dagger; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -28,6 +27,7 @@ import android.view.LayoutInflater; import com.android.systemui.R; import com.android.systemui.clipboardoverlay.ClipboardOverlayView; +import com.android.systemui.settings.DisplayTracker; import java.lang.annotation.Documented; import java.lang.annotation.Retention; @@ -46,8 +46,9 @@ public interface ClipboardOverlayModule { */ @Provides @OverlayWindowContext - static Context provideWindowContext(DisplayManager displayManager, Context context) { - Display display = displayManager.getDisplay(DEFAULT_DISPLAY); + static Context provideWindowContext(DisplayManager displayManager, + DisplayTracker displayTracker, Context context) { + Display display = displayManager.getDisplay(displayTracker.getDefaultDisplayId()); return context.createWindowContext(display, TYPE_SCREENSHOT, null); } diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableConstraintLayout.kt b/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableConstraintLayout.kt new file mode 100644 index 000000000000..9763665c5b7c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableConstraintLayout.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.common.ui.view + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import com.android.systemui.animation.LaunchableView +import com.android.systemui.animation.LaunchableViewDelegate + +/** A [ConstraintLayout] that also implements [LaunchableView]. */ +open class LaunchableConstraintLayout : ConstraintLayout, LaunchableView { + private val delegate = + LaunchableViewDelegate( + this, + superSetVisibility = { super.setVisibility(it) }, + ) + + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int + ) : super(context, attrs, defStyleAttr) + + constructor( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int + ) : super(context, attrs, defStyleAttr, defStyleRes) + + override fun setShouldBlockVisibilityChanges(block: Boolean) { + delegate.setShouldBlockVisibilityChanges(block) + } + + override fun setVisibility(visibility: Int) { + delegate.setVisibility(visibility) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableLinearLayout.kt b/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableLinearLayout.kt index ddde6280f3a2..2edac528b037 100644 --- a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableLinearLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableLinearLayout.kt @@ -23,7 +23,7 @@ import com.android.systemui.animation.LaunchableView import com.android.systemui.animation.LaunchableViewDelegate /** A [LinearLayout] that also implements [LaunchableView]. */ -class LaunchableLinearLayout : LinearLayout, LaunchableView { +open class LaunchableLinearLayout : LinearLayout, LaunchableView { private val delegate = LaunchableViewDelegate( this, diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 31cc0bde4602..c3f24f086ee9 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -64,6 +64,7 @@ import com.android.systemui.qs.footer.dagger.FooterActionsModule; import com.android.systemui.recents.Recents; import com.android.systemui.screenshot.dagger.ScreenshotModule; import com.android.systemui.security.data.repository.SecurityRepositoryModule; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.shade.ShadeController; import com.android.systemui.smartspace.dagger.SmartspaceModule; import com.android.systemui.statusbar.CommandQueue; @@ -107,6 +108,8 @@ import com.android.wm.shell.bubbles.Bubbles; import java.util.Optional; import java.util.concurrent.Executor; +import javax.inject.Named; + import dagger.Binds; import dagger.BindsOptionalOf; import dagger.Module; @@ -196,8 +199,8 @@ public abstract class SystemUIModule { @SysUISingleton @Provides - static SysUiState provideSysUiState(DumpManager dumpManager) { - final SysUiState state = new SysUiState(); + static SysUiState provideSysUiState(DisplayTracker displayTracker, DumpManager dumpManager) { + final SysUiState state = new SysUiState(displayTracker); dumpManager.registerDumpable(state); return state; } @@ -215,6 +218,10 @@ public abstract class SystemUIModule { abstract BcSmartspaceConfigPlugin optionalBcSmartspaceConfigPlugin(); @BindsOptionalOf + @Named(SmartspaceModule.WEATHER_SMARTSPACE_DATA_PLUGIN) + abstract BcSmartspaceDataPlugin optionalWeatherSmartspaceConfigPlugin(); + + @BindsOptionalOf abstract Recents optionalRecents(); @BindsOptionalOf diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java index 43827573470f..e1d03392044a 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java @@ -21,10 +21,10 @@ import static com.android.systemui.dreams.touch.dagger.DreamTouchModule.PILFER_O import android.os.Looper; import android.view.Choreographer; -import android.view.Display; import android.view.GestureDetector; import android.view.MotionEvent; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.shared.system.InputChannelCompat; import com.android.systemui.shared.system.InputMonitorCompat; @@ -55,8 +55,9 @@ public class InputSession { public InputSession(@Named(INPUT_SESSION_NAME) String sessionName, InputChannelCompat.InputEventListener inputEventListener, GestureDetector.OnGestureListener gestureListener, + DisplayTracker displayTracker, @Named(PILFER_ON_GESTURE_CONSUME) boolean pilferOnGestureConsume) { - mInputMonitor = new InputMonitorCompat(sessionName, Display.DEFAULT_DISPLAY); + mInputMonitor = new InputMonitorCompat(sessionName, displayTracker.getDefaultDisplayId()); mGestureDetector = new GestureDetector(gestureListener); mInputEventReceiver = mInputMonitor.getInputReceiver(Looper.getMainLooper(), diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java index 267e0366b00e..61e4c32e3737 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java +++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java @@ -19,7 +19,7 @@ package com.android.systemui.flags; import static com.android.systemui.flags.FlagManager.ACTION_GET_FLAGS; import static com.android.systemui.flags.FlagManager.ACTION_SET_FLAG; import static com.android.systemui.flags.FlagManager.EXTRA_FLAGS; -import static com.android.systemui.flags.FlagManager.EXTRA_ID; +import static com.android.systemui.flags.FlagManager.EXTRA_NAME; import static com.android.systemui.flags.FlagManager.EXTRA_VALUE; import static com.android.systemui.flags.FlagsCommonModule.ALL_FLAGS; @@ -40,6 +40,7 @@ import androidx.annotation.Nullable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.util.settings.GlobalSettings; import com.android.systemui.util.settings.SecureSettings; import org.jetbrains.annotations.NotNull; @@ -73,14 +74,15 @@ public class FeatureFlagsDebug implements FeatureFlags { private final FlagManager mFlagManager; private final Context mContext; + private final GlobalSettings mGlobalSettings; private final SecureSettings mSecureSettings; private final Resources mResources; private final SystemPropertiesHelper mSystemProperties; private final ServerFlagReader mServerFlagReader; - private final Map<Integer, Flag<?>> mAllFlags; - private final Map<Integer, Boolean> mBooleanFlagCache = new TreeMap<>(); - private final Map<Integer, String> mStringFlagCache = new TreeMap<>(); - private final Map<Integer, Integer> mIntFlagCache = new TreeMap<>(); + private final Map<String, Flag<?>> mAllFlags; + private final Map<String, Boolean> mBooleanFlagCache = new TreeMap<>(); + private final Map<String, String> mStringFlagCache = new TreeMap<>(); + private final Map<String, Integer> mIntFlagCache = new TreeMap<>(); private final Restarter mRestarter; private final ServerFlagReader.ChangeListener mOnPropertiesChanged = @@ -95,14 +97,16 @@ public class FeatureFlagsDebug implements FeatureFlags { public FeatureFlagsDebug( FlagManager flagManager, Context context, + GlobalSettings globalSettings, SecureSettings secureSettings, SystemPropertiesHelper systemProperties, @Main Resources resources, ServerFlagReader serverFlagReader, - @Named(ALL_FLAGS) Map<Integer, Flag<?>> allFlags, + @Named(ALL_FLAGS) Map<String, Flag<?>> allFlags, Restarter restarter) { mFlagManager = flagManager; mContext = context; + mGlobalSettings = globalSettings; mSecureSettings = secureSettings; mResources = resources; mSystemProperties = systemProperties; @@ -134,96 +138,103 @@ public class FeatureFlagsDebug implements FeatureFlags { } private boolean isEnabledInternal(@NotNull BooleanFlag flag) { - int id = flag.getId(); - if (!mBooleanFlagCache.containsKey(id)) { - mBooleanFlagCache.put(id, + String name = flag.getName(); + if (!mBooleanFlagCache.containsKey(name)) { + mBooleanFlagCache.put(name, readBooleanFlagInternal(flag, flag.getDefault())); } - return mBooleanFlagCache.get(id); + return mBooleanFlagCache.get(name); } @Override public boolean isEnabled(@NonNull ResourceBooleanFlag flag) { - int id = flag.getId(); - if (!mBooleanFlagCache.containsKey(id)) { - mBooleanFlagCache.put(id, + String name = flag.getName(); + if (!mBooleanFlagCache.containsKey(name)) { + mBooleanFlagCache.put(name, readBooleanFlagInternal(flag, mResources.getBoolean(flag.getResourceId()))); } - return mBooleanFlagCache.get(id); + return mBooleanFlagCache.get(name); } @Override public boolean isEnabled(@NonNull SysPropBooleanFlag flag) { - int id = flag.getId(); - if (!mBooleanFlagCache.containsKey(id)) { + String name = flag.getName(); + if (!mBooleanFlagCache.containsKey(name)) { // Use #readFlagValue to get the default. That will allow it to fall through to // teamfood if need be. mBooleanFlagCache.put( - id, + name, mSystemProperties.getBoolean( flag.getName(), readBooleanFlagInternal(flag, flag.getDefault()))); } - return mBooleanFlagCache.get(id); + return mBooleanFlagCache.get(name); } @NonNull @Override public String getString(@NonNull StringFlag flag) { - int id = flag.getId(); - if (!mStringFlagCache.containsKey(id)) { - mStringFlagCache.put(id, - readFlagValueInternal(id, flag.getDefault(), StringFlagSerializer.INSTANCE)); + String name = flag.getName(); + if (!mStringFlagCache.containsKey(name)) { + mStringFlagCache.put(name, + readFlagValueInternal( + flag.getId(), name, flag.getDefault(), StringFlagSerializer.INSTANCE)); } - return mStringFlagCache.get(id); + return mStringFlagCache.get(name); } @NonNull @Override public String getString(@NonNull ResourceStringFlag flag) { - int id = flag.getId(); - if (!mStringFlagCache.containsKey(id)) { - mStringFlagCache.put(id, - readFlagValueInternal(id, mResources.getString(flag.getResourceId()), + String name = flag.getName(); + if (!mStringFlagCache.containsKey(name)) { + mStringFlagCache.put(name, + readFlagValueInternal( + flag.getId(), name, mResources.getString(flag.getResourceId()), StringFlagSerializer.INSTANCE)); } - return mStringFlagCache.get(id); + return mStringFlagCache.get(name); } @NonNull @Override public int getInt(@NonNull IntFlag flag) { - int id = flag.getId(); - if (!mIntFlagCache.containsKey(id)) { - mIntFlagCache.put(id, - readFlagValueInternal(id, flag.getDefault(), IntFlagSerializer.INSTANCE)); + String name = flag.getName(); + if (!mIntFlagCache.containsKey(name)) { + mIntFlagCache.put(name, + readFlagValueInternal( + flag.getId(), name, flag.getDefault(), IntFlagSerializer.INSTANCE)); } - return mIntFlagCache.get(id); + return mIntFlagCache.get(name); } @NonNull @Override public int getInt(@NonNull ResourceIntFlag flag) { - int id = flag.getId(); - if (!mIntFlagCache.containsKey(id)) { - mIntFlagCache.put(id, - readFlagValueInternal(id, mResources.getInteger(flag.getResourceId()), + String name = flag.getName(); + if (!mIntFlagCache.containsKey(name)) { + mIntFlagCache.put(name, + readFlagValueInternal( + flag.getId(), name, mResources.getInteger(flag.getResourceId()), IntFlagSerializer.INSTANCE)); } - return mIntFlagCache.get(id); + return mIntFlagCache.get(name); } /** Specific override for Boolean flags that checks against the teamfood list.*/ private boolean readBooleanFlagInternal(Flag<Boolean> flag, boolean defaultValue) { - Boolean result = readBooleanFlagOverride(flag.getId()); + Boolean result = readBooleanFlagOverride(flag.getName()); + if (result == null) { + result = readBooleanFlagOverride(flag.getId()); + } boolean hasServerOverride = mServerFlagReader.hasOverride( flag.getNamespace(), flag.getName()); @@ -232,7 +243,7 @@ public class FeatureFlagsDebug implements FeatureFlags { if (!hasServerOverride && !defaultValue && result == null - && flag.getId() != Flags.TEAMFOOD.getId() + && !flag.getName().equals(Flags.TEAMFOOD.getName()) && flag.getTeamfood()) { return isEnabled(Flags.TEAMFOOD); } @@ -245,16 +256,31 @@ public class FeatureFlagsDebug implements FeatureFlags { return readFlagValueInternal(id, BooleanFlagSerializer.INSTANCE); } + private Boolean readBooleanFlagOverride(String name) { + return readFlagValueInternal(name, BooleanFlagSerializer.INSTANCE); + } + + // TODO(b/265188950): Remove id from this method once ids are fully deprecated. @NonNull private <T> T readFlagValueInternal( - int id, @NonNull T defaultValue, FlagSerializer<T> serializer) { + int id, String name, @NonNull T defaultValue, FlagSerializer<T> serializer) { requireNonNull(defaultValue, "defaultValue"); - T result = readFlagValueInternal(id, serializer); - return result == null ? defaultValue : result; + T resultForName = readFlagValueInternal(name, serializer); + if (resultForName == null) { + T resultForId = readFlagValueInternal(id, serializer); + if (resultForId == null) { + return defaultValue; + } else { + setFlagValue(name, resultForId, serializer); + return resultForId; + } + } + return resultForName; } /** Returns the stored value or null if not set. */ + // TODO(b/265188950): Remove method this once ids are fully deprecated. @Nullable private <T> T readFlagValueInternal(int id, FlagSerializer<T> serializer) { try { @@ -265,51 +291,71 @@ public class FeatureFlagsDebug implements FeatureFlags { return null; } - private <T> void setFlagValue(int id, @NonNull T value, FlagSerializer<T> serializer) { + /** Returns the stored value or null if not set. */ + @Nullable + private <T> T readFlagValueInternal(String name, FlagSerializer<T> serializer) { + try { + return mFlagManager.readFlagValue(name, serializer); + } catch (Exception e) { + eraseInternal(name); + } + return null; + } + + private <T> void setFlagValue(String name, @NonNull T value, FlagSerializer<T> serializer) { requireNonNull(value, "Cannot set a null value"); - T currentValue = readFlagValueInternal(id, serializer); + T currentValue = readFlagValueInternal(name, serializer); if (Objects.equals(currentValue, value)) { - Log.i(TAG, "Flag id " + id + " is already " + value); + Log.i(TAG, "Flag id " + name + " is already " + value); return; } final String data = serializer.toSettingsData(value); if (data == null) { - Log.w(TAG, "Failed to set id " + id + " to " + value); + Log.w(TAG, "Failed to set id " + name + " to " + value); return; } - mSecureSettings.putStringForUser(mFlagManager.idToSettingsKey(id), data, + mGlobalSettings.putStringForUser(mFlagManager.nameToSettingsKey(name), data, UserHandle.USER_CURRENT); - Log.i(TAG, "Set id " + id + " to " + value); - removeFromCache(id); - mFlagManager.dispatchListenersAndMaybeRestart(id, this::restartSystemUI); + Log.i(TAG, "Set id " + name + " to " + value); + removeFromCache(name); + mFlagManager.dispatchListenersAndMaybeRestart(name, this::restartSystemUI); } <T> void eraseFlag(Flag<T> flag) { if (flag instanceof SysPropFlag) { mSystemProperties.erase(((SysPropFlag<T>) flag).getName()); - dispatchListenersAndMaybeRestart(flag.getId(), this::restartAndroid); + dispatchListenersAndMaybeRestart(flag.getName(), this::restartAndroid); } else { - eraseFlag(flag.getId()); + eraseFlag(flag.getName()); } } /** Erase a flag's overridden value if there is one. */ - private void eraseFlag(int id) { - eraseInternal(id); - removeFromCache(id); - dispatchListenersAndMaybeRestart(id, this::restartSystemUI); + private void eraseFlag(String name) { + eraseInternal(name); + removeFromCache(name); + dispatchListenersAndMaybeRestart(name, this::restartSystemUI); } - private void dispatchListenersAndMaybeRestart(int id, Consumer<Boolean> restartAction) { - mFlagManager.dispatchListenersAndMaybeRestart(id, restartAction); + private void dispatchListenersAndMaybeRestart(String name, Consumer<Boolean> restartAction) { + mFlagManager.dispatchListenersAndMaybeRestart(name, restartAction); } - /** Works just like {@link #eraseFlag(int)} except that it doesn't restart SystemUI. */ + /** Works just like {@link #eraseFlag(String)} except that it doesn't restart SystemUI. */ + // TODO(b/265188950): Remove method this once ids are fully deprecated. private void eraseInternal(int id) { - // We can't actually "erase" things from sysprops, but we can set them to empty! - mSecureSettings.putStringForUser(mFlagManager.idToSettingsKey(id), "", + // We can't actually "erase" things from settings, but we can set them to empty! + mGlobalSettings.putStringForUser(mFlagManager.idToSettingsKey(id), "", + UserHandle.USER_CURRENT); + Log.i(TAG, "Erase name " + id); + } + + /** Works just like {@link #eraseFlag(String)} except that it doesn't restart SystemUI. */ + private void eraseInternal(String name) { + // We can't actually "erase" things from settings, but we can set them to empty! + mGlobalSettings.putStringForUser(mFlagManager.nameToSettingsKey(name), "", UserHandle.USER_CURRENT); - Log.i(TAG, "Erase id " + id); + Log.i(TAG, "Erase name " + name); } @Override @@ -340,13 +386,13 @@ public class FeatureFlagsDebug implements FeatureFlags { void setBooleanFlagInternal(Flag<?> flag, boolean value) { if (flag instanceof BooleanFlag) { - setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE); + setFlagValue(flag.getName(), value, BooleanFlagSerializer.INSTANCE); } else if (flag instanceof ResourceBooleanFlag) { - setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE); + setFlagValue(flag.getName(), value, BooleanFlagSerializer.INSTANCE); } else if (flag instanceof SysPropBooleanFlag) { // Store SysProp flags in SystemProperties where they can read by outside parties. mSystemProperties.setBoolean(((SysPropBooleanFlag) flag).getName(), value); - dispatchListenersAndMaybeRestart(flag.getId(), + dispatchListenersAndMaybeRestart(flag.getName(), FeatureFlagsDebug.this::restartAndroid); } else { throw new IllegalArgumentException("Unknown flag type"); @@ -355,9 +401,9 @@ public class FeatureFlagsDebug implements FeatureFlags { void setStringFlagInternal(Flag<?> flag, String value) { if (flag instanceof StringFlag) { - setFlagValue(flag.getId(), value, StringFlagSerializer.INSTANCE); + setFlagValue(flag.getName(), value, StringFlagSerializer.INSTANCE); } else if (flag instanceof ResourceStringFlag) { - setFlagValue(flag.getId(), value, StringFlagSerializer.INSTANCE); + setFlagValue(flag.getName(), value, StringFlagSerializer.INSTANCE); } else { throw new IllegalArgumentException("Unknown flag type"); } @@ -365,9 +411,9 @@ public class FeatureFlagsDebug implements FeatureFlags { void setIntFlagInternal(Flag<?> flag, int value) { if (flag instanceof IntFlag) { - setFlagValue(flag.getId(), value, IntFlagSerializer.INSTANCE); + setFlagValue(flag.getName(), value, IntFlagSerializer.INSTANCE); } else if (flag instanceof ResourceIntFlag) { - setFlagValue(flag.getId(), value, IntFlagSerializer.INSTANCE); + setFlagValue(flag.getName(), value, IntFlagSerializer.INSTANCE); } else { throw new IllegalArgumentException("Unknown flag type"); } @@ -406,17 +452,17 @@ public class FeatureFlagsDebug implements FeatureFlags { Log.w(TAG, "No extras"); return; } - int id = extras.getInt(EXTRA_ID); - if (id <= 0) { - Log.w(TAG, "ID not set or less than or equal to 0: " + id); + String name = extras.getString(EXTRA_NAME); + if (name == null || name.isEmpty()) { + Log.w(TAG, "NAME not set or is empty: " + name); return; } - if (!mAllFlags.containsKey(id)) { - Log.w(TAG, "Tried to set unknown id: " + id); + if (!mAllFlags.containsKey(name)) { + Log.w(TAG, "Tried to set unknown name: " + name); return; } - Flag<?> flag = mAllFlags.get(id); + Flag<?> flag = mAllFlags.get(name); if (!extras.containsKey(EXTRA_VALUE)) { eraseFlag(flag); @@ -453,13 +499,16 @@ public class FeatureFlagsDebug implements FeatureFlags { if (f instanceof ReleasedFlag) { enabled = isEnabled((ReleasedFlag) f); - overridden = readBooleanFlagOverride(f.getId()) != null; + overridden = readBooleanFlagOverride(f.getName()) != null + || readBooleanFlagOverride(f.getId()) != null; } else if (f instanceof UnreleasedFlag) { enabled = isEnabled((UnreleasedFlag) f); - overridden = readBooleanFlagOverride(f.getId()) != null; + overridden = readBooleanFlagOverride(f.getName()) != null + || readBooleanFlagOverride(f.getId()) != null; } else if (f instanceof ResourceBooleanFlag) { enabled = isEnabled((ResourceBooleanFlag) f); - overridden = readBooleanFlagOverride(f.getId()) != null; + overridden = readBooleanFlagOverride(f.getName()) != null + || readBooleanFlagOverride(f.getId()) != null; } else if (f instanceof SysPropBooleanFlag) { // TODO(b/223379190): Teamfood not supported for sysprop flags yet. enabled = isEnabled((SysPropBooleanFlag) f); @@ -481,9 +530,9 @@ public class FeatureFlagsDebug implements FeatureFlags { } }; - private void removeFromCache(int id) { - mBooleanFlagCache.remove(id); - mStringFlagCache.remove(id); + private void removeFromCache(String name) { + mBooleanFlagCache.remove(name); + mStringFlagCache.remove(name); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java index 8bddacc4e32c..7e1423706fc9 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java +++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java @@ -21,18 +21,16 @@ import static com.android.systemui.flags.FlagsCommonModule.ALL_FLAGS; import static java.util.Objects.requireNonNull; import android.content.res.Resources; -import android.util.SparseArray; -import android.util.SparseBooleanArray; import androidx.annotation.NonNull; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.util.DeviceConfigProxy; import org.jetbrains.annotations.NotNull; import java.io.PrintWriter; +import java.util.HashMap; import java.util.Map; import javax.inject.Inject; @@ -50,12 +48,11 @@ public class FeatureFlagsRelease implements FeatureFlags { private final Resources mResources; private final SystemPropertiesHelper mSystemProperties; - private final DeviceConfigProxy mDeviceConfigProxy; private final ServerFlagReader mServerFlagReader; private final Restarter mRestarter; - private final Map<Integer, Flag<?>> mAllFlags; - SparseBooleanArray mBooleanCache = new SparseBooleanArray(); - SparseArray<String> mStringCache = new SparseArray<>(); + private final Map<String, Flag<?>> mAllFlags; + private final Map<String, Boolean> mBooleanCache = new HashMap<>(); + private final Map<String, String> mStringCache = new HashMap<>(); private final ServerFlagReader.ChangeListener mOnPropertiesChanged = new ServerFlagReader.ChangeListener() { @@ -69,13 +66,11 @@ public class FeatureFlagsRelease implements FeatureFlags { public FeatureFlagsRelease( @Main Resources resources, SystemPropertiesHelper systemProperties, - DeviceConfigProxy deviceConfigProxy, ServerFlagReader serverFlagReader, - @Named(ALL_FLAGS) Map<Integer, Flag<?>> allFlags, + @Named(ALL_FLAGS) Map<String, Flag<?>> allFlags, Restarter restarter) { mResources = resources; mSystemProperties = systemProperties; - mDeviceConfigProxy = deviceConfigProxy; mServerFlagReader = serverFlagReader; mAllFlags = allFlags; mRestarter = restarter; @@ -106,50 +101,48 @@ public class FeatureFlagsRelease implements FeatureFlags { @Override public boolean isEnabled(ResourceBooleanFlag flag) { - int cacheIndex = mBooleanCache.indexOfKey(flag.getId()); - if (cacheIndex < 0) { - return isEnabled(flag.getId(), mResources.getBoolean(flag.getResourceId())); + if (!mBooleanCache.containsKey(flag.getName())) { + return isEnabled(flag.getName(), mResources.getBoolean(flag.getResourceId())); } - return mBooleanCache.valueAt(cacheIndex); + return mBooleanCache.get(flag.getName()); } @Override public boolean isEnabled(SysPropBooleanFlag flag) { - int cacheIndex = mBooleanCache.indexOfKey(flag.getId()); - if (cacheIndex < 0) { + if (!mBooleanCache.containsKey(flag.getName())) { return isEnabled( - flag.getId(), mSystemProperties.getBoolean(flag.getName(), flag.getDefault())); + flag.getName(), + mSystemProperties.getBoolean(flag.getName(), flag.getDefault())); } - return mBooleanCache.valueAt(cacheIndex); + return mBooleanCache.get(flag.getName()); } - private boolean isEnabled(int key, boolean defaultValue) { - mBooleanCache.append(key, defaultValue); + private boolean isEnabled(String name, boolean defaultValue) { + mBooleanCache.put(name, defaultValue); return defaultValue; } @NonNull @Override public String getString(@NonNull StringFlag flag) { - return getString(flag.getId(), flag.getDefault()); + return getString(flag.getName(), flag.getDefault()); } @NonNull @Override public String getString(@NonNull ResourceStringFlag flag) { - int cacheIndex = mStringCache.indexOfKey(flag.getId()); - if (cacheIndex < 0) { - return getString(flag.getId(), + if (!mStringCache.containsKey(flag.getName())) { + return getString(flag.getName(), requireNonNull(mResources.getString(flag.getResourceId()))); } - return mStringCache.valueAt(cacheIndex); + return mStringCache.get(flag.getName()); } - private String getString(int key, String defaultValue) { - mStringCache.append(key, defaultValue); + private String getString(String name, String defaultValue) { + mStringCache.put(name, defaultValue); return defaultValue; } @@ -169,11 +162,17 @@ public class FeatureFlagsRelease implements FeatureFlags { public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { pw.println("can override: false"); Map<String, Flag<?>> knownFlags = FlagsFactory.INSTANCE.getKnownFlags(); + pw.println("Booleans: "); for (Map.Entry<String, Flag<?>> nameToFlag : knownFlags.entrySet()) { Flag<?> flag = nameToFlag.getValue(); - int id = flag.getId(); + if (!(flag instanceof BooleanFlag) + || !(flag instanceof ResourceBooleanFlag) + || !(flag instanceof SysPropBooleanFlag)) { + continue; + } + boolean def = false; - if (mBooleanCache.indexOfKey(flag.getId()) < 0) { + if (!mBooleanCache.containsKey(flag.getName())) { if (flag instanceof SysPropBooleanFlag) { SysPropBooleanFlag f = (SysPropBooleanFlag) flag; def = mSystemProperties.getBoolean(f.getName(), f.getDefault()); @@ -185,15 +184,32 @@ public class FeatureFlagsRelease implements FeatureFlags { def = f.getDefault(); } } - pw.println(" sysui_flag_" + id + ": " + (mBooleanCache.get(id, def))); + pw.println( + " " + flag.getName() + ": " + + (mBooleanCache.getOrDefault(flag.getName(), def))); } - int numStrings = mStringCache.size(); - pw.println("Strings: " + numStrings); - for (int i = 0; i < numStrings; i++) { - final int id = mStringCache.keyAt(i); - final String value = mStringCache.valueAt(i); - final int length = value.length(); - pw.println(" sysui_flag_" + id + ": [length=" + length + "] \"" + value + "\""); + + pw.println("Strings: "); + for (Map.Entry<String, Flag<?>> nameToFlag : knownFlags.entrySet()) { + Flag<?> flag = nameToFlag.getValue(); + if (!(flag instanceof StringFlag) + || !(flag instanceof ResourceStringFlag)) { + continue; + } + + String def = ""; + if (!mBooleanCache.containsKey(flag.getName())) { + if (flag instanceof ResourceStringFlag) { + ResourceStringFlag f = (ResourceStringFlag) flag; + def = mResources.getString(f.getResourceId()); + } else if (flag instanceof StringFlag) { + StringFlag f = (StringFlag) flag; + def = f.getDefault(); + } + } + String value = mStringCache.getOrDefault(flag.getName(), def); + pw.println( + " " + flag.getName() + ": [length=" + value.length() + "] \"" + value + "\""); } } } diff --git a/packages/SystemUI/src/com/android/systemui/flags/FlagCommand.java b/packages/SystemUI/src/com/android/systemui/flags/FlagCommand.java index b7fc0e41ea69..daf9429344a7 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FlagCommand.java +++ b/packages/SystemUI/src/com/android/systemui/flags/FlagCommand.java @@ -39,12 +39,12 @@ public class FlagCommand implements Command { private final List<String> mOffCommands = List.of("false", "off", "0", "disable"); private final List<String> mSetCommands = List.of("set", "put"); private final FeatureFlagsDebug mFeatureFlags; - private final Map<Integer, Flag<?>> mAllFlags; + private final Map<String, Flag<?>> mAllFlags; @Inject FlagCommand( FeatureFlagsDebug featureFlags, - @Named(ALL_FLAGS) Map<Integer, Flag<?>> allFlags + @Named(ALL_FLAGS) Map<String, Flag<?>> allFlags ) { mFeatureFlags = featureFlags; mAllFlags = allFlags; @@ -53,30 +53,22 @@ public class FlagCommand implements Command { @Override public void execute(@NonNull PrintWriter pw, @NonNull List<String> args) { if (args.size() == 0) { - pw.println("Error: no flag id supplied"); + pw.println("Error: no flag name supplied"); help(pw); pw.println(); printKnownFlags(pw); return; } - int id = 0; - try { - id = Integer.parseInt(args.get(0)); - if (!mAllFlags.containsKey(id)) { - pw.println("Unknown flag id: " + id); - pw.println(); - printKnownFlags(pw); - return; - } - } catch (NumberFormatException e) { - id = flagNameToId(args.get(0)); - if (id == 0) { - pw.println("Invalid flag. Must an integer id or flag name: " + args.get(0)); - return; - } + String name = args.get(0); + if (!mAllFlags.containsKey(name)) { + pw.println("Unknown flag name: " + name); + pw.println(); + printKnownFlags(pw); + return; } - Flag<?> flag = mAllFlags.get(id); + + Flag<?> flag = mAllFlags.get(name); String cmd = ""; if (args.size() > 1) { @@ -117,7 +109,7 @@ public class FlagCommand implements Command { return; } - pw.println("Flag " + id + " is " + newValue); + pw.println("Flag " + name + " is " + newValue); pw.flush(); // Next command will restart sysui, so flush before we do so. if (shouldSet) { mFeatureFlags.setBooleanFlagInternal(flag, newValue); @@ -136,11 +128,11 @@ public class FlagCommand implements Command { return; } String value = args.get(2); - pw.println("Setting Flag " + id + " to " + value); + pw.println("Setting Flag " + name + " to " + value); pw.flush(); // Next command will restart sysui, so flush before we do so. mFeatureFlags.setStringFlagInternal(flag, args.get(2)); } else { - pw.println("Flag " + id + " is " + getStringFlag(flag)); + pw.println("Flag " + name + " is " + getStringFlag(flag)); } return; } else if (isIntFlag(flag)) { @@ -155,11 +147,11 @@ public class FlagCommand implements Command { return; } int value = Integer.parseInt(args.get(2)); - pw.println("Setting Flag " + id + " to " + value); + pw.println("Setting Flag " + name + " to " + value); pw.flush(); // Next command will restart sysui, so flush before we do so. mFeatureFlags.setIntFlagInternal(flag, value); } else { - pw.println("Flag " + id + " is " + getIntFlag(flag)); + pw.println("Flag " + name + " is " + getIntFlag(flag)); } return; } @@ -182,8 +174,7 @@ public class FlagCommand implements Command { private boolean isBooleanFlag(Flag<?> flag) { return (flag instanceof BooleanFlag) || (flag instanceof ResourceBooleanFlag) - || (flag instanceof SysPropFlag) - || (flag instanceof DeviceConfigBooleanFlag); + || (flag instanceof SysPropFlag); } private boolean isBooleanFlagEnabled(Flag<?> flag) { @@ -252,15 +243,14 @@ public class FlagCommand implements Command { for (int i = 0; i < longestFieldName - "Flag Name".length() + 1; i++) { pw.print(" "); } - pw.println("ID Value"); + pw.println(" Value"); for (int i = 0; i < longestFieldName; i++) { pw.print("="); } - pw.println(" ==== ========"); + pw.println(" ========"); for (String fieldName : fields.keySet()) { Flag<?> flag = fields.get(fieldName); - int id = flag.getId(); - if (id == 0 || !mAllFlags.containsKey(id)) { + if (!mAllFlags.containsKey(flag.getName())) { continue; } pw.print(fieldName); @@ -268,9 +258,9 @@ public class FlagCommand implements Command { for (int i = 0; i < longestFieldName - fieldWidth + 1; i++) { pw.print(" "); } - pw.printf("%-4d ", id); + pw.print(" "); if (isBooleanFlag(flag)) { - pw.println(isBooleanFlagEnabled(mAllFlags.get(id))); + pw.println(isBooleanFlagEnabled(flag)); } else if (isStringFlag(flag)) { pw.println(getStringFlag(flag)); } else if (isIntFlag(flag)) { diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index a6977e1fa8dd..fa0ce24183a3 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -129,13 +129,6 @@ object Flags { val LOCKSCREEN_CUSTOM_CLOCKS = unreleasedFlag(207, "lockscreen_custom_clocks", teamfood = true) /** - * Flag to enable the usage of the new bouncer data source. This is a refactor of and eventual - * replacement of KeyguardBouncer.java. - */ - // TODO(b/254512385): Tracking Bug - @JvmField val MODERN_BOUNCER = releasedFlag(208, "modern_bouncer") - - /** * Whether the clock on a wide lock screen should use the new "stepping" animation for moving * the digits when the clock moves. */ @@ -364,6 +357,10 @@ object Flags { // TODO(b/266157412): Tracking Bug val MEDIA_RETAIN_SESSIONS = unreleasedFlag(913, "media_retain_sessions") + // TODO(b/266739309): Tracking Bug + @JvmField + val MEDIA_RECOMMENDATION_CARD_UPDATE = unreleasedFlag(914, "media_recommendation_card_update") + // 1000 - dock val SIMULATE_DOCK_THROUGH_CHARGING = releasedFlag(1000, "simulate_dock_through_charging") diff --git a/packages/SystemUI/src/com/android/systemui/flags/FlagsCommonModule.kt b/packages/SystemUI/src/com/android/systemui/flags/FlagsCommonModule.kt index 8442230fc5b1..0054d266c283 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FlagsCommonModule.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/FlagsCommonModule.kt @@ -28,8 +28,8 @@ interface FlagsCommonModule { @JvmStatic @Provides @Named(ALL_FLAGS) - fun providesAllFlags(): Map<Int, Flag<*>> { - return FlagsFactory.knownFlags.map { it.value.id to it.value }.toMap() + fun providesAllFlags(): Map<String, Flag<*>> { + return FlagsFactory.knownFlags } } } diff --git a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt index ae05c4656349..a02b795f074e 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt @@ -54,10 +54,11 @@ class ServerFlagReaderImpl @Inject constructor( return } + for ((listener, flags) in listeners) { propLoop@ for (propName in properties.keyset) { for (flag in flags) { - if (propName == getServerOverrideName(flag.id)) { + if (propName == getServerOverrideName(flag.id) || propName == flag.name) { listener.onChange() break@propLoop } diff --git a/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java b/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java index d9bcb508c8e2..418aeca42889 100644 --- a/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java +++ b/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java @@ -37,9 +37,14 @@ public class ExtensionFragmentListener<T extends FragmentBase> implements Consum private final int mId; private String mOldClass; - private ExtensionFragmentListener(View view, String tag, int id, Extension<T> extension) { + private ExtensionFragmentListener( + FragmentService fragmentService, + View view, + String tag, + int id, + Extension<T> extension) { mTag = tag; - mFragmentHostManager = FragmentHostManager.get(view); + mFragmentHostManager = fragmentService.getFragmentHostManager(view); mExtension = extension; mId = id; mFragmentHostManager.getFragmentManager().beginTransaction() @@ -60,8 +65,13 @@ public class ExtensionFragmentListener<T extends FragmentBase> implements Consum mExtension.clearItem(true); } - public static <T> void attachExtensonToFragment(View view, String tag, int id, + public static <T> void attachExtensonToFragment( + FragmentService fragmentService, + View view, + String tag, + int id, Extension<T> extension) { - extension.addCallback(new ExtensionFragmentListener(view, tag, id, extension)); + extension.addCallback( + new ExtensionFragmentListener(fragmentService, view, tag, id, extension)); } } diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java index 9c7411bf3649..6a27ee7c0c89 100644 --- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java +++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java @@ -36,7 +36,6 @@ import android.view.View; import androidx.annotation.NonNull; import com.android.settingslib.applications.InterestingConfigChanges; -import com.android.systemui.Dependency; import com.android.systemui.plugins.Plugin; import com.android.systemui.util.leak.LeakDetector; @@ -46,12 +45,17 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; +import dagger.assisted.Assisted; +import dagger.assisted.AssistedFactory; +import dagger.assisted.AssistedInject; + public class FragmentHostManager { private final Handler mHandler = new Handler(Looper.getMainLooper()); private final Context mContext; private final HashMap<String, ArrayList<FragmentListener>> mListeners = new HashMap<>(); private final View mRootView; + private final LeakDetector mLeakDetector; private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges( ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_ASSETS_PATHS); @@ -61,14 +65,24 @@ public class FragmentHostManager { private FragmentController mFragments; private FragmentLifecycleCallbacks mLifecycleCallbacks; - FragmentHostManager(FragmentService manager, View rootView) { + @AssistedInject + FragmentHostManager( + @Assisted View rootView, + FragmentService manager, + LeakDetector leakDetector) { mContext = rootView.getContext(); mManager = manager; mRootView = rootView; + mLeakDetector = leakDetector; mConfigChanges.applyNewConfig(mContext.getResources()); createFragmentHost(null); } + @AssistedFactory + public interface Factory { + FragmentHostManager create(View rootView); + } + private void createFragmentHost(Parcelable savedState) { mFragments = FragmentController.createController(new HostCallbacks()); mFragments.attachHost(null); @@ -86,7 +100,7 @@ public class FragmentHostManager { @Override public void onFragmentDestroyed(FragmentManager fm, Fragment f) { - Dependency.get(LeakDetector.class).trackGarbage(f); + mLeakDetector.trackGarbage(f); } }; mFragments.getFragmentManager().registerFragmentLifecycleCallbacks(mLifecycleCallbacks, @@ -211,19 +225,6 @@ public class FragmentHostManager { } } - public static FragmentHostManager get(View view) { - try { - return Dependency.get(FragmentService.class).getFragmentHostManager(view); - } catch (ClassCastException e) { - // TODO: Some auto handling here? - throw e; - } - } - - public static void removeAndDestroy(View view) { - Dependency.get(FragmentService.class).removeAndDestroy(view); - } - public void reloadFragments() { Trace.beginSection("FrargmentHostManager#reloadFragments"); // Save the old state. diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java index fe945fb2fa28..d302b13a68b6 100644 --- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java +++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java @@ -53,6 +53,7 @@ public class FragmentService implements Dumpable { */ private final ArrayMap<String, FragmentInstantiationInfo> mInjectionMap = new ArrayMap<>(); private final Handler mHandler = new Handler(); + private final FragmentHostManager.Factory mFragmentHostManagerFactory; private ConfigurationController.ConfigurationListener mConfigurationListener = new ConfigurationController.ConfigurationListener() { @@ -67,8 +68,10 @@ public class FragmentService implements Dumpable { @Inject public FragmentService( FragmentCreator.Factory fragmentCreatorFactory, + FragmentHostManager.Factory fragmentHostManagerFactory, ConfigurationController configurationController, DumpManager dumpManager) { + mFragmentHostManagerFactory = fragmentHostManagerFactory; addFragmentInstantiationProvider(fragmentCreatorFactory.build()); configurationController.addCallback(mConfigurationListener); @@ -152,7 +155,7 @@ public class FragmentService implements Dumpable { public FragmentHostState(View view) { mView = view; - mFragmentHostManager = new FragmentHostManager(FragmentService.this, mView); + mFragmentHostManager = mFragmentHostManagerFactory.create(mView); } public void sendConfigurationChange(Configuration newConfig) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 4a3071dba33e..7a891b0058af 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -17,7 +17,6 @@ package com.android.systemui.keyguard; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.WindowManager.TRANSIT_CLOSE; @@ -79,6 +78,7 @@ import com.android.internal.policy.IKeyguardService; import com.android.internal.policy.IKeyguardStateCallback; import com.android.keyguard.mediator.ScreenOnCoordinator; import com.android.systemui.SystemUIApplication; +import com.android.systemui.settings.DisplayTracker; import com.android.wm.shell.transition.ShellTransitions; import com.android.wm.shell.transition.Transitions; @@ -94,6 +94,7 @@ public class KeyguardService extends Service { private final KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher; private final ScreenOnCoordinator mScreenOnCoordinator; private final ShellTransitions mShellTransitions; + private final DisplayTracker mDisplayTracker; private static int newModeToLegacyMode(int newMode) { switch (newMode) { @@ -257,12 +258,14 @@ public class KeyguardService extends Service { public KeyguardService(KeyguardViewMediator keyguardViewMediator, KeyguardLifecyclesDispatcher keyguardLifecyclesDispatcher, ScreenOnCoordinator screenOnCoordinator, - ShellTransitions shellTransitions) { + ShellTransitions shellTransitions, + DisplayTracker displayTracker) { super(); mKeyguardViewMediator = keyguardViewMediator; mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher; mScreenOnCoordinator = screenOnCoordinator; mShellTransitions = shellTransitions; + mDisplayTracker = displayTracker; } @Override @@ -295,7 +298,7 @@ public class KeyguardService extends Service { definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_UNOCCLUDE, unoccludeAnimationAdapter); ActivityTaskManager.getInstance().registerRemoteAnimationsForDisplay( - DEFAULT_DISPLAY, definition); + mDisplayTracker.getDefaultDisplayId(), definition); return; } Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_GOING_AWAY"); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt index e9d7a5b8ed6f..3319f9d467ec 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt @@ -49,6 +49,7 @@ import kotlin.math.pow import kotlin.math.sqrt import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest @@ -163,12 +164,26 @@ object KeyguardBottomAreaViewBinder { ambientIndicationArea?.alpha = alpha indicationArea.alpha = alpha - startButton.alpha = alpha - endButton.alpha = alpha } } launch { + updateButtonAlpha( + view = startButton, + viewModel = viewModel.startButton, + alphaFlow = viewModel.alpha, + ) + } + + launch { + updateButtonAlpha( + view = endButton, + viewModel = viewModel.endButton, + alphaFlow = viewModel.alpha, + ) + } + + launch { viewModel.indicationAreaTranslationX.collect { translationX -> indicationArea.translationX = translationX ambientIndicationArea?.translationX = translationX @@ -321,7 +336,6 @@ object KeyguardBottomAreaViewBinder { .animate() .scaleX(if (viewModel.isSelected) SCALE_SELECTED_BUTTON else 1f) .scaleY(if (viewModel.isSelected) SCALE_SELECTED_BUTTON else 1f) - .alpha(if (viewModel.isDimmed) DIM_ALPHA else 1f) .start() view.isClickable = viewModel.isClickable @@ -341,6 +355,17 @@ object KeyguardBottomAreaViewBinder { view.isSelected = viewModel.isSelected } + private suspend fun updateButtonAlpha( + view: View, + viewModel: Flow<KeyguardQuickAffordanceViewModel>, + alphaFlow: Flow<Float>, + ) { + combine(viewModel.map { it.isDimmed }, alphaFlow) { isDimmed, alpha -> + if (isDimmed) DIM_ALPHA else alpha + } + .collect { view.alpha = it } + } + private class OnTouchListener( private val view: View, private val viewModel: KeyguardQuickAffordanceViewModel, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt index 5e46c5d1f67a..c1731e031333 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt @@ -106,13 +106,6 @@ object KeyguardBouncerViewBinder { hostViewController.appear( SystemBarUtils.getStatusBarHeight(view.context) ) - } - } - - launch { - viewModel.showWithFullExpansion.collect { model -> - hostViewController.resetSecurityContainer() - hostViewController.showPromptReason(model.promptReason) hostViewController.onResume() } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt index c6002d6db91a..737c35d866c2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt @@ -20,12 +20,10 @@ import android.view.View import com.android.systemui.keyguard.data.BouncerView import com.android.systemui.keyguard.data.BouncerViewDelegate import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor -import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel import javax.inject.Inject import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map /** Models UI state for the lock screen bouncer; handles user input. */ @@ -44,10 +42,6 @@ constructor( /** Observe whether bouncer is showing. */ val show: Flow<KeyguardBouncerModel> = interactor.show - /** Observe visible expansion when bouncer is showing. */ - val showWithFullExpansion: Flow<KeyguardBouncerModel> = - interactor.show.filter { it.expansionAmount == EXPANSION_VISIBLE } - /** Observe whether bouncer is hiding. */ val hide: Flow<Unit> = interactor.hide diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt index 1a10b18a5a69..8c1ec166fb2e 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt @@ -21,6 +21,7 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import com.android.internal.widget.CachingIconView import com.android.systemui.R import com.android.systemui.media.controls.models.GutsViewHolder import com.android.systemui.media.controls.ui.IlluminationDrawable @@ -29,18 +30,15 @@ import com.android.systemui.util.animation.TransitionLayout private const val TAG = "RecommendationViewHolder" /** ViewHolder for a Smartspace media recommendation. */ -class RecommendationViewHolder private constructor(itemView: View) { +class RecommendationViewHolder private constructor(itemView: View, updatedView: Boolean) { val recommendations = itemView as TransitionLayout // Recommendation screen - val cardIcon = itemView.requireViewById<ImageView>(R.id.recommendation_card_icon) - val mediaCoverItems = - listOf<ImageView>( - itemView.requireViewById(R.id.media_cover1), - itemView.requireViewById(R.id.media_cover2), - itemView.requireViewById(R.id.media_cover3) - ) + lateinit var cardIcon: ImageView + lateinit var mediaAppIcons: List<CachingIconView> + lateinit var cardTitle: TextView + val mediaCoverContainers = listOf<ViewGroup>( itemView.requireViewById(R.id.media_cover1_container), @@ -48,21 +46,45 @@ class RecommendationViewHolder private constructor(itemView: View) { itemView.requireViewById(R.id.media_cover3_container) ) val mediaTitles: List<TextView> = - listOf( - itemView.requireViewById(R.id.media_title1), - itemView.requireViewById(R.id.media_title2), - itemView.requireViewById(R.id.media_title3) - ) + if (updatedView) { + mediaCoverContainers.map { it.requireViewById(R.id.media_title) } + } else { + listOf( + itemView.requireViewById(R.id.media_title1), + itemView.requireViewById(R.id.media_title2), + itemView.requireViewById(R.id.media_title3) + ) + } val mediaSubtitles: List<TextView> = - listOf( - itemView.requireViewById(R.id.media_subtitle1), - itemView.requireViewById(R.id.media_subtitle2), - itemView.requireViewById(R.id.media_subtitle3) - ) + if (updatedView) { + mediaCoverContainers.map { it.requireViewById(R.id.media_subtitle) } + } else { + listOf( + itemView.requireViewById(R.id.media_subtitle1), + itemView.requireViewById(R.id.media_subtitle2), + itemView.requireViewById(R.id.media_subtitle3) + ) + } + val mediaCoverItems: List<ImageView> = + if (updatedView) { + mediaCoverContainers.map { it.requireViewById(R.id.media_cover) } + } else { + listOf( + itemView.requireViewById(R.id.media_cover1), + itemView.requireViewById(R.id.media_cover2), + itemView.requireViewById(R.id.media_cover3) + ) + } val gutsViewHolder = GutsViewHolder(itemView) init { + if (updatedView) { + mediaAppIcons = mediaCoverContainers.map { it.requireViewById(R.id.media_rec_app_icon) } + cardTitle = itemView.requireViewById(R.id.media_rec_title) + } else { + cardIcon = itemView.requireViewById<ImageView>(R.id.recommendation_card_icon) + } (recommendations.background as IlluminationDrawable).let { background -> mediaCoverContainers.forEach { background.registerLightSource(it) } background.registerLightSource(gutsViewHolder.cancel) @@ -83,36 +105,52 @@ class RecommendationViewHolder private constructor(itemView: View) { * @param parent Parent of inflated view. */ @JvmStatic - fun create(inflater: LayoutInflater, parent: ViewGroup): RecommendationViewHolder { + fun create( + inflater: LayoutInflater, + parent: ViewGroup, + updatedView: Boolean, + ): RecommendationViewHolder { val itemView = - inflater.inflate( - R.layout.media_smartspace_recommendations, - parent, - false /* attachToRoot */ - ) + if (updatedView) { + inflater.inflate( + R.layout.media_recommendations, + parent, + false /* attachToRoot */ + ) + } else { + inflater.inflate( + R.layout.media_smartspace_recommendations, + parent, + false /* attachToRoot */ + ) + } // Because this media view (a TransitionLayout) is used to measure and layout the views // in various states before being attached to its parent, we can't depend on the default // LAYOUT_DIRECTION_INHERIT to correctly resolve the ltr direction. itemView.layoutDirection = View.LAYOUT_DIRECTION_LOCALE - return RecommendationViewHolder(itemView) + return RecommendationViewHolder(itemView, updatedView) } // Res Ids for the control components on the recommendation view. val controlsIds = setOf( R.id.recommendation_card_icon, + R.id.media_rec_title, R.id.media_cover1, R.id.media_cover2, R.id.media_cover3, + R.id.media_cover, R.id.media_cover1_container, R.id.media_cover2_container, R.id.media_cover3_container, R.id.media_title1, R.id.media_title2, R.id.media_title3, + R.id.media_title, R.id.media_subtitle1, R.id.media_subtitle2, - R.id.media_subtitle3 + R.id.media_subtitle3, + R.id.media_subtitle, ) val mediaTitlesAndSubtitlesIds = @@ -120,9 +158,11 @@ class RecommendationViewHolder private constructor(itemView: View) { R.id.media_title1, R.id.media_title2, R.id.media_title3, + R.id.media_title, R.id.media_subtitle1, R.id.media_subtitle2, - R.id.media_subtitle3 + R.id.media_subtitle3, + R.id.media_subtitle, ) val mediaContainersIds = diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt index e7f7647797cd..b2ad15522743 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt @@ -43,6 +43,7 @@ import com.android.systemui.media.controls.models.recommendation.RecommendationV import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData import com.android.systemui.media.controls.pipeline.MediaDataManager import com.android.systemui.media.controls.ui.MediaControlPanel.SMARTSPACE_CARD_DISMISS_EVENT +import com.android.systemui.media.controls.util.MediaFlags import com.android.systemui.media.controls.util.MediaUiEventLogger import com.android.systemui.media.controls.util.SmallHash import com.android.systemui.plugins.ActivityStarter @@ -88,7 +89,8 @@ constructor( falsingManager: FalsingManager, dumpManager: DumpManager, private val logger: MediaUiEventLogger, - private val debugLogger: MediaCarouselControllerLogger + private val debugLogger: MediaCarouselControllerLogger, + private val mediaFlags: MediaFlags, ) : Dumpable { /** The current width of the carousel */ private var currentCarouselWidth: Int = 0 @@ -647,7 +649,11 @@ constructor( val newRecs = mediaControlPanelFactory.get() newRecs.attachRecommendation( - RecommendationViewHolder.create(LayoutInflater.from(context), mediaContent) + RecommendationViewHolder.create( + LayoutInflater.from(context), + mediaContent, + mediaFlags.isRecommendationCardUpdateEnabled() + ) ) newRecs.mediaViewController.sizeChangedListener = this::updateCarouselDimensions val lp = diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java index 39dd7336e4d1..2fd4f27a5bea 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java @@ -62,6 +62,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; +import androidx.appcompat.content.res.AppCompatResources; import androidx.constraintlayout.widget.ConstraintSet; import com.android.internal.annotations.VisibleForTesting; @@ -755,43 +756,16 @@ public class MediaControlPanel { int width = mMediaViewHolder.getAlbumView().getMeasuredWidth(); int height = mMediaViewHolder.getAlbumView().getMeasuredHeight(); - // WallpaperColors.fromBitmap takes a good amount of time. We do that work - // on the background executor to avoid stalling animations on the UI Thread. mBackgroundExecutor.execute(() -> { // Album art ColorScheme mutableColorScheme = null; Drawable artwork; boolean isArtworkBound; Icon artworkIcon = data.getArtwork(); - WallpaperColors wallpaperColors = null; - if (artworkIcon != null) { - if (artworkIcon.getType() == Icon.TYPE_BITMAP - || artworkIcon.getType() == Icon.TYPE_ADAPTIVE_BITMAP) { - // Avoids extra processing if this is already a valid bitmap - wallpaperColors = WallpaperColors - .fromBitmap(artworkIcon.getBitmap()); - } else { - Drawable artworkDrawable = artworkIcon.loadDrawable(mContext); - if (artworkDrawable != null) { - wallpaperColors = WallpaperColors - .fromDrawable(artworkIcon.loadDrawable(mContext)); - } - } - } + WallpaperColors wallpaperColors = getWallpaperColor(artworkIcon); if (wallpaperColors != null) { mutableColorScheme = new ColorScheme(wallpaperColors, true, Style.CONTENT); - Drawable albumArt = getScaledBackground(artworkIcon, width, height); - GradientDrawable gradient = (GradientDrawable) mContext - .getDrawable(R.drawable.qs_media_scrim); - gradient.setColors(new int[] { - ColorUtilKt.getColorWithAlpha( - MediaColorSchemesKt.backgroundStartFromScheme(mutableColorScheme), - 0.25f), - ColorUtilKt.getColorWithAlpha( - MediaColorSchemesKt.backgroundEndFromScheme(mutableColorScheme), - 0.9f), - }); - artwork = new LayerDrawable(new Drawable[] { albumArt, gradient }); + artwork = addGradientToIcon(artworkIcon, mutableColorScheme, width, height); isArtworkBound = true; } else { // If there's no artwork, use colors from the app icon @@ -870,6 +844,96 @@ public class MediaControlPanel { }); } + private void bindRecommendationArtwork( + SmartspaceAction recommendation, + String packageName, + int itemIndex + ) { + final int traceCookie = recommendation.hashCode(); + final String traceName = + "MediaControlPanel#bindRecommendationArtwork<" + packageName + ">"; + Trace.beginAsyncSection(traceName, traceCookie); + + // Capture width & height from views in foreground for artwork scaling in background + int width = mRecommendationViewHolder.getMediaCoverContainers().get(0).getMeasuredWidth(); + int height = mRecommendationViewHolder.getMediaCoverContainers().get(0).getMeasuredHeight(); + + mBackgroundExecutor.execute(() -> { + // Album art + ColorScheme mutableColorScheme = null; + Drawable artwork; + Icon artworkIcon = recommendation.getIcon(); + WallpaperColors wallpaperColors = getWallpaperColor(artworkIcon); + if (wallpaperColors != null) { + mutableColorScheme = new ColorScheme(wallpaperColors, true, Style.CONTENT); + artwork = addGradientToIcon(artworkIcon, mutableColorScheme, width, height); + } else { + artwork = new ColorDrawable(Color.TRANSPARENT); + } + + mMainExecutor.execute(() -> { + // Bind the artwork drawable to media cover. + ImageView mediaCover = + mRecommendationViewHolder.getMediaCoverItems().get(itemIndex); + mediaCover.setImageDrawable(artwork); + + // Set up the app icon. + ImageView appIconView = mRecommendationViewHolder.getMediaAppIcons().get(itemIndex); + appIconView.clearColorFilter(); + try { + Drawable icon = mContext.getPackageManager() + .getApplicationIcon(packageName); + appIconView.setImageDrawable(icon); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "Cannot find icon for package " + packageName, e); + appIconView.setImageResource(R.drawable.ic_music_note); + } + Trace.endAsyncSection(traceName, traceCookie); + }); + }); + } + + // This method should be called from a background thread. WallpaperColors.fromBitmap takes a + // good amount of time. We do that work on the background executor to avoid stalling animations + // on the UI Thread. + private WallpaperColors getWallpaperColor(Icon artworkIcon) { + if (artworkIcon != null) { + if (artworkIcon.getType() == Icon.TYPE_BITMAP + || artworkIcon.getType() == Icon.TYPE_ADAPTIVE_BITMAP) { + // Avoids extra processing if this is already a valid bitmap + return WallpaperColors + .fromBitmap(artworkIcon.getBitmap()); + } else { + Drawable artworkDrawable = artworkIcon.loadDrawable(mContext); + if (artworkDrawable != null) { + return WallpaperColors + .fromDrawable(artworkIcon.loadDrawable(mContext)); + } + } + } + return null; + } + + private LayerDrawable addGradientToIcon( + Icon artworkIcon, + ColorScheme mutableColorScheme, + int width, + int height + ) { + Drawable albumArt = getScaledBackground(artworkIcon, width, height); + GradientDrawable gradient = (GradientDrawable) AppCompatResources + .getDrawable(mContext, R.drawable.qs_media_scrim); + gradient.setColors(new int[] { + ColorUtilKt.getColorWithAlpha( + MediaColorSchemesKt.backgroundStartFromScheme(mutableColorScheme), + 0.25f), + ColorUtilKt.getColorWithAlpha( + MediaColorSchemesKt.backgroundEndFromScheme(mutableColorScheme), + 0.9f), + }); + return new LayerDrawable(new Drawable[] { albumArt, gradient }); + } + private void scaleTransitionDrawableLayer(TransitionDrawable transitionDrawable, int layer, int targetWidth, int targetHeight) { Drawable drawable = transitionDrawable.getDrawable(layer); @@ -1227,8 +1291,10 @@ public class MediaControlPanel { PackageManager packageManager = mContext.getPackageManager(); // Set up media source app's logo. Drawable icon = packageManager.getApplicationIcon(applicationInfo); - ImageView headerLogoImageView = mRecommendationViewHolder.getCardIcon(); - headerLogoImageView.setImageDrawable(icon); + if (!mFeatureFlags.isEnabled(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE)) { + ImageView headerLogoImageView = mRecommendationViewHolder.getCardIcon(); + headerLogoImageView.setImageDrawable(icon); + } fetchAndUpdateRecommendationColors(icon); // Set up media rec card's tap action if applicable. @@ -1248,7 +1314,15 @@ public class MediaControlPanel { // Set up media item cover. ImageView mediaCoverImageView = mediaCoverItems.get(itemIndex); - mediaCoverImageView.setImageIcon(recommendation.getIcon()); + if (mFeatureFlags.isEnabled(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE)) { + bindRecommendationArtwork( + recommendation, + data.getPackageName(), + itemIndex + ); + } else { + mediaCoverImageView.setImageIcon(recommendation.getIcon()); + } // Set up the media item's click listener if applicable. ViewGroup mediaCoverContainer = mediaCoverContainers.get(itemIndex); @@ -1278,7 +1352,6 @@ public class MediaControlPanel { recommendation.getTitle(), artistName, appName)); } - // Set up title CharSequence title = recommendation.getTitle(); hasTitle |= !TextUtils.isEmpty(title); @@ -1356,6 +1429,10 @@ public class MediaControlPanel { int textPrimaryColor = MediaColorSchemesKt.textPrimaryFromScheme(colorScheme); int textSecondaryColor = MediaColorSchemesKt.textSecondaryFromScheme(colorScheme); + if (mFeatureFlags.isEnabled(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE)) { + mRecommendationViewHolder.getCardTitle().setTextColor(textPrimaryColor); + } + mRecommendationViewHolder.getRecommendations() .setBackgroundTintList(ColorStateList.valueOf(backgroundColor)); mRecommendationViewHolder.getMediaTitles().forEach( diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt index 2ec7be6eaa32..1e6002cdc717 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt @@ -25,6 +25,7 @@ import com.android.systemui.media.controls.models.GutsViewHolder import com.android.systemui.media.controls.models.player.MediaViewHolder import com.android.systemui.media.controls.models.recommendation.RecommendationViewHolder import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.calculateAlpha +import com.android.systemui.media.controls.util.MediaFlags import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.animation.MeasurementOutput import com.android.systemui.util.animation.TransitionLayout @@ -45,7 +46,8 @@ constructor( private val context: Context, private val configurationController: ConfigurationController, private val mediaHostStatesManager: MediaHostStatesManager, - private val logger: MediaViewLogger + private val logger: MediaViewLogger, + private val mediaFlags: MediaFlags, ) { /** @@ -646,8 +648,13 @@ constructor( expandedLayout.load(context, R.xml.media_session_expanded) } TYPE.RECOMMENDATION -> { - collapsedLayout.load(context, R.xml.media_recommendation_collapsed) - expandedLayout.load(context, R.xml.media_recommendation_expanded) + if (mediaFlags.isRecommendationCardUpdateEnabled()) { + collapsedLayout.load(context, R.xml.media_recommendations_view_collapsed) + expandedLayout.load(context, R.xml.media_recommendations_view_expanded) + } else { + collapsedLayout.load(context, R.xml.media_recommendation_collapsed) + expandedLayout.load(context, R.xml.media_recommendation_expanded) + } } } refreshState() diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt index ab03930e42ac..81efa3688aab 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt @@ -51,4 +51,8 @@ class MediaFlags @Inject constructor(private val featureFlags: FeatureFlags) { * whether the underlying notification was dismissed */ fun isRetainingPlayersEnabled() = featureFlags.isEnabled(Flags.MEDIA_RETAIN_SESSIONS) + + /** Check whether we show the updated recommendation card. */ + fun isRecommendationCardUpdateEnabled() = + featureFlags.isEnabled(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE) } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java index 4e08050a6f65..dc75538c5d29 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java @@ -45,6 +45,7 @@ import android.widget.SeekBar; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; import androidx.recyclerview.widget.RecyclerView; import com.android.settingslib.Utils; @@ -142,11 +143,12 @@ public abstract class MediaOutputBaseAdapter extends final TextView mVolumeValueText; final ImageView mTitleIcon; final ProgressBar mProgressBar; - final MediaOutputSeekbar mSeekBar; final LinearLayout mTwoLineLayout; final ImageView mStatusIcon; final CheckBox mCheckBox; final ViewGroup mEndTouchArea; + @VisibleForTesting + MediaOutputSeekbar mSeekBar; private String mDeviceId; private ValueAnimator mCornerAnimator; private ValueAnimator mVolumeAnimator; @@ -390,6 +392,7 @@ public abstract class MediaOutputBaseAdapter extends mTitleIcon.setVisibility(View.VISIBLE); mVolumeValueText.setVisibility(View.GONE); } + mController.logInteractionAdjustVolume(device); mIsDragging = false; } }); diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java index 1587e6248595..5f5c686e36e2 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -141,7 +141,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, @VisibleForTesting LocalMediaManager mLocalMediaManager; @VisibleForTesting - private MediaOutputMetricLogger mMetricLogger; + MediaOutputMetricLogger mMetricLogger; private int mCurrentState; private int mColorItemContent; @@ -870,12 +870,15 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } void adjustVolume(MediaDevice device, int volume) { - mMetricLogger.logInteractionAdjustVolume(device); ThreadUtils.postOnBackgroundThread(() -> { device.requestSetVolume(volume); }); } + void logInteractionAdjustVolume(MediaDevice device) { + mMetricLogger.logInteractionAdjustVolume(device); + } + String getPackageName() { return mPackageName; } diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt index f8785fcf5de0..f1acae8e2685 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt @@ -79,9 +79,9 @@ class ReceiverChipRippleView(context: Context?, attrs: AttributeSet?) : RippleVi animator.addUpdateListener { updateListener -> val now = updateListener.currentPlayTime val progress = updateListener.animatedValue as Float - rippleShader.progress = startingPercentage + (progress * (1 - startingPercentage)) - rippleShader.distortionStrength = 1 - rippleShader.progress - rippleShader.pixelDensity = 1 - rippleShader.progress + rippleShader.rawProgress = startingPercentage + (progress * (1 - startingPercentage)) + rippleShader.distortionStrength = 1 - rippleShader.rawProgress + rippleShader.pixelDensity = 1 - rippleShader.rawProgress rippleShader.time = now.toFloat() invalidate() } diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt index 1edb837f3ca9..e665d832a568 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt @@ -34,8 +34,8 @@ import com.android.systemui.mediaprojection.appselector.data.RecentTaskThumbnail import com.android.systemui.mediaprojection.appselector.data.ShellRecentTaskListProvider import com.android.systemui.mediaprojection.appselector.view.MediaProjectionRecentsViewController import com.android.systemui.mediaprojection.appselector.view.TaskPreviewSizeProvider -import com.android.systemui.settings.UserTracker -import com.android.systemui.shared.system.ActivityManagerWrapper +import com.android.systemui.mediaprojection.devicepolicy.MediaProjectionDevicePolicyModule +import com.android.systemui.mediaprojection.devicepolicy.PersonalProfile import com.android.systemui.statusbar.phone.ConfigurationControllerImpl import com.android.systemui.statusbar.policy.ConfigurationController import dagger.Binds @@ -54,13 +54,12 @@ import kotlinx.coroutines.SupervisorJob @Qualifier @Retention(AnnotationRetention.BINARY) annotation class HostUserHandle -@Qualifier @Retention(AnnotationRetention.BINARY) annotation class PersonalProfile - -@Qualifier @Retention(AnnotationRetention.BINARY) annotation class WorkProfile - @Retention(AnnotationRetention.RUNTIME) @Scope annotation class MediaProjectionAppSelectorScope -@Module(subcomponents = [MediaProjectionAppSelectorComponent::class]) +@Module( + subcomponents = [MediaProjectionAppSelectorComponent::class], + includes = [MediaProjectionDevicePolicyModule::class] +) interface MediaProjectionModule { @Binds @IntoMap @@ -110,20 +109,6 @@ interface MediaProjectionAppSelectorModule { ): ConfigurationController = ConfigurationControllerImpl(activity) @Provides - @PersonalProfile - @MediaProjectionAppSelectorScope - fun personalUserHandle(activityManagerWrapper: ActivityManagerWrapper): UserHandle { - // Current foreground user is the 'personal' profile - return UserHandle.of(activityManagerWrapper.currentUserId) - } - - @Provides - @WorkProfile - @MediaProjectionAppSelectorScope - fun workProfileUserHandle(userTracker: UserTracker): UserHandle? = - userTracker.userProfiles.find { it.isManagedProfile }?.userHandle - - @Provides @HostUserHandle @MediaProjectionAppSelectorScope fun hostUserHandle(activity: MediaProjectionAppSelectorActivity): UserHandle { diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt new file mode 100644 index 000000000000..829b0ddbe3a8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.mediaprojection.appselector + +import android.content.Context +import android.os.UserHandle +import com.android.internal.R as AndroidR +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState +import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider +import com.android.internal.app.ResolverListAdapter +import com.android.systemui.R +import com.android.systemui.mediaprojection.devicepolicy.PersonalProfile +import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver +import javax.inject.Inject + +@MediaProjectionAppSelectorScope +class MediaProjectionBlockerEmptyStateProvider +@Inject +constructor( + @HostUserHandle private val hostAppHandle: UserHandle, + @PersonalProfile private val personalProfileHandle: UserHandle, + private val policyResolver: ScreenCaptureDevicePolicyResolver, + private val context: Context +) : EmptyStateProvider { + + override fun getEmptyState(resolverListAdapter: ResolverListAdapter): EmptyState? { + val screenCaptureAllowed = + policyResolver.isScreenCaptureAllowed( + targetAppUserHandle = resolverListAdapter.userHandle, + hostAppUserHandle = hostAppHandle + ) + + val isHostAppInPersonalProfile = hostAppHandle == personalProfileHandle + + val subtitle = + if (isHostAppInPersonalProfile) { + AndroidR.string.resolver_cant_share_with_personal_apps_explanation + } else { + AndroidR.string.resolver_cant_share_with_work_apps_explanation + } + + if (!screenCaptureAllowed) { + return object : EmptyState { + override fun getSubtitle(): String = context.resources.getString(subtitle) + override fun getTitle(): String = + context.resources.getString( + R.string.screen_capturing_disabled_by_policy_dialog_title + ) + override fun onEmptyStateShown() { + // TODO(b/237397740) report analytics + } + override fun shouldSkipDataRebuild(): Boolean = true + } + } + return null + } +} diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/MediaProjectionDevicePolicyModule.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/MediaProjectionDevicePolicyModule.kt new file mode 100644 index 000000000000..13b71a727dd9 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/MediaProjectionDevicePolicyModule.kt @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.mediaprojection.devicepolicy + +import android.os.UserHandle +import com.android.systemui.settings.UserTracker +import com.android.systemui.shared.system.ActivityManagerWrapper +import dagger.Module +import dagger.Provides +import javax.inject.Qualifier + +@Qualifier @Retention(AnnotationRetention.BINARY) annotation class WorkProfile + +@Qualifier @Retention(AnnotationRetention.BINARY) annotation class PersonalProfile + +/** Module for media projection device policy related dependencies */ +@Module +class MediaProjectionDevicePolicyModule { + @Provides + @PersonalProfile + fun personalUserHandle(activityManagerWrapper: ActivityManagerWrapper): UserHandle { + // Current foreground user is the 'personal' profile + return UserHandle.of(activityManagerWrapper.currentUserId) + } + + @Provides + @WorkProfile + fun workProfileUserHandle(userTracker: UserTracker): UserHandle? = + userTracker.userProfiles.find { it.isManagedProfile }?.userHandle +} diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDevicePolicyResolver.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDevicePolicyResolver.kt new file mode 100644 index 000000000000..6bd33e7e5c97 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDevicePolicyResolver.kt @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.mediaprojection.devicepolicy + +import android.app.admin.DevicePolicyManager +import android.os.UserHandle +import android.os.UserManager +import javax.inject.Inject + +/** + * Utility class to resolve if screen capture allowed for a particular target app/host app pair. It + * caches the state of the policies, so you need to create a new instance of this class if you want + * to react to updated policies state. + */ +class ScreenCaptureDevicePolicyResolver +@Inject +constructor( + private val devicePolicyManager: DevicePolicyManager, + private val userManager: UserManager, + @PersonalProfile private val personalProfileUserHandle: UserHandle, + @WorkProfile private val workProfileUserHandle: UserHandle? +) { + + /** + * Returns true if [hostAppUserHandle] is allowed to perform screen capture of + * [targetAppUserHandle] + */ + fun isScreenCaptureAllowed( + targetAppUserHandle: UserHandle, + hostAppUserHandle: UserHandle, + ): Boolean { + if (hostAppUserHandle.isWorkProfile() && workProfileScreenCaptureDisabled) { + // Disable screen capturing as host apps should not capture the screen + return false + } + + if (!hostAppUserHandle.isWorkProfile() && personalProfileScreenCaptureDisabled) { + // Disable screen capturing as personal apps should not capture the screen + return false + } + + if (targetAppUserHandle.isWorkProfile()) { + // Work profile target + if (workProfileScreenCaptureDisabled) { + // Do not allow sharing work profile apps as work profile capturing is disabled + return false + } + } else { + // Personal profile target + if (hostAppUserHandle.isWorkProfile() && disallowSharingIntoManagedProfile) { + // Do not allow sharing of personal apps into work profile apps + return false + } + + if (personalProfileScreenCaptureDisabled) { + // Disable screen capturing as personal apps should not be captured + return false + } + } + + return true + } + + /** + * Returns true if [hostAppUserHandle] is NOT allowed to capture an app from any profile, + * could be useful to finish the screen capture flow as soon as possible when the screen + * could not be captured at all. + */ + fun isScreenCaptureCompletelyDisabled(hostAppUserHandle: UserHandle): Boolean { + val isWorkAppsCaptureDisabled = + if (workProfileUserHandle != null) { + !isScreenCaptureAllowed( + targetAppUserHandle = workProfileUserHandle, + hostAppUserHandle = hostAppUserHandle + ) + } else true + + val isPersonalAppsCaptureDisabled = + !isScreenCaptureAllowed( + targetAppUserHandle = personalProfileUserHandle, + hostAppUserHandle = hostAppUserHandle + ) + + return isWorkAppsCaptureDisabled && isPersonalAppsCaptureDisabled + } + + private val personalProfileScreenCaptureDisabled: Boolean by lazy { + devicePolicyManager.getScreenCaptureDisabled( + /* admin */ null, + personalProfileUserHandle.identifier + ) + } + + private val workProfileScreenCaptureDisabled: Boolean by lazy { + workProfileUserHandle?.let { + devicePolicyManager.getScreenCaptureDisabled(/* admin */ null, it.identifier) + } + ?: false + } + + private val disallowSharingIntoManagedProfile: Boolean by lazy { + workProfileUserHandle?.let { + userManager.hasUserRestrictionForUser( + UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE, + it + ) + } + ?: false + } + + private fun UserHandle?.isWorkProfile(): Boolean = this == workProfileUserHandle +} diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialog.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialog.kt new file mode 100644 index 000000000000..a6b3da04ad80 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialog.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.mediaprojection.devicepolicy + +import android.content.Context +import com.android.systemui.R +import com.android.systemui.statusbar.phone.SystemUIDialog + +/** Dialog that shows that screen capture is disabled on this device. */ +class ScreenCaptureDisabledDialog(context: Context) : SystemUIDialog(context) { + + init { + setTitle(context.getString(R.string.screen_capturing_disabled_by_policy_dialog_title)) + setMessage( + context.getString(R.string.screen_capturing_disabled_by_policy_dialog_description) + ) + setIcon(R.drawable.ic_cast) + setButton(BUTTON_POSITIVE, context.getString(android.R.string.ok)) { _, _ -> cancel() } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUiState.java b/packages/SystemUI/src/com/android/systemui/model/SysUiState.java index 3ecf15471c31..8d809908d78b 100644 --- a/packages/SystemUI/src/com/android/systemui/model/SysUiState.java +++ b/packages/SystemUI/src/com/android/systemui/model/SysUiState.java @@ -16,13 +16,12 @@ package com.android.systemui.model; -import static android.view.Display.DEFAULT_DISPLAY; - import android.annotation.NonNull; import android.util.Log; import com.android.systemui.Dumpable; import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.shared.system.QuickStepContract; import java.io.PrintWriter; @@ -39,11 +38,16 @@ public class SysUiState implements Dumpable { private static final String TAG = SysUiState.class.getSimpleName(); public static final boolean DEBUG = false; + private final DisplayTracker mDisplayTracker; private @QuickStepContract.SystemUiStateFlags int mFlags; private final List<SysUiStateCallback> mCallbacks = new ArrayList<>(); private int mFlagsToSet = 0; private int mFlagsToClear = 0; + public SysUiState(DisplayTracker displayTracker) { + mDisplayTracker = displayTracker; + } + /** * Add listener to be notified of changes made to SysUI state. * The callback will also be called as part of this function. @@ -81,7 +85,7 @@ public class SysUiState implements Dumpable { } private void updateFlags(int displayId) { - if (displayId != DEFAULT_DISPLAY) { + if (displayId != mDisplayTracker.getDefaultDisplayId()) { // Ignore non-default displays for now Log.w(TAG, "Ignoring flag update for display: " + displayId, new Throwable()); return; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 32dee922bf8f..79b4b3a4ab28 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -25,7 +25,6 @@ import static android.app.StatusBarManager.WindowType; import static android.app.StatusBarManager.WindowVisibleState; import static android.app.StatusBarManager.windowStateToString; import static android.app.WindowConfiguration.ROTATION_UNDEFINED; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES; import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT; import static android.view.InsetsState.ITYPE_LEFT_GESTURES; @@ -136,6 +135,7 @@ import com.android.systemui.navigationbar.gestural.QuickswitchOrientedNavHandle; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserContextProvider; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.ShadeController; @@ -224,6 +224,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener; private final UserContextProvider mUserContextProvider; private final WakefulnessLifecycle mWakefulnessLifecycle; + private final DisplayTracker mDisplayTracker; private final RegionSamplingHelper mRegionSamplingHelper; private final int mNavColorSampleMargin; private NavigationBarFrame mFrame; @@ -473,7 +474,8 @@ public class NavigationBar extends ViewController<NavigationBarView> implements @Override public void onStartedWakingUp() { notifyScreenStateChanged(true); - if (isGesturalModeOnDefaultDisplay(getContext(), mNavBarMode)) { + if (isGesturalModeOnDefaultDisplay(getContext(), mDisplayTracker, + mNavBarMode)) { mRegionSamplingHelper.start(mSamplingBounds); } } @@ -557,7 +559,8 @@ public class NavigationBar extends ViewController<NavigationBarView> implements Optional<BackAnimation> backAnimation, UserContextProvider userContextProvider, WakefulnessLifecycle wakefulnessLifecycle, - TaskStackChangeListeners taskStackChangeListeners) { + TaskStackChangeListeners taskStackChangeListeners, + DisplayTracker displayTracker) { super(navigationBarView); mFrame = navigationBarFrame; mContext = context; @@ -597,6 +600,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements mUserContextProvider = userContextProvider; mWakefulnessLifecycle = wakefulnessLifecycle; mTaskStackChangeListeners = taskStackChangeListeners; + mDisplayTracker = displayTracker; mNavColorSampleMargin = getResources() .getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin); @@ -644,12 +648,14 @@ public class NavigationBar extends ViewController<NavigationBarView> implements @Override public boolean isSamplingEnabled() { - return isGesturalModeOnDefaultDisplay(getContext(), mNavBarMode); + return isGesturalModeOnDefaultDisplay(getContext(), mDisplayTracker, + mNavBarMode); } }, mainExecutor, bgExecutor); mView.setBackgroundExecutor(bgExecutor); mView.setEdgeBackGestureHandler(mEdgeBackGestureHandler); + mView.setDisplayTracker(mDisplayTracker); mNavBarMode = mNavigationModeController.addListener(mModeChangedListener); } @@ -681,7 +687,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements getBarLayoutParams(mContext.getResources().getConfiguration().windowConfiguration .getRotation())); mDisplayId = mContext.getDisplayId(); - mIsOnDefaultDisplay = mDisplayId == DEFAULT_DISPLAY; + mIsOnDefaultDisplay = mDisplayId == mDisplayTracker.getDefaultDisplayId(); // Ensure we try to get currentSysuiState from navBarHelper before command queue callbacks // start firing, since the latter is source of truth @@ -1484,7 +1490,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements private void onAccessibilityClick(View v) { final Display display = v.getDisplay(); mAccessibilityManager.notifyAccessibilityButtonClicked( - display != null ? display.getDisplayId() : DEFAULT_DISPLAY); + display != null ? display.getDisplayId() : mDisplayTracker.getDefaultDisplayId()); } private boolean onAccessibilityLongClick(View v) { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index 046a284ca32a..3c1746532a02 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -19,7 +19,6 @@ package com.android.systemui.navigationbar; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR; -import static android.view.Display.DEFAULT_DISPLAY; import static com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler.DEBUG_MISSING_GESTURE_TAG; import static com.android.systemui.shared.recents.utilities.Utilities.isTablet; @@ -55,6 +54,7 @@ import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.model.SysUiState; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.systemui.statusbar.CommandQueue; @@ -87,6 +87,7 @@ public class NavigationBarController implements private final NavigationBarComponent.Factory mNavigationBarComponentFactory; private FeatureFlags mFeatureFlags; private final SecureSettings mSecureSettings; + private final DisplayTracker mDisplayTracker; private final DisplayManager mDisplayManager; private final TaskbarDelegate mTaskbarDelegate; private int mNavMode; @@ -119,12 +120,14 @@ public class NavigationBarController implements Optional<Pip> pipOptional, Optional<BackAnimation> backAnimation, FeatureFlags featureFlags, - SecureSettings secureSettings) { + SecureSettings secureSettings, + DisplayTracker displayTracker) { mContext = context; mHandler = mainHandler; mNavigationBarComponentFactory = navigationBarComponentFactory; mFeatureFlags = featureFlags; mSecureSettings = secureSettings; + mDisplayTracker = displayTracker; mDisplayManager = mContext.getSystemService(DisplayManager.class); commandQueue.addCallback(this); configurationController.addCallback(this); @@ -296,9 +299,10 @@ public class NavigationBarController implements // Don't need to create nav bar on the default display if we initialize TaskBar. final boolean shouldCreateDefaultNavbar = includeDefaultDisplay && !initializeTaskbarIfNecessary(); - Display[] displays = mDisplayManager.getDisplays(); + Display[] displays = mDisplayTracker.getAllDisplays(); for (Display display : displays) { - if (shouldCreateDefaultNavbar || display.getDisplayId() != DEFAULT_DISPLAY) { + if (shouldCreateDefaultNavbar + || display.getDisplayId() != mDisplayTracker.getDefaultDisplayId()) { createNavigationBar(display, null /* savedState */, result); } } @@ -317,7 +321,7 @@ public class NavigationBarController implements } final int displayId = display.getDisplayId(); - final boolean isOnDefaultDisplay = displayId == DEFAULT_DISPLAY; + final boolean isOnDefaultDisplay = displayId == mDisplayTracker.getDefaultDisplayId(); // We may show TaskBar on the default display for large screen device. Don't need to create // navigation bar for this case. @@ -412,7 +416,7 @@ public class NavigationBarController implements /** @return {@link NavigationBarView} on the default display. */ public @Nullable NavigationBarView getDefaultNavigationBarView() { - return getNavigationBarView(DEFAULT_DISPLAY); + return getNavigationBarView(mDisplayTracker.getDefaultDisplayId()); } /** @@ -433,7 +437,8 @@ public class NavigationBarController implements final NavigationBarView navBarView = getNavigationBarView(displayId); if (navBarView != null) { navBarView.showPinningEnterExitToast(entering); - } else if (displayId == DEFAULT_DISPLAY && mTaskbarDelegate.isInitialized()) { + } else if (displayId == mDisplayTracker.getDefaultDisplayId() + && mTaskbarDelegate.isInitialized()) { mTaskbarDelegate.showPinningEnterExitToast(entering); } } @@ -442,7 +447,8 @@ public class NavigationBarController implements final NavigationBarView navBarView = getNavigationBarView(displayId); if (navBarView != null) { navBarView.showPinningEscapeToast(); - } else if (displayId == DEFAULT_DISPLAY && mTaskbarDelegate.isInitialized()) { + } else if (displayId == mDisplayTracker.getDefaultDisplayId() + && mTaskbarDelegate.isInitialized()) { mTaskbarDelegate.showPinningEscapeToast(); } } @@ -459,7 +465,7 @@ public class NavigationBarController implements /** @return {@link NavigationBar} on the default display. */ @Nullable public NavigationBar getDefaultNavigationBar() { - return mNavigationBars.get(DEFAULT_DISPLAY); + return mNavigationBars.get(mDisplayTracker.getDefaultDisplayId()); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java index 43cf6231aaf0..20b50325f65f 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java @@ -24,7 +24,6 @@ import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; import android.util.SparseArray; -import android.view.Display; import android.view.IWallpaperVisibilityListener; import android.view.IWindowManager; import android.view.View; @@ -32,6 +31,7 @@ import android.view.View; import com.android.systemui.R; import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope; import com.android.systemui.navigationbar.buttons.ButtonDispatcher; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.statusbar.phone.BarTransitions; import com.android.systemui.statusbar.phone.LightBarTransitionsController; @@ -66,6 +66,7 @@ public final class NavigationBarTransitions extends BarTransitions implements @org.jetbrains.annotations.NotNull private final IWindowManager mWindowManagerService; private final LightBarTransitionsController mLightTransitionsController; + private final DisplayTracker mDisplayTracker; private final boolean mAllowAutoDimWallpaperNotVisible; private boolean mWallpaperVisible; @@ -102,12 +103,14 @@ public final class NavigationBarTransitions extends BarTransitions implements public NavigationBarTransitions( NavigationBarView view, IWindowManager windowManagerService, - LightBarTransitionsController.Factory lightBarTransitionsControllerFactory) { + LightBarTransitionsController.Factory lightBarTransitionsControllerFactory, + DisplayTracker displayTracker) { super(view, R.drawable.nav_background); mView = view; mWindowManagerService = windowManagerService; mLightTransitionsController = lightBarTransitionsControllerFactory.create(this); + mDisplayTracker = displayTracker; mAllowAutoDimWallpaperNotVisible = view.getContext().getResources() .getBoolean(R.bool.config_navigation_bar_enable_auto_dim_no_visible_wallpaper); mDarkIntensityListeners = new ArrayList(); @@ -115,7 +118,7 @@ public final class NavigationBarTransitions extends BarTransitions implements mWallpaperVisibilityListener = new WallpaperVisibilityListener(this); try { mWallpaperVisible = mWindowManagerService.registerWallpaperVisibilityListener( - mWallpaperVisibilityListener, Display.DEFAULT_DISPLAY); + mWallpaperVisibilityListener, mDisplayTracker.getDefaultDisplayId()); } catch (RemoteException e) { } mView.addOnLayoutChangeListener( @@ -141,7 +144,7 @@ public final class NavigationBarTransitions extends BarTransitions implements public void destroy() { try { mWindowManagerService.unregisterWallpaperVisibilityListener(mWallpaperVisibilityListener, - Display.DEFAULT_DISPLAY); + mDisplayTracker.getDefaultDisplayId()); } catch (RemoteException e) { } mLightTransitionsController.destroy(); @@ -150,7 +153,10 @@ public final class NavigationBarTransitions extends BarTransitions implements @Override public void setAutoDim(boolean autoDim) { // Ensure we aren't in gestural nav if we are triggering auto dim - if (autoDim && isGesturalModeOnDefaultDisplay(mView.getContext(), mNavBarMode)) return; + if (autoDim && isGesturalModeOnDefaultDisplay(mView.getContext(), mDisplayTracker, + mNavBarMode)) { + return; + } if (mAutoDim == autoDim) return; mAutoDim = autoDim; applyLightsOut(true, false); @@ -234,7 +240,7 @@ public final class NavigationBarTransitions extends BarTransitions implements @Override public int getTintAnimationDuration() { - if (isGesturalModeOnDefaultDisplay(mView.getContext(), mNavBarMode)) { + if (isGesturalModeOnDefaultDisplay(mView.getContext(), mDisplayTracker, mNavBarMode)) { return Math.max(DEFAULT_COLOR_ADAPT_TRANSITION_TIME, MIN_COLOR_ADAPT_TRANSITION_TIME); } return LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java index 88c4fd524b79..63fb4996fbbf 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java @@ -16,13 +16,11 @@ package com.android.systemui.navigationbar; -import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; import static android.inputmethodservice.InputMethodService.canImeRenderGesturalNavButtons; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SEARCH_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode; @@ -75,13 +73,12 @@ import com.android.systemui.navigationbar.buttons.NearestTouchFrame; import com.android.systemui.navigationbar.buttons.RotationContextButton; import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; import com.android.systemui.recents.Recents; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shared.rotation.FloatingRotationButton; import com.android.systemui.shared.rotation.RotationButton.RotationButtonUpdatesCallback; import com.android.systemui.shared.rotation.RotationButtonController; -import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.QuickStepContract; -import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.LightBarTransitionsController; @@ -127,6 +124,7 @@ public class NavigationBarView extends FrameLayout { private int mDarkIconColor; private EdgeBackGestureHandler mEdgeBackGestureHandler; + private DisplayTracker mDisplayTracker; private final DeadZone mDeadZone; private NavigationBarTransitions mBarTransitions; @Nullable @@ -303,7 +301,8 @@ public class NavigationBarView extends FrameLayout { R.dimen.floating_rotation_button_taskbar_left_margin, R.dimen.floating_rotation_button_taskbar_bottom_margin, R.dimen.floating_rotation_button_diameter, - R.dimen.key_button_ripple_max_width); + R.dimen.key_button_ripple_max_width, + R.bool.floating_rotation_button_position_left); mRotationButtonController = new RotationButtonController(mLightContext, mLightIconColor, mDarkIconColor, R.drawable.ic_sysbar_rotate_button_ccw_start_0, R.drawable.ic_sysbar_rotate_button_ccw_start_90, @@ -361,6 +360,10 @@ public class NavigationBarView extends FrameLayout { mBgExecutor = bgExecutor; } + public void setDisplayTracker(DisplayTracker displayTracker) { + mDisplayTracker = displayTracker; + } + public void setTouchHandler(Gefingerpoken touchHandler) { mTouchHandler = touchHandler; } @@ -558,7 +561,8 @@ public class NavigationBarView extends FrameLayout { } public void setBehavior(@Behavior int behavior) { - mRotationButtonController.onBehaviorChanged(Display.DEFAULT_DISPLAY, behavior); + mRotationButtonController.onBehaviorChanged(mDisplayTracker.getDefaultDisplayId(), + behavior); } @Override @@ -678,7 +682,7 @@ public class NavigationBarView extends FrameLayout { @VisibleForTesting boolean isRecentsButtonDisabled() { return mUseCarModeUi || !isOverviewEnabled() - || getContext().getDisplayId() != Display.DEFAULT_DISPLAY; + || getContext().getDisplayId() != mDisplayTracker.getDefaultDisplayId(); } private Display getContextDisplay() { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java index 4a07159001de..de0f9b242e20 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java @@ -16,8 +16,6 @@ package com.android.systemui.navigationbar.gestural; -import static android.view.Display.DEFAULT_DISPLAY; - import static com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler.DEBUG_MISSING_GESTURE; import static com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler.DEBUG_MISSING_GESTURE_TAG; @@ -55,9 +53,9 @@ import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; import com.android.systemui.dagger.qualifiers.Background; -import com.android.systemui.flags.FeatureFlags; import com.android.systemui.plugins.MotionEventsHandlerBase; import com.android.systemui.plugins.NavigationEdgeBackPlugin; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.shared.navigationbar.RegionSamplingHelper; import com.android.systemui.statusbar.VibratorHelper; @@ -291,7 +289,8 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl Context context, LatencyTracker latencyTracker, VibratorHelper vibratorHelper, - @Background Executor backgroundExecutor) { + @Background Executor backgroundExecutor, + DisplayTracker displayTracker) { super(context); mWindowManager = context.getSystemService(WindowManager.class); @@ -367,7 +366,7 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl setVisibility(GONE); - boolean isPrimaryDisplay = mContext.getDisplayId() == DEFAULT_DISPLAY; + boolean isPrimaryDisplay = mContext.getDisplayId() == displayTracker.getDefaultDisplayId(); mRegionSamplingHelper = new RegionSamplingHelper(this, new RegionSamplingHelper.SamplingCallback() { @Override diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt index 2a6ca1acb38e..8ad2f867a073 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt @@ -17,11 +17,11 @@ package com.android.systemui.privacy import android.content.Context import android.util.AttributeSet import android.view.ViewGroup -import android.widget.FrameLayout import android.widget.ImageView import android.widget.LinearLayout import com.android.settingslib.Utils import com.android.systemui.R +import com.android.systemui.animation.LaunchableFrameLayout import com.android.systemui.statusbar.events.BackgroundAnimatableView class OngoingPrivacyChip @JvmOverloads constructor( @@ -29,7 +29,7 @@ class OngoingPrivacyChip @JvmOverloads constructor( attrs: AttributeSet? = null, defStyleAttrs: Int = 0, defStyleRes: Int = 0 -) : FrameLayout(context, attrs, defStyleAttrs, defStyleRes), BackgroundAnimatableView { +) : LaunchableFrameLayout(context, attrs, defStyleAttrs, defStyleRes), BackgroundAnimatableView { private var iconMargin = 0 private var iconSize = 0 diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java index 100853caa2d7..98af9dfe7f37 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java @@ -314,7 +314,6 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, P if (!TILES_SETTING.equals(key)) { return; } - Log.d(TAG, "Recreating tiles"); if (newValue == null && UserManager.isDeviceInDemoMode(mContext)) { newValue = mContext.getResources().getString(R.string.quick_settings_tiles_retail_mode); } @@ -327,6 +326,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, P } } if (tileSpecs.equals(mTileSpecs) && currentUser == mCurrentUser) return; + Log.d(TAG, "Recreating tiles: " + tileSpecs); mTiles.entrySet().stream().filter(tile -> !tileSpecs.contains(tile.getKey())).forEach( tile -> { Log.d(TAG, "Destroying tile: " + tile.getKey()); @@ -372,6 +372,8 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, P Log.d(TAG, "Destroying not available tile: " + tileSpec); mQSLogger.logTileDestroyed(tileSpec, "Tile not available"); } + } else { + Log.d(TAG, "No factory for a spec: " + tileSpec); } } catch (Throwable t) { Log.w(TAG, "Error creating tile for spec: " + tileSpec, t); diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java index cfda9fd6cb96..7c2536dac56e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java @@ -15,7 +15,6 @@ */ package com.android.systemui.qs.external; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; import android.app.PendingIntent; @@ -63,6 +62,7 @@ import com.android.systemui.qs.QSHost; import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; +import com.android.systemui.settings.DisplayTracker; import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; @@ -90,6 +90,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener private final TileServiceManager mServiceManager; private final int mUser; private final CustomTileStatePersister mCustomTileStatePersister; + private final DisplayTracker mDisplayTracker; @Nullable private android.graphics.drawable.Icon mDefaultIcon; @Nullable @@ -120,7 +121,8 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener String action, Context userContext, CustomTileStatePersister customTileStatePersister, - TileServices tileServices + TileServices tileServices, + DisplayTracker displayTracker ) { super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger, statusBarStateController, activityStarter, qsLogger); @@ -135,6 +137,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener mServiceManager = tileServices.getTileWrapper(this); mService = mServiceManager.getTileService(); mCustomTileStatePersister = customTileStatePersister; + mDisplayTracker = displayTracker; } @Override @@ -310,7 +313,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener mIsShowingDialog = false; try { if (DEBUG) Log.d(TAG, "Removing token"); - mWindowManager.removeWindowToken(mToken, DEFAULT_DISPLAY); + mWindowManager.removeWindowToken(mToken, mDisplayTracker.getDefaultDisplayId()); } catch (RemoteException e) { } } @@ -335,7 +338,8 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener if (mIsTokenGranted && !mIsShowingDialog) { try { if (DEBUG) Log.d(TAG, "Removing token"); - mWindowManager.removeWindowToken(mToken, DEFAULT_DISPLAY); + mWindowManager.removeWindowToken(mToken, + mDisplayTracker.getDefaultDisplayId()); } catch (RemoteException e) { } mIsTokenGranted = false; @@ -354,7 +358,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener if (mIsTokenGranted) { try { if (DEBUG) Log.d(TAG, "Removing token"); - mWindowManager.removeWindowToken(mToken, DEFAULT_DISPLAY); + mWindowManager.removeWindowToken(mToken, mDisplayTracker.getDefaultDisplayId()); } catch (RemoteException e) { } } @@ -398,8 +402,8 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener mViewClicked = view; try { if (DEBUG) Log.d(TAG, "Adding token"); - mWindowManager.addWindowToken(mToken, TYPE_QS_DIALOG, DEFAULT_DISPLAY, - null /* options */); + mWindowManager.addWindowToken(mToken, TYPE_QS_DIALOG, + mDisplayTracker.getDefaultDisplayId(), null /* options */); mIsTokenGranted = true; } catch (RemoteException e) { } @@ -566,6 +570,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener final QSLogger mQSLogger; final CustomTileStatePersister mCustomTileStatePersister; private TileServices mTileServices; + final DisplayTracker mDisplayTracker; Context mUserContext; String mSpec = ""; @@ -581,7 +586,8 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener ActivityStarter activityStarter, QSLogger qsLogger, CustomTileStatePersister customTileStatePersister, - TileServices tileServices + TileServices tileServices, + DisplayTracker displayTracker ) { mQSHostLazy = hostLazy; mBackgroundLooper = backgroundLooper; @@ -593,6 +599,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener mQSLogger = qsLogger; mCustomTileStatePersister = customTileStatePersister; mTileServices = tileServices; + mDisplayTracker = displayTracker; } Builder setSpec(@NonNull String spec) { @@ -623,7 +630,8 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener action, mUserContext, mCustomTileStatePersister, - mTileServices + mTileServices, + mDisplayTracker ); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index dd7ea7658cb1..a979e5a99fa8 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -17,7 +17,6 @@ package com.android.systemui.recents; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_UP; @@ -89,6 +88,7 @@ import com.android.systemui.navigationbar.NavigationBarView; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.buttons.KeyButtonView; import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shared.recents.IOverviewProxy; @@ -145,6 +145,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private final UserTracker mUserTracker; private final KeyguardUnlockAnimationController mSysuiUnlockAnimationController; private final UiEventLogger mUiEventLogger; + private final DisplayTracker mDisplayTracker; private Region mActiveNavBarRegion; private SurfaceControl mNavigationBarSurface; @@ -226,11 +227,11 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis @Override public void onImeSwitcherPressed() { - // TODO(b/204901476) We're intentionally using DEFAULT_DISPLAY for now since + // TODO(b/204901476) We're intentionally using the default display for now since // Launcher/Taskbar isn't display aware. mContext.getSystemService(InputMethodManager.class) .showInputMethodPickerFromSystem(true /* showAuxiliarySubtypes */, - DEFAULT_DISPLAY); + mDisplayTracker.getDefaultDisplayId()); mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP); } @@ -508,6 +509,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis UserTracker userTracker, ScreenLifecycle screenLifecycle, UiEventLogger uiEventLogger, + DisplayTracker displayTracker, KeyguardUnlockAnimationController sysuiUnlockAnimationController, AssistUtils assistUtils, DumpManager dumpManager) { @@ -535,6 +537,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis mSysUiState = sysUiState; mSysUiState.addCallback(this::notifySystemUiStateFlags); mUiEventLogger = uiEventLogger; + mDisplayTracker = displayTracker; dumpManager.registerDumpable(getClass().getSimpleName(), this); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt index 01e32b7ada5f..aa8e2c039684 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt @@ -22,7 +22,6 @@ import android.os.Bundle import android.os.RemoteException import android.os.UserHandle import android.util.Log -import android.view.Display import android.view.IRemoteAnimationFinishedCallback import android.view.IRemoteAnimationRunner import android.view.RemoteAnimationAdapter @@ -33,6 +32,7 @@ import com.android.internal.infra.ServiceConnector import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.settings.DisplayTracker import javax.inject.Inject import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineDispatcher @@ -47,6 +47,7 @@ constructor( @Application private val applicationScope: CoroutineScope, @Main private val mainDispatcher: CoroutineDispatcher, private val context: Context, + private val displayTracker: DisplayTracker ) { /** * Execute the given intent with startActivity while performing operations for screenshot action @@ -82,7 +83,7 @@ constructor( val runner = RemoteAnimationAdapter(SCREENSHOT_REMOTE_RUNNER, 0, 0) try { WindowManagerGlobal.getWindowManagerService() - .overridePendingAppTransitionRemote(runner, Display.DEFAULT_DISPLAY) + .overridePendingAppTransitionRemote(runner, displayTracker.defaultDisplayId) } catch (e: Exception) { Log.e(TAG, "Error overriding screenshot app transition", e) } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java index 814b8e90e0dd..4f5cb72438bc 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java @@ -16,8 +16,6 @@ package com.android.systemui.screenshot; -import static android.view.Display.DEFAULT_DISPLAY; - import static com.android.systemui.screenshot.ScreenshotController.ACTION_TYPE_EDIT; import static com.android.systemui.screenshot.ScreenshotController.ACTION_TYPE_SHARE; import static com.android.systemui.screenshot.ScreenshotController.EXTRA_ACTION_INTENT; @@ -35,6 +33,7 @@ import android.util.Log; import android.view.RemoteAnimationAdapter; import android.view.WindowManagerGlobal; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.statusbar.phone.CentralSurfaces; @@ -52,14 +51,17 @@ public class ActionProxyReceiver extends BroadcastReceiver { private final CentralSurfaces mCentralSurfaces; private final ActivityManagerWrapper mActivityManagerWrapper; private final ScreenshotSmartActions mScreenshotSmartActions; + private final DisplayTracker mDisplayTracker; @Inject public ActionProxyReceiver(Optional<CentralSurfaces> centralSurfacesOptional, ActivityManagerWrapper activityManagerWrapper, - ScreenshotSmartActions screenshotSmartActions) { + ScreenshotSmartActions screenshotSmartActions, + DisplayTracker displayTracker) { mCentralSurfaces = centralSurfacesOptional.orElse(null); mActivityManagerWrapper = activityManagerWrapper; mScreenshotSmartActions = screenshotSmartActions; + mDisplayTracker = displayTracker; } @Override @@ -78,7 +80,8 @@ public class ActionProxyReceiver extends BroadcastReceiver { ScreenshotController.SCREENSHOT_REMOTE_RUNNER, 0, 0); try { WindowManagerGlobal.getWindowManagerService() - .overridePendingAppTransitionRemote(runner, DEFAULT_DISPLAY); + .overridePendingAppTransitionRemote(runner, + mDisplayTracker.getDefaultDisplayId()); } catch (Exception e) { Log.e(TAG, "Error overriding screenshot app transition", e); } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt new file mode 100644 index 000000000000..1e531ba7a6e0 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt @@ -0,0 +1,113 @@ +package com.android.systemui.screenshot + +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.animation.ValueAnimator +import android.graphics.drawable.Drawable +import android.view.View +import android.view.ViewGroup +import android.view.ViewGroup.MarginLayoutParams +import android.view.ViewTreeObserver +import android.view.animation.AccelerateDecelerateInterpolator +import android.widget.ImageView +import android.widget.TextView +import androidx.constraintlayout.widget.Guideline +import com.android.systemui.R + +/** + * MessageContainerController controls the display of content in the screenshot message container. + */ +class MessageContainerController +constructor( + parent: ViewGroup, +) { + private val guideline: Guideline = parent.requireViewById(R.id.guideline) + private val messageContainer: ViewGroup = + parent.requireViewById(R.id.screenshot_message_container) + + /** + * Show a notification under the screenshot view indicating that a work profile screenshot has + * been taken and which app can be used to view it. + * + * @param appName The name of the app to use to view screenshots + * @param appIcon Optional icon for the relevant files app + * @param onDismiss Runnable to be run when the user dismisses this message + */ + fun showWorkProfileMessage(appName: CharSequence, appIcon: Drawable?, onDismiss: Runnable) { + // Eventually this container will support multiple notification types, but for now just make + // sure we don't double inflate. + if (messageContainer.childCount == 0) { + View.inflate( + messageContainer.context, + R.layout.screenshot_work_profile_first_run, + messageContainer + ) + } + if (appIcon != null) { + // Replace the default icon if one is provided. + val imageView: ImageView = + messageContainer.requireViewById<ImageView>(R.id.screenshot_message_icon) + imageView.setImageDrawable(appIcon) + } + val messageContent = + messageContainer.requireViewById<TextView>(R.id.screenshot_message_content) + messageContent.text = + messageContainer.context.getString( + R.string.screenshot_work_profile_notification, + appName + ) + messageContainer.requireViewById<View>(R.id.message_dismiss_button).setOnClickListener { + animateOutMessageContainer() + onDismiss.run() + } + + // Need the container to be fully measured before animating in (to know animation offset + // destination) + messageContainer.viewTreeObserver.addOnPreDrawListener( + object : ViewTreeObserver.OnPreDrawListener { + override fun onPreDraw(): Boolean { + messageContainer.viewTreeObserver.removeOnPreDrawListener(this) + animateInMessageContainer() + return false + } + } + ) + } + + private fun animateInMessageContainer() { + if (messageContainer.visibility == View.VISIBLE) return + + messageContainer.visibility = View.VISIBLE + getAnimator(true).start() + } + + private fun animateOutMessageContainer() { + getAnimator(false).apply { + addListener( + object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + super.onAnimationEnd(animation) + messageContainer.visibility = View.INVISIBLE + } + } + ) + start() + } + } + + private fun getAnimator(animateIn: Boolean): Animator { + val params = messageContainer.layoutParams as MarginLayoutParams + val offset = messageContainer.height + params.topMargin + params.bottomMargin + val anim = if (animateIn) ValueAnimator.ofFloat(0f, 1f) else ValueAnimator.ofFloat(1f, 0f) + with(anim) { + duration = ScreenshotView.SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS + interpolator = AccelerateDecelerateInterpolator() + addUpdateListener { valueAnimator: ValueAnimator -> + val interpolation = valueAnimator.animatedValue as Float + guideline.setGuidelineEnd((interpolation * offset).toInt()) + messageContainer.alpha = interpolation + } + } + return anim + } +} diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index adff6e1757f6..ab13962b405d 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -17,7 +17,6 @@ package com.android.systemui.screenshot; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT; import static com.android.systemui.flags.Flags.SCREENSHOT_WORK_PROFILE_POLICY; @@ -102,6 +101,7 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition; import com.android.systemui.screenshot.TakeScreenshotService.RequestCallback; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.util.Assert; import com.google.common.util.concurrent.ListenableFuture; @@ -273,6 +273,7 @@ public class ScreenshotController { private final ScrollCaptureClient mScrollCaptureClient; private final PhoneWindow mWindow; private final DisplayManager mDisplayManager; + private final DisplayTracker mDisplayTracker; private final ScrollCaptureController mScrollCaptureController; private final LongScreenshotData mLongScreenshotHolder; private final boolean mIsLowRamDevice; @@ -292,6 +293,7 @@ public class ScreenshotController { }; private ScreenshotView mScreenshotView; + private MessageContainerController mMessageContainerController; private Bitmap mScreenBitmap; private SaveImageInBackgroundTask mSaveInBgTask; private boolean mScreenshotTakenInPortrait; @@ -331,7 +333,8 @@ public class ScreenshotController { ActionIntentExecutor actionExecutor, UserManager userManager, WorkProfileMessageController workProfileMessageController, - AssistContentRequester assistContentRequester + AssistContentRequester assistContentRequester, + DisplayTracker displayTracker ) { mScreenshotSmartActions = screenshotSmartActions; mNotificationsController = screenshotNotificationsController; @@ -357,6 +360,7 @@ public class ScreenshotController { }); mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class)); + mDisplayTracker = displayTracker; final Context displayContext = context.createDisplayContext(getDefaultDisplay()); mContext = (WindowContext) displayContext.createWindowContext(TYPE_SCREENSHOT, null); mWindowManager = mContext.getSystemService(WindowManager.class); @@ -400,7 +404,8 @@ public class ScreenshotController { mCurrentRequestCallback = requestCallback; if (screenshot.getType() == WindowManager.TAKE_SCREENSHOT_FULLSCREEN) { Rect bounds = getFullScreenRect(); - screenshot.setBitmap(mImageCapture.captureDisplay(DEFAULT_DISPLAY, bounds)); + screenshot.setBitmap( + mImageCapture.captureDisplay(mDisplayTracker.getDefaultDisplayId(), bounds)); screenshot.setScreenBounds(bounds); } @@ -627,6 +632,7 @@ public class ScreenshotController { // Inflate the screenshot layout mScreenshotView = (ScreenshotView) LayoutInflater.from(mContext).inflate(R.layout.screenshot, null); + mMessageContainerController = new MessageContainerController(mScreenshotView); mScreenshotView.addOnAttachStateChangeListener( new View.OnAttachStateChangeListener() { @Override @@ -667,6 +673,7 @@ public class ScreenshotController { setWindowFocusable(false); } }, mActionExecutor, mFlags); + mScreenshotView.setDefaultDisplay(mDisplayTracker.getDefaultDisplayId()); mScreenshotView.setDefaultTimeoutMillis(mScreenshotHandler.getDefaultTimeoutMillis()); mScreenshotView.setOnKeyListener((v, keyCode, event) -> { @@ -700,7 +707,8 @@ public class ScreenshotController { // copy the input Rect, since SurfaceControl.screenshot can mutate it Rect screenRect = new Rect(crop); - Bitmap screenshot = mImageCapture.captureDisplay(DEFAULT_DISPLAY, crop); + Bitmap screenshot = mImageCapture.captureDisplay(mDisplayTracker.getDefaultDisplayId(), + crop); if (screenshot == null) { Log.e(TAG, "takeScreenshotInternal: Screenshot bitmap was null"); @@ -856,7 +864,7 @@ public class ScreenshotController { mLastScrollCaptureRequest.cancel(true); } final ListenableFuture<ScrollCaptureResponse> future = - mScrollCaptureClient.request(DEFAULT_DISPLAY); + mScrollCaptureClient.request(mDisplayTracker.getDefaultDisplayId()); mLastScrollCaptureRequest = future; mLastScrollCaptureRequest.addListener(() -> onScrollCaptureResponseReady(future, owner), mMainExecutor); @@ -887,7 +895,8 @@ public class ScreenshotController { mScreenshotView.showScrollChip(response.getPackageName(), /* onClick */ () -> { DisplayMetrics displayMetrics = new DisplayMetrics(); getDefaultDisplay().getRealMetrics(displayMetrics); - Bitmap newScreenshot = mImageCapture.captureDisplay(DEFAULT_DISPLAY, + Bitmap newScreenshot = mImageCapture.captureDisplay( + mDisplayTracker.getDefaultDisplayId(), new Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)); mScreenshotView.prepareScrollingTransition(response, mScreenBitmap, newScreenshot, @@ -951,7 +960,8 @@ public class ScreenshotController { SCREENSHOT_REMOTE_RUNNER, 0, 0); try { WindowManagerGlobal.getWindowManagerService() - .overridePendingAppTransitionRemote(runner, DEFAULT_DISPLAY); + .overridePendingAppTransitionRemote(runner, + mDisplayTracker.getDefaultDisplayId()); } catch (Exception e) { Log.e(TAG, "Error overriding screenshot app transition", e); } @@ -1185,7 +1195,8 @@ public class ScreenshotController { private void doPostAnimation(ScreenshotController.SavedImageData imageData) { mScreenshotView.setChipIntents(imageData); if (mFlags.isEnabled(SCREENSHOT_WORK_PROFILE_POLICY)) { - mWorkProfileMessageController.onScreenshotTaken(imageData.owner, mScreenshotView); + mWorkProfileMessageController.onScreenshotTaken(imageData.owner, + mMessageContainerController); } } @@ -1289,7 +1300,7 @@ public class ScreenshotController { } private Display getDefaultDisplay() { - return mDisplayManager.getDisplay(DEFAULT_DISPLAY); + return mDisplayManager.getDisplay(mDisplayTracker.getDefaultDisplayId()); } private boolean allowLongScreenshots() { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt index 3a3528606302..21a73100da06 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt @@ -32,12 +32,12 @@ import android.os.RemoteException import android.os.UserHandle import android.os.UserManager import android.util.Log -import android.view.Display.DEFAULT_DISPLAY import com.android.internal.annotations.VisibleForTesting import com.android.internal.infra.ServiceConnector import com.android.systemui.SystemUIService import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.settings.DisplayTracker import com.android.systemui.screenshot.ScreenshotPolicy.DisplayContentInfo import java.util.Arrays import javax.inject.Inject @@ -52,6 +52,7 @@ internal open class ScreenshotPolicyImpl @Inject constructor( private val userMgr: UserManager, private val atmService: IActivityTaskManager, @Background val bgDispatcher: CoroutineDispatcher, + private val displayTracker: DisplayTracker ) : ScreenshotPolicy { private val proxyConnector: ServiceConnector<IScreenshotProxy> = @@ -64,7 +65,7 @@ internal open class ScreenshotPolicyImpl @Inject constructor( ) override fun getDefaultDisplayId(): Int { - return DEFAULT_DISPLAY + return displayTracker.defaultDisplayId } override suspend fun isManagedProfile(@UserIdInt userId: Int): Boolean { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java index bd4ea11eef5a..80f2717f27c3 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java @@ -33,7 +33,6 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ValueAnimator; -import android.annotation.Nullable; import android.app.ActivityManager; import android.app.BroadcastOptions; import android.app.Notification; @@ -84,7 +83,6 @@ import android.widget.FrameLayout; import android.widget.HorizontalScrollView; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.TextView; import androidx.constraintlayout.widget.ConstraintLayout; @@ -104,8 +102,7 @@ import java.util.ArrayList; * Handles the visual elements and animations for the screenshot flow. */ public class ScreenshotView extends FrameLayout implements - ViewTreeObserver.OnComputeInternalInsetsListener, - WorkProfileMessageController.WorkProfileMessageDisplay { + ViewTreeObserver.OnComputeInternalInsetsListener { interface ScreenshotViewCallback { void onUserInteraction(); @@ -125,7 +122,7 @@ public class ScreenshotView extends FrameLayout implements private static final long SCREENSHOT_TO_CORNER_X_DURATION_MS = 234; private static final long SCREENSHOT_TO_CORNER_Y_DURATION_MS = 500; private static final long SCREENSHOT_TO_CORNER_SCALE_DURATION_MS = 234; - private static final long SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS = 400; + public static final long SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS = 400; private static final long SCREENSHOT_ACTIONS_ALPHA_DURATION_MS = 100; private static final float SCREENSHOT_ACTIONS_START_SCALE_X = .7f; private static final int SWIPE_PADDING_DP = 12; // extra padding around views to allow swipe @@ -137,14 +134,13 @@ public class ScreenshotView extends FrameLayout implements private final AccessibilityManager mAccessibilityManager; private final GestureDetector mSwipeDetector; + private int mDefaultDisplay = Display.DEFAULT_DISPLAY; private int mNavMode; private boolean mOrientationPortrait; private boolean mDirectionLTR; private ImageView mScrollingScrim; private DraggableConstraintLayout mScreenshotStatic; - private ViewGroup mMessageContainer; - private TextView mMessageContent; private ImageView mScreenshotPreview; private ImageView mScreenshotBadge; private View mScreenshotPreviewBorder; @@ -301,8 +297,11 @@ public class ScreenshotView extends FrameLayout implements mDismissButton.getBoundsOnScreen(tmpRect); swipeRegion.op(tmpRect, Region.Op.UNION); - mMessageContainer.findViewById(R.id.message_dismiss_button).getBoundsOnScreen(tmpRect); - swipeRegion.op(tmpRect, Region.Op.UNION); + View messageDismiss = findViewById(R.id.message_dismiss_button); + if (messageDismiss != null) { + messageDismiss.getBoundsOnScreen(tmpRect); + swipeRegion.op(tmpRect, Region.Op.UNION); + } return swipeRegion; } @@ -333,7 +332,7 @@ public class ScreenshotView extends FrameLayout implements private void startInputListening() { stopInputListening(); - mInputMonitor = new InputMonitorCompat("Screenshot", Display.DEFAULT_DISPLAY); + mInputMonitor = new InputMonitorCompat("Screenshot", mDefaultDisplay); mInputEventReceiver = mInputMonitor.getInputReceiver( Looper.getMainLooper(), Choreographer.getInstance(), ev -> { if (ev instanceof MotionEvent) { @@ -358,39 +357,11 @@ public class ScreenshotView extends FrameLayout implements } } - /** - * Show a notification under the screenshot view indicating that a work profile screenshot has - * been taken and which app can be used to view it. - * - * @param appName The name of the app to use to view screenshots - * @param appIcon Optional icon for the relevant files app - * @param onDismiss Runnable to be run when the user dismisses this message - */ - @Override - public void showWorkProfileMessage(CharSequence appName, @Nullable Drawable appIcon, - Runnable onDismiss) { - if (appIcon != null) { - // Replace the default icon if one is provided. - ImageView imageView = mMessageContainer.findViewById(R.id.screenshot_message_icon); - imageView.setImageDrawable(appIcon); - } - mMessageContent.setText( - mContext.getString(R.string.screenshot_work_profile_notification, appName)); - mMessageContainer.setVisibility(VISIBLE); - mMessageContainer.findViewById(R.id.message_dismiss_button).setOnClickListener((v) -> { - mMessageContainer.setVisibility(View.GONE); - onDismiss.run(); - }); - } - @Override // View protected void onFinishInflate() { + super.onFinishInflate(); mScrollingScrim = requireNonNull(findViewById(R.id.screenshot_scrolling_scrim)); mScreenshotStatic = requireNonNull(findViewById(R.id.screenshot_static)); - mMessageContainer = - requireNonNull(mScreenshotStatic.findViewById(R.id.screenshot_message_container)); - mMessageContent = - requireNonNull(mMessageContainer.findViewById(R.id.screenshot_message_content)); mScreenshotPreview = requireNonNull(findViewById(R.id.screenshot_preview)); mScreenshotPreviewBorder = requireNonNull( @@ -491,6 +462,10 @@ public class ScreenshotView extends FrameLayout implements mPackageName = packageName; } + void setDefaultDisplay(int displayId) { + mDefaultDisplay = displayId; + } + void updateInsets(WindowInsets insets) { int orientation = mContext.getResources().getConfiguration().orientation; mOrientationPortrait = (orientation == ORIENTATION_PORTRAIT); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt index 5d7e56f6c98a..b4a07d4321a9 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt @@ -40,10 +40,10 @@ constructor( ) { /** - * Determine if a message should be shown to the user, send message details to messageDisplay if - * appropriate. + * Determine if a message should be shown to the user, send message details to + * MessageContainerController if appropriate. */ - fun onScreenshotTaken(userHandle: UserHandle, messageDisplay: WorkProfileMessageDisplay) { + fun onScreenshotTaken(userHandle: UserHandle, messageContainer: MessageContainerController) { if (userManager.isManagedProfile(userHandle.identifier) && !messageAlreadyDismissed()) { var badgedIcon: Drawable? = null var label: CharSequence? = null @@ -65,7 +65,9 @@ constructor( val badgedLabel = packageManager.getUserBadgedLabel(label ?: defaultFileAppName(), userHandle) - messageDisplay.showWorkProfileMessage(badgedLabel, badgedIcon) { onMessageDismissed() } + messageContainer.showWorkProfileMessage(badgedLabel, badgedIcon) { + onMessageDismissed() + } } } @@ -89,15 +91,6 @@ constructor( private fun defaultFileAppName() = context.getString(R.string.screenshot_default_files_app_name) - /** UI that can show work profile messages (ScreenshotView in practice) */ - interface WorkProfileMessageDisplay { - /** - * Show the given message and icon, calling onDismiss if the user explicitly dismisses the - * message. - */ - fun showWorkProfileMessage(text: CharSequence, icon: Drawable?, onDismiss: Runnable) - } - companion object { const val TAG = "WorkProfileMessageCtrl" const val SHARED_PREFERENCES_NAME = "com.android.systemui.screenshot" diff --git a/packages/SystemUI/src/com/android/systemui/settings/DisplayTracker.kt b/packages/SystemUI/src/com/android/systemui/settings/DisplayTracker.kt new file mode 100644 index 000000000000..bb7f721ad61f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/settings/DisplayTracker.kt @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.settings + +import android.view.Display +import java.util.concurrent.Executor + +/** + * Display tracker for SystemUI. + * + * This tracker provides async access to display information, as well as callbacks for display + * changes. + */ +interface DisplayTracker { + + /** The id for the default display for the current SystemUI instance. */ + val defaultDisplayId: Int + + /** All displays that should be associated with the current SystemUI instance. */ + val allDisplays: Array<Display> + + /** + * Add a [Callback] to be notified of display changes, including additions, removals, and + * configuration changes, on a particular [Executor]. + */ + fun addDisplayChangeCallback(callback: Callback, executor: Executor) + + /** + * Add a [Callback] to be notified of display brightness changes, on a particular [Executor]. + * This callback will trigger Callback#onDisplayChanged for a display brightness change. + */ + fun addBrightnessChangeCallback(callback: Callback, executor: Executor) + + /** Remove a [Callback] previously added. */ + fun removeCallback(callback: Callback) + + /** Ćallback for notifying of changes. */ + interface Callback { + + /** Notifies that a display has been added. */ + @JvmDefault fun onDisplayAdded(displayId: Int) {} + + /** Notifies that a display has been removed. */ + @JvmDefault fun onDisplayRemoved(displayId: Int) {} + + /** Notifies a display has been changed */ + @JvmDefault fun onDisplayChanged(displayId: Int) {} + } +} diff --git a/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt new file mode 100644 index 000000000000..5169f88c373c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.settings + +import android.hardware.display.DisplayManager +import android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS +import android.os.Handler +import android.view.Display +import androidx.annotation.GuardedBy +import androidx.annotation.VisibleForTesting +import androidx.annotation.WorkerThread +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.util.Assert +import java.lang.ref.WeakReference +import java.util.concurrent.Executor + +class DisplayTrackerImpl +internal constructor( + val displayManager: DisplayManager, + @Background val backgroundHandler: Handler +) : DisplayTracker { + override val defaultDisplayId: Int = Display.DEFAULT_DISPLAY + override val allDisplays: Array<Display> + get() = displayManager.displays + + @GuardedBy("displayCallbacks") + private val displayCallbacks: MutableList<DisplayTrackerDataItem> = ArrayList() + @GuardedBy("brightnessCallbacks") + private val brightnessCallbacks: MutableList<DisplayTrackerDataItem> = ArrayList() + + @VisibleForTesting + val displayChangedListener: DisplayManager.DisplayListener = + object : DisplayManager.DisplayListener { + override fun onDisplayAdded(displayId: Int) { + val list = synchronized(displayCallbacks) { displayCallbacks.toList() } + onDisplayAdded(displayId, list) + } + + override fun onDisplayRemoved(displayId: Int) { + val list = synchronized(displayCallbacks) { displayCallbacks.toList() } + onDisplayRemoved(displayId, list) + } + + override fun onDisplayChanged(displayId: Int) { + val list = synchronized(displayCallbacks) { displayCallbacks.toList() } + onDisplayChanged(displayId, list) + } + } + + @VisibleForTesting + val displayBrightnessChangedListener: DisplayManager.DisplayListener = + object : DisplayManager.DisplayListener { + override fun onDisplayAdded(displayId: Int) {} + + override fun onDisplayRemoved(displayId: Int) {} + + override fun onDisplayChanged(displayId: Int) { + val list = synchronized(brightnessCallbacks) { brightnessCallbacks.toList() } + onDisplayChanged(displayId, list) + } + } + + override fun addDisplayChangeCallback(callback: DisplayTracker.Callback, executor: Executor) { + synchronized(displayCallbacks) { + if (displayCallbacks.isEmpty()) { + displayManager.registerDisplayListener(displayChangedListener, backgroundHandler) + } + displayCallbacks.add(DisplayTrackerDataItem(WeakReference(callback), executor)) + } + } + + override fun addBrightnessChangeCallback( + callback: DisplayTracker.Callback, + executor: Executor + ) { + synchronized(brightnessCallbacks) { + if (brightnessCallbacks.isEmpty()) { + displayManager.registerDisplayListener( + displayBrightnessChangedListener, + backgroundHandler, + EVENT_FLAG_DISPLAY_BRIGHTNESS + ) + } + brightnessCallbacks.add(DisplayTrackerDataItem(WeakReference(callback), executor)) + } + } + + override fun removeCallback(callback: DisplayTracker.Callback) { + synchronized(displayCallbacks) { + val changed = displayCallbacks.removeIf { it.sameOrEmpty(callback) } + if (changed && displayCallbacks.isEmpty()) { + displayManager.unregisterDisplayListener(displayChangedListener) + } + } + + synchronized(brightnessCallbacks) { + val changed = brightnessCallbacks.removeIf { it.sameOrEmpty(callback) } + if (changed && brightnessCallbacks.isEmpty()) { + displayManager.unregisterDisplayListener(displayBrightnessChangedListener) + } + } + } + + @WorkerThread + private fun onDisplayAdded(displayId: Int, list: List<DisplayTrackerDataItem>) { + Assert.isNotMainThread() + + notifySubscribers({ onDisplayAdded(displayId) }, list) + } + + @WorkerThread + private fun onDisplayRemoved(displayId: Int, list: List<DisplayTrackerDataItem>) { + Assert.isNotMainThread() + + notifySubscribers({ onDisplayRemoved(displayId) }, list) + } + + @WorkerThread + private fun onDisplayChanged(displayId: Int, list: List<DisplayTrackerDataItem>) { + Assert.isNotMainThread() + + notifySubscribers({ onDisplayChanged(displayId) }, list) + } + + private inline fun notifySubscribers( + crossinline action: DisplayTracker.Callback.() -> Unit, + list: List<DisplayTrackerDataItem> + ) { + list.forEach { + if (it.callback.get() != null) { + it.executor.execute { it.callback.get()?.action() } + } + } + } + + private data class DisplayTrackerDataItem( + val callback: WeakReference<DisplayTracker.Callback>, + val executor: Executor + ) { + fun sameOrEmpty(other: DisplayTracker.Callback): Boolean { + return callback.get()?.equals(other) ?: true + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java index b69786ee625b..9594ba374fc3 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java @@ -27,10 +27,10 @@ import android.content.Context; import android.database.ContentObserver; import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManager; -import android.hardware.display.DisplayManager.DisplayListener; import android.net.Uri; import android.os.AsyncTask; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; @@ -49,6 +49,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.policy.BrightnessMirrorController; @@ -73,19 +74,14 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig private final ToggleSlider mControl; private final DisplayManager mDisplayManager; private final UserTracker mUserTracker; + private final DisplayTracker mDisplayTracker; private final IVrManager mVrManager; private final Executor mMainExecutor; private final Handler mBackgroundHandler; private final BrightnessObserver mBrightnessObserver; - private final DisplayListener mDisplayListener = new DisplayListener() { - @Override - public void onDisplayAdded(int displayId) {} - - @Override - public void onDisplayRemoved(int displayId) {} - + private final DisplayTracker.Callback mBrightnessListener = new DisplayTracker.Callback() { @Override public void onDisplayChanged(int displayId) { mBackgroundHandler.post(mUpdateSliderRunnable); @@ -133,14 +129,14 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig cr.registerContentObserver( BRIGHTNESS_MODE_URI, false, this, UserHandle.USER_ALL); - mDisplayManager.registerDisplayListener(mDisplayListener, mHandler, - DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS); + mDisplayTracker.addBrightnessChangeCallback(mBrightnessListener, + new HandlerExecutor(mHandler)); } public void stopObserving() { final ContentResolver cr = mContext.getContentResolver(); cr.unregisterContentObserver(this); - mDisplayManager.unregisterDisplayListener(mDisplayListener); + mDisplayTracker.removeCallback(mBrightnessListener); } } @@ -282,6 +278,7 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig Context context, ToggleSlider control, UserTracker userTracker, + DisplayTracker displayTracker, @Main Executor mainExecutor, @Background Handler bgHandler) { mContext = context; @@ -290,6 +287,7 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig mMainExecutor = mainExecutor; mBackgroundHandler = bgHandler; mUserTracker = userTracker; + mDisplayTracker = displayTracker; mBrightnessObserver = new BrightnessObserver(mHandler); mDisplayId = mContext.getDisplayId(); @@ -424,6 +422,7 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig public static class Factory { private final Context mContext; private final UserTracker mUserTracker; + private final DisplayTracker mDisplayTracker; private final Executor mMainExecutor; private final Handler mBackgroundHandler; @@ -431,10 +430,12 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig public Factory( Context context, UserTracker userTracker, + DisplayTracker displayTracker, @Main Executor mainExecutor, @Background Handler bgHandler) { mContext = context; mUserTracker = userTracker; + mDisplayTracker = displayTracker; mMainExecutor = mainExecutor; mBackgroundHandler = bgHandler; } @@ -445,6 +446,7 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig mContext, toggleSlider, mUserTracker, + mDisplayTracker, mMainExecutor, mBackgroundHandler); } diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java index e208be957510..8879501fa03d 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java @@ -36,6 +36,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import java.util.List; @@ -49,16 +50,19 @@ public class BrightnessDialog extends Activity { private BrightnessController mBrightnessController; private final BrightnessSliderController.Factory mToggleSliderFactory; private final UserTracker mUserTracker; + private final DisplayTracker mDisplayTracker; private final Executor mMainExecutor; private final Handler mBackgroundHandler; @Inject public BrightnessDialog( UserTracker userTracker, + DisplayTracker displayTracker, BrightnessSliderController.Factory factory, @Main Executor mainExecutor, @Background Handler bgHandler) { mUserTracker = userTracker; + mDisplayTracker = displayTracker; mToggleSliderFactory = factory; mMainExecutor = mainExecutor; mBackgroundHandler = bgHandler; @@ -106,7 +110,7 @@ public class BrightnessDialog extends Activity { frame.addView(controller.getRootView(), MATCH_PARENT, WRAP_CONTENT); mBrightnessController = new BrightnessController( - this, controller, mUserTracker, mMainExecutor, mBackgroundHandler); + this, controller, mUserTracker, mDisplayTracker, mMainExecutor, mBackgroundHandler); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java b/packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java index 809fa2976911..e9a1dd7e6ecb 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java +++ b/packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java @@ -19,6 +19,7 @@ package com.android.systemui.settings.dagger; import android.app.ActivityManager; import android.app.IActivityManager; import android.content.Context; +import android.hardware.display.DisplayManager; import android.os.Handler; import android.os.UserManager; @@ -26,6 +27,8 @@ import com.android.systemui.CoreStartable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dump.DumpManager; +import com.android.systemui.settings.DisplayTracker; +import com.android.systemui.settings.DisplayTrackerImpl; import com.android.systemui.settings.UserContentResolverProvider; import com.android.systemui.settings.UserContextProvider; import com.android.systemui.settings.UserFileManager; @@ -69,6 +72,15 @@ public abstract class MultiUserUtilsModule { return tracker; } + @SysUISingleton + @Provides + static DisplayTracker provideDisplayTracker( + DisplayManager displayManager, + @Background Handler handler + ) { + return new DisplayTrackerImpl(displayManager, handler); + } + @Binds @IntoMap @ClassKey(UserFileManagerImpl.class) diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java index 7ed6e3e55623..60fa865b83bc 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java @@ -160,12 +160,10 @@ public class NotificationShadeWindowViewController { // This view is not part of the newly inflated expanded status bar. mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container); - if (featureFlags.isEnabled(Flags.MODERN_BOUNCER)) { - KeyguardBouncerViewBinder.bind( - mView.findViewById(R.id.keyguard_bouncer_container), - keyguardBouncerViewModel, - keyguardBouncerComponentFactory); - } + KeyguardBouncerViewBinder.bind( + mView.findViewById(R.id.keyguard_bouncer_container), + keyguardBouncerViewModel, + keyguardBouncerComponentFactory); if (featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION)) { collectFlow(mView, keyguardTransitionInteractor.getLockscreenToDreamingTransition(), diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt index 85b259e54f37..de02115184b6 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt @@ -31,6 +31,7 @@ import com.android.systemui.R import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.fragments.FragmentService import com.android.systemui.navigationbar.NavigationModeController import com.android.systemui.plugins.qs.QS import com.android.systemui.plugins.qs.QSContainerController @@ -54,6 +55,7 @@ class NotificationsQSContainerController @Inject constructor( private val largeScreenShadeHeaderController: LargeScreenShadeHeaderController, private val shadeExpansionStateManager: ShadeExpansionStateManager, private val featureFlags: FeatureFlags, + private val fragmentService: FragmentService, @Main private val delayableExecutor: DelayableExecutor ) : ViewController<NotificationsQuickSettingsContainer>(view), QSContainerController { @@ -128,6 +130,7 @@ class NotificationsQSContainerController @Inject constructor( mView.setInsetsChangedListener(delayedInsetSetter) mView.setQSFragmentAttachedListener { qs: QS -> qs.setContainerController(this) } mView.setConfigurationChangedListener { updateResources() } + fragmentService.getFragmentHostManager(mView).addTagListener(QS.TAG, mView) } override fun onViewDetached() { @@ -136,6 +139,7 @@ class NotificationsQSContainerController @Inject constructor( mView.removeOnInsetsChangedListener() mView.removeQSFragmentAttachedListener() mView.setConfigurationChangedListener(null) + fragmentService.getFragmentHostManager(mView).removeTagListener(QS.TAG, mView) } fun updateResources() { diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java index 02316b7965ca..f73dde632051 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java @@ -29,7 +29,6 @@ import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; import com.android.systemui.R; -import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; import com.android.systemui.plugins.qs.QS; import com.android.systemui.statusbar.notification.AboveShelfObserver; @@ -133,18 +132,6 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout } @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - FragmentHostManager.get(this).addTagListener(QS.TAG, this); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - FragmentHostManager.get(this).removeTagListener(QS.TAG, this); - } - - @Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { mInsetsChangedListener.accept(insets); return insets; diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt index b02a45a913db..393279b0b054 100644 --- a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt +++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt @@ -18,7 +18,6 @@ package com.android.systemui.smartspace.dagger import com.android.systemui.plugins.BcSmartspaceDataPlugin import com.android.systemui.smartspace.SmartspacePrecondition import com.android.systemui.smartspace.SmartspaceTargetFilter -import com.android.systemui.smartspace.filters.LockscreenAndDreamTargetFilter import com.android.systemui.smartspace.preconditions.LockscreenPrecondition import dagger.Binds import dagger.BindsOptionalOf @@ -35,11 +34,6 @@ abstract class SmartspaceModule { const val DREAM_SMARTSPACE_DATA_PLUGIN = "dreams_smartspace_data_plugin" /** - * The lockscreen smartspace target filter. - */ - const val LOCKSCREEN_SMARTSPACE_TARGET_FILTER = "lockscreen_smartspace_target_filter" - - /** * The dream smartspace target filter. */ const val DREAM_SMARTSPACE_TARGET_FILTER = "dream_smartspace_target_filter" @@ -48,6 +42,11 @@ abstract class SmartspaceModule { * The precondition for dream smartspace */ const val DREAM_SMARTSPACE_PRECONDITION = "dream_smartspace_precondition" + + /** + * The BcSmartspaceDataPlugin for the standalone weather. + */ + const val WEATHER_SMARTSPACE_DATA_PLUGIN = "weather_smartspace_data_plugin" } @BindsOptionalOf @@ -59,12 +58,6 @@ abstract class SmartspaceModule { abstract fun optionalDreamsBcSmartspaceDataPlugin(): BcSmartspaceDataPlugin? @Binds - @Named(LOCKSCREEN_SMARTSPACE_TARGET_FILTER) - abstract fun provideLockscreenSmartspaceTargetFilter( - filter: LockscreenAndDreamTargetFilter? - ): SmartspaceTargetFilter? - - @Binds @Named(DREAM_SMARTSPACE_PRECONDITION) abstract fun bindSmartspacePrecondition( lockscreenPrecondition: LockscreenPrecondition? diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedButton.java index 87c12c25a0a5..6577cf696b61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedButton.java @@ -20,10 +20,21 @@ import android.content.Context; import android.util.AttributeSet; import android.widget.Button; +import com.android.systemui.animation.LaunchableView; +import com.android.systemui.animation.LaunchableViewDelegate; + +import kotlin.Unit; + /** * A Button which doesn't have overlapping drawing commands */ -public class AlphaOptimizedButton extends Button { +public class AlphaOptimizedButton extends Button implements LaunchableView { + private LaunchableViewDelegate mDelegate = new LaunchableViewDelegate(this, + (visibility) -> { + super.setVisibility(visibility); + return Unit.INSTANCE; + }); + public AlphaOptimizedButton(Context context) { super(context); } @@ -45,4 +56,14 @@ public class AlphaOptimizedButton extends Button { public boolean hasOverlappingRendering() { return false; } + + @Override + public void setShouldBlockVisibilityChanges(boolean block) { + mDelegate.setShouldBlockVisibilityChanges(block); + } + + @Override + public void setVisibility(int visibility) { + mDelegate.setVisibility(visibility); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index a0a7586c6a7a..3aaad87b8eab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -20,7 +20,6 @@ import static android.app.StatusBarManager.DISABLE2_NONE; import static android.app.StatusBarManager.DISABLE_NONE; import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT; import static android.inputmethodservice.InputMethodService.IME_INVISIBLE; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import android.annotation.Nullable; @@ -38,7 +37,6 @@ import android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode; import android.hardware.biometrics.IBiometricContextListener; import android.hardware.biometrics.IBiometricSysuiReceiver; import android.hardware.biometrics.PromptInfo; -import android.hardware.display.DisplayManager; import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback; import android.inputmethodservice.InputMethodService.BackDispositionMode; import android.media.INearbyMediaDevicesProvider; @@ -46,6 +44,7 @@ import android.media.MediaRoute2Info; import android.os.Binder; import android.os.Bundle; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.IBinder; import android.os.Looper; import android.os.Message; @@ -60,6 +59,7 @@ import android.view.WindowInsetsController.Appearance; import android.view.WindowInsetsController.Behavior; import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; import com.android.internal.os.SomeArgs; import com.android.internal.statusbar.IAddTileResultCallback; @@ -70,6 +70,7 @@ import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.util.GcUtils; import com.android.internal.view.AppearanceRegion; import com.android.systemui.dump.DumpHandler; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.statusbar.CommandQueue.Callbacks; import com.android.systemui.statusbar.commandline.CommandRegistry; import com.android.systemui.statusbar.policy.CallbackController; @@ -89,8 +90,7 @@ import java.util.ArrayList; * are coalesced, note that they are all idempotent. */ public class CommandQueue extends IStatusBar.Stub implements - CallbackController<Callbacks>, - DisplayManager.DisplayListener { + CallbackController<Callbacks> { private static final String TAG = CommandQueue.class.getSimpleName(); private static final int INDEX_MASK = 0xffff; @@ -189,6 +189,7 @@ public class CommandQueue extends IStatusBar.Stub implements * event. */ private int mLastUpdatedImeDisplayId = INVALID_DISPLAY; + private final DisplayTracker mDisplayTracker; private ProtoTracer mProtoTracer; private final @Nullable CommandRegistry mRegistry; private final @Nullable DumpHandler mDumpHandler; @@ -351,7 +352,7 @@ public class CommandQueue extends IStatusBar.Stub implements } /** - * @see DisplayManager.DisplayListener#onDisplayRemoved(int) + * @see DisplayTracker.Callback#onDisplayRemoved(int) */ default void onDisplayRemoved(int displayId) { } @@ -500,46 +501,43 @@ public class CommandQueue extends IStatusBar.Stub implements default void showMediaOutputSwitcher(String packageName) {} } - public CommandQueue(Context context) { - this(context, null, null, null); + @VisibleForTesting + public CommandQueue(Context context, DisplayTracker displayTracker) { + this(context, displayTracker, null, null, null); } public CommandQueue( Context context, + DisplayTracker displayTracker, ProtoTracer protoTracer, CommandRegistry registry, DumpHandler dumpHandler ) { + mDisplayTracker = displayTracker; mProtoTracer = protoTracer; mRegistry = registry; mDumpHandler = dumpHandler; - context.getSystemService(DisplayManager.class).registerDisplayListener(this, mHandler); + mDisplayTracker.addDisplayChangeCallback(new DisplayTracker.Callback() { + @Override + public void onDisplayRemoved(int displayId) { + synchronized (mLock) { + mDisplayDisabled.remove(displayId); + } + // This callback is registered with {@link #mHandler} that already posts to run on + // main thread, so it is safe to dispatch directly. + for (int i = mCallbacks.size() - 1; i >= 0; i--) { + mCallbacks.get(i).onDisplayRemoved(displayId); + } + } + }, new HandlerExecutor(mHandler)); // We always have default display. - setDisabled(DEFAULT_DISPLAY, DISABLE_NONE, DISABLE2_NONE); + setDisabled(mDisplayTracker.getDefaultDisplayId(), DISABLE_NONE, DISABLE2_NONE); } - @Override - public void onDisplayAdded(int displayId) { } - - @Override - public void onDisplayRemoved(int displayId) { - synchronized (mLock) { - mDisplayDisabled.remove(displayId); - } - // This callback is registered with {@link #mHandler} that already posts to run on main - // thread, so it is safe to dispatch directly. - for (int i = mCallbacks.size() - 1; i >= 0; i--) { - mCallbacks.get(i).onDisplayRemoved(displayId); - } - } - - @Override - public void onDisplayChanged(int displayId) { } - // TODO(b/118592525): add multi-display support if needed. public boolean panelsEnabled() { - final int disabled1 = getDisabled1(DEFAULT_DISPLAY); - final int disabled2 = getDisabled2(DEFAULT_DISPLAY); + final int disabled1 = getDisabled1(mDisplayTracker.getDefaultDisplayId()); + final int disabled2 = getDisabled2(mDisplayTracker.getDefaultDisplayId()); return (disabled1 & StatusBarManager.DISABLE_EXPAND) == 0 && (disabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java index 098c6175a93e..d7568a9bd89c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java @@ -39,6 +39,7 @@ import com.android.systemui.media.controls.pipeline.MediaDataManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.carrier.QSCarrierGroupController; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.statusbar.ActionClickLogger; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.MediaArtworkProcessor; @@ -184,11 +185,12 @@ public interface CentralSurfacesDependenciesModule { @SysUISingleton static CommandQueue provideCommandQueue( Context context, + DisplayTracker displayTracker, ProtoTracer protoTracer, CommandRegistry registry, DumpHandler dumpHandler ) { - return new CommandQueue(context, protoTracer, registry, dumpHandler); + return new CommandQueue(context, displayTracker, protoTracer, registry, dumpHandler); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt index 3a4731a5a6aa..92a8356b7f07 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt @@ -20,9 +20,9 @@ package com.android.systemui.statusbar.gesture import android.annotation.CallSuper import android.os.Looper import android.view.Choreographer -import android.view.Display import android.view.InputEvent import android.view.MotionEvent +import com.android.systemui.settings.DisplayTracker import com.android.systemui.shared.system.InputChannelCompat import com.android.systemui.shared.system.InputMonitorCompat @@ -38,7 +38,8 @@ import com.android.systemui.shared.system.InputMonitorCompat * gesture is detected, they should call [onGestureDetected] (which will notify the callbacks). */ abstract class GenericGestureDetector( - private val tag: String + private val tag: String, + private val displayTracker: DisplayTracker ) { /** * Active callbacks, each associated with a tag. Gestures will only be monitored if @@ -86,7 +87,7 @@ abstract class GenericGestureDetector( internal open fun startGestureListening() { stopGestureListening() - inputMonitor = InputMonitorCompat(tag, Display.DEFAULT_DISPLAY).also { + inputMonitor = InputMonitorCompat(tag, displayTracker.defaultDisplayId).also { inputReceiver = it.getInputReceiver( Looper.getMainLooper(), Choreographer.getInstance(), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt index 5ab3d7ce9bec..693ae6617feb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.gesture import android.content.Context import android.view.MotionEvent import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.settings.DisplayTracker import com.android.systemui.statusbar.window.StatusBarWindowController import javax.inject.Inject @@ -28,9 +29,10 @@ class SwipeStatusBarAwayGestureHandler @Inject constructor( context: Context, + displayTracker: DisplayTracker, logger: SwipeUpGestureLogger, private val statusBarWindowController: StatusBarWindowController, -) : SwipeUpGestureHandler(context, logger, loggerTag = LOGGER_TAG) { +) : SwipeUpGestureHandler(context, displayTracker, logger, loggerTag = LOGGER_TAG) { override fun startOfGestureIsWithinBounds(ev: MotionEvent): Boolean { // Gesture starts just below the status bar return ev.y >= statusBarWindowController.statusBarHeight && diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt index 5ecc35ca4576..6d60f4a9affa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt @@ -24,6 +24,7 @@ import android.view.MotionEvent.ACTION_DOWN import android.view.MotionEvent.ACTION_MOVE import android.view.MotionEvent.ACTION_UP import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.settings.DisplayTracker /** * A class to detect a generic "swipe up" gesture. To be notified when the swipe up gesture is @@ -32,9 +33,10 @@ import com.android.systemui.dagger.SysUISingleton @SysUISingleton abstract class SwipeUpGestureHandler( context: Context, + displayTracker: DisplayTracker, private val logger: SwipeUpGestureLogger, private val loggerTag: String, -) : GenericGestureDetector(SwipeUpGestureHandler::class.simpleName!!) { +) : GenericGestureDetector(SwipeUpGestureHandler::class.simpleName!!, displayTracker) { private var startY: Float = 0f private var startTime: Long = 0L diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/TapGestureDetector.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/TapGestureDetector.kt index 7ffb07aa77d0..a901d5979576 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/TapGestureDetector.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/TapGestureDetector.kt @@ -21,6 +21,7 @@ import android.view.GestureDetector import android.view.InputEvent import android.view.MotionEvent import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.settings.DisplayTracker import javax.inject.Inject /** @@ -29,8 +30,9 @@ import javax.inject.Inject */ @SysUISingleton class TapGestureDetector @Inject constructor( - private val context: Context -) : GenericGestureDetector(TapGestureDetector::class.simpleName!!) { + private val context: Context, + displayTracker: DisplayTracker +) : GenericGestureDetector(TapGestureDetector::class.simpleName!!, displayTracker) { private val gestureListener = object : GestureDetector.SimpleOnGestureListener() { override fun onSingleTapUp(e: MotionEvent): Boolean { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt index daed28611f93..5b62d3068030 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt @@ -52,6 +52,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.settings.UserTracker import com.android.systemui.shared.regionsampling.RegionSampler import com.android.systemui.shared.regionsampling.UpdateColorCallback +import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.WEATHER_SMARTSPACE_DATA_PLUGIN import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.DeviceProvisionedController @@ -60,6 +61,7 @@ import com.android.systemui.util.settings.SecureSettings import java.util.Optional import java.util.concurrent.Executor import javax.inject.Inject +import javax.inject.Named /** Controller for managing the smartspace view on the lockscreen */ @SysUISingleton @@ -82,6 +84,8 @@ constructor( @Main private val uiExecutor: Executor, @Background private val bgExecutor: Executor, @Main private val handler: Handler, + @Named(WEATHER_SMARTSPACE_DATA_PLUGIN) + optionalWeatherPlugin: Optional<BcSmartspaceDataPlugin>, optionalPlugin: Optional<BcSmartspaceDataPlugin>, optionalConfigPlugin: Optional<BcSmartspaceConfigPlugin>, ) { @@ -90,6 +94,7 @@ constructor( } private var session: SmartspaceSession? = null + private val weatherPlugin: BcSmartspaceDataPlugin? = optionalWeatherPlugin.orElse(null) private val plugin: BcSmartspaceDataPlugin? = optionalPlugin.orElse(null) private val configPlugin: BcSmartspaceConfigPlugin? = optionalConfigPlugin.orElse(null) @@ -132,6 +137,10 @@ constructor( private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets -> execution.assertIsMainThread() + + // The weather data plugin takes unfiltered targets and performs the filtering internally. + weatherPlugin?.onTargetsAvailable(targets) + val filteredTargets = targets.filter(::filterSmartspaceTarget) plugin?.onTargetsAvailable(filteredTargets) if (!isContentUpdatedOnce) { @@ -210,32 +219,58 @@ constructor( return plugin != null } + fun isDateWeatherDecoupled(): Boolean { + execution.assertIsMainThread() + + return featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED) && + weatherPlugin != null + } + private fun updateBypassEnabled() { val bypassEnabled = bypassController.bypassEnabled smartspaceViews.forEach { it.setKeyguardBypassEnabled(bypassEnabled) } } /** - * Constructs the smartspace view and connects it to the smartspace service. + * Constructs the weather view and connects it to the smartspace service. */ - fun buildAndConnectView(parent: ViewGroup): View? { + fun buildAndConnectWeatherView(parent: ViewGroup): View? { execution.assertIsMainThread() if (!isEnabled()) { throw RuntimeException("Cannot build view when not enabled") } + if (!isDateWeatherDecoupled()) { + throw RuntimeException("Cannot build weather view when not decoupled") + } - val view = buildView(parent) + val view = buildView(parent, weatherPlugin) connectSession() return view } - fun requestSmartspaceUpdate() { - session?.requestSmartspaceUpdate() + /** + * Constructs the smartspace view and connects it to the smartspace service. + */ + fun buildAndConnectView(parent: ViewGroup): View? { + execution.assertIsMainThread() + + if (!isEnabled()) { + throw RuntimeException("Cannot build view when not enabled") + } + + val view = buildView(parent, plugin, configPlugin) + connectSession() + + return view } - private fun buildView(parent: ViewGroup): View? { + private fun buildView( + parent: ViewGroup, + plugin: BcSmartspaceDataPlugin?, + configPlugin: BcSmartspaceConfigPlugin? = null + ): View? { if (plugin == null) { return null } @@ -243,7 +278,7 @@ constructor( val ssView = plugin.getView(parent) ssView.setUiSurface(BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD) ssView.registerDataProvider(plugin) - ssView.registerConfigProvider(configPlugin) + configPlugin?.let { ssView.registerConfigProvider(it) } ssView.setIntentStarter(object : BcSmartspaceDataPlugin.IntentStarter { override fun startIntent(view: View, intent: Intent, showOnLockscreen: Boolean) { @@ -274,7 +309,8 @@ constructor( } private fun connectSession() { - if (plugin == null || session != null || smartspaceViews.isEmpty()) { + if (weatherPlugin == null && plugin == null) return + if (session != null || smartspaceViews.isEmpty()) { return } @@ -311,15 +347,21 @@ constructor( statusBarStateController.addCallback(statusBarStateListener) bypassController.registerOnBypassStateChangedListener(bypassStateChangedListener) - plugin.registerSmartspaceEventNotifier { - e -> session?.notifySmartspaceEvent(e) - } + weatherPlugin?.registerSmartspaceEventNotifier { e -> session?.notifySmartspaceEvent(e) } + plugin?.registerSmartspaceEventNotifier { e -> session?.notifySmartspaceEvent(e) } updateBypassEnabled() reloadSmartspace() } /** + * Requests the smartspace session for an update. + */ + fun requestSmartspaceUpdate() { + session?.requestSmartspaceUpdate() + } + + /** * Disconnects the smartspace view from the smartspace service and cleans up any resources. */ fun disconnect() { @@ -342,9 +384,13 @@ constructor( bypassController.unregisterOnBypassStateChangedListener(bypassStateChangedListener) session = null + weatherPlugin?.registerSmartspaceEventNotifier(null) + weatherPlugin?.onTargetsAvailable(emptyList()) + plugin?.registerSmartspaceEventNotifier(null) plugin?.onTargetsAvailable(emptyList()) - Log.d(TAG, "Ending smartspace session for lockscreen") + + Log.d(TAG, "Ended smartspace session for lockscreen") } fun addListener(listener: SmartspaceTargetListener) { @@ -358,8 +404,11 @@ constructor( } private fun filterSmartspaceTarget(t: SmartspaceTarget): Boolean { + if (isDateWeatherDecoupled()) { + return t.featureType != SmartspaceTarget.FEATURE_WEATHER + } if (!showNotifications) { - return t.getFeatureType() == SmartspaceTarget.FEATURE_WEATHER + return t.featureType == SmartspaceTarget.FEATURE_WEATHER } return when (t.userHandle) { userTracker.userHandle -> { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java index 058042c4bccd..0c95eab979a5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java @@ -71,11 +71,9 @@ public class DeviceProvisionedCoordinator implements Coordinator { * marking them as relevant for setup are allowed to show when device is unprovisioned */ private boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) { - final boolean hasPermission = checkUidPermission( - Manifest.permission.NOTIFICATION_DURING_SETUP, - sbn.getUid()) == PackageManager.PERMISSION_GRANTED; - return hasPermission - && sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP); + // system_server checks the permission so systemui can just check whether the + // extra exists + return sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP); } private int checkUidPermission(String permission, int uid) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index b86c243b0d12..e595ddf46a89 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -1308,8 +1308,13 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { // Set up the quick settings tile panel final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame); if (container != null) { - FragmentHostManager fragmentHostManager = FragmentHostManager.get(container); - ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame, + FragmentHostManager fragmentHostManager = + mFragmentService.getFragmentHostManager(container); + ExtensionFragmentListener.attachExtensonToFragment( + mFragmentService, + container, + QS.TAG, + R.id.qs_frame, mExtensionController .newExtension(QS.class) .withPlugin(QS.class) @@ -1480,7 +1485,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } protected QS createDefaultQSFragment() { - return FragmentHostManager.get(mNotificationShadeWindowView).create(QSFragment.class); + return mFragmentService + .getFragmentHostManager(mNotificationShadeWindowView) + .create(QSFragment.class); } private void setUpPresenter() { @@ -3773,6 +3780,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { }); } else if (mDozing && !unlocking) { mScrimController.transitionTo(ScrimState.AOD); + // This will cancel the keyguardFadingAway animation if it is running. We need to do + // this as otherwise it can remain pending and leave keyguard in a weird state. + mUnlockScrimCallback.onCancelled(); } else if (mKeyguardStateController.isShowing() && !isOccluded() && !unlocking) { mScrimController.transitionTo(ScrimState.KEYGUARD); } else if (mKeyguardStateController.isShowing() && mKeyguardUpdateMonitor.isDreaming() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java index 4d1454232853..fe2a9137c1a9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.phone; -import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; @@ -38,6 +37,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.statusbar.policy.BatteryController; import java.io.PrintWriter; @@ -94,7 +94,8 @@ public class LightBarController implements BatteryController.BatteryStateChangeC DarkIconDispatcher darkIconDispatcher, BatteryController batteryController, NavigationModeController navModeController, - DumpManager dumpManager) { + DumpManager dumpManager, + DisplayTracker displayTracker) { mDarkIconColor = ctx.getColor(R.color.dark_mode_icon_color_single_tone); mLightIconColor = ctx.getColor(R.color.light_mode_icon_color_single_tone); mStatusBarIconController = (SysuiDarkIconDispatcher) darkIconDispatcher; @@ -104,7 +105,7 @@ public class LightBarController implements BatteryController.BatteryStateChangeC mNavigationMode = mode; }); - if (ctx.getDisplayId() == DEFAULT_DISPLAY) { + if (ctx.getDisplayId() == displayTracker.getDefaultDisplayId()) { dumpManager.registerDumpable(getClass().getSimpleName(), this); } } @@ -317,24 +318,27 @@ public class LightBarController implements BatteryController.BatteryStateChangeC private final BatteryController mBatteryController; private final NavigationModeController mNavModeController; private final DumpManager mDumpManager; + private final DisplayTracker mDisplayTracker; @Inject public Factory( DarkIconDispatcher darkIconDispatcher, BatteryController batteryController, NavigationModeController navModeController, - DumpManager dumpManager) { + DumpManager dumpManager, + DisplayTracker displayTracker) { mDarkIconDispatcher = darkIconDispatcher; mBatteryController = batteryController; mNavModeController = navModeController; mDumpManager = dumpManager; + mDisplayTracker = displayTracker; } /** Create an {@link LightBarController} */ public LightBarController create(Context context) { return new LightBarController(context, mDarkIconDispatcher, mBatteryController, - mNavModeController, mDumpManager); + mNavModeController, mDumpManager, mDisplayTracker); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt index 2c8677dee4d9..2d80edb8d2f4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt @@ -19,14 +19,14 @@ package com.android.systemui.statusbar.phone.userswitcher import android.content.Context import android.util.AttributeSet import android.widget.ImageView -import android.widget.LinearLayout import android.widget.TextView import com.android.systemui.R +import com.android.systemui.common.ui.view.LaunchableLinearLayout class StatusBarUserSwitcherContainer( context: Context?, attrs: AttributeSet? -) : LinearLayout(context, attrs) { +) : LaunchableLinearLayout(context, attrs) { lateinit var text: TextView private set lateinit var avatar: ImageView diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java index afcf7a9ec66d..853de7b5ecab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java @@ -53,6 +53,7 @@ import com.android.systemui.animation.DelegateLaunchAnimatorController; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.fragments.FragmentHostManager; +import com.android.systemui.fragments.FragmentService; import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider; import com.android.systemui.unfold.UnfoldTransitionProgressProvider; import com.android.systemui.unfold.util.JankMonitorTransitionProgressListener; @@ -78,6 +79,7 @@ public class StatusBarWindowController { private boolean mIsAttached; private final ViewGroup mStatusBarWindowView; + private final FragmentService mFragmentService; // The container in which we should run launch animations started from the status bar and // expanding into the opening window. private final ViewGroup mLaunchAnimationContainer; @@ -91,6 +93,7 @@ public class StatusBarWindowController { WindowManager windowManager, IWindowManager iWindowManager, StatusBarContentInsetsProvider contentInsetsProvider, + FragmentService fragmentService, @Main Resources resources, Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider) { mContext = context; @@ -98,6 +101,7 @@ public class StatusBarWindowController { mIWindowManager = iWindowManager; mContentInsetsProvider = contentInsetsProvider; mStatusBarWindowView = statusBarWindowView; + mFragmentService = fragmentService; mLaunchAnimationContainer = mStatusBarWindowView.findViewById( R.id.status_bar_launch_animation_container); mLpChanged = new WindowManager.LayoutParams(); @@ -162,7 +166,7 @@ public class StatusBarWindowController { /** Returns a fragment host manager for the status bar window view. */ public FragmentHostManager getFragmentHostManager() { - return FragmentHostManager.get(mStatusBarWindowView); + return mFragmentService.getFragmentHostManager(mStatusBarWindowView); } /** diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandler.kt index 6e3cb4823afa..9dbc4b398ab3 100644 --- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandler.kt @@ -19,6 +19,7 @@ package com.android.systemui.temporarydisplay.chipbar import android.content.Context import android.view.MotionEvent import android.view.View +import com.android.systemui.settings.DisplayTracker import com.android.systemui.statusbar.gesture.SwipeUpGestureHandler import com.android.systemui.statusbar.gesture.SwipeUpGestureLogger import com.android.systemui.util.boundsOnScreen @@ -31,8 +32,9 @@ import com.android.systemui.util.boundsOnScreen */ class SwipeChipbarAwayGestureHandler( context: Context, + displayTracker: DisplayTracker, logger: SwipeUpGestureLogger, -) : SwipeUpGestureHandler(context, logger, loggerTag = LOGGER_TAG) { +) : SwipeUpGestureHandler(context, displayTracker, logger, loggerTag = LOGGER_TAG) { private var viewFetcher: () -> View? = { null } diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/dagger/TemporaryDisplayModule.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/dagger/TemporaryDisplayModule.kt index 933c0604a3b9..b1be4045eb43 100644 --- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/dagger/TemporaryDisplayModule.kt +++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/dagger/TemporaryDisplayModule.kt @@ -21,6 +21,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.log.LogBufferFactory import com.android.systemui.media.taptotransfer.MediaTttFlags import com.android.systemui.plugins.log.LogBuffer +import com.android.systemui.settings.DisplayTracker import com.android.systemui.statusbar.gesture.SwipeUpGestureLogger import com.android.systemui.temporarydisplay.chipbar.SwipeChipbarAwayGestureHandler import dagger.Module @@ -41,10 +42,11 @@ interface TemporaryDisplayModule { fun provideSwipeChipbarAwayGestureHandler( mediaTttFlags: MediaTttFlags, context: Context, + displayTracker: DisplayTracker, logger: SwipeUpGestureLogger, ): SwipeChipbarAwayGestureHandler? { return if (mediaTttFlags.isMediaTttDismissGestureEnabled()) { - SwipeChipbarAwayGestureHandler(context, logger) + SwipeChipbarAwayGestureHandler(context, displayTracker, logger) } else { null } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java index 79811c5de42d..24758908cff2 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java @@ -28,8 +28,9 @@ import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settingslib.Utils; +import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.fragments.FragmentHostManager; +import com.android.systemui.fragments.FragmentService; import java.util.Objects; @@ -74,7 +75,7 @@ public class RadioListPreference extends CustomListPreference { RadioFragment f = new RadioFragment(); f.setPreference(this); - FragmentHostManager.get(v).getFragmentManager() + Dependency.get(FragmentService.class).getFragmentHostManager(v).getFragmentManager() .beginTransaction() .add(android.R.id.content, f) .commit(); @@ -86,8 +87,10 @@ public class RadioListPreference extends CustomListPreference { Bundle savedInstanceState) { super.onDialogStateRestored(fragment, dialog, savedInstanceState); View view = dialog.findViewById(R.id.content); - RadioFragment radioFragment = (RadioFragment) FragmentHostManager.get(view) - .getFragmentManager().findFragmentById(R.id.content); + RadioFragment radioFragment = (RadioFragment) Dependency.get(FragmentService.class) + .getFragmentHostManager(view) + .getFragmentManager() + .findFragmentById(R.id.content); if (radioFragment != null) { radioFragment.setPreference(this); } diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt index 0069bb545ef4..19a0866cd0a8 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt @@ -38,6 +38,7 @@ import android.view.WindowlessWindowManager import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.settings.DisplayTracker import com.android.systemui.statusbar.LightRevealEffect import com.android.systemui.statusbar.LightRevealScrim import com.android.systemui.statusbar.LinearLightRevealEffect @@ -68,6 +69,7 @@ constructor( @Main private val executor: Executor, private val threadFactory: ThreadFactory, private val rotationChangeProvider: RotationChangeProvider, + private val displayTracker: DisplayTracker ) { private val transitionListener = TransitionListener() @@ -104,7 +106,7 @@ constructor( .setName("unfold-overlay-container") displayAreaHelper.get().attachToRootDisplayArea( - Display.DEFAULT_DISPLAY, + displayTracker.defaultDisplayId, containerBuilder ) { builder -> executor.execute { diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java index d54de3fa9a3f..c2727fc32465 100644 --- a/packages/SystemUI/src/com/android/systemui/util/Utils.java +++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java @@ -14,8 +14,6 @@ package com.android.systemui.util; -import static android.view.Display.DEFAULT_DISPLAY; - import android.Manifest; import android.content.Context; import android.content.Intent; @@ -26,6 +24,7 @@ import android.view.DisplayCutout; import com.android.internal.policy.SystemBarUtils; import com.android.systemui.R; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.shared.system.QuickStepContract; import java.util.List; @@ -71,8 +70,9 @@ public class Utils { * {@link android.view.WindowManagerPolicyConstants#NAV_BAR_MODE_GESTURAL} AND * the context is that of the default display */ - public static boolean isGesturalModeOnDefaultDisplay(Context context, int navMode) { - return context.getDisplayId() == DEFAULT_DISPLAY + public static boolean isGesturalModeOnDefaultDisplay(Context context, + DisplayTracker displayTracker, int navMode) { + return context.getDisplayId() == displayTracker.getDefaultDisplayId() && QuickStepContract.isGesturalMode(navMode); } diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt index 08ee0af17fb0..56c5d3b433ff 100644 --- a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt @@ -27,6 +27,8 @@ import android.view.ViewTreeObserver import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet +import com.android.systemui.animation.LaunchableView +import com.android.systemui.animation.LaunchableViewDelegate import com.android.systemui.statusbar.CrossFadeHelper /** @@ -38,7 +40,7 @@ class TransitionLayout @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : ConstraintLayout(context, attrs, defStyleAttr) { +) : ConstraintLayout(context, attrs, defStyleAttr), LaunchableView { private val boundsRect = Rect() private val originalGoneChildrenSet: MutableSet<Int> = mutableSetOf() @@ -50,7 +52,11 @@ class TransitionLayout @JvmOverloads constructor( private var desiredMeasureWidth = 0 private var desiredMeasureHeight = 0 - private var transitionVisibility = View.VISIBLE + private val delegate = + LaunchableViewDelegate( + this, + superSetVisibility = { super.setVisibility(it) }, + ) /** * The measured state of this view which is the one we will lay ourselves out with. This @@ -83,11 +89,12 @@ class TransitionLayout @JvmOverloads constructor( } } - override fun setTransitionVisibility(visibility: Int) { - // We store the last transition visibility assigned to this view to restore it later if - // necessary. - super.setTransitionVisibility(visibility) - transitionVisibility = visibility + override fun setShouldBlockVisibilityChanges(block: Boolean) { + delegate.setShouldBlockVisibilityChanges(block) + } + + override fun setVisibility(visibility: Int) { + delegate.setVisibility(visibility) } override fun onFinishInflate() { @@ -173,14 +180,6 @@ class TransitionLayout @JvmOverloads constructor( translationY = currentState.translation.y CrossFadeHelper.fadeIn(this, currentState.alpha) - - // CrossFadeHelper#fadeIn will change this view visibility, which overrides the transition - // visibility. We set the transition visibility again to make sure that this view plays well - // with GhostView, which sets the transition visibility and is used for activity launch - // animations. - if (transitionVisibility != View.VISIBLE) { - setTransitionVisibility(transitionVisibility) - } } private fun applyCurrentStateOnPredraw() { diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index 8ef98f08c60d..bd60401034b3 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -16,8 +16,6 @@ package com.android.systemui.wmshell; -import static android.view.Display.DEFAULT_DISPLAY; - import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED; @@ -50,6 +48,7 @@ import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.model.SysUiState; import com.android.systemui.notetask.NoteTaskInitializer; +import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.shared.tracing.ProtoTraceable; import com.android.systemui.statusbar.CommandQueue; @@ -124,6 +123,7 @@ public final class WMShell implements private final WakefulnessLifecycle mWakefulnessLifecycle; private final ProtoTracer mProtoTracer; private final UserTracker mUserTracker; + private final DisplayTracker mDisplayTracker; private final NoteTaskInitializer mNoteTaskInitializer; private final Executor mSysUiMainExecutor; @@ -186,6 +186,7 @@ public final class WMShell implements ProtoTracer protoTracer, WakefulnessLifecycle wakefulnessLifecycle, UserTracker userTracker, + DisplayTracker displayTracker, NoteTaskInitializer noteTaskInitializer, @Main Executor sysUiMainExecutor) { mContext = context; @@ -203,6 +204,7 @@ public final class WMShell implements mWakefulnessLifecycle = wakefulnessLifecycle; mProtoTracer = protoTracer; mUserTracker = userTracker; + mDisplayTracker = displayTracker; mNoteTaskInitializer = noteTaskInitializer; mSysUiMainExecutor = sysUiMainExecutor; } @@ -268,7 +270,7 @@ public final class WMShell implements public void onStartTransition(boolean isEntering) { mSysUiMainExecutor.execute(() -> { mSysUiState.setFlag(SYSUI_STATE_ONE_HANDED_ACTIVE, - true).commitUpdate(DEFAULT_DISPLAY); + true).commitUpdate(mDisplayTracker.getDefaultDisplayId()); }); } @@ -276,7 +278,7 @@ public final class WMShell implements public void onStartFinished(Rect bounds) { mSysUiMainExecutor.execute(() -> { mSysUiState.setFlag(SYSUI_STATE_ONE_HANDED_ACTIVE, - true).commitUpdate(DEFAULT_DISPLAY); + true).commitUpdate(mDisplayTracker.getDefaultDisplayId()); }); } @@ -284,7 +286,7 @@ public final class WMShell implements public void onStopFinished(Rect bounds) { mSysUiMainExecutor.execute(() -> { mSysUiState.setFlag(SYSUI_STATE_ONE_HANDED_ACTIVE, - false).commitUpdate(DEFAULT_DISPLAY); + false).commitUpdate(mDisplayTracker.getDefaultDisplayId()); }); } }); @@ -333,7 +335,8 @@ public final class WMShell implements @Override public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher) { - if (displayId == DEFAULT_DISPLAY && (vis & InputMethodService.IME_VISIBLE) != 0) { + if (displayId == mDisplayTracker.getDefaultDisplayId() + && (vis & InputMethodService.IME_VISIBLE) != 0) { oneHanded.stopOneHanded( OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_POP_IME_OUT); } @@ -346,7 +349,7 @@ public final class WMShell implements @Override public void onVisibilityChanged(boolean hasFreeformTasks) { mSysUiState.setFlag(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE, hasFreeformTasks) - .commitUpdate(DEFAULT_DISPLAY); + .commitUpdate(mDisplayTracker.getDefaultDisplayId()); } }, mSysUiMainExecutor); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt index 00b2fbe8a4cb..b9c23d4af8a1 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt @@ -15,7 +15,6 @@ */ package com.android.keyguard -import com.android.systemui.statusbar.CommandQueue import android.content.BroadcastReceiver import android.testing.AndroidTestingRunner import android.view.View @@ -34,6 +33,7 @@ import com.android.systemui.plugins.ClockEvents import com.android.systemui.plugins.ClockFaceController import com.android.systemui.plugins.ClockFaceEvents import com.android.systemui.plugins.log.LogBuffer +import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.mockito.any @@ -41,8 +41,6 @@ import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock -import java.util.TimeZone -import java.util.concurrent.Executor import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.yield @@ -57,8 +55,10 @@ import org.mockito.Mock import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` as whenever import org.mockito.junit.MockitoJUnit +import java.util.* +import java.util.concurrent.Executor +import org.mockito.Mockito.`when` as whenever @RunWith(AndroidTestingRunner::class) @SmallTest diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java index 10595439200a..50645e5daa09 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java @@ -150,4 +150,11 @@ public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase { getContext().getResources().getString(R.string.kg_prompt_reason_restart_password), false); } + + + @Test + public void testReset() { + mKeyguardAbsKeyInputViewController.reset(); + verify(mKeyguardMessageAreaController).setMessage("", false); + } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java index 01365b43b4b8..30e3d09299f2 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java @@ -25,9 +25,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerGlobal; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -39,6 +37,7 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.dagger.KeyguardStatusViewComponent; import com.android.systemui.SysuiTestCase; import com.android.systemui.navigationbar.NavigationBarController; +import com.android.systemui.settings.FakeDisplayTracker; import org.junit.Before; import org.junit.Test; @@ -58,12 +57,12 @@ public class KeyguardDisplayManagerTest extends SysuiTestCase { @Mock private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory; @Mock - private DisplayManager mDisplayManager; - @Mock private KeyguardDisplayManager.KeyguardPresentation mKeyguardPresentation; + private Executor mMainExecutor = Runnable::run; private Executor mBackgroundExecutor = Runnable::run; private KeyguardDisplayManager mManager; + private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); // The default and secondary displays are both in the default group private Display mDefaultDisplay; @@ -75,9 +74,9 @@ public class KeyguardDisplayManagerTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - mContext.addMockSystemService(DisplayManager.class, mDisplayManager); mManager = spy(new KeyguardDisplayManager(mContext, () -> mNavigationBarController, - mKeyguardStatusViewComponentFactory, mBackgroundExecutor)); + mKeyguardStatusViewComponentFactory, mDisplayTracker, mMainExecutor, + mBackgroundExecutor)); doReturn(mKeyguardPresentation).when(mManager).createPresentation(any()); mDefaultDisplay = new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY, @@ -96,23 +95,21 @@ public class KeyguardDisplayManagerTest extends SysuiTestCase { @Test public void testShow_defaultDisplayOnly() { - when(mDisplayManager.getDisplays()).thenReturn(new Display[]{mDefaultDisplay}); + mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay}); mManager.show(); verify(mManager, never()).createPresentation(any()); } @Test public void testShow_includeSecondaryDisplay() { - when(mDisplayManager.getDisplays()).thenReturn( - new Display[]{mDefaultDisplay, mSecondaryDisplay}); + mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay, mSecondaryDisplay}); mManager.show(); verify(mManager, times(1)).createPresentation(eq(mSecondaryDisplay)); } @Test public void testShow_includeAlwaysUnlockedDisplay() { - when(mDisplayManager.getDisplays()).thenReturn( - new Display[]{mDefaultDisplay, mAlwaysUnlockedDisplay}); + mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay, mAlwaysUnlockedDisplay}); mManager.show(); verify(mManager, never()).createPresentation(any()); @@ -120,7 +117,7 @@ public class KeyguardDisplayManagerTest extends SysuiTestCase { @Test public void testShow_includeSecondaryAndAlwaysUnlockedDisplays() { - when(mDisplayManager.getDisplays()).thenReturn( + mDisplayTracker.setAllDisplays( new Display[]{mDefaultDisplay, mSecondaryDisplay, mAlwaysUnlockedDisplay}); mManager.show(); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java index 06082b61ec26..68dc6c04bc79 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java @@ -29,6 +29,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardSliceProvider; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.tuner.TunerService; @@ -52,6 +53,7 @@ public class KeyguardSliceViewControllerTest extends SysuiTestCase { private ConfigurationController mConfigurationController; @Mock private ActivityStarter mActivityStarter; + private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); private DumpManager mDumpManager = new DumpManager(); private KeyguardSliceViewController mController; @@ -63,7 +65,7 @@ public class KeyguardSliceViewControllerTest extends SysuiTestCase { when(mView.getContext()).thenReturn(mContext); mController = new KeyguardSliceViewController( mView, mActivityStarter, mConfigurationController, - mTunerService, mDumpManager); + mTunerService, mDumpManager, mDisplayTracker); mController.setupUri(KeyguardSliceProvider.KEYGUARD_SLICE_URI); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt index 81d0034128b1..32edf8f23aed 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt @@ -148,7 +148,7 @@ class ChooserSelectorTest : SysuiTestCase() { // Act whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true) - flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.id)) + flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.name)) // Assert verify(mockPackageManager, times(2)).setComponentEnabledSetting( @@ -175,7 +175,7 @@ class ChooserSelectorTest : SysuiTestCase() { // Act whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) - flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.id)) + flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.name)) // Assert verify(mockPackageManager, times(2)).setComponentEnabledSetting( @@ -198,13 +198,13 @@ class ChooserSelectorTest : SysuiTestCase() { // Act whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) - flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.id + 1)) + flagListener.value.onFlagChanged(TestFlagEvent("other flag")) // Assert verifyZeroInteractions(mockPackageManager) } - private class TestFlagEvent(override val flagId: Int) : FlagListenable.FlagEvent { + private class TestFlagEvent(override val flagName: String) : FlagListenable.FlagEvent { override fun requestNoRestart() {} } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index 0627fc6c542f..e918c1cc9b10 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -89,6 +89,7 @@ import com.android.systemui.decor.PrivacyDotCornerDecorProviderImpl; import com.android.systemui.decor.PrivacyDotDecorProviderFactory; import com.android.systemui.decor.RoundedCornerResDelegate; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.events.PrivacyDotViewController; import com.android.systemui.tuner.TunerService; @@ -117,6 +118,7 @@ public class ScreenDecorationsTest extends SysuiTestCase { private DisplayManager mDisplayManager; private SecureSettings mSecureSettings; private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); + private final FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); private FakeThreadFactory mThreadFactory; private ArrayList<DecorProvider> mPrivacyDecorProviders; private ArrayList<DecorProvider> mFaceScanningProviders; @@ -220,7 +222,7 @@ public class ScreenDecorationsTest extends SysuiTestCase { mExecutor)); mScreenDecorations = spy(new ScreenDecorations(mContext, mExecutor, mSecureSettings, - mTunerService, mUserTracker, mDotViewController, mThreadFactory, + mTunerService, mUserTracker, mDisplayTracker, mDotViewController, mThreadFactory, mPrivacyDotDecorProviderFactory, mFaceScanningProviderFactory) { @Override public void start() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java index 47dff51e3f6a..213ce9e4d6a1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java @@ -39,6 +39,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.model.SysUiState; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.util.settings.SecureSettings; @@ -79,6 +80,7 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase { private IWindowMagnificationConnection mIWindowMagnificationConnection; private WindowMagnification mWindowMagnification; + private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); @Before public void setUp() throws Exception { @@ -91,7 +93,8 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase { any(IWindowMagnificationConnection.class)); mWindowMagnification = new WindowMagnification(getContext(), getContext().getMainThreadHandler(), mCommandQueue, - mModeSwitchesController, mSysUiState, mOverviewProxyService, mSecureSettings); + mModeSwitchesController, mSysUiState, mOverviewProxyService, mSecureSettings, + mDisplayTracker); mWindowMagnification.mMagnificationControllerSupplier = new FakeControllerSupplier( mContext.getSystemService(DisplayManager.class)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java index 89ab83583d15..201f0208531e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java @@ -87,6 +87,7 @@ import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.model.SysUiState; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.util.leak.ReferenceTestUtils; import com.android.systemui.util.settings.SecureSettings; import com.android.systemui.utils.os.FakeHandler; @@ -131,12 +132,13 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { private Handler mHandler; private TestableWindowManager mWindowManager; - private SysUiState mSysUiState = new SysUiState(); + private SysUiState mSysUiState; private Resources mResources; private WindowMagnificationAnimationController mWindowMagnificationAnimationController; private WindowMagnificationController mWindowMagnificationController; private Instrumentation mInstrumentation; private final ValueAnimator mValueAnimator = ValueAnimator.ofFloat(0, 1.0f).setDuration(0); + private final FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); private IWindowSession mWindowSessionSpy; @@ -162,6 +164,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { return null; }).when(mSfVsyncFrameProvider).postFrameCallback( any(FrameCallback.class)); + mSysUiState = new SysUiState(mDisplayTracker); mSysUiState.addCallback(Mockito.mock(SysUiState.SysUiStateCallback.class)); when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).then( returnsSecondArg()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java index 14b00cad6b38..583f2db20570 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java @@ -45,6 +45,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.model.SysUiState; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.util.settings.SecureSettings; @@ -77,6 +78,8 @@ public class WindowMagnificationTest extends SysuiTestCase { private CommandQueue mCommandQueue; private WindowMagnification mWindowMagnification; private OverviewProxyListener mOverviewProxyListener; + private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); @@ -90,10 +93,10 @@ public class WindowMagnificationTest extends SysuiTestCase { when(mSysUiState.setFlag(anyInt(), anyBoolean())).thenReturn(mSysUiState); - mCommandQueue = new CommandQueue(getContext()); + mCommandQueue = new CommandQueue(getContext(), mDisplayTracker); mWindowMagnification = new WindowMagnification(getContext(), getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController, - mSysUiState, mOverviewProxyService, mSecureSettings); + mSysUiState, mOverviewProxyService, mSecureSettings, mDisplayTracker); mWindowMagnification.start(); final ArgumentCaptor<OverviewProxyListener> listenerArgumentCaptor = diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java index 15a314515c31..aac0b511a56c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java @@ -47,6 +47,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.accessibility.AccessibilityButtonModeObserver; import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver; import com.android.systemui.flags.FakeFeatureFlags; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.util.settings.SecureSettings; import org.junit.After; @@ -353,13 +354,14 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { private AccessibilityFloatingMenuController setUpController(FakeFeatureFlags featureFlags) { final WindowManager windowManager = mContext.getSystemService(WindowManager.class); final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); + final FakeDisplayTracker displayTracker = new FakeDisplayTracker(mContext); mTargetsObserver = spy(Dependency.get(AccessibilityButtonTargetsObserver.class)); mModeObserver = spy(Dependency.get(AccessibilityButtonModeObserver.class)); mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class); final AccessibilityFloatingMenuController controller = new AccessibilityFloatingMenuController(mContextWrapper, windowManager, displayManager, mAccessibilityManager, mTargetsObserver, mModeObserver, - mKeyguardUpdateMonitor, featureFlags, mSecureSettings); + mKeyguardUpdateMonitor, featureFlags, mSecureSettings, displayTracker); controller.init(); return controller; diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt index a61cd23b60fc..578e1d4d02ce 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt @@ -15,6 +15,7 @@ import android.view.RemoteAnimationAdapter import android.view.RemoteAnimationTarget import android.view.SurfaceControl import android.view.ViewGroup +import android.widget.FrameLayout import android.widget.LinearLayout import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase @@ -26,6 +27,7 @@ import junit.framework.Assert.assertTrue import junit.framework.AssertionFailedError import kotlin.concurrent.thread import org.junit.After +import org.junit.Assert.assertThrows import org.junit.Before import org.junit.Rule import org.junit.Test @@ -195,6 +197,13 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { verify(controller).onLaunchAnimationStart(anyBoolean()) } + @Test + fun creatingControllerFromNormalViewThrows() { + assertThrows(IllegalArgumentException::class.java) { + ActivityLaunchAnimator.Controller.fromView(FrameLayout(mContext)) + } + } + private fun fakeWindow(): RemoteAnimationTarget { val bounds = Rect(10 /* left */, 20 /* top */, 30 /* right */, 40 /* bottom */) val taskInfo = ActivityManager.RunningTaskInfo() diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt index cac4a0e5432c..1e62fd2332c3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt @@ -26,6 +26,7 @@ import junit.framework.Assert.assertNull import junit.framework.Assert.assertTrue import org.junit.After import org.junit.Assert.assertNotEquals +import org.junit.Assert.assertThrows import org.junit.Before import org.junit.Rule import org.junit.Test @@ -260,6 +261,13 @@ class DialogLaunchAnimatorTest : SysuiTestCase() { assertThat(touchSurface.visibility).isEqualTo(View.GONE) } + @Test + fun creatingControllerFromNormalViewThrows() { + assertThrows(IllegalArgumentException::class.java) { + DialogLaunchAnimator.Controller.fromView(FrameLayout(mContext)) + } + } + private fun createAndShowDialog( animator: DialogLaunchAnimator = dialogLaunchAnimator, ): TestDialog { diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewLaunchAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewLaunchAnimatorControllerTest.kt index 3696ec540baf..0798d73cc2f2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewLaunchAnimatorControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewLaunchAnimatorControllerTest.kt @@ -16,58 +16,34 @@ package com.android.systemui.animation -import android.graphics.drawable.Drawable import android.testing.AndroidTestingRunner import android.testing.TestableLooper -import android.view.View -import android.view.ViewGroup -import android.view.ViewParent +import android.widget.FrameLayout import androidx.test.filters.SmallTest -import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.SysuiTestCase -import org.junit.Before +import org.junit.Assert.assertThrows import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.any -import org.mockito.ArgumentMatchers.anyInt -import org.mockito.Mock -import org.mockito.Mockito.`when` as whenever -import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidTestingRunner::class) @TestableLooper.RunWithLooper class GhostedViewLaunchAnimatorControllerTest : SysuiTestCase() { - @Mock lateinit var interactionJankMonitor: InteractionJankMonitor - @Mock lateinit var view: View - @Mock lateinit var rootView: ViewGroup - @Mock lateinit var viewParent: ViewParent - @Mock lateinit var drawable: Drawable - lateinit var controller: GhostedViewLaunchAnimatorController - - @Before - fun setup() { - MockitoAnnotations.initMocks(this) - whenever(view.rootView).thenReturn(rootView) - whenever(view.background).thenReturn(drawable) - whenever(view.height).thenReturn(0) - whenever(view.width).thenReturn(0) - whenever(view.parent).thenReturn(viewParent) - whenever(view.visibility).thenReturn(View.VISIBLE) - whenever(view.invalidate()).then { /* NO-OP */ } - whenever(view.getLocationOnScreen(any())).then { /* NO-OP */ } - whenever(interactionJankMonitor.begin(any(), anyInt())).thenReturn(true) - whenever(interactionJankMonitor.end(anyInt())).thenReturn(true) - controller = GhostedViewLaunchAnimatorController(view, 0, interactionJankMonitor) - } - @Test fun animatingOrphanViewDoesNotCrash() { val state = LaunchAnimator.State(top = 0, bottom = 0, left = 0, right = 0) + val controller = GhostedViewLaunchAnimatorController(LaunchableFrameLayout(mContext)) controller.onIntentStarted(willAnimate = true) controller.onLaunchAnimationStart(isExpandingFullyAbove = true) controller.onLaunchAnimationProgress(state, progress = 0f, linearProgress = 0f) controller.onLaunchAnimationEnd(isExpandingFullyAbove = true) } + + @Test + fun creatingControllerFromNormalViewThrows() { + assertThrows(IllegalArgumentException::class.java) { + GhostedViewLaunchAnimatorController(FrameLayout(mContext)) + } + } }
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerBaseTest.java index 498cc2926a71..dbbc2663a879 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerBaseTest.java @@ -147,7 +147,6 @@ public class UdfpsKeyguardViewControllerBaseTest extends SysuiTestCase { protected UdfpsKeyguardViewController createUdfpsKeyguardViewController( boolean useModernBouncer, boolean useExpandedOverlay) { - mFeatureFlags.set(Flags.MODERN_BOUNCER, useModernBouncer); mFeatureFlags.set(Flags.MODERN_ALTERNATE_BOUNCER, useModernBouncer); mFeatureFlags.set(Flags.UDFPS_NEW_TOUCH_DETECTION, useExpandedOverlay); UdfpsKeyguardViewController controller = new UdfpsKeyguardViewController( diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java index b4e85c06933a..ca5b7af5695a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java @@ -47,6 +47,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.screenshot.TimeoutHandler; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; @@ -81,6 +82,7 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { private ClipboardOverlayUtils mClipboardUtils; @Mock private UiEventLogger mUiEventLogger; + private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); private FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags(); @Mock @@ -116,7 +118,8 @@ public class ClipboardOverlayControllerTest extends SysuiTestCase { mFeatureFlags, mClipboardUtils, mExecutor, - mUiEventLogger); + mUiEventLogger, + mDisplayTracker); verify(mClipboardOverlayView).setCallbacks(mOverlayCallbacksCaptor.capture()); mCallbacks = mOverlayCallbacksCaptor.getValue(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java index b73bfc366b4b..9d4bef621988 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java @@ -31,6 +31,8 @@ import android.os.IBinder; import android.os.RemoteException; import android.service.dreams.IDreamOverlay; import android.service.dreams.IDreamOverlayCallback; +import android.service.dreams.IDreamOverlayClient; +import android.service.dreams.IDreamOverlayClientCallback; import android.testing.AndroidTestingRunner; import android.view.View; import android.view.ViewGroup; @@ -61,6 +63,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; @SmallTest @@ -189,13 +192,25 @@ public class DreamOverlayServiceTest extends SysuiTestCase { mDreamOverlayCallbackController); } - @Test - public void testOnStartMetricsLogged() throws Exception { + public IDreamOverlayClient getClient() throws RemoteException { final IBinder proxy = mService.onBind(new Intent()); final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); + final IDreamOverlayClientCallback callback = + Mockito.mock(IDreamOverlayClientCallback.class); + overlay.getClient(callback); + final ArgumentCaptor<IDreamOverlayClient> clientCaptor = + ArgumentCaptor.forClass(IDreamOverlayClient.class); + verify(callback).onDreamOverlayClient(clientCaptor.capture()); + + return clientCaptor.getValue(); + } + + @Test + public void testOnStartMetricsLogged() throws Exception { + final IDreamOverlayClient client = getClient(); // Inform the overlay service of dream starting. - overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, + client.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, false /*shouldShowComplication*/); mMainExecutor.runAllReady(); @@ -206,11 +221,10 @@ public class DreamOverlayServiceTest extends SysuiTestCase { @Test public void testOverlayContainerViewAddedToWindow() throws Exception { - final IBinder proxy = mService.onBind(new Intent()); - final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); + final IDreamOverlayClient client = getClient(); // Inform the overlay service of dream starting. - overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, + client.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, false /*shouldShowComplication*/); mMainExecutor.runAllReady(); @@ -219,11 +233,10 @@ public class DreamOverlayServiceTest extends SysuiTestCase { @Test public void testDreamOverlayContainerViewControllerInitialized() throws Exception { - final IBinder proxy = mService.onBind(new Intent()); - final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); + final IDreamOverlayClient client = getClient(); // Inform the overlay service of dream starting. - overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, + client.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, false /*shouldShowComplication*/); mMainExecutor.runAllReady(); @@ -237,11 +250,10 @@ public class DreamOverlayServiceTest extends SysuiTestCase { .thenReturn(mDreamOverlayContainerViewParent) .thenReturn(null); - final IBinder proxy = mService.onBind(new Intent()); - final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); + final IDreamOverlayClient client = getClient(); // Inform the overlay service of dream starting. - overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, + client.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, false /*shouldShowComplication*/); mMainExecutor.runAllReady(); @@ -250,11 +262,10 @@ public class DreamOverlayServiceTest extends SysuiTestCase { @Test public void testShouldShowComplicationsSetByStartDream() throws RemoteException { - final IBinder proxy = mService.onBind(new Intent()); - final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); + final IDreamOverlayClient client = getClient(); // Inform the overlay service of dream starting. - overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, + client.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, true /*shouldShowComplication*/); assertThat(mService.shouldShowComplications()).isTrue(); @@ -262,11 +273,10 @@ public class DreamOverlayServiceTest extends SysuiTestCase { @Test public void testLowLightSetByStartDream() throws RemoteException { - final IBinder proxy = mService.onBind(new Intent()); - final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); + final IDreamOverlayClient client = getClient(); // Inform the overlay service of dream starting. - overlay.startDream(mWindowParams, mDreamOverlayCallback, + client.startDream(mWindowParams, mDreamOverlayCallback, LOW_LIGHT_COMPONENT.flattenToString(), false /*shouldShowComplication*/); mMainExecutor.runAllReady(); @@ -276,11 +286,10 @@ public class DreamOverlayServiceTest extends SysuiTestCase { @Test public void testOnEndDream() throws RemoteException { - final IBinder proxy = mService.onBind(new Intent()); - final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); + final IDreamOverlayClient client = getClient(); // Inform the overlay service of dream starting. - overlay.startDream(mWindowParams, mDreamOverlayCallback, + client.startDream(mWindowParams, mDreamOverlayCallback, LOW_LIGHT_COMPONENT.flattenToString(), false /*shouldShowComplication*/); mMainExecutor.runAllReady(); @@ -302,11 +311,10 @@ public class DreamOverlayServiceTest extends SysuiTestCase { @Test public void testDestroy() throws RemoteException { - final IBinder proxy = mService.onBind(new Intent()); - final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); + final IDreamOverlayClient client = getClient(); // Inform the overlay service of dream starting. - overlay.startDream(mWindowParams, mDreamOverlayCallback, + client.startDream(mWindowParams, mDreamOverlayCallback, LOW_LIGHT_COMPONENT.flattenToString(), false /*shouldShowComplication*/); mMainExecutor.runAllReady(); @@ -346,15 +354,14 @@ public class DreamOverlayServiceTest extends SysuiTestCase { @Test public void testDecorViewNotAddedToWindowAfterDestroy() throws Exception { - final IBinder proxy = mService.onBind(new Intent()); - final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); + final IDreamOverlayClient client = getClient(); // Destroy the service. mService.onDestroy(); mMainExecutor.runAllReady(); // Inform the overlay service of dream starting. - overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, + client.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, false /*shouldShowComplication*/); mMainExecutor.runAllReady(); @@ -372,11 +379,10 @@ public class DreamOverlayServiceTest extends SysuiTestCase { @Test public void testResetCurrentOverlayWhenConnectedToNewDream() throws RemoteException { - final IBinder proxy = mService.onBind(new Intent()); - final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); + final IDreamOverlayClient client = getClient(); // Inform the overlay service of dream starting. Do not show dream complications. - overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, + client.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, false /*shouldShowComplication*/); mMainExecutor.runAllReady(); @@ -393,7 +399,7 @@ public class DreamOverlayServiceTest extends SysuiTestCase { // New dream starting with dream complications showing. Note that when a new dream is // binding to the dream overlay service, it receives the same instance of IBinder as the // first one. - overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, + client.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, true /*shouldShowComplication*/); mMainExecutor.runAllReady(); @@ -412,11 +418,10 @@ public class DreamOverlayServiceTest extends SysuiTestCase { @Test public void testWakeUp() throws RemoteException { - final IBinder proxy = mService.onBind(new Intent()); - final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); + final IDreamOverlayClient client = getClient(); // Inform the overlay service of dream starting. - overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, + client.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT, true /*shouldShowComplication*/); mMainExecutor.runAllReady(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java index 89c728082cc5..a4cf15c3fafa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java @@ -31,13 +31,13 @@ import android.content.ComponentName; import android.content.Context; import android.testing.AndroidTestingRunner; import android.view.View; -import android.widget.ImageView; import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.common.ui.view.LaunchableImageView; import com.android.systemui.controls.ControlsServiceInfo; import com.android.systemui.controls.controller.ControlsController; import com.android.systemui.controls.controller.StructureInfo; @@ -90,7 +90,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase { private View mView; @Mock - private ImageView mHomeControlsView; + private LaunchableImageView mHomeControlsView; @Mock private ActivityStarter mActivityStarter; diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt index 170a70f2fc40..35f0f6c68798 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt @@ -125,7 +125,7 @@ class FakeFeatureFlagsTest : SysuiTestCase() { flags.set(unreleasedFlag, false) flags.set(unreleasedFlag, false) - listener.verifyInOrder(unreleasedFlag.id, unreleasedFlag.id) + listener.verifyInOrder(unreleasedFlag.name, unreleasedFlag.name) } @Test @@ -137,7 +137,7 @@ class FakeFeatureFlagsTest : SysuiTestCase() { flags.set(stringFlag, "Test") flags.set(stringFlag, "Test") - listener.verifyInOrder(stringFlag.id) + listener.verifyInOrder(stringFlag.name) } @Test @@ -149,7 +149,7 @@ class FakeFeatureFlagsTest : SysuiTestCase() { flags.removeListener(listener) flags.set(unreleasedFlag, false) - listener.verifyInOrder(unreleasedFlag.id) + listener.verifyInOrder(unreleasedFlag.name) } @Test @@ -162,7 +162,7 @@ class FakeFeatureFlagsTest : SysuiTestCase() { flags.removeListener(listener) flags.set(stringFlag, "Other") - listener.verifyInOrder(stringFlag.id) + listener.verifyInOrder(stringFlag.name) } @Test @@ -175,7 +175,7 @@ class FakeFeatureFlagsTest : SysuiTestCase() { flags.set(releasedFlag, true) flags.set(unreleasedFlag, true) - listener.verifyInOrder(releasedFlag.id, unreleasedFlag.id) + listener.verifyInOrder(releasedFlag.name, unreleasedFlag.name) } @Test @@ -191,7 +191,7 @@ class FakeFeatureFlagsTest : SysuiTestCase() { flags.set(releasedFlag, false) flags.set(unreleasedFlag, false) - listener.verifyInOrder(releasedFlag.id, unreleasedFlag.id) + listener.verifyInOrder(releasedFlag.name, unreleasedFlag.name) } @Test @@ -204,8 +204,8 @@ class FakeFeatureFlagsTest : SysuiTestCase() { flags.set(releasedFlag, true) - listener1.verifyInOrder(releasedFlag.id) - listener2.verifyInOrder(releasedFlag.id) + listener1.verifyInOrder(releasedFlag.name) + listener2.verifyInOrder(releasedFlag.name) } @Test @@ -220,18 +220,18 @@ class FakeFeatureFlagsTest : SysuiTestCase() { flags.removeListener(listener2) flags.set(releasedFlag, false) - listener1.verifyInOrder(releasedFlag.id, releasedFlag.id) - listener2.verifyInOrder(releasedFlag.id) + listener1.verifyInOrder(releasedFlag.name, releasedFlag.name) + listener2.verifyInOrder(releasedFlag.name) } class VerifyingListener : FlagListenable.Listener { - var flagEventIds = mutableListOf<Int>() + var flagEventNames = mutableListOf<String>() override fun onFlagChanged(event: FlagListenable.FlagEvent) { - flagEventIds.add(event.flagId) + flagEventNames.add(event.flagName) } - fun verifyInOrder(vararg eventIds: Int) { - assertThat(flagEventIds).containsExactlyElementsIn(eventIds.asList()) + fun verifyInOrder(vararg eventNames: String) { + assertThat(flagEventNames).containsExactlyElementsIn(eventNames.asList()) } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt index 7592cc527190..d8bbd04bfd4a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt @@ -23,12 +23,11 @@ import android.content.res.Resources import android.content.res.Resources.NotFoundException import android.test.suitebuilder.annotation.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.statusbar.commandline.CommandRegistry -import com.android.systemui.util.DeviceConfigProxyFake import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.nullable import com.android.systemui.util.mockito.withArgCaptor +import com.android.systemui.util.settings.GlobalSettings import com.android.systemui.util.settings.SecureSettings import com.google.common.truth.Truth.assertThat import org.junit.Assert @@ -62,21 +61,20 @@ class FeatureFlagsDebugTest : SysuiTestCase() { @Mock private lateinit var mockContext: Context @Mock + private lateinit var globalSettings: GlobalSettings + @Mock private lateinit var secureSettings: SecureSettings @Mock private lateinit var systemProperties: SystemPropertiesHelper @Mock private lateinit var resources: Resources @Mock - private lateinit var commandRegistry: CommandRegistry - @Mock private lateinit var restarter: Restarter - private val flagMap = mutableMapOf<Int, Flag<*>>() + private val flagMap = mutableMapOf<String, Flag<*>>() private lateinit var broadcastReceiver: BroadcastReceiver - private lateinit var clearCacheAction: Consumer<Int> + private lateinit var clearCacheAction: Consumer<String> private val serverFlagReader = ServerFlagReaderFake() - private val deviceConfig = DeviceConfigProxyFake() private val teamfoodableFlagA = UnreleasedFlag( 500, name = "a", namespace = "test", teamfood = true ) @@ -87,11 +85,13 @@ class FeatureFlagsDebugTest : SysuiTestCase() { @Before fun setup() { MockitoAnnotations.initMocks(this) - flagMap.put(teamfoodableFlagA.id, teamfoodableFlagA) - flagMap.put(teamfoodableFlagB.id, teamfoodableFlagB) + flagMap.put(Flags.TEAMFOOD.name, Flags.TEAMFOOD) + flagMap.put(teamfoodableFlagA.name, teamfoodableFlagA) + flagMap.put(teamfoodableFlagB.name, teamfoodableFlagB) mFeatureFlagsDebug = FeatureFlagsDebug( flagManager, mockContext, + globalSettings, secureSettings, systemProperties, resources, @@ -110,14 +110,14 @@ class FeatureFlagsDebugTest : SysuiTestCase() { clearCacheAction = withArgCaptor { verify(flagManager).clearCacheAction = capture() } - whenever(flagManager.idToSettingsKey(any())).thenAnswer { "key-${it.arguments[0]}" } + whenever(flagManager.nameToSettingsKey(any())).thenAnswer { "key-${it.arguments[0]}" } } @Test fun readBooleanFlag() { // Remember that the TEAMFOOD flag is id#1 and has special behavior. - whenever(flagManager.readFlagValue<Boolean>(eq(3), any())).thenReturn(true) - whenever(flagManager.readFlagValue<Boolean>(eq(4), any())).thenReturn(false) + whenever(flagManager.readFlagValue<Boolean>(eq("3"), any())).thenReturn(true) + whenever(flagManager.readFlagValue<Boolean>(eq("4"), any())).thenReturn(false) assertThat( mFeatureFlagsDebug.isEnabled( @@ -141,7 +141,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { mFeatureFlagsDebug.isEnabled( ReleasedFlag( 4, - name = "3", + name = "4", namespace = "test" ) ) @@ -150,7 +150,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { mFeatureFlagsDebug.isEnabled( UnreleasedFlag( 5, - name = "4", + name = "5", namespace = "test" ) ) @@ -159,7 +159,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() { @Test fun teamFoodFlag_False() { - whenever(flagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(false) + whenever(flagManager.readFlagValue<Boolean>( + eq(Flags.TEAMFOOD.name), any())).thenReturn(false) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() @@ -170,7 +171,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() { @Test fun teamFoodFlag_True() { - whenever(flagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true) + whenever(flagManager.readFlagValue<Boolean>( + eq(Flags.TEAMFOOD.name), any())).thenReturn(true) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() @@ -181,11 +183,12 @@ class FeatureFlagsDebugTest : SysuiTestCase() { @Test fun teamFoodFlag_Overridden() { - whenever(flagManager.readFlagValue<Boolean>(eq(teamfoodableFlagA.id), any())) + whenever(flagManager.readFlagValue<Boolean>(eq(teamfoodableFlagA.name), any())) .thenReturn(true) - whenever(flagManager.readFlagValue<Boolean>(eq(teamfoodableFlagB.id), any())) + whenever(flagManager.readFlagValue<Boolean>(eq(teamfoodableFlagB.name), any())) .thenReturn(false) - whenever(flagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true) + whenever(flagManager.readFlagValue<Boolean>( + eq(Flags.TEAMFOOD.name), any())).thenReturn(true) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse() @@ -202,8 +205,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(resources.getBoolean(1004)).thenAnswer { throw NameNotFoundException() } whenever(resources.getBoolean(1005)).thenAnswer { throw NameNotFoundException() } - whenever(flagManager.readFlagValue<Boolean>(eq(3), any())).thenReturn(true) - whenever(flagManager.readFlagValue<Boolean>(eq(5), any())).thenReturn(false) + whenever(flagManager.readFlagValue<Boolean>(eq("3"), any())).thenReturn(true) + whenever(flagManager.readFlagValue<Boolean>(eq("5"), any())).thenReturn(false) assertThat( mFeatureFlagsDebug.isEnabled( @@ -255,8 +258,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() { @Test fun readStringFlag() { - whenever(flagManager.readFlagValue<String>(eq(3), any())).thenReturn("foo") - whenever(flagManager.readFlagValue<String>(eq(4), any())).thenReturn("bar") + whenever(flagManager.readFlagValue<String>(eq("3"), any())).thenReturn("foo") + whenever(flagManager.readFlagValue<String>(eq("4"), any())).thenReturn("bar") assertThat(mFeatureFlagsDebug.getString(StringFlag(1, "1", "test", "biz"))).isEqualTo("biz") assertThat(mFeatureFlagsDebug.getString(StringFlag(2, "2", "test", "baz"))).isEqualTo("baz") assertThat(mFeatureFlagsDebug.getString(StringFlag(3, "3", "test", "buz"))).isEqualTo("foo") @@ -272,9 +275,9 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(resources.getString(1005)).thenAnswer { throw NameNotFoundException() } whenever(resources.getString(1006)).thenAnswer { throw NameNotFoundException() } - whenever(flagManager.readFlagValue<String>(eq(3), any())).thenReturn("override3") - whenever(flagManager.readFlagValue<String>(eq(4), any())).thenReturn("override4") - whenever(flagManager.readFlagValue<String>(eq(6), any())).thenReturn("override6") + whenever(flagManager.readFlagValue<String>(eq("3"), any())).thenReturn("override3") + whenever(flagManager.readFlagValue<String>(eq("4"), any())).thenReturn("override4") + whenever(flagManager.readFlagValue<String>(eq("6"), any())).thenReturn("override6") assertThat( mFeatureFlagsDebug.getString( @@ -322,8 +325,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() { @Test fun readIntFlag() { - whenever(flagManager.readFlagValue<Int>(eq(3), any())).thenReturn(22) - whenever(flagManager.readFlagValue<Int>(eq(4), any())).thenReturn(48) + whenever(flagManager.readFlagValue<Int>(eq("3"), any())).thenReturn(22) + whenever(flagManager.readFlagValue<Int>(eq("4"), any())).thenReturn(48) assertThat(mFeatureFlagsDebug.getInt(IntFlag(1, "1", "test", 12))).isEqualTo(12) assertThat(mFeatureFlagsDebug.getInt(IntFlag(2, "2", "test", 93))).isEqualTo(93) assertThat(mFeatureFlagsDebug.getInt(IntFlag(3, "3", "test", 8))).isEqualTo(22) @@ -368,12 +371,12 @@ class FeatureFlagsDebugTest : SysuiTestCase() { broadcastReceiver.onReceive(mockContext, Intent()) broadcastReceiver.onReceive(mockContext, Intent("invalid action")) broadcastReceiver.onReceive(mockContext, Intent(FlagManager.ACTION_SET_FLAG)) - setByBroadcast(0, false) // unknown id does nothing - setByBroadcast(1, "string") // wrong type does nothing - setByBroadcast(2, 123) // wrong type does nothing - setByBroadcast(3, false) // wrong type does nothing - setByBroadcast(4, 123) // wrong type does nothing - verifyNoMoreInteractions(flagManager, secureSettings) + setByBroadcast("0", false) // unknown id does nothing + setByBroadcast("1", "string") // wrong type does nothing + setByBroadcast("2", 123) // wrong type does nothing + setByBroadcast("3", false) // wrong type does nothing + setByBroadcast("4", 123) // wrong type does nothing + verifyNoMoreInteractions(flagManager, globalSettings) } @Test @@ -383,16 +386,16 @@ class FeatureFlagsDebugTest : SysuiTestCase() { // trying to erase an id not in the map does nothing broadcastReceiver.onReceive( mockContext, - Intent(FlagManager.ACTION_SET_FLAG).putExtra(FlagManager.EXTRA_ID, 0) + Intent(FlagManager.ACTION_SET_FLAG).putExtra(FlagManager.EXTRA_NAME, "") ) - verifyNoMoreInteractions(flagManager, secureSettings) + verifyNoMoreInteractions(flagManager, globalSettings) // valid id with no value puts empty string in the setting broadcastReceiver.onReceive( mockContext, - Intent(FlagManager.ACTION_SET_FLAG).putExtra(FlagManager.EXTRA_ID, 1) + Intent(FlagManager.ACTION_SET_FLAG).putExtra(FlagManager.EXTRA_NAME, "1") ) - verifyPutData(1, "", numReads = 0) + verifyPutData("1", "", numReads = 0) } @Test @@ -402,51 +405,51 @@ class FeatureFlagsDebugTest : SysuiTestCase() { addFlag(ResourceBooleanFlag(3, "3", "test", 1003)) addFlag(ResourceBooleanFlag(4, "4", "test", 1004)) - setByBroadcast(1, false) - verifyPutData(1, "{\"type\":\"boolean\",\"value\":false}") + setByBroadcast("1", false) + verifyPutData("1", "{\"type\":\"boolean\",\"value\":false}") - setByBroadcast(2, true) - verifyPutData(2, "{\"type\":\"boolean\",\"value\":true}") + setByBroadcast("2", true) + verifyPutData("2", "{\"type\":\"boolean\",\"value\":true}") - setByBroadcast(3, false) - verifyPutData(3, "{\"type\":\"boolean\",\"value\":false}") + setByBroadcast("3", false) + verifyPutData("3", "{\"type\":\"boolean\",\"value\":false}") - setByBroadcast(4, true) - verifyPutData(4, "{\"type\":\"boolean\",\"value\":true}") + setByBroadcast("4", true) + verifyPutData("4", "{\"type\":\"boolean\",\"value\":true}") } @Test fun setStringFlag() { - addFlag(StringFlag(1, "flag1", "1", "test")) + addFlag(StringFlag(1, "1", "1", "test")) addFlag(ResourceStringFlag(2, "2", "test", 1002)) - setByBroadcast(1, "override1") - verifyPutData(1, "{\"type\":\"string\",\"value\":\"override1\"}") + setByBroadcast("1", "override1") + verifyPutData("1", "{\"type\":\"string\",\"value\":\"override1\"}") - setByBroadcast(2, "override2") - verifyPutData(2, "{\"type\":\"string\",\"value\":\"override2\"}") + setByBroadcast("2", "override2") + verifyPutData("2", "{\"type\":\"string\",\"value\":\"override2\"}") } @Test fun setFlag_ClearsCache() { val flag1 = addFlag(StringFlag(1, "1", "test", "flag1")) - whenever(flagManager.readFlagValue<String>(eq(1), any())).thenReturn("original") + whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("original") // gets the flag & cache it assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("original") - verify(flagManager).readFlagValue(eq(1), eq(StringFlagSerializer)) + verify(flagManager, times(1)).readFlagValue(eq("1"), eq(StringFlagSerializer)) // hit the cache assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("original") verifyNoMoreInteractions(flagManager) // set the flag - setByBroadcast(1, "new") - verifyPutData(1, "{\"type\":\"string\",\"value\":\"new\"}", numReads = 2) - whenever(flagManager.readFlagValue<String>(eq(1), any())).thenReturn("new") + setByBroadcast("1", "new") + verifyPutData("1", "{\"type\":\"string\",\"value\":\"new\"}", numReads = 2) + whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("new") assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("new") - verify(flagManager, times(3)).readFlagValue(eq(1), eq(StringFlagSerializer)) + verify(flagManager, times(3)).readFlagValue(eq("1"), eq(StringFlagSerializer)) } @Test @@ -463,7 +466,6 @@ class FeatureFlagsDebugTest : SysuiTestCase() { val flag = UnreleasedFlag(100, name = "100", namespace = "test") serverFlagReader.setFlagValue(flag.namespace, flag.name, true) - assertThat(mFeatureFlagsDebug.isEnabled(flag)).isTrue() } @@ -503,26 +505,26 @@ class FeatureFlagsDebugTest : SysuiTestCase() { assertThat(dump).contains(" sysui_flag_7: [length=9] \"override7\"\n") } - private fun verifyPutData(id: Int, data: String, numReads: Int = 1) { - inOrder(flagManager, secureSettings).apply { - verify(flagManager, times(numReads)).readFlagValue(eq(id), any<FlagSerializer<*>>()) - verify(flagManager).idToSettingsKey(eq(id)) - verify(secureSettings).putStringForUser(eq("key-$id"), eq(data), anyInt()) - verify(flagManager).dispatchListenersAndMaybeRestart(eq(id), any()) + private fun verifyPutData(name: String, data: String, numReads: Int = 1) { + inOrder(flagManager, globalSettings).apply { + verify(flagManager, times(numReads)).readFlagValue(eq(name), any<FlagSerializer<*>>()) + verify(flagManager).nameToSettingsKey(eq(name)) + verify(globalSettings).putStringForUser(eq("key-$name"), eq(data), anyInt()) + verify(flagManager).dispatchListenersAndMaybeRestart(eq(name), any()) }.verifyNoMoreInteractions() - verifyNoMoreInteractions(flagManager, secureSettings) + verifyNoMoreInteractions(flagManager, globalSettings) } - private fun setByBroadcast(id: Int, value: Serializable?) { + private fun setByBroadcast(name: String, value: Serializable?) { val intent = Intent(FlagManager.ACTION_SET_FLAG) - intent.putExtra(FlagManager.EXTRA_ID, id) + intent.putExtra(FlagManager.EXTRA_NAME, name) intent.putExtra(FlagManager.EXTRA_VALUE, value) broadcastReceiver.onReceive(mockContext, intent) } private fun <F : Flag<*>> addFlag(flag: F): F { - val old = flagMap.put(flag.id, flag) - check(old == null) { "Flag ${flag.id} already registered" } + val old = flagMap.put(flag.name, flag) + check(old == null) { "Flag ${flag.name} already registered" } return flag } diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt index d5b5a4a4101e..4c6028c4c9b7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt @@ -19,7 +19,6 @@ import android.content.pm.PackageManager.NameNotFoundException import android.content.res.Resources import android.test.suitebuilder.annotation.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.util.DeviceConfigProxyFake import com.google.common.truth.Truth.assertThat import org.junit.Assert.assertThrows import org.junit.Before @@ -39,9 +38,8 @@ class FeatureFlagsReleaseTest : SysuiTestCase() { @Mock private lateinit var mResources: Resources @Mock private lateinit var mSystemProperties: SystemPropertiesHelper @Mock private lateinit var restarter: Restarter - private val flagMap = mutableMapOf<Int, Flag<*>>() + private val flagMap = mutableMapOf<String, Flag<*>>() private val serverFlagReader = ServerFlagReaderFake() - private val deviceConfig = DeviceConfigProxyFake() @Before fun setup() { @@ -49,7 +47,6 @@ class FeatureFlagsReleaseTest : SysuiTestCase() { mFeatureFlagsRelease = FeatureFlagsRelease( mResources, mSystemProperties, - deviceConfig, serverFlagReader, flagMap, restarter) diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagCommandTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagCommandTest.kt index fea91c53424d..28131b50f04c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagCommandTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagCommandTest.kt @@ -32,7 +32,7 @@ class FlagCommandTest : SysuiTestCase() { @Mock private lateinit var featureFlags: FeatureFlagsDebug @Mock private lateinit var pw: PrintWriter - private val flagMap = mutableMapOf<Int, Flag<*>>() + private val flagMap = mutableMapOf<String, Flag<*>>() private val flagA = UnreleasedFlag(500, "500", "test") private val flagB = ReleasedFlag(501, "501", "test") private val stringFlag = StringFlag(502, "502", "test", "abracadabra") @@ -53,59 +53,59 @@ class FlagCommandTest : SysuiTestCase() { (invocation.getArgument(0) as IntFlag).default } - flagMap.put(flagA.id, flagA) - flagMap.put(flagB.id, flagB) - flagMap.put(stringFlag.id, stringFlag) - flagMap.put(intFlag.id, intFlag) + flagMap.put(flagA.name, flagA) + flagMap.put(flagB.name, flagB) + flagMap.put(stringFlag.name, stringFlag) + flagMap.put(intFlag.name, intFlag) cmd = FlagCommand(featureFlags, flagMap) } @Test fun readBooleanFlagCommand() { - cmd.execute(pw, listOf(flagA.id.toString())) + cmd.execute(pw, listOf(flagA.name)) Mockito.verify(featureFlags).isEnabled(flagA) } @Test fun readStringFlagCommand() { - cmd.execute(pw, listOf(stringFlag.id.toString())) + cmd.execute(pw, listOf(stringFlag.name)) Mockito.verify(featureFlags).getString(stringFlag) } @Test fun readIntFlag() { - cmd.execute(pw, listOf(intFlag.id.toString())) + cmd.execute(pw, listOf(intFlag.name)) Mockito.verify(featureFlags).getInt(intFlag) } @Test fun setBooleanFlagCommand() { - cmd.execute(pw, listOf(flagB.id.toString(), "on")) + cmd.execute(pw, listOf(flagB.name, "on")) Mockito.verify(featureFlags).setBooleanFlagInternal(flagB, true) } @Test fun setStringFlagCommand() { - cmd.execute(pw, listOf(stringFlag.id.toString(), "set", "foobar")) + cmd.execute(pw, listOf(stringFlag.name, "set", "foobar")) Mockito.verify(featureFlags).setStringFlagInternal(stringFlag, "foobar") } @Test fun setIntFlag() { - cmd.execute(pw, listOf(intFlag.id.toString(), "put", "123")) + cmd.execute(pw, listOf(intFlag.name, "put", "123")) Mockito.verify(featureFlags).setIntFlagInternal(intFlag, 123) } @Test fun toggleBooleanFlagCommand() { - cmd.execute(pw, listOf(flagB.id.toString(), "toggle")) + cmd.execute(pw, listOf(flagB.name, "toggle")) Mockito.verify(featureFlags).setBooleanFlagInternal(flagB, false) } @Test fun eraseFlagCommand() { - cmd.execute(pw, listOf(flagA.id.toString(), "erase")) + cmd.execute(pw, listOf(flagA.name, "erase")) Mockito.verify(featureFlags).eraseFlag(flagA) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt index fca7e96fb148..e679d47537b5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt @@ -87,14 +87,14 @@ class FlagManagerTest : SysuiTestCase() { @Test fun testObserverClearsCache() { val listener = mock<FlagListenable.Listener>() - val clearCacheAction = mock<Consumer<Int>>() + val clearCacheAction = mock<Consumer<String>>() mFlagManager.clearCacheAction = clearCacheAction mFlagManager.addListener(ReleasedFlag(1, "1", "test"), listener) val observer = withArgCaptor<ContentObserver> { verify(mFlagSettingsHelper).registerContentObserver(any(), any(), capture()) } observer.onChange(false, flagUri(1)) - verify(clearCacheAction).accept(eq(1)) + verify(clearCacheAction).accept(eq("1")) } @Test @@ -110,14 +110,14 @@ class FlagManagerTest : SysuiTestCase() { val flagEvent1 = withArgCaptor<FlagListenable.FlagEvent> { verify(listener1).onFlagChanged(capture()) } - assertThat(flagEvent1.flagId).isEqualTo(1) + assertThat(flagEvent1.flagName).isEqualTo("1") verifyNoMoreInteractions(listener1, listener10) observer.onChange(false, flagUri(10)) val flagEvent10 = withArgCaptor<FlagListenable.FlagEvent> { verify(listener10).onFlagChanged(capture()) } - assertThat(flagEvent10.flagId).isEqualTo(10) + assertThat(flagEvent10.flagName).isEqualTo("10") verifyNoMoreInteractions(listener1, listener10) } @@ -130,18 +130,18 @@ class FlagManagerTest : SysuiTestCase() { mFlagManager.addListener(ReleasedFlag(1, "1", "test"), listener1) mFlagManager.addListener(ReleasedFlag(10, "10", "test"), listener10) - mFlagManager.dispatchListenersAndMaybeRestart(1, null) + mFlagManager.dispatchListenersAndMaybeRestart("1", null) val flagEvent1 = withArgCaptor<FlagListenable.FlagEvent> { verify(listener1).onFlagChanged(capture()) } - assertThat(flagEvent1.flagId).isEqualTo(1) + assertThat(flagEvent1.flagName).isEqualTo("1") verifyNoMoreInteractions(listener1, listener10) - mFlagManager.dispatchListenersAndMaybeRestart(10, null) + mFlagManager.dispatchListenersAndMaybeRestart("10", null) val flagEvent10 = withArgCaptor<FlagListenable.FlagEvent> { verify(listener10).onFlagChanged(capture()) } - assertThat(flagEvent10.flagId).isEqualTo(10) + assertThat(flagEvent10.flagName).isEqualTo("10") verifyNoMoreInteractions(listener1, listener10) } @@ -151,25 +151,25 @@ class FlagManagerTest : SysuiTestCase() { mFlagManager.addListener(ReleasedFlag(1, "1", "test"), listener) mFlagManager.addListener(ReleasedFlag(10, "10", "test"), listener) - mFlagManager.dispatchListenersAndMaybeRestart(1, null) + mFlagManager.dispatchListenersAndMaybeRestart("1", null) val flagEvent1 = withArgCaptor<FlagListenable.FlagEvent> { verify(listener).onFlagChanged(capture()) } - assertThat(flagEvent1.flagId).isEqualTo(1) + assertThat(flagEvent1.flagName).isEqualTo("1") verifyNoMoreInteractions(listener) - mFlagManager.dispatchListenersAndMaybeRestart(10, null) + mFlagManager.dispatchListenersAndMaybeRestart("10", null) val flagEvent10 = withArgCaptor<FlagListenable.FlagEvent> { verify(listener, times(2)).onFlagChanged(capture()) } - assertThat(flagEvent10.flagId).isEqualTo(10) + assertThat(flagEvent10.flagName).isEqualTo("10") verifyNoMoreInteractions(listener) } @Test fun testRestartWithNoListeners() { val restartAction = mock<Consumer<Boolean>>() - mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction) + mFlagManager.dispatchListenersAndMaybeRestart("1", restartAction) verify(restartAction).accept(eq(false)) verifyNoMoreInteractions(restartAction) } @@ -180,7 +180,7 @@ class FlagManagerTest : SysuiTestCase() { mFlagManager.addListener(ReleasedFlag(1, "1", "test")) { event -> event.requestNoRestart() } - mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction) + mFlagManager.dispatchListenersAndMaybeRestart("1", restartAction) verify(restartAction).accept(eq(true)) verifyNoMoreInteractions(restartAction) } @@ -191,7 +191,7 @@ class FlagManagerTest : SysuiTestCase() { mFlagManager.addListener(ReleasedFlag(10, "10", "test")) { event -> event.requestNoRestart() } - mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction) + mFlagManager.dispatchListenersAndMaybeRestart("1", restartAction) verify(restartAction).accept(eq(false)) verifyNoMoreInteractions(restartAction) } @@ -205,7 +205,7 @@ class FlagManagerTest : SysuiTestCase() { mFlagManager.addListener(ReleasedFlag(10, "10", "test")) { // do not request } - mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction) + mFlagManager.dispatchListenersAndMaybeRestart("1", restartAction) verify(restartAction).accept(eq(false)) verifyNoMoreInteractions(restartAction) } @@ -214,31 +214,31 @@ class FlagManagerTest : SysuiTestCase() { fun testReadBooleanFlag() { // test that null string returns null whenever(mFlagSettingsHelper.getString(any())).thenReturn(null) - assertThat(mFlagManager.readFlagValue(1, BooleanFlagSerializer)).isNull() + assertThat(mFlagManager.readFlagValue("1", BooleanFlagSerializer)).isNull() // test that empty string returns null whenever(mFlagSettingsHelper.getString(any())).thenReturn("") - assertThat(mFlagManager.readFlagValue(1, BooleanFlagSerializer)).isNull() + assertThat(mFlagManager.readFlagValue("1", BooleanFlagSerializer)).isNull() // test false whenever(mFlagSettingsHelper.getString(any())) .thenReturn("{\"type\":\"boolean\",\"value\":false}") - assertThat(mFlagManager.readFlagValue(1, BooleanFlagSerializer)).isFalse() + assertThat(mFlagManager.readFlagValue("1", BooleanFlagSerializer)).isFalse() // test true whenever(mFlagSettingsHelper.getString(any())) .thenReturn("{\"type\":\"boolean\",\"value\":true}") - assertThat(mFlagManager.readFlagValue(1, BooleanFlagSerializer)).isTrue() + assertThat(mFlagManager.readFlagValue("1", BooleanFlagSerializer)).isTrue() // Reading a value of a different type should just return null whenever(mFlagSettingsHelper.getString(any())) .thenReturn("{\"type\":\"string\",\"value\":\"foo\"}") - assertThat(mFlagManager.readFlagValue(1, BooleanFlagSerializer)).isNull() + assertThat(mFlagManager.readFlagValue("1", BooleanFlagSerializer)).isNull() // Reading a value that isn't json should throw an exception assertThrows(InvalidFlagStorageException::class.java) { whenever(mFlagSettingsHelper.getString(any())).thenReturn("1") - mFlagManager.readFlagValue(1, BooleanFlagSerializer) + mFlagManager.readFlagValue("1", BooleanFlagSerializer) } } @@ -257,31 +257,31 @@ class FlagManagerTest : SysuiTestCase() { fun testReadStringFlag() { // test that null string returns null whenever(mFlagSettingsHelper.getString(any())).thenReturn(null) - assertThat(mFlagManager.readFlagValue(1, StringFlagSerializer)).isNull() + assertThat(mFlagManager.readFlagValue("1", StringFlagSerializer)).isNull() // test that empty string returns null whenever(mFlagSettingsHelper.getString(any())).thenReturn("") - assertThat(mFlagManager.readFlagValue(1, StringFlagSerializer)).isNull() + assertThat(mFlagManager.readFlagValue("1", StringFlagSerializer)).isNull() // test json with the empty string value returns empty string whenever(mFlagSettingsHelper.getString(any())) .thenReturn("{\"type\":\"string\",\"value\":\"\"}") - assertThat(mFlagManager.readFlagValue(1, StringFlagSerializer)).isEqualTo("") + assertThat(mFlagManager.readFlagValue("1", StringFlagSerializer)).isEqualTo("") // test string with value is returned whenever(mFlagSettingsHelper.getString(any())) .thenReturn("{\"type\":\"string\",\"value\":\"foo\"}") - assertThat(mFlagManager.readFlagValue(1, StringFlagSerializer)).isEqualTo("foo") + assertThat(mFlagManager.readFlagValue("1", StringFlagSerializer)).isEqualTo("foo") // Reading a value of a different type should just return null whenever(mFlagSettingsHelper.getString(any())) .thenReturn("{\"type\":\"boolean\",\"value\":false}") - assertThat(mFlagManager.readFlagValue(1, StringFlagSerializer)).isNull() + assertThat(mFlagManager.readFlagValue("1", StringFlagSerializer)).isNull() // Reading a value that isn't json should throw an exception assertThrows(InvalidFlagStorageException::class.java) { whenever(mFlagSettingsHelper.getString(any())).thenReturn("1") - mFlagManager.readFlagValue(1, StringFlagSerializer) + mFlagManager.readFlagValue("1", StringFlagSerializer) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt index 77c837b803af..a2dc1eb606ed 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt @@ -14,6 +14,7 @@ import org.junit.Test @SmallTest class FragmentServiceTest : SysuiTestCase() { private val fragmentCreator = TestFragmentCreator() + private val fragmenetHostManagerFactory: FragmentHostManager.Factory = mock() private val fragmentCreatorFactory = FragmentService.FragmentCreator.Factory { fragmentCreator } private lateinit var fragmentService: FragmentService @@ -24,7 +25,13 @@ class FragmentServiceTest : SysuiTestCase() { Looper.prepare() } - fragmentService = FragmentService(fragmentCreatorFactory, mock(), DumpManager()) + fragmentService = + FragmentService( + fragmentCreatorFactory, + fragmenetHostManagerFactory, + mock(), + DumpManager() + ) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt index e4e95e580a7c..5e5dc8b20c65 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt @@ -33,6 +33,7 @@ import com.android.systemui.media.controls.models.recommendation.SmartspaceMedia import com.android.systemui.media.controls.pipeline.EMPTY_SMARTSPACE_MEDIA_DATA import com.android.systemui.media.controls.pipeline.MediaDataManager import com.android.systemui.media.controls.ui.MediaHierarchyManager.Companion.LOCATION_QS +import com.android.systemui.media.controls.util.MediaFlags import com.android.systemui.media.controls.util.MediaUiEventLogger import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager @@ -87,6 +88,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { @Mock lateinit var smartspaceMediaData: SmartspaceMediaData @Mock lateinit var mediaCarousel: MediaScrollView @Mock lateinit var pageIndicator: PageIndicator + @Mock lateinit var mediaFlags: MediaFlags @Captor lateinit var listener: ArgumentCaptor<MediaDataManager.Listener> @Captor lateinit var configListener: ArgumentCaptor<ConfigurationController.ConfigurationListener> @@ -114,7 +116,8 @@ class MediaCarouselControllerTest : SysuiTestCase() { falsingManager, dumpManager, logger, - debugLogger + debugLogger, + mediaFlags, ) verify(configurationController).addCallback(capture(configListener)) verify(mediaDataManager).addListener(capture(listener)) diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt index b35dd266e422..ce22b19b3721 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt @@ -204,6 +204,9 @@ public class MediaControlPanelTest : SysuiTestCase() { @Mock private lateinit var coverContainer1: ViewGroup @Mock private lateinit var coverContainer2: ViewGroup @Mock private lateinit var coverContainer3: ViewGroup + @Mock private lateinit var recAppIconItem: CachingIconView + @Mock private lateinit var recCardTitle: TextView + @Mock private lateinit var coverItem: ImageView private lateinit var coverItem1: ImageView private lateinit var coverItem2: ImageView private lateinit var coverItem3: ImageView @@ -220,6 +223,7 @@ public class MediaControlPanelTest : SysuiTestCase() { this.set(Flags.UMO_TURBULENCE_NOISE, false) this.set(Flags.MEDIA_FALSING_PENALTY, true) this.set(Flags.MEDIA_EXPLICIT_INDICATOR, true) + this.set(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE, false) } @JvmField @Rule val mockito = MockitoJUnit.rule() @@ -2059,6 +2063,51 @@ public class MediaControlPanelTest : SysuiTestCase() { } @Test + fun bindRecommendation_setAfterExecutors() { + fakeFeatureFlag.set(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE, true) + whenever(recommendationViewHolder.mediaAppIcons) + .thenReturn(listOf(recAppIconItem, recAppIconItem, recAppIconItem)) + whenever(recommendationViewHolder.cardTitle).thenReturn(recCardTitle) + whenever(recommendationViewHolder.mediaCoverItems) + .thenReturn(listOf(coverItem, coverItem, coverItem)) + + val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888) + val canvas = Canvas(bmp) + canvas.drawColor(Color.RED) + val albumArt = Icon.createWithBitmap(bmp) + val data = + smartspaceData.copy( + recommendations = + listOf( + SmartspaceAction.Builder("id1", "title1") + .setSubtitle("subtitle1") + .setIcon(albumArt) + .setExtras(Bundle.EMPTY) + .build(), + SmartspaceAction.Builder("id2", "title2") + .setSubtitle("subtitle1") + .setIcon(albumArt) + .setExtras(Bundle.EMPTY) + .build(), + SmartspaceAction.Builder("id3", "title3") + .setSubtitle("subtitle1") + .setIcon(albumArt) + .setExtras(Bundle.EMPTY) + .build() + ) + ) + + player.attachRecommendation(recommendationViewHolder) + player.bindRecommendation(data) + bgExecutor.runAllReady() + mainExecutor.runAllReady() + + verify(recCardTitle).setTextColor(any<Int>()) + verify(recAppIconItem, times(3)).setImageDrawable(any(Drawable::class.java)) + verify(coverItem, times(3)).setImageDrawable(any(Drawable::class.java)) + } + + @Test fun onButtonClick_touchRippleFlagEnabled_playsTouchRipple() { fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true) val semanticActions = diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt index 4ed6d7cf6bd0..2f7eac2ad4ae 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt @@ -22,6 +22,7 @@ import android.view.View import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase +import com.android.systemui.media.controls.util.MediaFlags import com.android.systemui.util.animation.MeasurementInput import com.android.systemui.util.animation.TransitionLayout import com.android.systemui.util.animation.TransitionViewState @@ -55,6 +56,7 @@ class MediaViewControllerTest : SysuiTestCase() { @Mock private lateinit var mediaTitleWidgetState: WidgetState @Mock private lateinit var mediaSubTitleWidgetState: WidgetState @Mock private lateinit var mediaContainerWidgetState: WidgetState + @Mock private lateinit var mediaFlags: MediaFlags val delta = 0.1F @@ -64,7 +66,13 @@ class MediaViewControllerTest : SysuiTestCase() { fun setup() { MockitoAnnotations.initMocks(this) mediaViewController = - MediaViewController(context, configurationController, mediaHostStatesManager, logger) + MediaViewController( + context, + configurationController, + mediaHostStatesManager, + logger, + mediaFlags, + ) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java index 77daa3f1c207..5564774d2b70 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java @@ -31,6 +31,7 @@ import android.graphics.drawable.Icon; import android.testing.AndroidTestingRunner; import android.view.View; import android.widget.LinearLayout; +import android.widget.SeekBar; import androidx.core.graphics.drawable.IconCompat; import androidx.test.filters.SmallTest; @@ -45,6 +46,8 @@ import com.google.common.collect.ImmutableList; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import java.util.ArrayList; import java.util.List; @@ -72,6 +75,8 @@ public class MediaOutputAdapterTest extends SysuiTestCase { private IconCompat mIconCompat = mock(IconCompat.class); private View mDialogLaunchView = mock(View.class); + @Captor + private ArgumentCaptor<SeekBar.OnSeekBarChangeListener> mOnSeekBarChangeListenerCaptor; private MediaOutputAdapter mMediaOutputAdapter; private MediaOutputAdapter.MediaDeviceViewHolder mViewHolder; private List<MediaDevice> mMediaDevices = new ArrayList<>(); @@ -352,6 +357,24 @@ public class MediaOutputAdapterTest extends SysuiTestCase { } @Test + public void onBindViewHolder_dragSeekbar_setsVolume() { + mOnSeekBarChangeListenerCaptor = ArgumentCaptor.forClass( + SeekBar.OnSeekBarChangeListener.class); + MediaOutputSeekbar mSpySeekbar = spy(mViewHolder.mSeekBar); + mViewHolder.mSeekBar = mSpySeekbar; + when(mMediaDevice1.getMaxVolume()).thenReturn(TEST_MAX_VOLUME); + when(mMediaDevice1.getCurrentVolume()).thenReturn(TEST_MAX_VOLUME); + mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0); + + verify(mViewHolder.mSeekBar).setOnSeekBarChangeListener( + mOnSeekBarChangeListenerCaptor.capture()); + + mOnSeekBarChangeListenerCaptor.getValue().onStopTrackingTouch(mViewHolder.mSeekBar); + assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE); + verify(mMediaOutputController).logInteractionAdjustVolume(mMediaDevice1); + } + + @Test public void onBindViewHolder_bindSelectableDevice_verifyView() { List<MediaDevice> selectableDevices = new ArrayList<>(); selectableDevices.add(mMediaDevice2); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java index 117751c47004..7c36e4680a72 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java @@ -93,6 +93,11 @@ public class MediaOutputControllerTest extends SysuiTestCase { private static final String TEST_SONG = "test_song"; private static final String TEST_SESSION_ID = "test_session_id"; private static final String TEST_SESSION_NAME = "test_session_name"; + private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); + private final ActivityLaunchAnimator.Controller mActivityLaunchAnimatorController = mock( + ActivityLaunchAnimator.Controller.class); + private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock( + NearbyMediaDevicesManager.class); // Mock private MediaController mMediaController = mock(MediaController.class); private MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class); @@ -111,12 +116,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { private KeyguardManager mKeyguardManager = mock(KeyguardManager.class); private PowerExemptionManager mPowerExemptionManager = mock(PowerExemptionManager.class); private CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class); - private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); private FeatureFlags mFlags = mock(FeatureFlags.class); - private final ActivityLaunchAnimator.Controller mActivityLaunchAnimatorController = mock( - ActivityLaunchAnimator.Controller.class); - private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock( - NearbyMediaDevicesManager.class); private View mDialogLaunchView = mock(View.class); private MediaOutputController.Callback mCallback = mock(MediaOutputController.Callback.class); @@ -522,6 +522,17 @@ public class MediaOutputControllerTest extends SysuiTestCase { } @Test + public void logInteractionAdjustVolume_triggersFromMetricLogger() { + MediaOutputMetricLogger spyMediaOutputMetricLogger = spy( + mMediaOutputController.mMetricLogger); + mMediaOutputController.mMetricLogger = spyMediaOutputMetricLogger; + + mMediaOutputController.logInteractionAdjustVolume(mMediaDevice1); + + verify(spyMediaOutputMetricLogger).logInteractionAdjustVolume(mMediaDevice1); + } + + @Test public void getSessionVolumeMax_triggersFromLocalMediaManager() { mMediaOutputController.getSessionVolumeMax(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDevicePolicyResolverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDevicePolicyResolverTest.kt new file mode 100644 index 000000000000..e8b6f9bd3478 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDevicePolicyResolverTest.kt @@ -0,0 +1,703 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.mediaprojection.devicepolicy + +import android.app.admin.DevicePolicyManager +import android.os.UserHandle +import android.os.UserManager +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +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.assertWithMessage +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.junit.runners.Parameterized.Parameters +import org.mockito.ArgumentMatchers.any + +abstract class BaseScreenCaptureDevicePolicyResolverTest(private val precondition: Preconditions) : + SysuiTestCase() { + + abstract class Preconditions( + val personalScreenCaptureDisabled: Boolean, + val workScreenCaptureDisabled: Boolean, + val disallowShareIntoManagedProfile: Boolean + ) + + protected val devicePolicyManager: DevicePolicyManager = mock() + protected val userManager: UserManager = mock() + + protected val personalUserHandle: UserHandle = UserHandle.of(123) + protected val workUserHandle: UserHandle = UserHandle.of(456) + + protected val policyResolver = + ScreenCaptureDevicePolicyResolver( + devicePolicyManager, + userManager, + personalUserHandle, + workUserHandle + ) + + @Before + fun setUp() { + setUpPolicies() + } + + private fun setUpPolicies() { + whenever( + devicePolicyManager.getScreenCaptureDisabled( + any(), + eq(personalUserHandle.identifier) + ) + ) + .thenReturn(precondition.personalScreenCaptureDisabled) + + whenever(devicePolicyManager.getScreenCaptureDisabled(any(), eq(workUserHandle.identifier))) + .thenReturn(precondition.workScreenCaptureDisabled) + + whenever( + userManager.hasUserRestrictionForUser( + eq(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE), + eq(workUserHandle) + ) + ) + .thenReturn(precondition.disallowShareIntoManagedProfile) + } +} + +@RunWith(Parameterized::class) +@SmallTest +class IsAllowedScreenCaptureDevicePolicyResolverTest( + private val test: IsScreenCaptureAllowedTestCase +) : BaseScreenCaptureDevicePolicyResolverTest(test.given) { + + companion object { + @Parameters(name = "{0}") + @JvmStatic + fun getParams() = + listOf( + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false, + ), + expectedScreenCaptureAllowed = true, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true, + ), + expectedScreenCaptureAllowed = true, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false, + ), + expectedScreenCaptureAllowed = true, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true, + ), + expectedScreenCaptureAllowed = true, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = true, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = true, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = true, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = true, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = true, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = true, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = true, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureAllowed = false, + ), + IsScreenCaptureAllowedTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + isTargetInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureAllowed = false, + ), + ) + } + + class Preconditions( + personalScreenCaptureDisabled: Boolean, + workScreenCaptureDisabled: Boolean, + disallowShareIntoManagedProfile: Boolean, + val isHostInWorkProfile: Boolean, + val isTargetInWorkProfile: Boolean, + ) : + BaseScreenCaptureDevicePolicyResolverTest.Preconditions( + personalScreenCaptureDisabled, + workScreenCaptureDisabled, + disallowShareIntoManagedProfile + ) + + data class IsScreenCaptureAllowedTestCase( + val given: Preconditions, + val expectedScreenCaptureAllowed: Boolean + ) { + override fun toString(): String = + "isScreenCaptureAllowed: " + + "host[${if (given.isHostInWorkProfile) "work" else "personal"} profile], " + + "target[${if (given.isTargetInWorkProfile) "work" else "personal"} profile], " + + "personal screen capture disabled = ${given.personalScreenCaptureDisabled}, " + + "work screen capture disabled = ${given.workScreenCaptureDisabled}, " + + "disallow share into managed profile = ${given.disallowShareIntoManagedProfile}, " + + "expected screen capture allowed = $expectedScreenCaptureAllowed" + } + + @Test + fun test() { + val targetAppUserHandle = + if (test.given.isTargetInWorkProfile) workUserHandle else personalUserHandle + val hostAppUserHandle = + if (test.given.isHostInWorkProfile) workUserHandle else personalUserHandle + + val screenCaptureAllowed = + policyResolver.isScreenCaptureAllowed(targetAppUserHandle, hostAppUserHandle) + + assertWithMessage("Screen capture policy resolved incorrectly") + .that(screenCaptureAllowed) + .isEqualTo(test.expectedScreenCaptureAllowed) + } +} + +@RunWith(Parameterized::class) +@SmallTest +class IsCompletelyNotAllowedScreenCaptureDevicePolicyResolverTest( + private val test: IsScreenCaptureCompletelyDisabledTestCase +) : BaseScreenCaptureDevicePolicyResolverTest(test.given) { + + companion object { + @Parameters(name = "{0}") + @JvmStatic + fun getParams() = + listOf( + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureCompletelyDisabled = false, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureCompletelyDisabled = false, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureCompletelyDisabled = false, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureCompletelyDisabled = false, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureCompletelyDisabled = true, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureCompletelyDisabled = true, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureCompletelyDisabled = true, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = false, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureCompletelyDisabled = true, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureCompletelyDisabled = false, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureCompletelyDisabled = false, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureCompletelyDisabled = true, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + personalScreenCaptureDisabled = false, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureCompletelyDisabled = true, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureCompletelyDisabled = false, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = false, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureCompletelyDisabled = false, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = false + ), + expectedScreenCaptureCompletelyDisabled = true, + ), + IsScreenCaptureCompletelyDisabledTestCase( + given = + Preconditions( + isHostInWorkProfile = true, + personalScreenCaptureDisabled = true, + workScreenCaptureDisabled = true, + disallowShareIntoManagedProfile = true + ), + expectedScreenCaptureCompletelyDisabled = true, + ) + ) + } + + class Preconditions( + personalScreenCaptureDisabled: Boolean, + workScreenCaptureDisabled: Boolean, + disallowShareIntoManagedProfile: Boolean, + val isHostInWorkProfile: Boolean, + ) : + BaseScreenCaptureDevicePolicyResolverTest.Preconditions( + personalScreenCaptureDisabled, + workScreenCaptureDisabled, + disallowShareIntoManagedProfile + ) + + data class IsScreenCaptureCompletelyDisabledTestCase( + val given: Preconditions, + val expectedScreenCaptureCompletelyDisabled: Boolean + ) { + override fun toString(): String = + "isScreenCaptureCompletelyDisabled: " + + "host[${if (given.isHostInWorkProfile) "work" else "personal"} profile], " + + "personal screen capture disabled = ${given.personalScreenCaptureDisabled}, " + + "work screen capture disabled = ${given.workScreenCaptureDisabled}, " + + "disallow share into managed profile = ${given.disallowShareIntoManagedProfile}, " + + "expected screen capture completely disabled = $expectedScreenCaptureCompletelyDisabled" + } + + @Test + fun test() { + val hostAppUserHandle = + if (test.given.isHostInWorkProfile) workUserHandle else personalUserHandle + + val completelyDisabled = policyResolver.isScreenCaptureCompletelyDisabled(hostAppUserHandle) + + assertWithMessage("Screen capture policy resolved incorrectly") + .that(completelyDisabled) + .isEqualTo(test.expectedScreenCaptureCompletelyDisabled) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/model/SysUiStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/model/SysUiStateTest.java index 9bcfd5b2ae52..1a93adc7a631 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/model/SysUiStateTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/model/SysUiStateTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.verify; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.settings.FakeDisplayTracker; import org.junit.Before; import org.junit.Test; @@ -46,7 +47,8 @@ public class SysUiStateTest extends SysuiTestCase { @Before public void setup() { - mFlagsContainer = new SysUiState(); + FakeDisplayTracker displayTracker = new FakeDisplayTracker(mContext); + mFlagsContainer = new SysUiState(displayTracker); mCallback = mock(SysUiState.SysUiStateCallback.class); mFlagsContainer.addCallback(mCallback); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java index 92652a788bcb..3eb73290636f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java @@ -40,6 +40,7 @@ import com.android.systemui.SysuiTestableContext; import com.android.systemui.assist.AssistManager; import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.statusbar.policy.KeyguardStateController; import org.junit.After; @@ -65,6 +66,7 @@ public class NavigationBarButtonTest extends SysuiTestCase { private ImageReader mReader; private NavigationBarView mNavBar; private VirtualDisplay mVirtualDisplay; + private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); @Before public void setup() { @@ -83,6 +85,7 @@ public class NavigationBarButtonTest extends SysuiTestCase { mDependency.injectTestDependency(EdgeBackGestureHandler.Factory.class, mEdgeBackGestureHandlerFactory); mNavBar = new NavigationBarView(context, null); + mNavBar.setDisplayTracker(mDisplayTracker); } private Display createVirtualDisplay() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java index 8058b85e205a..2212bbda8021 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java @@ -50,6 +50,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.model.SysUiState; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.shared.recents.utilities.Utilities; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.systemui.statusbar.CommandQueue; @@ -81,6 +82,7 @@ public class NavigationBarControllerTest extends SysuiTestCase { private NavigationBar mDefaultNavBar; private NavigationBar mSecondaryNavBar; private StaticMockitoSession mMockitoSession; + private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); @Mock private CommandQueue mCommandQueue; @@ -110,7 +112,8 @@ public class NavigationBarControllerTest extends SysuiTestCase { Optional.of(mock(Pip.class)), Optional.of(mock(BackAnimation.class)), mock(FeatureFlags.class), - mock(SecureSettings.class))); + mock(SecureSettings.class), + mDisplayTracker)); initializeNavigationBars(); mMockitoSession = mockitoSession().mockStatic(Utilities.class).startMocking(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java index 2ad865e6ef11..764ddc49d110 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java @@ -87,6 +87,7 @@ import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.settings.UserContextProvider; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.NotificationShadeWindowView; @@ -495,7 +496,8 @@ public class NavigationBarTest extends SysuiTestCase { Optional.of(mock(BackAnimation.class)), mUserContextProvider, mWakefulnessLifecycle, - mTaskStackChangeListeners)); + mTaskStackChangeListeners, + new FakeDisplayTracker(mContext))); } private void processAllMessages() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java index cafd2cf7cea0..54e6509ba5b7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java @@ -36,6 +36,7 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.statusbar.phone.BarTransitions; import com.android.systemui.statusbar.phone.LightBarTransitionsController; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -63,6 +64,7 @@ public class NavigationBarTransitionsTest extends SysuiTestCase { IWindowManager mIWindowManager; private NavigationBarTransitions mTransitions; + private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); @Before public void setup() { @@ -86,7 +88,7 @@ public class NavigationBarTransitionsTest extends SysuiTestCase { when(navBar.getCurrentView()).thenReturn(navBar); when(navBar.findViewById(anyInt())).thenReturn(navBar); mTransitions = new NavigationBarTransitions( - navBar, mIWindowManager, mLightBarTransitionsFactory); + navBar, mIWindowManager, mLightBarTransitionsFactory, mDisplayTracker); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt index 36e02cb1df06..bc67df6507fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt @@ -16,40 +16,50 @@ import org.junit.runners.Parameterized internal class FloatingRotationButtonPositionCalculatorTest(private val testCase: TestCase) : SysuiTestCase() { - private val calculator = FloatingRotationButtonPositionCalculator( - MARGIN_DEFAULT, MARGIN_TASKBAR_LEFT, MARGIN_TASKBAR_BOTTOM - ) - @Test fun calculatePosition() { - val position = calculator.calculatePosition( + val position = testCase.calculator.calculatePosition( testCase.rotation, testCase.taskbarVisible, testCase.taskbarStashed ) - assertThat(position).isEqualTo(testCase.expectedPosition) } internal class TestCase( + val calculator: FloatingRotationButtonPositionCalculator, val rotation: Int, val taskbarVisible: Boolean, val taskbarStashed: Boolean, val expectedPosition: Position ) { override fun toString(): String = - "when rotation = $rotation, " + + "when calculator = $calculator, " + + "rotation = $rotation, " + "taskbarVisible = $taskbarVisible, " + "taskbarStashed = $taskbarStashed - " + "expected $expectedPosition" } companion object { + private const val MARGIN_DEFAULT = 10 + private const val MARGIN_TASKBAR_LEFT = 20 + private const val MARGIN_TASKBAR_BOTTOM = 30 + + private val posLeftCalculator = FloatingRotationButtonPositionCalculator( + MARGIN_DEFAULT, MARGIN_TASKBAR_LEFT, MARGIN_TASKBAR_BOTTOM, true + ) + private val posRightCalculator = FloatingRotationButtonPositionCalculator( + MARGIN_DEFAULT, MARGIN_TASKBAR_LEFT, MARGIN_TASKBAR_BOTTOM, false + ) + @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): Collection<TestCase> = listOf( + // Position left TestCase( + calculator = posLeftCalculator, rotation = Surface.ROTATION_0, taskbarVisible = false, taskbarStashed = false, @@ -60,6 +70,7 @@ internal class FloatingRotationButtonPositionCalculatorTest(private val testCase ) ), TestCase( + calculator = posLeftCalculator, rotation = Surface.ROTATION_90, taskbarVisible = false, taskbarStashed = false, @@ -70,6 +81,7 @@ internal class FloatingRotationButtonPositionCalculatorTest(private val testCase ) ), TestCase( + calculator = posLeftCalculator, rotation = Surface.ROTATION_180, taskbarVisible = false, taskbarStashed = false, @@ -80,6 +92,7 @@ internal class FloatingRotationButtonPositionCalculatorTest(private val testCase ) ), TestCase( + calculator = posLeftCalculator, rotation = Surface.ROTATION_270, taskbarVisible = false, taskbarStashed = false, @@ -90,6 +103,7 @@ internal class FloatingRotationButtonPositionCalculatorTest(private val testCase ) ), TestCase( + calculator = posLeftCalculator, rotation = Surface.ROTATION_0, taskbarVisible = true, taskbarStashed = false, @@ -100,6 +114,7 @@ internal class FloatingRotationButtonPositionCalculatorTest(private val testCase ) ), TestCase( + calculator = posLeftCalculator, rotation = Surface.ROTATION_0, taskbarVisible = true, taskbarStashed = true, @@ -110,6 +125,7 @@ internal class FloatingRotationButtonPositionCalculatorTest(private val testCase ) ), TestCase( + calculator = posLeftCalculator, rotation = Surface.ROTATION_90, taskbarVisible = true, taskbarStashed = false, @@ -118,11 +134,86 @@ internal class FloatingRotationButtonPositionCalculatorTest(private val testCase translationX = -MARGIN_TASKBAR_LEFT, translationY = -MARGIN_TASKBAR_BOTTOM ) + ), + + // Position right + TestCase( + calculator = posRightCalculator, + rotation = Surface.ROTATION_0, + taskbarVisible = false, + taskbarStashed = false, + expectedPosition = Position( + gravity = Gravity.BOTTOM or Gravity.RIGHT, + translationX = -MARGIN_DEFAULT, + translationY = -MARGIN_DEFAULT + ) + ), + TestCase( + calculator = posRightCalculator, + rotation = Surface.ROTATION_90, + taskbarVisible = false, + taskbarStashed = false, + expectedPosition = Position( + gravity = Gravity.TOP or Gravity.RIGHT, + translationX = -MARGIN_DEFAULT, + translationY = MARGIN_DEFAULT + ) + ), + TestCase( + calculator = posRightCalculator, + rotation = Surface.ROTATION_180, + taskbarVisible = false, + taskbarStashed = false, + expectedPosition = Position( + gravity = Gravity.TOP or Gravity.LEFT, + translationX = MARGIN_DEFAULT, + translationY = MARGIN_DEFAULT + ) + ), + TestCase( + calculator = posRightCalculator, + rotation = Surface.ROTATION_270, + taskbarVisible = false, + taskbarStashed = false, + expectedPosition = Position( + gravity = Gravity.BOTTOM or Gravity.LEFT, + translationX = MARGIN_DEFAULT, + translationY = -MARGIN_DEFAULT + ) + ), + TestCase( + calculator = posRightCalculator, + rotation = Surface.ROTATION_0, + taskbarVisible = true, + taskbarStashed = false, + expectedPosition = Position( + gravity = Gravity.BOTTOM or Gravity.RIGHT, + translationX = -MARGIN_TASKBAR_LEFT, + translationY = -MARGIN_TASKBAR_BOTTOM + ) + ), + TestCase( + calculator = posRightCalculator, + rotation = Surface.ROTATION_0, + taskbarVisible = true, + taskbarStashed = true, + expectedPosition = Position( + gravity = Gravity.BOTTOM or Gravity.RIGHT, + translationX = -MARGIN_DEFAULT, + translationY = -MARGIN_DEFAULT + ) + ), + TestCase( + calculator = posRightCalculator, + rotation = Surface.ROTATION_90, + taskbarVisible = true, + taskbarStashed = false, + expectedPosition = Position( + gravity = Gravity.TOP or Gravity.RIGHT, + translationX = -MARGIN_TASKBAR_LEFT, + translationY = MARGIN_TASKBAR_BOTTOM + ) ) ) - - private const val MARGIN_DEFAULT = 10 - private const val MARGIN_TASKBAR_LEFT = 20 - private const val MARGIN_TASKBAR_BOTTOM = 30 } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java index 42ef9c2914ce..4caa50fa847d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java @@ -60,6 +60,7 @@ import com.android.systemui.qs.dagger.QSFragmentComponent; import com.android.systemui.qs.external.TileServiceRequestController; import com.android.systemui.qs.footer.ui.binder.FooterActionsViewBinder; import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; @@ -494,7 +495,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest { @Override protected Fragment instantiate(Context context, String className, Bundle arguments) { MockitoAnnotations.initMocks(this); - CommandQueue commandQueue = new CommandQueue(context); + CommandQueue commandQueue = new CommandQueue(context, new FakeDisplayTracker(context)); setupQsComponent(); setUpViews(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt index 2bd068a674ae..d6dfc8509165 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt @@ -35,12 +35,14 @@ import android.view.View import com.android.internal.logging.MetricsLogger import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityLaunchAnimator +import com.android.systemui.animation.LaunchableFrameLayout import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.qs.QSTile import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.QSHost import com.android.systemui.qs.logging.QSLogger +import com.android.systemui.settings.FakeDisplayTracker import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.nullable @@ -87,6 +89,7 @@ class CustomTileTest : SysuiTestCase() { @Mock private lateinit var serviceInfo: ServiceInfo @Mock private lateinit var customTileStatePersister: CustomTileStatePersister + private var displayTracker = FakeDisplayTracker(mContext) private lateinit var customTile: CustomTile private lateinit var testableLooper: TestableLooper private lateinit var customTileBuilder: CustomTile.Builder @@ -119,7 +122,8 @@ class CustomTileTest : SysuiTestCase() { activityStarter, qsLogger, customTileStatePersister, - tileServices + tileServices, + displayTracker ) customTile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext) @@ -339,7 +343,7 @@ class CustomTileTest : SysuiTestCase() { val tile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext) tile.qsTile.activityLaunchForClick = pi - tile.handleClick(mock(View::class.java)) + tile.handleClick(mock(LaunchableFrameLayout::class.java)) testableLooper.processAllMessages() diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java index e1eda117177d..7d583258e4e5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java @@ -39,6 +39,7 @@ import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.statusbar.phone.CentralSurfaces; @@ -67,6 +68,7 @@ public class ActionProxyReceiverTest extends SysuiTestCase { private PendingIntent mMockPendingIntent; private Intent mIntent; + private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); @Before public void setup() throws InterruptedException, ExecutionException, TimeoutException { @@ -135,10 +137,11 @@ public class ActionProxyReceiverTest extends SysuiTestCase { if (withStatusBar) { return new ActionProxyReceiver( Optional.of(mMockCentralSurfaces), mMockActivityManagerWrapper, - mMockScreenshotSmartActions); + mMockScreenshotSmartActions, mDisplayTracker); } else { return new ActionProxyReceiver( - Optional.empty(), mMockActivityManagerWrapper, mMockScreenshotSmartActions); + Optional.empty(), mMockActivityManagerWrapper, mMockScreenshotSmartActions, + mDisplayTracker); } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt index 17396b13036c..ee61f5736263 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt @@ -31,6 +31,7 @@ import android.os.UserManager import android.testing.AndroidTestingRunner import com.android.systemui.SysuiTestCase import com.android.systemui.screenshot.ScreenshotPolicy.DisplayContentInfo +import com.android.systemui.settings.FakeDisplayTracker import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.Dispatchers @@ -126,8 +127,10 @@ class ScreenshotPolicyImplTest : SysuiTestCase() { val userManager = mock<UserManager>() val atmService = mock<IActivityTaskManager>() val dispatcher = Dispatchers.Unconfined + val displayTracker = FakeDisplayTracker(context) - return object : ScreenshotPolicyImpl(context, userManager, atmService, dispatcher) { + return object : ScreenshotPolicyImpl(context, userManager, atmService, dispatcher, + displayTracker) { override suspend fun isManagedProfile(userId: Int) = (userId == MANAGED_PROFILE_USER) override suspend fun getAllRootTaskInfosOnDisplay(displayId: Int) = tasks override suspend fun isNotificationShadeExpanded() = shadeExpanded diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java index bd04b3ccc039..e8905ab22bc0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java @@ -65,7 +65,7 @@ public class WorkProfileMessageControllerTest { @Mock private Context mContext; @Mock - private WorkProfileMessageController.WorkProfileMessageDisplay mMessageDisplay; + private MessageContainerController mMessageDisplay; @Mock private Drawable mActivityIcon; @Mock diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/DisplayTrackerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/DisplayTrackerImplTest.kt new file mode 100644 index 000000000000..ae976a0ea703 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/settings/DisplayTrackerImplTest.kt @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.settings + +import android.hardware.display.DisplayManager +import android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS +import android.hardware.display.DisplayManagerGlobal +import android.os.Handler +import android.testing.AndroidTestingRunner +import android.view.Display +import android.view.DisplayAdjustments +import android.view.DisplayInfo +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import java.util.concurrent.Executor +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.any +import org.mockito.Mockito.eq +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class DisplayTrackerImplTest : SysuiTestCase() { + @Mock private lateinit var displayManager: DisplayManager + @Mock private lateinit var handler: Handler + + private val executor = Executor(Runnable::run) + private lateinit var mDefaultDisplay: Display + private lateinit var mSecondaryDisplay: Display + private lateinit var tracker: DisplayTrackerImpl + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + mDefaultDisplay = + Display( + DisplayManagerGlobal.getInstance(), + Display.DEFAULT_DISPLAY, + DisplayInfo(), + DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS + ) + mSecondaryDisplay = + Display( + DisplayManagerGlobal.getInstance(), + Display.DEFAULT_DISPLAY + 1, + DisplayInfo(), + DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS + ) + + `when`(displayManager.displays).thenReturn(arrayOf(mDefaultDisplay, mSecondaryDisplay)) + + tracker = DisplayTrackerImpl(displayManager, handler) + } + + @Test + fun testGetDefaultDisplay() { + assertThat(tracker.defaultDisplayId).isEqualTo(Display.DEFAULT_DISPLAY) + } + + @Test + fun testGetAllDisplays() { + assertThat(tracker.allDisplays).isEqualTo(arrayOf(mDefaultDisplay, mSecondaryDisplay)) + } + + @Test + fun registerCallback_registersDisplayListener() { + tracker.addDisplayChangeCallback(TestCallback(), executor) + verify(displayManager).registerDisplayListener(any(), any()) + } + + @Test + fun registerBrightnessCallback_registersDisplayListener() { + tracker.addBrightnessChangeCallback(TestCallback(), executor) + verify(displayManager) + .registerDisplayListener(any(), any(), eq(EVENT_FLAG_DISPLAY_BRIGHTNESS)) + } + + @Test + fun unregisterCallback_displayListenerStillRegistered() { + val callback1 = TestCallback() + tracker.addDisplayChangeCallback(callback1, executor) + tracker.addDisplayChangeCallback(TestCallback(), executor) + tracker.removeCallback(callback1) + + verify(displayManager, never()).unregisterDisplayListener(any()) + } + + @Test + fun unregisterLastCallback_unregistersDisplayListener() { + val callback = TestCallback() + tracker.addDisplayChangeCallback(callback, executor) + tracker.removeCallback(callback) + + verify(displayManager).unregisterDisplayListener(any()) + } + + @Test + fun callbackCalledOnDisplayAdd() { + val testDisplay = 2 + val callback = TestCallback() + tracker.addDisplayChangeCallback(callback, executor) + tracker.displayChangedListener.onDisplayAdded(testDisplay) + + assertThat(callback.lastDisplayAdded).isEqualTo(testDisplay) + } + + @Test + fun callbackCalledOnDisplayRemoved() { + val testDisplay = 2 + val callback = TestCallback() + tracker.addDisplayChangeCallback(callback, executor) + tracker.displayChangedListener.onDisplayRemoved(testDisplay) + + assertThat(callback.lastDisplayRemoved).isEqualTo(testDisplay) + } + + @Test + fun callbackCalledOnDisplayChanged() { + val testDisplay = 2 + val callback = TestCallback() + tracker.addDisplayChangeCallback(callback, executor) + tracker.displayChangedListener.onDisplayChanged(testDisplay) + + assertThat(callback.lastDisplayChanged).isEqualTo(testDisplay) + } + + @Test + fun callbackCalledOnBrightnessChanged() { + val testDisplay = 2 + val callback = TestCallback() + tracker.addBrightnessChangeCallback(callback, executor) + tracker.displayBrightnessChangedListener.onDisplayChanged(testDisplay) + + assertThat(callback.lastDisplayChanged).isEqualTo(testDisplay) + } + + private class TestCallback : DisplayTracker.Callback { + var lastDisplayAdded = -1 + var lastDisplayRemoved = -1 + var lastDisplayChanged = -1 + + override fun onDisplayAdded(displayId: Int) { + lastDisplayAdded = displayId + } + + override fun onDisplayRemoved(displayId: Int) { + lastDisplayRemoved = displayId + } + + override fun onDisplayChanged(displayId: Int) { + lastDisplayChanged = displayId + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt index 9d1802a686fa..764619340592 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt @@ -28,6 +28,7 @@ import androidx.test.rule.ActivityTestRule import androidx.test.runner.intercepting.SingleActivityFactory import com.android.systemui.R import com.android.systemui.SysuiTestCase +import com.android.systemui.settings.FakeDisplayTracker import com.android.systemui.settings.UserTracker import com.android.systemui.util.mockito.any import com.google.common.truth.Truth.assertThat @@ -52,6 +53,8 @@ class BrightnessDialogTest : SysuiTestCase() { @Mock private lateinit var backgroundHandler: Handler @Mock private lateinit var brightnessSliderController: BrightnessSliderController + private var displayTracker = FakeDisplayTracker(mContext) + @Rule @JvmField var activityRule = @@ -60,6 +63,7 @@ class BrightnessDialogTest : SysuiTestCase() { override fun create(intent: Intent?): TestDialog { return TestDialog( userTracker, + displayTracker, brightnessSliderControllerFactory, mainExecutor, backgroundHandler @@ -105,12 +109,14 @@ class BrightnessDialogTest : SysuiTestCase() { class TestDialog( userTracker: UserTracker, + displayTracker: FakeDisplayTracker, brightnessSliderControllerFactory: BrightnessSliderController.Factory, mainExecutor: Executor, backgroundHandler: Handler ) : BrightnessDialog( userTracker, + displayTracker, brightnessSliderControllerFactory, mainExecutor, backgroundHandler diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt index bdafc7df33bc..c915502ad42e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt @@ -13,8 +13,11 @@ import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags +import com.android.systemui.fragments.FragmentHostManager +import com.android.systemui.fragments.FragmentService import com.android.systemui.navigationbar.NavigationModeController import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener +import com.android.systemui.plugins.qs.QS import com.android.systemui.recents.OverviewProxyService import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener import com.android.systemui.util.concurrency.FakeExecutor @@ -29,6 +32,7 @@ import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito import org.mockito.Mockito.RETURNS_DEEP_STUBS +import org.mockito.Mockito.any import org.mockito.Mockito.anyInt import org.mockito.Mockito.doNothing import org.mockito.Mockito.eq @@ -69,6 +73,10 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { private lateinit var shadeExpansionStateManager: ShadeExpansionStateManager @Mock private lateinit var featureFlags: FeatureFlags + @Mock + private lateinit var fragmentService: FragmentService + @Mock + private lateinit var fragmentHostManager: FragmentHostManager @Captor lateinit var navigationModeCaptor: ArgumentCaptor<ModeChangedListener> @Captor @@ -77,6 +85,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { lateinit var windowInsetsCallbackCaptor: ArgumentCaptor<Consumer<WindowInsets>> @Captor lateinit var constraintSetCaptor: ArgumentCaptor<ConstraintSet> + @Captor + lateinit var attachStateListenerCaptor: ArgumentCaptor<View.OnAttachStateChangeListener> private lateinit var controller: NotificationsQSContainerController private lateinit var navigationModeCallback: ModeChangedListener @@ -91,8 +101,10 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { mContext.ensureTestableResources() whenever(notificationsQSContainer.context).thenReturn(mContext) whenever(notificationsQSContainer.resources).thenReturn(mContext.resources) + whenever(fragmentService.getFragmentHostManager(any())).thenReturn(fragmentHostManager) fakeSystemClock = FakeSystemClock() delayableExecutor = FakeExecutor(fakeSystemClock) + controller = NotificationsQSContainerController( notificationsQSContainer, navigationModeController, @@ -100,6 +112,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { largeScreenShadeHeaderController, shadeExpansionStateManager, featureFlags, + fragmentService, delayableExecutor ) @@ -114,9 +127,10 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { doNothing().`when`(notificationsQSContainer) .setInsetsChangedListener(windowInsetsCallbackCaptor.capture()) doNothing().`when`(notificationsQSContainer).applyConstraints(constraintSetCaptor.capture()) - + doNothing().`when`(notificationsQSContainer) + .addOnAttachStateChangeListener(attachStateListenerCaptor.capture()) controller.init() - controller.onViewAttached() + attachStateListenerCaptor.value.onViewAttachedToWindow(notificationsQSContainer) navigationModeCallback = navigationModeCaptor.value taskbarVisibilityCallback = taskbarVisibilityCaptor.value @@ -385,6 +399,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { largeScreenShadeHeaderController, shadeExpansionStateManager, featureFlags, + fragmentService, delayableExecutor ) controller.updateConstraints() @@ -426,6 +441,17 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { verify(largeScreenShadeHeaderController).startCustomizingAnimation(false, 100L) } + @Test + fun testTagListenerAdded() { + verify(fragmentHostManager).addTagListener(eq(QS.TAG), eq(notificationsQSContainer)) + } + + @Test + fun testTagListenerRemoved() { + attachStateListenerCaptor.value.onViewDetachedFromWindow(notificationsQSContainer) + verify(fragmentHostManager).removeTagListener(eq(QS.TAG), eq(notificationsQSContainer)) + } + private fun disableSplitShade() { setSplitShadeEnabled(false) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt index 4c768253202a..e5d5e3b8433a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt @@ -45,13 +45,16 @@ import com.android.systemui.statusbar.phone.CentralSurfaces import com.android.systemui.statusbar.phone.PhoneStatusBarViewController import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.android.systemui.statusbar.window.StatusBarWindowStateController +import com.android.systemui.util.mockito.any import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.Mock +import org.mockito.Mockito import org.mockito.Mockito.anyFloat +import org.mockito.Mockito.mock import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.Mockito.`when` as whenever @@ -102,7 +105,6 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { @Mock private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor @Mock lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory - @Mock lateinit var keyguardBouncerContainer: ViewGroup @Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent @Mock lateinit var keyguardHostViewController: KeyguardHostViewController @Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor @@ -116,6 +118,12 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) whenever(view.bottom).thenReturn(VIEW_BOTTOM) + whenever(view.findViewById<ViewGroup>(R.id.keyguard_bouncer_container)) + .thenReturn(mock(ViewGroup::class.java)) + whenever(keyguardBouncerComponentFactory.create(any(ViewGroup::class.java))) + .thenReturn(keyguardBouncerComponent) + whenever(keyguardBouncerComponent.keyguardHostViewController) + .thenReturn(keyguardHostViewController) underTest = NotificationShadeWindowViewController( lockscreenShadeTransitionController, FalsingCollectorFake(), @@ -275,6 +283,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { @Test fun testGetBouncerContainer() { + Mockito.clearInvocations(view) underTest.bouncerContainer verify(view).findViewById<ViewGroup>(R.id.keyguard_bouncer_container) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java index d43562443d6e..5cc3ef1def9e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java @@ -29,9 +29,11 @@ import android.os.SystemClock; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.MotionEvent; +import android.view.ViewGroup; import androidx.test.filters.SmallTest; +import com.android.keyguard.KeyguardHostViewController; import com.android.keyguard.LockIconViewController; import com.android.keyguard.dagger.KeyguardBouncerComponent; import com.android.systemui.R; @@ -94,6 +96,8 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase { @Mock private FeatureFlags mFeatureFlags; @Mock private KeyguardBouncerViewModel mKeyguardBouncerViewModel; @Mock private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory; + @Mock private KeyguardBouncerComponent mKeyguardBouncerComponent; + @Mock private KeyguardHostViewController mKeyguardHostViewController; @Mock private NotificationInsetsController mNotificationInsetsController; @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor; @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor; @@ -110,6 +114,12 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase { when(mView.findViewById(R.id.notification_stack_scroller)) .thenReturn(mNotificationStackScrollLayout); + when(mView.findViewById(R.id.keyguard_bouncer_container)).thenReturn(mock(ViewGroup.class)); + when(mKeyguardBouncerComponentFactory.create(any(ViewGroup.class))).thenReturn( + mKeyguardBouncerComponent); + when(mKeyguardBouncerComponent.getKeyguardHostViewController()).thenReturn( + mKeyguardHostViewController); + when(mStatusBarStateController.isDozing()).thenReturn(false); mDependency.injectTestDependency(ShadeController.class, mShadeController); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java index 0000c32aa60d..b1ca1c02f6da 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java @@ -46,6 +46,7 @@ import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.view.AppearanceRegion; import com.android.systemui.SysuiTestCase; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.statusbar.CommandQueue.Callbacks; import org.junit.After; @@ -63,12 +64,13 @@ public class CommandQueueTest extends SysuiTestCase { }; private CommandQueue mCommandQueue; + private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); private Callbacks mCallbacks; private static final int SECONDARY_DISPLAY = 1; @Before public void setup() { - mCommandQueue = new CommandQueue(mContext); + mCommandQueue = new CommandQueue(mContext, mDisplayTracker); mCallbacks = mock(Callbacks.class); mCommandQueue.addCallback(mCallbacks); verify(mCallbacks).disable(anyInt(), eq(0), eq(0), eq(false)); @@ -418,7 +420,7 @@ public class CommandQueueTest extends SysuiTestCase { @Test public void testOnDisplayRemoved() { - mCommandQueue.onDisplayRemoved(SECONDARY_DISPLAY); + mDisplayTracker.triggerOnDisplayRemoved(SECONDARY_DISPLAY); waitForIdleSync(); verify(mCallbacks).onDisplayRemoved(eq(SECONDARY_DISPLAY)); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt index ea066471a802..746544a3563f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt @@ -6,6 +6,7 @@ import android.view.InputEvent import android.view.MotionEvent import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.settings.FakeDisplayTracker import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test @@ -17,9 +18,11 @@ import org.junit.runner.RunWith class GenericGestureDetectorTest : SysuiTestCase() { private lateinit var gestureDetector: TestGestureDetector + private lateinit var displayTracker: FakeDisplayTracker @Before fun setUp() { + displayTracker = FakeDisplayTracker(mContext) gestureDetector = TestGestureDetector() } @@ -101,12 +104,21 @@ class GenericGestureDetectorTest : SysuiTestCase() { gestureDetector.addOnGestureDetectedCallback("tag2"){} gestureDetector.removeOnGestureDetectedCallback("tag") - gestureDetector.onInputEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, CORRECT_X, 0f, 0)) + gestureDetector.onInputEvent( + MotionEvent.obtain( + 0, + 0, + MotionEvent.ACTION_DOWN, + CORRECT_X, + 0f, + 0 + ) + ) assertThat(oldCallbackNotified).isFalse() } - inner class TestGestureDetector : GenericGestureDetector("fakeTag") { + inner class TestGestureDetector : GenericGestureDetector("fakeTag", displayTracker) { var isGestureListening = false override fun onInputEvent(ev: InputEvent) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt index 43b6e4144a2e..2423f13e6494 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt @@ -34,6 +34,7 @@ import android.widget.FrameLayout import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags +import com.android.systemui.flags.Flags import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.BcSmartspaceConfigPlugin import com.android.systemui.plugins.BcSmartspaceDataPlugin @@ -112,6 +113,9 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { private lateinit var handler: Handler @Mock + private lateinit var weatherPlugin: BcSmartspaceDataPlugin + + @Mock private lateinit var plugin: BcSmartspaceDataPlugin @Mock @@ -151,6 +155,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { KeyguardBypassController.OnBypassStateChangedListener private lateinit var deviceProvisionedListener: DeviceProvisionedListener + private lateinit var weatherSmartspaceView: SmartspaceView private lateinit var smartspaceView: SmartspaceView private val clock = FakeSystemClock() @@ -176,16 +181,22 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) + // Todo(b/261760571): flip the flag value here when feature is launched, and update relevant + // tests. + `when`(featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)).thenReturn(false) + `when`(secureSettings.getUriFor(PRIVATE_LOCKSCREEN_SETTING)) .thenReturn(fakePrivateLockscreenSettingUri) `when`(secureSettings.getUriFor(NOTIF_ON_LOCKSCREEN_SETTING)) .thenReturn(fakeNotifOnLockscreenSettingUri) `when`(smartspaceManager.createSmartspaceSession(any())).thenReturn(smartspaceSession) + `when`(weatherPlugin.getView(any())).thenReturn( + createWeatherSmartspaceView(), createWeatherSmartspaceView()) `when`(plugin.getView(any())).thenReturn(createSmartspaceView(), createSmartspaceView()) `when`(userTracker.userProfiles).thenReturn(userList) `when`(statusBarStateController.dozeAmount).thenReturn(0.5f) - `when`(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true) - `when`(deviceProvisionedController.isCurrentUserSetup()).thenReturn(true) + `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(true) setActiveUser(userHandlePrimary) setAllowPrivateNotifications(userHandlePrimary, true) @@ -210,6 +221,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { executor, bgExecutor, handler, + Optional.of(weatherPlugin), Optional.of(plugin), Optional.of(configPlugin), ) @@ -218,11 +230,22 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { deviceProvisionedListener = deviceProvisionedCaptor.value } + @Test(expected = RuntimeException::class) + fun testBuildAndConnectWeatherView_throwsIfDecouplingDisabled() { + // GIVEN the feature flag is disabled + `when`(featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)).thenReturn(false) + + // WHEN we try to build the view + controller.buildAndConnectWeatherView(fakeParent) + + // THEN an exception is thrown + } + @Test - fun connectOnlyAfterDeviceIsProvisioned() { + fun testBuildAndConnectView_connectsOnlyAfterDeviceIsProvisioned() { // GIVEN an unprovisioned device and an attempt to connect - `when`(deviceProvisionedController.isDeviceProvisioned()).thenReturn(false) - `when`(deviceProvisionedController.isCurrentUserSetup()).thenReturn(false) + `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(false) + `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(false) // WHEN a connection attempt is made and view is attached val view = controller.buildAndConnectView(fakeParent) @@ -232,8 +255,8 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { verify(smartspaceManager, never()).createSmartspaceSession(any()) // WHEN it does become provisioned - `when`(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true) - `when`(deviceProvisionedController.isCurrentUserSetup()).thenReturn(true) + `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(true) deviceProvisionedListener.onUserSetupChanged() // THEN the session is created @@ -243,7 +266,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { } @Test - fun testListenersAreRegistered() { + fun testAddListener_registersListenersForPlugin() { // GIVEN a listener is added after a session is created connectSession() @@ -252,10 +275,12 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { // THEN the listener is registered to the underlying plugin verify(plugin).registerListener(controllerListener) + // The listener is registered only for the plugin, not the weather plugin. + verify(weatherPlugin, never()).registerListener(any()) } @Test - fun testEarlyRegisteredListenersAreAttachedAfterConnected() { + fun testAddListener_earlyRegisteredListenersAreAttachedAfterConnected() { // GIVEN a listener that is registered before the session is created controller.addListener(controllerListener) @@ -264,10 +289,12 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { // THEN the listener is subsequently registered verify(plugin).registerListener(controllerListener) + // The listener is registered only for the plugin, not the weather plugin. + verify(weatherPlugin, never()).registerListener(any()) } @Test - fun testEmptyListIsEmittedAndNotifierRemovedAfterDisconnect() { + fun testDisconnect_emitsEmptyListAndRemovesNotifier() { // GIVEN a registered listener on an active session connectSession() clearInvocations(plugin) @@ -279,10 +306,12 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { // THEN the listener receives an empty list of targets and unregisters the notifier verify(plugin).onTargetsAvailable(emptyList()) verify(plugin).registerSmartspaceEventNotifier(null) + verify(weatherPlugin).onTargetsAvailable(emptyList()) + verify(weatherPlugin).registerSmartspaceEventNotifier(null) } @Test - fun testUserChangeReloadsSmartspace() { + fun testUserChange_reloadsSmartspace() { // GIVEN a connected smartspace session connectSession() @@ -294,7 +323,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { } @Test - fun testSettingsChangeReloadsSmartspace() { + fun testSettingsChange_reloadsSmartspace() { // GIVEN a connected smartspace session connectSession() @@ -306,7 +335,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { } @Test - fun testThemeChangeUpdatesTextColor() { + fun testThemeChange_updatesTextColor() { // GIVEN a connected smartspace session connectSession() @@ -318,7 +347,36 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { } @Test - fun testDozeAmountChangeUpdatesView() { + fun testThemeChange_ifDecouplingEnabled_updatesTextColor() { + `when`(featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)).thenReturn(true) + + // GIVEN a connected smartspace session + connectSession() + + // WHEN the theme changes + configChangeListener.onThemeChanged() + + // We update the new text color to match the wallpaper color + verify(weatherSmartspaceView).setPrimaryTextColor(anyInt()) + verify(smartspaceView).setPrimaryTextColor(anyInt()) + } + + @Test + fun testDozeAmountChange_updatesView() { + // GIVEN a connected smartspace session + connectSession() + + // WHEN the doze amount changes + statusBarStateListener.onDozeAmountChanged(0.1f, 0.7f) + + // We pass that along to the view + verify(smartspaceView).setDozeAmount(0.7f) + } + + @Test + fun testDozeAmountChange_ifDecouplingEnabled_updatesViews() { + `when`(featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)).thenReturn(true) + // GIVEN a connected smartspace session connectSession() @@ -326,11 +384,12 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { statusBarStateListener.onDozeAmountChanged(0.1f, 0.7f) // We pass that along to the view + verify(weatherSmartspaceView).setDozeAmount(0.7f) verify(smartspaceView).setDozeAmount(0.7f) } @Test - fun testKeyguardBypassEnabledUpdatesView() { + fun testKeyguardBypassEnabled_updatesView() { // GIVEN a connected smartspace session connectSession() `when`(keyguardBypassController.bypassEnabled).thenReturn(true) @@ -425,6 +484,27 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { } @Test + fun testSessionListener_ifDecouplingEnabled_weatherTargetIsFilteredOut() { + `when`(featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)).thenReturn(true) + connectSession() + + // WHEN we receive a list of targets + val targets = listOf( + makeTarget(1, userHandlePrimary, isSensitive = true), + makeTarget(2, userHandlePrimary), + makeTarget(3, userHandleManaged), + makeTarget(4, userHandlePrimary, featureType = SmartspaceTarget.FEATURE_WEATHER) + ) + + sessionListener.onTargetsAvailable(targets) + + // THEN all non-sensitive content is still shown + verify(plugin).onTargetsAvailable(eq(listOf(targets[0], targets[1], targets[2]))) + // No filtering is applied for the weather plugin + verify(weatherPlugin).onTargetsAvailable(eq(targets)) + } + + @Test fun testSettingsAreReloaded() { // GIVEN a connected session where the privacy settings later flip to false connectSession() @@ -515,6 +595,16 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { } @Test + fun testWeatherViewUsesSameSession() { + `when`(featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)).thenReturn(true) + // GIVEN a connected session + connectSession() + + // No checks is needed here, since connectSession() already checks internally that + // createSmartspaceSession is invoked only once. + } + + @Test fun testViewGetInitializedWithBypassEnabledState() { // GIVEN keyguard bypass is enabled. `when`(keyguardBypassController.bypassEnabled).thenReturn(true) @@ -531,8 +621,8 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { fun testConnectAttemptBeforeInitializationShouldNotCreateSession() { // GIVEN an uninitalized smartspaceView // WHEN the device is provisioned - `when`(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true) - `when`(deviceProvisionedController.isCurrentUserSetup()).thenReturn(true) + `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(true) deviceProvisionedListener.onDeviceProvisionedChanged() // THEN no calls to createSmartspaceSession should occur @@ -542,9 +632,23 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { } private fun connectSession() { + if (controller.isDateWeatherDecoupled()) { + val weatherView = controller.buildAndConnectWeatherView(fakeParent) + weatherSmartspaceView = weatherView as SmartspaceView + fakeParent.addView(weatherView) + controller.stateChangeListener.onViewAttachedToWindow(weatherView) + + verify(weatherSmartspaceView).setUiSurface( + BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD) + verify(weatherSmartspaceView).registerDataProvider(weatherPlugin) + + verify(weatherSmartspaceView).setPrimaryTextColor(anyInt()) + verify(weatherSmartspaceView).setDozeAmount(0.5f) + } + val view = controller.buildAndConnectView(fakeParent) smartspaceView = view as SmartspaceView - + fakeParent.addView(view) controller.stateChangeListener.onViewAttachedToWindow(view) verify(smartspaceView).setUiSurface(BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD) @@ -554,6 +658,8 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { .addOnTargetsAvailableListener(any(), capture(sessionListenerCaptor)) sessionListener = sessionListenerCaptor.value + verify(smartspaceManager).createSmartspaceSession(any()) + verify(userTracker).addCallback(capture(userTrackerCaptor), any()) userListener = userTrackerCaptor.value @@ -578,9 +684,11 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { verify(smartspaceView).setPrimaryTextColor(anyInt()) verify(smartspaceView).setDozeAmount(0.5f) - clearInvocations(view) - fakeParent.addView(view) + if (controller.isDateWeatherDecoupled()) { + clearInvocations(weatherSmartspaceView) + } + clearInvocations(smartspaceView) } private fun setActiveUser(userHandle: UserHandle) { @@ -626,6 +734,31 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { ).thenReturn(if (value) 1 else 0) } + // Separate function for the weather view, which doesn't implement all functions in interface. + private fun createWeatherSmartspaceView(): SmartspaceView { + return spy(object : View(context), SmartspaceView { + override fun registerDataProvider(plugin: BcSmartspaceDataPlugin?) { + } + + override fun setPrimaryTextColor(color: Int) { + } + + override fun setIsDreaming(isDreaming: Boolean) { + } + + override fun setUiSurface(uiSurface: String) { + } + + override fun setDozeAmount(amount: Float) { + } + + override fun setIntentStarter(intentStarter: BcSmartspaceDataPlugin.IntentStarter?) { + } + + override fun setFalsingManager(falsingManager: FalsingManager?) { + } + }) + } private fun createSmartspaceView(): SmartspaceView { return spy(object : View(context), SmartspaceView { override fun registerDataProvider(plugin: BcSmartspaceDataPlugin?) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java index 701cf95736ea..af5245934c12 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java @@ -117,10 +117,6 @@ public class DeviceProvisionedCoordinatorTest extends SysuiTestCase { extras.putBoolean(SHOW_WHEN_UNPROVISIONED_FLAG, true); mNotification.extras = extras; - // GIVEN notification has the permission to display during setup - when(mIPackageManager.checkUidPermission(SETUP_NOTIF_PERMISSION, NOTIF_UID)) - .thenReturn(PackageManager.PERMISSION_GRANTED); - // THEN don't filter out the notification assertFalse(mDeviceProvisionedFilter.shouldFilterOut(mEntry, 0)); } @@ -130,15 +126,10 @@ public class DeviceProvisionedCoordinatorTest extends SysuiTestCase { // GIVEN device is unprovisioned when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(false); - // GIVEN notification has a flag to allow the notification during setup + // GIVEN notification does not have the flag to allow the notification during setup Bundle extras = new Bundle(); - extras.putBoolean(SHOW_WHEN_UNPROVISIONED_FLAG, true); mNotification.extras = extras; - // GIVEN notification does NOT have permission to display during setup - when(mIPackageManager.checkUidPermission(SETUP_NOTIF_PERMISSION, NOTIF_UID)) - .thenReturn(PackageManager.PERMISSION_DENIED); - // THEN filter out the notification assertTrue(mDeviceProvisionedFilter.shouldFilterOut(mEntry, 0)); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java index 4559a23a4f5c..9e23d548e5b5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java @@ -82,19 +82,14 @@ import org.mockito.junit.MockitoRule; import java.util.Arrays; import java.util.List; +import java.util.function.Consumer; @SmallTest @RunWith(AndroidTestingRunner.class) @RunWithLooper public class ExpandableNotificationRowTest extends SysuiTestCase { - private ExpandableNotificationRow mGroupRow; - private ExpandableNotificationRow mNotifRow; - private ExpandableNotificationRow mPublicRow; - private NotificationTestHelper mNotificationTestHelper; - boolean mHeadsUpAnimatingAway = false; - @Rule public MockitoRule mockito = MockitoJUnit.rule(); @Before @@ -105,112 +100,108 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { mDependency, TestableLooper.get(this)); mNotificationTestHelper.setDefaultInflationFlags(FLAG_CONTENT_VIEW_ALL); + FakeFeatureFlags fakeFeatureFlags = new FakeFeatureFlags(); fakeFeatureFlags.set(Flags.NOTIFICATION_ANIMATE_BIG_PICTURE, true); mNotificationTestHelper.setFeatureFlags(fakeFeatureFlags); - // create a standard private notification row - Notification normalNotif = mNotificationTestHelper.createNotification(); - normalNotif.publicVersion = null; - mNotifRow = mNotificationTestHelper.createRow(normalNotif); - // create a notification row whose public version is identical - Notification publicNotif = mNotificationTestHelper.createNotification(); - publicNotif.publicVersion = mNotificationTestHelper.createNotification(); - mPublicRow = mNotificationTestHelper.createRow(publicNotif); - // create a group row - mGroupRow = mNotificationTestHelper.createGroup(); - mGroupRow.setHeadsUpAnimatingAwayListener( - animatingAway -> mHeadsUpAnimatingAway = animatingAway); - } @Test - public void testUpdateBackgroundColors_isRecursive() { - mGroupRow.setTintColor(Color.RED); - mGroupRow.getChildNotificationAt(0).setTintColor(Color.GREEN); - mGroupRow.getChildNotificationAt(1).setTintColor(Color.BLUE); + public void testUpdateBackgroundColors_isRecursive() throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + group.setTintColor(Color.RED); + group.getChildNotificationAt(0).setTintColor(Color.GREEN); + group.getChildNotificationAt(1).setTintColor(Color.BLUE); - assertThat(mGroupRow.getCurrentBackgroundTint()).isEqualTo(Color.RED); - assertThat(mGroupRow.getChildNotificationAt(0).getCurrentBackgroundTint()) + assertThat(group.getCurrentBackgroundTint()).isEqualTo(Color.RED); + assertThat(group.getChildNotificationAt(0).getCurrentBackgroundTint()) .isEqualTo(Color.GREEN); - assertThat(mGroupRow.getChildNotificationAt(1).getCurrentBackgroundTint()) + assertThat(group.getChildNotificationAt(1).getCurrentBackgroundTint()) .isEqualTo(Color.BLUE); - mGroupRow.updateBackgroundColors(); + group.updateBackgroundColors(); - int resetTint = mGroupRow.getCurrentBackgroundTint(); + int resetTint = group.getCurrentBackgroundTint(); assertThat(resetTint).isNotEqualTo(Color.RED); - assertThat(mGroupRow.getChildNotificationAt(0).getCurrentBackgroundTint()) + assertThat(group.getChildNotificationAt(0).getCurrentBackgroundTint()) .isEqualTo(resetTint); - assertThat(mGroupRow.getChildNotificationAt(1).getCurrentBackgroundTint()) + assertThat(group.getChildNotificationAt(1).getCurrentBackgroundTint()) .isEqualTo(resetTint); } @Test - public void testSetSensitiveOnNotifRowNotifiesOfHeightChange() throws InterruptedException { + public void testSetSensitiveOnNotifRowNotifiesOfHeightChange() throws Exception { // GIVEN a sensitive notification row that's currently redacted - measureAndLayout(mNotifRow); - mNotifRow.setHideSensitiveForIntrinsicHeight(true); - mNotifRow.setSensitive(true, true); - assertThat(mNotifRow.getShowingLayout()).isSameInstanceAs(mNotifRow.getPublicLayout()); - assertThat(mNotifRow.getIntrinsicHeight()).isGreaterThan(0); + ExpandableNotificationRow row = mNotificationTestHelper.createRow(); + measureAndLayout(row); + row.setHideSensitiveForIntrinsicHeight(true); + row.setSensitive(true, true); + assertThat(row.getShowingLayout()).isSameInstanceAs(row.getPublicLayout()); + assertThat(row.getIntrinsicHeight()).isGreaterThan(0); // GIVEN that the row has a height change listener OnHeightChangedListener listener = mock(OnHeightChangedListener.class); - mNotifRow.setOnHeightChangedListener(listener); + row.setOnHeightChangedListener(listener); // WHEN the row is set to no longer be sensitive - mNotifRow.setSensitive(false, true); + row.setSensitive(false, true); // VERIFY that the height change listener is invoked - assertThat(mNotifRow.getShowingLayout()).isSameInstanceAs(mNotifRow.getPrivateLayout()); - assertThat(mNotifRow.getIntrinsicHeight()).isGreaterThan(0); - verify(listener).onHeightChanged(eq(mNotifRow), eq(false)); + assertThat(row.getShowingLayout()).isSameInstanceAs(row.getPrivateLayout()); + assertThat(row.getIntrinsicHeight()).isGreaterThan(0); + verify(listener).onHeightChanged(eq(row), eq(false)); } @Test - public void testSetSensitiveOnGroupRowNotifiesOfHeightChange() { + public void testSetSensitiveOnGroupRowNotifiesOfHeightChange() throws Exception { // GIVEN a sensitive group row that's currently redacted - measureAndLayout(mGroupRow); - mGroupRow.setHideSensitiveForIntrinsicHeight(true); - mGroupRow.setSensitive(true, true); - assertThat(mGroupRow.getShowingLayout()).isSameInstanceAs(mGroupRow.getPublicLayout()); - assertThat(mGroupRow.getIntrinsicHeight()).isGreaterThan(0); + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + measureAndLayout(group); + group.setHideSensitiveForIntrinsicHeight(true); + group.setSensitive(true, true); + assertThat(group.getShowingLayout()).isSameInstanceAs(group.getPublicLayout()); + assertThat(group.getIntrinsicHeight()).isGreaterThan(0); // GIVEN that the row has a height change listener OnHeightChangedListener listener = mock(OnHeightChangedListener.class); - mGroupRow.setOnHeightChangedListener(listener); + group.setOnHeightChangedListener(listener); // WHEN the row is set to no longer be sensitive - mGroupRow.setSensitive(false, true); + group.setSensitive(false, true); // VERIFY that the height change listener is invoked - assertThat(mGroupRow.getShowingLayout()).isSameInstanceAs(mGroupRow.getPrivateLayout()); - assertThat(mGroupRow.getIntrinsicHeight()).isGreaterThan(0); - verify(listener).onHeightChanged(eq(mGroupRow), eq(false)); + assertThat(group.getShowingLayout()).isSameInstanceAs(group.getPrivateLayout()); + assertThat(group.getIntrinsicHeight()).isGreaterThan(0); + verify(listener).onHeightChanged(eq(group), eq(false)); } @Test - public void testSetSensitiveOnPublicRowDoesNotNotifyOfHeightChange() { + public void testSetSensitiveOnPublicRowDoesNotNotifyOfHeightChange() throws Exception { + // create a notification row whose public version is identical + Notification publicNotif = mNotificationTestHelper.createNotification(); + publicNotif.publicVersion = mNotificationTestHelper.createNotification(); + ExpandableNotificationRow publicRow = mNotificationTestHelper.createRow(publicNotif); + // GIVEN a sensitive public row that's currently redacted - measureAndLayout(mPublicRow); - mPublicRow.setHideSensitiveForIntrinsicHeight(true); - mPublicRow.setSensitive(true, true); - assertThat(mPublicRow.getShowingLayout()).isSameInstanceAs(mPublicRow.getPublicLayout()); - assertThat(mPublicRow.getIntrinsicHeight()).isGreaterThan(0); + measureAndLayout(publicRow); + publicRow.setHideSensitiveForIntrinsicHeight(true); + publicRow.setSensitive(true, true); + assertThat(publicRow.getShowingLayout()).isSameInstanceAs(publicRow.getPublicLayout()); + assertThat(publicRow.getIntrinsicHeight()).isGreaterThan(0); // GIVEN that the row has a height change listener OnHeightChangedListener listener = mock(OnHeightChangedListener.class); - mPublicRow.setOnHeightChangedListener(listener); + publicRow.setOnHeightChangedListener(listener); // WHEN the row is set to no longer be sensitive - mPublicRow.setSensitive(false, true); + publicRow.setSensitive(false, true); // VERIFY that the height change listener is not invoked, because the height didn't change - assertThat(mPublicRow.getShowingLayout()).isSameInstanceAs(mPublicRow.getPrivateLayout()); - assertThat(mPublicRow.getIntrinsicHeight()).isGreaterThan(0); - assertThat(mPublicRow.getPrivateLayout().getMinHeight()) - .isEqualTo(mPublicRow.getPublicLayout().getMinHeight()); - verify(listener, never()).onHeightChanged(eq(mPublicRow), eq(false)); + assertThat(publicRow.getShowingLayout()).isSameInstanceAs(publicRow.getPrivateLayout()); + assertThat(publicRow.getIntrinsicHeight()).isGreaterThan(0); + assertThat(publicRow.getPrivateLayout().getMinHeight()) + .isEqualTo(publicRow.getPublicLayout().getMinHeight()); + verify(listener, never()).onHeightChanged(eq(publicRow), eq(false)); } private void measureAndLayout(ExpandableNotificationRow row) { @@ -227,36 +218,43 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { } @Test - public void testGroupSummaryNotShowingIconWhenPublic() { - mGroupRow.setSensitive(true, true); - mGroupRow.setHideSensitiveForIntrinsicHeight(true); - assertTrue(mGroupRow.isSummaryWithChildren()); - assertFalse(mGroupRow.isShowingIcon()); + public void testGroupSummaryNotShowingIconWhenPublic() throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + + group.setSensitive(true, true); + group.setHideSensitiveForIntrinsicHeight(true); + assertTrue(group.isSummaryWithChildren()); + assertFalse(group.isShowingIcon()); } @Test - public void testNotificationHeaderVisibleWhenAnimating() { - mGroupRow.setSensitive(true, true); - mGroupRow.setHideSensitive(true, false, 0, 0); - mGroupRow.setHideSensitive(false, true, 0, 0); - assertEquals(View.VISIBLE, mGroupRow.getChildrenContainer().getVisibleWrapper() + public void testNotificationHeaderVisibleWhenAnimating() throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + + group.setSensitive(true, true); + group.setHideSensitive(true, false, 0, 0); + group.setHideSensitive(false, true, 0, 0); + assertEquals(View.VISIBLE, group.getChildrenContainer().getVisibleWrapper() .getNotificationHeader().getVisibility()); } @Test - public void testUserLockedResetEvenWhenNoChildren() { - mGroupRow.setUserLocked(true); - mGroupRow.setUserLocked(false); + public void testUserLockedResetEvenWhenNoChildren() throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + + group.setUserLocked(true); + group.setUserLocked(false); assertFalse("The childrencontainer should not be userlocked but is, the state " - + "seems out of sync.", mGroupRow.getChildrenContainer().isUserLocked()); + + "seems out of sync.", group.getChildrenContainer().isUserLocked()); } @Test - public void testReinflatedOnDensityChange() { + public void testReinflatedOnDensityChange() throws Exception { + ExpandableNotificationRow row = mNotificationTestHelper.createRow(); NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class); - mNotifRow.setChildrenContainer(mockContainer); + row.setChildrenContainer(mockContainer); - mNotifRow.onDensityOrFontScaleChanged(); + row.onDensityOrFontScaleChanged(); verify(mockContainer).reInflateViews(any(), any()); } @@ -299,64 +297,73 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { @Test public void testAboveShelfChangedListenerCalledWhenGoingBelow() throws Exception { ExpandableNotificationRow row = mNotificationTestHelper.createRow(); - row.setHeadsUp(true); AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class); row.setAboveShelfChangedListener(listener); + Mockito.reset(listener); + row.setHeadsUp(true); row.setAboveShelf(false); verify(listener).onAboveShelfStateChanged(false); } @Test public void testClickSound() throws Exception { - assertTrue("Should play sounds by default.", mGroupRow.isSoundEffectsEnabled()); + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + + assertTrue("Should play sounds by default.", group.isSoundEffectsEnabled()); StatusBarStateController mock = mNotificationTestHelper.getStatusBarStateController(); when(mock.isDozing()).thenReturn(true); - mGroupRow.setSecureStateProvider(()-> false); + group.setSecureStateProvider(()-> false); assertFalse("Shouldn't play sounds when dark and trusted.", - mGroupRow.isSoundEffectsEnabled()); - mGroupRow.setSecureStateProvider(()-> true); + group.isSoundEffectsEnabled()); + group.setSecureStateProvider(()-> true); assertTrue("Should always play sounds when not trusted.", - mGroupRow.isSoundEffectsEnabled()); + group.isSoundEffectsEnabled()); } @Test - public void testSetDismissed_longPressListenerRemoved() { + public void testSetDismissed_longPressListenerRemoved() throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + ExpandableNotificationRow.LongPressListener listener = mock(ExpandableNotificationRow.LongPressListener.class); - mGroupRow.setLongPressListener(listener); - mGroupRow.doLongClickCallback(0,0); - verify(listener, times(1)).onLongPress(eq(mGroupRow), eq(0), eq(0), + group.setLongPressListener(listener); + group.doLongClickCallback(0, 0); + verify(listener, times(1)).onLongPress(eq(group), eq(0), eq(0), any(NotificationMenuRowPlugin.MenuItem.class)); reset(listener); - mGroupRow.dismiss(true); - mGroupRow.doLongClickCallback(0,0); - verify(listener, times(0)).onLongPress(eq(mGroupRow), eq(0), eq(0), + group.dismiss(true); + group.doLongClickCallback(0, 0); + verify(listener, times(0)).onLongPress(eq(group), eq(0), eq(0), any(NotificationMenuRowPlugin.MenuItem.class)); } @Test - public void testFeedback_noHeader() { + public void testFeedback_noHeader() throws Exception { + ExpandableNotificationRow groupRow = mNotificationTestHelper.createGroup(); + // public notification is custom layout - no header - mGroupRow.setSensitive(true, true); - mGroupRow.setOnFeedbackClickListener(null); - mGroupRow.setFeedbackIcon(null); + groupRow.setSensitive(true, true); + groupRow.setOnFeedbackClickListener(null); + groupRow.setFeedbackIcon(null); } @Test - public void testFeedback_header() { + public void testFeedback_header() throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + NotificationContentView publicLayout = mock(NotificationContentView.class); - mGroupRow.setPublicLayout(publicLayout); + group.setPublicLayout(publicLayout); NotificationContentView privateLayout = mock(NotificationContentView.class); - mGroupRow.setPrivateLayout(privateLayout); + group.setPrivateLayout(privateLayout); NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class); when(mockContainer.getNotificationChildCount()).thenReturn(1); - mGroupRow.setChildrenContainer(mockContainer); + group.setChildrenContainer(mockContainer); final boolean show = true; final FeedbackIcon icon = new FeedbackIcon( R.drawable.ic_feedback_alerted, R.string.notification_feedback_indicator_alerted); - mGroupRow.setFeedbackIcon(icon); + group.setFeedbackIcon(icon); verify(mockContainer, times(1)).setFeedbackIcon(icon); verify(privateLayout, times(1)).setFeedbackIcon(icon); @@ -364,43 +371,60 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { } @Test - public void testFeedbackOnClick() { + public void testFeedbackOnClick() throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + ExpandableNotificationRow.CoordinateOnClickListener l = mock( ExpandableNotificationRow.CoordinateOnClickListener.class); View view = mock(View.class); - mGroupRow.setOnFeedbackClickListener(l); + group.setOnFeedbackClickListener(l); - mGroupRow.getFeedbackOnClickListener().onClick(view); + group.getFeedbackOnClickListener().onClick(view); verify(l, times(1)).onClick(any(), anyInt(), anyInt(), any()); } @Test - public void testHeadsUpAnimatingAwayListener() { - mGroupRow.setHeadsUpAnimatingAway(true); - Assert.assertEquals(true, mHeadsUpAnimatingAway); - mGroupRow.setHeadsUpAnimatingAway(false); - Assert.assertEquals(false, mHeadsUpAnimatingAway); + public void testHeadsUpAnimatingAwayListener() throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + Consumer<Boolean> headsUpListener = mock(Consumer.class); + AboveShelfChangedListener aboveShelfChangedListener = mock(AboveShelfChangedListener.class); + group.setHeadsUpAnimatingAwayListener(headsUpListener); + group.setAboveShelfChangedListener(aboveShelfChangedListener); + + group.setHeadsUpAnimatingAway(true); + verify(headsUpListener).accept(true); + verify(aboveShelfChangedListener).onAboveShelfStateChanged(true); + + group.setHeadsUpAnimatingAway(false); + verify(headsUpListener).accept(false); + verify(aboveShelfChangedListener).onAboveShelfStateChanged(false); } @Test - public void testIsBlockingHelperShowing_isCorrectlyUpdated() { - mGroupRow.setBlockingHelperShowing(true); - assertTrue(mGroupRow.isBlockingHelperShowing()); + public void testIsBlockingHelperShowing_isCorrectlyUpdated() throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); - mGroupRow.setBlockingHelperShowing(false); - assertFalse(mGroupRow.isBlockingHelperShowing()); + group.setBlockingHelperShowing(true); + assertTrue(group.isBlockingHelperShowing()); + + group.setBlockingHelperShowing(false); + assertFalse(group.isBlockingHelperShowing()); } @Test - public void testGetNumUniqueChildren_defaultChannel() { - assertEquals(1, mGroupRow.getNumUniqueChannels()); + public void testGetNumUniqueChildren_defaultChannel() throws Exception { + ExpandableNotificationRow groupRow = mNotificationTestHelper.createGroup(); + + assertEquals(1, groupRow.getNumUniqueChannels()); } @Test - public void testGetNumUniqueChildren_multiChannel() { + public void testGetNumUniqueChildren_multiChannel() throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + List<ExpandableNotificationRow> childRows = - mGroupRow.getChildrenContainer().getAttachedChildren(); + group.getChildrenContainer().getAttachedChildren(); // Give each child a unique channel id/name. int i = 0; for (ExpandableNotificationRow childRow : childRows) { @@ -412,25 +436,29 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { i++; } - assertEquals(3, mGroupRow.getNumUniqueChannels()); + assertEquals(3, group.getNumUniqueChannels()); } @Test public void testIconScrollXAfterTranslationAndReset() throws Exception { - mGroupRow.setDismissUsingRowTranslationX(false); - mGroupRow.setTranslation(50); - assertEquals(50, -mGroupRow.getEntry().getIcons().getShelfIcon().getScrollX()); + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + + group.setDismissUsingRowTranslationX(false); + group.setTranslation(50); + assertEquals(50, -group.getEntry().getIcons().getShelfIcon().getScrollX()); - mGroupRow.resetTranslation(); - assertEquals(0, mGroupRow.getEntry().getIcons().getShelfIcon().getScrollX()); + group.resetTranslation(); + assertEquals(0, group.getEntry().getIcons().getShelfIcon().getScrollX()); } @Test - public void testIsExpanded_userExpanded() { - mGroupRow.setExpandable(true); - Assert.assertFalse(mGroupRow.isExpanded()); - mGroupRow.setUserExpanded(true); - Assert.assertTrue(mGroupRow.isExpanded()); + public void testIsExpanded_userExpanded() throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + + group.setExpandable(true); + Assert.assertFalse(group.isExpanded()); + group.setUserExpanded(true); + Assert.assertTrue(group.isExpanded()); } @Test @@ -549,72 +577,80 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { } @Test - public void applyRoundnessAndInv_should_be_immediately_applied_on_childrenContainer_legacy() { - mGroupRow.useRoundnessSourceTypes(false); - Assert.assertEquals(0f, mGroupRow.getBottomRoundness(), 0.001f); - Assert.assertEquals(0f, mGroupRow.getChildrenContainer().getBottomRoundness(), 0.001f); + public void applyRoundnessAndInv_should_be_immediately_applied_on_childrenContainer_legacy() + throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + group.useRoundnessSourceTypes(false); + Assert.assertEquals(0f, group.getBottomRoundness(), 0.001f); + Assert.assertEquals(0f, group.getChildrenContainer().getBottomRoundness(), 0.001f); - mGroupRow.requestBottomRoundness(1f, SourceType.from(""), false); + group.requestBottomRoundness(1f, SourceType.from(""), false); - Assert.assertEquals(1f, mGroupRow.getBottomRoundness(), 0.001f); - Assert.assertEquals(1f, mGroupRow.getChildrenContainer().getBottomRoundness(), 0.001f); + Assert.assertEquals(1f, group.getBottomRoundness(), 0.001f); + Assert.assertEquals(1f, group.getChildrenContainer().getBottomRoundness(), 0.001f); } @Test - public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_childrenContainer() { - mGroupRow.useRoundnessSourceTypes(true); - Assert.assertEquals(0f, mGroupRow.getBottomRoundness(), 0.001f); - Assert.assertEquals(0f, mGroupRow.getChildrenContainer().getBottomRoundness(), 0.001f); + public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_childrenContainer() + throws Exception { + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + group.useRoundnessSourceTypes(true); + Assert.assertEquals(0f, group.getBottomRoundness(), 0.001f); + Assert.assertEquals(0f, group.getChildrenContainer().getBottomRoundness(), 0.001f); - mGroupRow.requestBottomRoundness(1f, SourceType.from(""), false); + group.requestBottomRoundness(1f, SourceType.from(""), false); - Assert.assertEquals(1f, mGroupRow.getBottomRoundness(), 0.001f); - Assert.assertEquals(1f, mGroupRow.getChildrenContainer().getBottomRoundness(), 0.001f); + Assert.assertEquals(1f, group.getBottomRoundness(), 0.001f); + Assert.assertEquals(1f, group.getChildrenContainer().getBottomRoundness(), 0.001f); } @Test public void testSetContentAnimationRunning_Run() throws Exception { // Create views for the notification row. + ExpandableNotificationRow row = mNotificationTestHelper.createRow(); NotificationContentView publicLayout = mock(NotificationContentView.class); - mNotifRow.setPublicLayout(publicLayout); + row.setPublicLayout(publicLayout); NotificationContentView privateLayout = mock(NotificationContentView.class); - mNotifRow.setPrivateLayout(privateLayout); + row.setPrivateLayout(privateLayout); - mNotifRow.setAnimationRunning(true); + row.setAnimationRunning(true); verify(publicLayout, times(1)).setContentAnimationRunning(true); verify(privateLayout, times(1)).setContentAnimationRunning(true); } @Test - public void testSetContentAnimationRunning_Stop() { + public void testSetContentAnimationRunning_Stop() throws Exception { // Create views for the notification row. + ExpandableNotificationRow row = mNotificationTestHelper.createRow(); NotificationContentView publicLayout = mock(NotificationContentView.class); - mNotifRow.setPublicLayout(publicLayout); + row.setPublicLayout(publicLayout); NotificationContentView privateLayout = mock(NotificationContentView.class); - mNotifRow.setPrivateLayout(privateLayout); + row.setPrivateLayout(privateLayout); - mNotifRow.setAnimationRunning(false); + row.setAnimationRunning(false); verify(publicLayout, times(1)).setContentAnimationRunning(false); verify(privateLayout, times(1)).setContentAnimationRunning(false); } @Test - public void testSetContentAnimationRunningInGroupChild_Run() { - // Creates parent views on mGroupRow. + public void testSetContentAnimationRunningInGroupChild_Run() throws Exception { + // Creates parent views on groupRow. + ExpandableNotificationRow groupRow = mNotificationTestHelper.createGroup(); NotificationContentView publicParentLayout = mock(NotificationContentView.class); - mGroupRow.setPublicLayout(publicParentLayout); + groupRow.setPublicLayout(publicParentLayout); NotificationContentView privateParentLayout = mock(NotificationContentView.class); - mGroupRow.setPrivateLayout(privateParentLayout); + groupRow.setPrivateLayout(privateParentLayout); - // Create child views on mNotifRow. + // Create child views on row. + ExpandableNotificationRow row = mNotificationTestHelper.createRow(); NotificationContentView publicChildLayout = mock(NotificationContentView.class); - mNotifRow.setPublicLayout(publicChildLayout); + row.setPublicLayout(publicChildLayout); NotificationContentView privateChildLayout = mock(NotificationContentView.class); - mNotifRow.setPrivateLayout(privateChildLayout); - when(mNotifRow.isGroupExpanded()).thenReturn(true); - setMockChildrenContainer(mGroupRow, mNotifRow); + row.setPrivateLayout(privateChildLayout); + when(row.isGroupExpanded()).thenReturn(true); + setMockChildrenContainer(groupRow, row); - mGroupRow.setAnimationRunning(true); + groupRow.setAnimationRunning(true); verify(publicParentLayout, times(1)).setContentAnimationRunning(true); verify(privateParentLayout, times(1)).setContentAnimationRunning(true); // The child layouts should be started too. @@ -624,23 +660,25 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { @Test - public void testSetIconAnimationRunningGroup_Run() { + public void testSetIconAnimationRunningGroup_Run() throws Exception { // Create views for a group row. + ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); + ExpandableNotificationRow child = mNotificationTestHelper.createRow(); NotificationContentView publicParentLayout = mock(NotificationContentView.class); - mGroupRow.setPublicLayout(publicParentLayout); + group.setPublicLayout(publicParentLayout); NotificationContentView privateParentLayout = mock(NotificationContentView.class); - mGroupRow.setPrivateLayout(privateParentLayout); - when(mGroupRow.isGroupExpanded()).thenReturn(true); + group.setPrivateLayout(privateParentLayout); + when(group.isGroupExpanded()).thenReturn(true); - // Sets up mNotifRow as a child ExpandableNotificationRow. + // Add the child to the group. NotificationContentView publicChildLayout = mock(NotificationContentView.class); - mNotifRow.setPublicLayout(publicChildLayout); + child.setPublicLayout(publicChildLayout); NotificationContentView privateChildLayout = mock(NotificationContentView.class); - mNotifRow.setPrivateLayout(privateChildLayout); - when(mNotifRow.isGroupExpanded()).thenReturn(true); + child.setPrivateLayout(privateChildLayout); + when(child.isGroupExpanded()).thenReturn(true); NotificationChildrenContainer mockContainer = - setMockChildrenContainer(mGroupRow, mNotifRow); + setMockChildrenContainer(group, child); // Mock the children view wrappers, and give them each an icon. NotificationViewWrapper mockViewWrapper = mock(NotificationViewWrapper.class); @@ -663,7 +701,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { AnimatedVectorDrawable lowPriVectorDrawable = mock(AnimatedVectorDrawable.class); setDrawableIconsInImageView(mockLowPriorityIcon, lowPriDrawable, lowPriVectorDrawable); - mGroupRow.setAnimationRunning(true); + group.setAnimationRunning(true); verify(drawable, times(1)).start(); verify(vectorDrawable, times(1)).start(); verify(lowPriDrawable, times(1)).start(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index e6f6a8d696b8..aca9c563de04 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -40,7 +40,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; import android.graphics.drawable.Icon; -import android.os.Handler; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.testing.TestableLooper; @@ -49,7 +48,6 @@ import android.view.LayoutInflater; import android.widget.RemoteViews; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.UiEventLogger; import com.android.systemui.TestableDependency; import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.classifier.FalsingManagerFake; @@ -57,7 +55,6 @@ import com.android.systemui.flags.FeatureFlags; import com.android.systemui.media.controls.util.MediaFeatureFlag; import com.android.systemui.media.dialog.MediaOutputDialogFactory; import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShadeWindowController; @@ -68,7 +65,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; -import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.icon.IconBuilder; @@ -77,11 +73,8 @@ import com.android.systemui.statusbar.notification.people.PeopleNotificationIden import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.ExpandableNotificationRowLogger; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.OnExpandClickListener; import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag; -import com.android.systemui.statusbar.phone.ConfigurationControllerImpl; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; -import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; -import com.android.systemui.statusbar.policy.HeadsUpManagerLogger; import com.android.systemui.statusbar.policy.InflatedSmartReplyState; import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; import com.android.systemui.statusbar.policy.SmartReplyConstants; @@ -121,12 +114,12 @@ public class NotificationTestHelper { private final GroupMembershipManager mGroupMembershipManager; private final GroupExpansionManager mGroupExpansionManager; private ExpandableNotificationRow mRow; - private HeadsUpManagerPhone mHeadsUpManager; + private final HeadsUpManagerPhone mHeadsUpManager; private final NotifBindPipeline mBindPipeline; private final NotifCollectionListener mBindPipelineEntryListener; private final RowContentBindStage mBindStage; private final IconManager mIconManager; - private StatusBarStateController mStatusBarStateController; + private final StatusBarStateController mStatusBarStateController; private final PeopleNotificationIdentifier mPeopleNotificationIdentifier; public final OnUserInteractionCallback mOnUserInteractionCallback; public final Runnable mFutureDismissalRunnable; @@ -146,19 +139,7 @@ public class NotificationTestHelper { mStatusBarStateController = mock(StatusBarStateController.class); mGroupMembershipManager = mock(GroupMembershipManager.class); mGroupExpansionManager = mock(GroupExpansionManager.class); - mHeadsUpManager = new HeadsUpManagerPhone( - mContext, - mock(HeadsUpManagerLogger.class), - mStatusBarStateController, - mock(KeyguardBypassController.class), - mock(GroupMembershipManager.class), - mock(VisualStabilityProvider.class), - mock(ConfigurationControllerImpl.class), - new Handler(mTestLooper.getLooper()), - mock(AccessibilityManagerWrapper.class), - mock(UiEventLogger.class), - mock(ShadeExpansionStateManager.class) - ); + mHeadsUpManager = mock(HeadsUpManagerPhone.class); mIconManager = new IconManager( mock(CommonNotifCollection.class), mock(LauncherApps.class), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index b1363a047307..06053987202c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -1010,6 +1010,18 @@ public class CentralSurfacesImplTest extends SysuiTestCase { } @Test + public void testSetDozingNotUnlocking_transitionToAOD_cancelKeyguardFadingAway() { + setDozing(true); + when(mKeyguardStateController.isShowing()).thenReturn(false); + when(mKeyguardStateController.isKeyguardFadingAway()).thenReturn(true); + + mCentralSurfaces.updateScrimController(); + + verify(mScrimController, times(2)).transitionTo(eq(ScrimState.AOD)); + verify(mStatusBarKeyguardViewManager).onKeyguardFadedAway(); + } + + @Test public void testShowKeyguardImplementation_setsState() { when(mLockscreenUserManager.getCurrentProfiles()).thenReturn(new SparseArray<>()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java index cc4abfcaa42f..529519a6246e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java @@ -38,6 +38,7 @@ import com.android.internal.view.AppearanceRegion; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.navigationbar.NavigationModeController; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.statusbar.policy.BatteryController; import org.junit.Before; @@ -67,7 +68,8 @@ public class LightBarControllerTest extends SysuiTestCase { mStatusBarIconController, mock(BatteryController.class), mock(NavigationModeController.class), - mock(DumpManager.class)); + mock(DumpManager.class), + new FakeDisplayTracker(mContext)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java index 189aa0f99b0f..0a68406882d4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java @@ -28,6 +28,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.LightBarTransitionsController.DarkIntensityApplier; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -56,7 +57,8 @@ public class LightBarTransitionsControllerTest extends SysuiTestCase { public void setup() { MockitoAnnotations.initMocks(this); mLightBarTransitionsController = new LightBarTransitionsController(mContext, mApplier, - new CommandQueue(mContext), mKeyguardStateController, mStatusBarStateController); + new CommandQueue(mContext, new FakeDisplayTracker(mContext)), + mKeyguardStateController, mStatusBarStateController); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java index eef43bde1a23..8841521c19f5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java @@ -40,6 +40,7 @@ import com.android.systemui.InitController; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.shade.ShadeController; @@ -92,7 +93,7 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { mMetricsLogger = new FakeMetricsLogger(); LockscreenGestureLogger lockscreenGestureLogger = new LockscreenGestureLogger( mMetricsLogger); - mCommandQueue = new CommandQueue(mContext); + mCommandQueue = new CommandQueue(mContext, new FakeDisplayTracker(mContext)); mDependency.injectTestDependency(StatusBarStateController.class, mock(SysuiStatusBarStateController.class)); mDependency.injectTestDependency(ShadeController.class, mShadeController); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java index 613238f7752e..929099a8f1f7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java @@ -32,6 +32,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.shade.ShadeController; import com.android.systemui.statusbar.ActionClickLogger; import com.android.systemui.statusbar.CommandQueue; @@ -78,7 +79,8 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase { mRemoteInputCallback = spy(new StatusBarRemoteInputCallback(mContext, mock(GroupExpansionManager.class), mNotificationLockscreenUserManager, mKeyguardStateController, mStatusBarStateController, mStatusBarKeyguardViewManager, - mActivityStarter, mShadeController, new CommandQueue(mContext), + mActivityStarter, mShadeController, + new CommandQueue(mContext, new FakeDisplayTracker(mContext)), mock(ActionClickLogger.class), mFakeExecutor)); mRemoteInputCallback.mChallengeReceiver = mRemoteInputCallback.new ChallengeReceiver(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt index a87a95060a7e..c539246d4902 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt @@ -22,6 +22,7 @@ import android.view.View import androidx.test.filters.SmallTest import com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer import com.android.systemui.SysuiTestCase +import com.android.systemui.settings.FakeDisplayTracker import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever @@ -36,7 +37,7 @@ class SwipeChipbarAwayGestureHandlerTest : SysuiTestCase() { @Before fun setUp() { - underTest = SwipeChipbarAwayGestureHandler(context, mock()) + underTest = SwipeChipbarAwayGestureHandler(context, FakeDisplayTracker(mContext), mock()) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index 0a1e3e4f7aff..9d518ac485db 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -91,6 +91,7 @@ import com.android.systemui.flags.FeatureFlags; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.NotificationShadeWindowControllerImpl; import com.android.systemui.shade.NotificationShadeWindowView; @@ -287,6 +288,8 @@ public class BubblesTest extends SysuiTestCase { private TestableLooper mTestableLooper; + private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); @@ -333,7 +336,7 @@ public class BubblesTest extends SysuiTestCase { mZenModeConfig.suppressedVisualEffects = 0; when(mZenModeController.getConfig()).thenReturn(mZenModeConfig); - mSysUiState = new SysUiState(); + mSysUiState = new SysUiState(mDisplayTracker); mSysUiState.addCallback(sysUiFlags -> { mSysUiStateBubblesManageMenuExpanded = (sysUiFlags diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java index 7ae47b41d5ae..8cae99893496 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java @@ -29,6 +29,7 @@ import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.model.SysUiState; import com.android.systemui.notetask.NoteTaskInitializer; +import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -84,6 +85,7 @@ public class WMShellTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); + FakeDisplayTracker displayTracker = new FakeDisplayTracker(mContext); mWMShell = new WMShell( mContext, mShellInterface, @@ -100,6 +102,7 @@ public class WMShellTest extends SysuiTestCase { mProtoTracer, mWakefulnessLifecycle, mUserTracker, + displayTracker, mNoteTaskInitializer, mSysUiMainExecutor ); diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt index 6c82cef22ddb..b94f816e1ca4 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt @@ -38,12 +38,6 @@ class FakeFeatureFlags : FeatureFlags { } } - fun set(flag: DeviceConfigBooleanFlag, value: Boolean) { - if (booleanFlags.put(flag.id, value)?.let { value != it } != false) { - notifyFlagChanged(flag) - } - } - fun set(flag: ResourceBooleanFlag, value: Boolean) { if (booleanFlags.put(flag.id, value)?.let { value != it } != false) { notifyFlagChanged(flag) @@ -73,7 +67,7 @@ class FakeFeatureFlags : FeatureFlags { listeners.forEach { listener -> listener.onFlagChanged( object : FlagListenable.FlagEvent { - override val flagId = flag.id + override val flagName = flag.name override fun requestNoRestart() {} } ) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeDisplayTracker.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeDisplayTracker.kt new file mode 100644 index 000000000000..6ae7c34e13f2 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeDisplayTracker.kt @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.settings + +import android.content.Context +import android.hardware.display.DisplayManager +import android.view.Display +import java.util.concurrent.Executor + +class FakeDisplayTracker internal constructor(val context: Context) : DisplayTracker { + val displayManager: DisplayManager = context.getSystemService(DisplayManager::class.java)!! + override var defaultDisplayId: Int = Display.DEFAULT_DISPLAY + override var allDisplays: Array<Display> = displayManager.displays + + private val displayCallbacks: MutableList<DisplayTracker.Callback> = ArrayList() + private val brightnessCallbacks: MutableList<DisplayTracker.Callback> = ArrayList() + override fun addDisplayChangeCallback(callback: DisplayTracker.Callback, executor: Executor) { + displayCallbacks.add(callback) + } + override fun addBrightnessChangeCallback( + callback: DisplayTracker.Callback, + executor: Executor + ) { + brightnessCallbacks.add(callback) + } + + override fun removeCallback(callback: DisplayTracker.Callback) { + displayCallbacks.remove(callback) + brightnessCallbacks.remove(callback) + } + + fun setDefaultDisplay(displayId: Int) { + defaultDisplayId = displayId + } + + fun setDisplays(displays: Array<Display>) { + allDisplays = displays + } + + fun triggerOnDisplayAdded(displayId: Int) { + notifyCallbacks({ onDisplayAdded(displayId) }, displayCallbacks) + } + + fun triggerOnDisplayRemoved(displayId: Int) { + notifyCallbacks({ onDisplayRemoved(displayId) }, displayCallbacks) + } + + fun triggerOnDisplayChanged(displayId: Int) { + notifyCallbacks({ onDisplayChanged(displayId) }, displayCallbacks) + } + + fun triggerOnDisplayBrightnessChanged(displayId: Int) { + notifyCallbacks({ onDisplayChanged(displayId) }, brightnessCallbacks) + } + + private inline fun notifyCallbacks( + crossinline action: DisplayTracker.Callback.() -> Unit, + list: List<DisplayTracker.Callback> + ) { + list.forEach { it.action() } + } +} diff --git a/rs/jni/Android.bp b/rs/jni/Android.bp index 9a6fa8e8e423..8a6897c055c5 100644 --- a/rs/jni/Android.bp +++ b/rs/jni/Android.bp @@ -51,4 +51,10 @@ cc_library_shared { "-Wunreachable-code", "-Wno-deprecated-declarations", ], + + target: { + android_riscv64: { + enabled: false, + }, + }, } diff --git a/services/api/current.txt b/services/api/current.txt index a92ccd42718e..f7d6ee96f162 100644 --- a/services/api/current.txt +++ b/services/api/current.txt @@ -225,19 +225,6 @@ package com.android.server.role { } -package com.android.server.security { - - public class FileIntegrityService extends com.android.server.SystemService { - method public void onStart(); - method public static void setUpFsVerity(@NonNull String) throws java.io.IOException; - } - - public class KeyChainSystemService extends com.android.server.SystemService { - method public void onStart(); - } - -} - package com.android.server.stats { public final class StatsHelper { diff --git a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java index 1e9632402da0..d7a77cd07116 100644 --- a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java +++ b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java @@ -164,6 +164,12 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange @Override public void onBluetoothCompanionDeviceDisconnected(int associationId) { + // If disconnected device is also a BLE device, skip the 2-minute timer and mark it as gone. + boolean isConnectableBleDevice = mNearbyBleDevices.remove(associationId); + if (DEBUG && isConnectableBleDevice) { + Log.d(TAG, "Bluetooth device disconnect was detected." + + " Pre-emptively marking the BLE device as lost."); + } onDeviceGone(mConnectedBtDevices, associationId, /* sourceLoggingTag */ "bt"); } diff --git a/services/core/Android.bp b/services/core/Android.bp index f65ed3357b13..bd072f523c7f 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -148,9 +148,10 @@ java_library_static { static_libs: [ "android.hardware.authsecret-V1.0-java", "android.hardware.authsecret-V1-java", - "android.hardware.boot-V1.0-java", - "android.hardware.boot-V1.1-java", - "android.hardware.boot-V1.2-java", + "android.hardware.boot-V1.0-java", // HIDL + "android.hardware.boot-V1.1-java", // HIDL + "android.hardware.boot-V1.2-java", // HIDL + "android.hardware.boot-V1-java", // AIDL "android.hardware.broadcastradio-V2.0-java", // HIDL "android.hardware.broadcastradio-V1-java", // AIDL "android.hardware.health-V1.0-java", // HIDL diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java index 66fa746a19e2..f93f50459a40 100644 --- a/services/core/java/com/android/server/BinaryTransparencyService.java +++ b/services/core/java/com/android/server/BinaryTransparencyService.java @@ -93,10 +93,8 @@ import java.io.PrintWriter; import java.security.PublicKey; import java.security.cert.CertificateException; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -300,15 +298,16 @@ public class BinaryTransparencyService extends SystemService { + " and is now updated to: " + currentTimeMs); mMeasurementsLastRecordedMs = currentTimeMs; - Set<String> packagesMeasured = new HashSet<>(); + Bundle packagesMeasured = new Bundle(); // measure all APEXs first if (DEBUG) { Slog.d(TAG, "Measuring APEXs..."); } - List<IBinaryTransparencyService.ApexInfo> allApexInfo = collectAllApexInfo(); + List<IBinaryTransparencyService.ApexInfo> allApexInfo = collectAllApexInfo( + /* includeTestOnly */ false); for (IBinaryTransparencyService.ApexInfo apexInfo : allApexInfo) { - packagesMeasured.add(apexInfo.packageName); + packagesMeasured.putBoolean(apexInfo.packageName, true); recordApexInfo(apexInfo); } @@ -321,7 +320,7 @@ public class BinaryTransparencyService extends SystemService { List<IBinaryTransparencyService.AppInfo> allUpdatedPreloadInfo = collectAllUpdatedPreloadInfo(packagesMeasured); for (IBinaryTransparencyService.AppInfo appInfo : allUpdatedPreloadInfo) { - packagesMeasured.add(appInfo.packageName); + packagesMeasured.putBoolean(appInfo.packageName, true); writeAppInfoToLog(appInfo); } if (DEBUG) { @@ -334,7 +333,7 @@ public class BinaryTransparencyService extends SystemService { List<IBinaryTransparencyService.AppInfo> allMbaInfo = collectAllMbaInfo(packagesMeasured); for (IBinaryTransparencyService.AppInfo appInfo : allUpdatedPreloadInfo) { - packagesMeasured.add(appInfo.packageName); + packagesMeasured.putBoolean(appInfo.packageName, true); writeAppInfoToLog(appInfo); } } @@ -345,7 +344,9 @@ public class BinaryTransparencyService extends SystemService { } } - private List<IBinaryTransparencyService.ApexInfo> collectAllApexInfo() { + @Override + public List<IBinaryTransparencyService.ApexInfo> collectAllApexInfo( + boolean includeTestOnly) { var results = new ArrayList<IBinaryTransparencyService.ApexInfo>(); for (PackageInfo packageInfo : getCurrentInstalledApexs()) { PackageState packageState = mPackageManagerInternal.getPackageStateInternal( @@ -371,13 +372,19 @@ public class BinaryTransparencyService extends SystemService { apexInfo.signerDigests = computePackageSignerSha256Digests(packageState.getSigningInfo()); + if (includeTestOnly) { + apexInfo.moduleName = apexPackageNameToModuleName( + packageState.getPackageName()); + } + results.add(apexInfo); } return results; } - private List<IBinaryTransparencyService.AppInfo> collectAllUpdatedPreloadInfo( - Set<String> packagesToSkip) { + @Override + public List<IBinaryTransparencyService.AppInfo> collectAllUpdatedPreloadInfo( + Bundle packagesToSkip) { final var results = new ArrayList<IBinaryTransparencyService.AppInfo>(); PackageManager pm = mContext.getPackageManager(); @@ -385,7 +392,7 @@ public class BinaryTransparencyService extends SystemService { if (!packageState.isUpdatedSystemApp()) { return; } - if (packagesToSkip.contains(packageState.getPackageName())) { + if (packagesToSkip.containsKey(packageState.getPackageName())) { return; } @@ -413,11 +420,10 @@ public class BinaryTransparencyService extends SystemService { return results; } - private List<IBinaryTransparencyService.AppInfo> collectAllMbaInfo( - Set<String> packagesToSkip) { + public List<IBinaryTransparencyService.AppInfo> collectAllMbaInfo(Bundle packagesToSkip) { var results = new ArrayList<IBinaryTransparencyService.AppInfo>(); for (PackageInfo packageInfo : getNewlyInstalledMbas()) { - if (packagesToSkip.contains(packageInfo.packageName)) { + if (packagesToSkip.containsKey(packageInfo.packageName)) { continue; } PackageState packageState = mPackageManagerInternal.getPackageStateInternal( @@ -1657,11 +1663,7 @@ public class BinaryTransparencyService extends SystemService { private String getOriginalApexPreinstalledLocation(String packageName, String currentInstalledLocation) { try { - // It appears that only apexd knows the preinstalled location, and it uses module name - // as the identifier instead of package name. Given the input is a package name, we - // need to covert to module name. - final String moduleName = ApexManager.getInstance().getApexModuleNameForPackageName( - packageName); + final String moduleName = apexPackageNameToModuleName(packageName); IApexService apexService = IApexService.Stub.asInterface( Binder.allowBlocking(ServiceManager.waitForService("apexservice"))); for (ApexInfo info : apexService.getAllPackages()) { @@ -1675,6 +1677,13 @@ public class BinaryTransparencyService extends SystemService { return APEX_PRELOAD_LOCATION_ERROR; } + private String apexPackageNameToModuleName(String packageName) { + // It appears that only apexd knows the preinstalled location, and it uses module name as + // the identifier instead of package name. Given the input is a package name, we need to + // covert to module name. + return ApexManager.getInstance().getApexModuleNameForPackageName(packageName); + } + /** * Wrapper method to call into IBICS to get a list of all newly installed MBAs. * diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 10d50c29f42f..57a89e384fb1 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -32,6 +32,7 @@ import static android.app.ActivityManager.INSTR_FLAG_DISABLE_TEST_API_CHECKS; import static android.app.ActivityManager.INSTR_FLAG_NO_RESTART; import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY; import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL; +import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.ActivityManager.PROCESS_STATE_TOP; @@ -3341,6 +3342,7 @@ public class ActivityManagerService extends IActivityManager.Stub } mBatteryStatsService.noteProcessDied(app.info.uid, pid); + mOomAdjuster.updateShortFgsOwner(app.info.uid, pid, false); if (!app.isKilled()) { if (!fromBinderDied) { @@ -16727,6 +16729,12 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override + public boolean startProfileWithListener(@UserIdInt int userId, + @Nullable IProgressListener unlockListener) { + return mUserController.startProfile(userId, unlockListener); + } + + @Override public boolean stopProfile(@UserIdInt int userId) { return mUserController.stopProfile(userId); } @@ -18305,6 +18313,23 @@ public class ActivityManagerService extends IActivityManager.Stub public void unregisterStrictModeCallback(int callingPid) { mStrictModeCallbacks.remove(callingPid); } + + @Override + public boolean canHoldWakeLocksInDeepDoze(int uid, int procstate) { + // This method is called with the PowerManager lock held. Do not hold AM here. + + // If the procstate is high enough, it's always allowed. + if (procstate <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { + return true; + } + // IF it's too low, it's not allowed. + if (procstate > PROCESS_STATE_IMPORTANT_FOREGROUND) { + return false; + } + // If it's PROCESS_STATE_IMPORTANT_FOREGROUND, then we allow it only wheen the UID + // has a SHORT_FGS. + return mOomAdjuster.hasUidShortForegroundService(uid); + } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, TimeoutRecord timeoutRecord) { diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 1e97285124a3..3ab1cd7f510f 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -39,6 +39,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NA import static com.android.server.am.AppBatteryTracker.BatteryUsage.BATTERY_USAGE_COUNT; import static com.android.server.am.LowMemDetector.ADJ_MEM_FACTOR_NOTHING; +import android.annotation.UserIdInt; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; @@ -113,10 +114,12 @@ import android.window.SplashScreen; import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.util.MemInfoReader; +import com.android.server.LocalServices; import com.android.server.am.LowMemDetector.MemFactor; import com.android.server.am.nano.Capabilities; import com.android.server.am.nano.Capability; import com.android.server.compat.PlatformCompat; +import com.android.server.pm.UserManagerInternal; import com.android.server.utils.Slogf; import dalvik.annotation.optimization.NeverCompile; @@ -536,18 +539,32 @@ final class ActivityManagerShellCommand extends ShellCommand { private class ProgressWaiter extends IProgressListener.Stub { private final CountDownLatch mFinishedLatch = new CountDownLatch(1); + private final @UserIdInt int mUserId; + + private ProgressWaiter(@UserIdInt int userId) { + mUserId = userId; + } @Override public void onStarted(int id, Bundle extras) {} @Override - public void onProgress(int id, int progress, Bundle extras) {} + public void onProgress(int id, int progress, Bundle extras) { + Slogf.d(TAG, "ProgressWaiter[user=%d]: onProgress(%d, %d)", mUserId, id, progress); + } @Override public void onFinished(int id, Bundle extras) { + Slogf.d(TAG, "ProgressWaiter[user=%d]: onFinished(%d)", mUserId, id); mFinishedLatch.countDown(); } + @Override + public String toString() { + return "ProgressWaiter[userId=" + mUserId + ", finished=" + + (mFinishedLatch.getCount() == 0) + "]"; + } + public boolean waitForFinish(long timeoutMillis) { try { return mFinishedLatch.await(timeoutMillis, TimeUnit.MILLISECONDS); @@ -2183,6 +2200,7 @@ final class ActivityManagerShellCommand extends ShellCommand { boolean wait = false; String opt; int displayId = Display.INVALID_DISPLAY; + boolean forceInvisible = false; while ((opt = getNextOption()) != null) { switch(opt) { case "-w": @@ -2191,32 +2209,47 @@ final class ActivityManagerShellCommand extends ShellCommand { case "--display": displayId = getDisplayIdFromNextArg(); break; + case "--force-invisible": + forceInvisible = true; + break; default: getErrPrintWriter().println("Error: unknown option: " + opt); return -1; } } - int userId = Integer.parseInt(getNextArgRequired()); - - final ProgressWaiter waiter = wait ? new ProgressWaiter() : null; + final int userId = Integer.parseInt(getNextArgRequired()); + final boolean callStartProfile = !forceInvisible && isProfile(userId); + final ProgressWaiter waiter = wait ? new ProgressWaiter(userId) : null; + Slogf.d(TAG, "runStartUser(): userId=%d, display=%d, waiter=%s, callStartProfile=%b, " + + "forceInvisible=%b", userId, displayId, waiter, callStartProfile, + forceInvisible); boolean success; - String displaySuffix; + String displaySuffix = ""; Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "shell_runStartUser" + userId); try { - if (displayId == Display.INVALID_DISPLAY) { + if (callStartProfile) { + Slogf.d(TAG, "calling startProfileWithListener(%d, %s)", userId, waiter); + // startProfileWithListener() will start the profile visible (as long its parent is + // the current user), while startUserInBackgroundWithListener() will always start + // the user (or profile) invisible + success = mInterface.startProfileWithListener(userId, waiter); + } else if (displayId == Display.INVALID_DISPLAY) { + Slogf.d(TAG, "calling startUserInBackgroundWithListener(%d)", userId); success = mInterface.startUserInBackgroundWithListener(userId, waiter); - displaySuffix = ""; } else { if (!UserManager.isVisibleBackgroundUsersEnabled()) { pw.println("Not supported"); return -1; } + Slogf.d(TAG, "calling startUserInBackgroundVisibleOnDisplay(%d,%d)", userId, + displayId); success = mInterface.startUserInBackgroundVisibleOnDisplay(userId, displayId); displaySuffix = " on display " + displayId; } if (wait && success) { + Slogf.d(TAG, "waiting %d ms", USER_OPERATION_TIMEOUT_MS); success = waiter.waitForFinish(USER_OPERATION_TIMEOUT_MS); } } finally { @@ -2273,27 +2306,40 @@ final class ActivityManagerShellCommand extends ShellCommand { } static final class StopUserCallback extends IStopUserCallback.Stub { + private final @UserIdInt int mUserId; private boolean mFinished = false; + private StopUserCallback(@UserIdInt int userId) { + mUserId = userId; + } + public synchronized void waitForFinish() { try { while (!mFinished) wait(); } catch (InterruptedException e) { throw new IllegalStateException(e); } + Slogf.d(TAG, "user %d finished stopping", mUserId); } @Override public synchronized void userStopped(int userId) { + Slogf.d(TAG, "StopUserCallback: userStopped(%d)", userId); mFinished = true; notifyAll(); } @Override public synchronized void userStopAborted(int userId) { + Slogf.d(TAG, "StopUserCallback: userStopAborted(%d)", userId); mFinished = true; notifyAll(); } + + @Override + public String toString() { + return "ProgressWaiter[userId=" + mUserId + ", finished=" + mFinished + "]"; + } } int runStopUser(PrintWriter pw) throws RemoteException { @@ -2310,10 +2356,11 @@ final class ActivityManagerShellCommand extends ShellCommand { return -1; } } - int user = Integer.parseInt(getNextArgRequired()); - StopUserCallback callback = wait ? new StopUserCallback() : null; + int userId = Integer.parseInt(getNextArgRequired()); + StopUserCallback callback = wait ? new StopUserCallback(userId) : null; - int res = mInterface.stopUser(user, force, callback); + Slogf.d(TAG, "Calling stopUser(%d, %b, %s)", userId, force, callback); + int res = mInterface.stopUser(userId, force, callback); if (res != ActivityManager.USER_OP_SUCCESS) { String txt = ""; switch (res) { @@ -2321,13 +2368,13 @@ final class ActivityManagerShellCommand extends ShellCommand { txt = " (Can't stop current user)"; break; case ActivityManager.USER_OP_UNKNOWN_USER: - txt = " (Unknown user " + user + ")"; + txt = " (Unknown user " + userId + ")"; break; case ActivityManager.USER_OP_ERROR_IS_SYSTEM: txt = " (System user cannot be stopped)"; break; case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP: - txt = " (Can't stop user " + user + txt = " (Can't stop user " + userId + " - one of its related users can't be stopped)"; break; } @@ -3822,6 +3869,11 @@ final class ActivityManagerShellCommand extends ShellCommand { return new Resources(AssetManager.getSystem(), metrics, config); } + private boolean isProfile(@UserIdInt int userId) { + final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class); + return umi.getProfileParentId(userId) != userId; + } + @Override public void onHelp() { PrintWriter pw = getOutPrintWriter(); @@ -4052,13 +4104,18 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" execution of that user if it is currently stopped."); pw.println(" get-current-user"); pw.println(" Returns id of the current foreground user."); - pw.println(" start-user [-w] [--display DISPLAY_ID] <USER_ID>"); + pw.println(" start-user [-w] [--display DISPLAY_ID] [--force-invisible] <USER_ID>"); pw.println(" Start USER_ID in background if it is currently stopped;"); pw.println(" use switch-user if you want to start the user in foreground."); pw.println(" -w: wait for start-user to complete and the user to be unlocked."); - pw.println(" --display <DISPLAY_ID>: allows the user to launch activities in the"); - pw.println(" given display, when supported (typically on automotive builds"); - pw.println(" wherethe vehicle has multiple displays)"); + pw.println(" --display <DISPLAY_ID>: starts the user visible in that display, " + + "which allows the user to launch activities on it."); + pw.println(" (not supported on all devices; typically only on automotive builds " + + "where the vehicle has passenger displays)"); + pw.println(" --force-invisible: always start the user invisible, even if it's a " + + "profile."); + pw.println(" (by default, a profile is visible in the default display when its " + + "parent is the current foreground user)"); pw.println(" unlock-user <USER_ID>"); pw.println(" Unlock the given user. This will only work if the user doesn't"); pw.println(" have an LSKF (PIN/pattern/password)."); diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java index e06ce2c91a40..4ad43fa2f320 100644 --- a/services/core/java/com/android/server/am/AppProfiler.java +++ b/services/core/java/com/android/server/am/AppProfiler.java @@ -1831,7 +1831,7 @@ public class AppProfiler { final BatteryStatsImpl bstats = mService.mBatteryStatsService.getActiveStatistics(); synchronized (bstats) { if (haveNewCpuStats) { - if (bstats.startAddingCpuLocked()) { + if (bstats.startAddingCpuStatsLocked()) { int totalUTime = 0; int totalSTime = 0; final int statsCount = mProcessCpuTracker.countStats(); @@ -1877,9 +1877,10 @@ public class AppProfiler { final int irqTime = mProcessCpuTracker.getLastIrqTime(); final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime(); final int idleTime = mProcessCpuTracker.getLastIdleTime(); - bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime, + bstats.addCpuStatsLocked(totalUTime, totalSTime, userTime, systemTime, iowaitTime, irqTime, softIrqTime, idleTime); } + bstats.finishAddingCpuStatsLocked(); } if (mLastWriteTime < (now - BATTERY_STATS_TIME)) { diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 114e2c139794..e02dda642b40 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -126,6 +126,7 @@ import android.os.Trace; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; +import android.util.SparseSetArray; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.CompositeRWLock; @@ -364,6 +365,19 @@ public class OomAdjuster { @GuardedBy("mService") private boolean mPendingFullOomAdjUpdate = false; + /** + * PIDs that has a SHORT_SERVICE. We need to access it with the PowerManager lock held, + * so we use a fine-grained lock here. + */ + @GuardedBy("mPidsWithShortFgs") + private final ArraySet<Integer> mPidsWithShortFgs = new ArraySet<>(); + + /** + * UIDs -> PIDs map, used with mPidsWithShortFgs. + */ + @GuardedBy("mPidsWithShortFgs") + private final SparseSetArray<Integer> mUidsToPidsWithShortFgs = new SparseSetArray<>(); + /** Overrideable by a test */ @VisibleForTesting protected boolean isChangeEnabled(@CachedCompatChangeId int cachedCompatChangeId, @@ -1849,6 +1863,11 @@ public class OomAdjuster { int capabilityFromFGS = 0; // capability from foreground service. + final boolean hasForegroundServices = psr.hasForegroundServices(); + final boolean hasNonShortForegroundServices = psr.hasNonShortForegroundServices(); + final boolean hasShortForegroundServices = hasForegroundServices + && !psr.areAllShortForegroundServicesProcstateTimedOut(now); + // Adjust for FGS or "has-overlay-ui". if (adj > PERCEPTIBLE_APP_ADJ || procState > PROCESS_STATE_FOREGROUND_SERVICE) { @@ -1856,7 +1875,7 @@ public class OomAdjuster { int newAdj = 0; int newProcState = 0; - if (psr.hasForegroundServices() && psr.hasNonShortForegroundServices()) { + if (hasForegroundServices && hasNonShortForegroundServices) { // For regular (non-short) FGS. adjType = "fg-service"; newAdj = PERCEPTIBLE_APP_ADJ; @@ -1867,11 +1886,11 @@ public class OomAdjuster { newAdj = PERCEPTIBLE_APP_ADJ; newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND; - } else if (psr.hasForegroundServices()) { + } else if (hasForegroundServices) { // If we get here, hasNonShortForegroundServices() must be false. // TODO(short-service): Proactively run OomAjudster when the grace period finish. - if (psr.areAllShortForegroundServicesProcstateTimedOut(now)) { + if (!hasShortForegroundServices) { // All the short-FGSes within this process are timed out. Don't promote to FGS. // TODO(short-service): Should we set some unique oom-adj to make it detectable, // in a long trace? @@ -1907,6 +1926,7 @@ public class OomAdjuster { } } } + updateShortFgsOwner(psr.mApp.uid, psr.mApp.mPid, hasShortForegroundServices); // If the app was recently in the foreground and moved to a foreground service status, // allow it to get a higher rank in memory for some time, compared to other foreground @@ -3337,4 +3357,40 @@ public class OomAdjuster { mCachedAppOptimizer.unfreezeAppLSP(app, oomAdjReason); } } + + /** + * Update {@link #mPidsWithShortFgs} and {@link #mUidsToPidsWithShortFgs} to keep track + * of which UID/PID has a short FGS. + * + * TODO(short-FGS): Remove it and all the relevant code once SHORT_FGS use the FGS procstate. + */ + void updateShortFgsOwner(int uid, int pid, boolean add) { + synchronized (mPidsWithShortFgs) { + if (add) { + mUidsToPidsWithShortFgs.add(uid, pid); + mPidsWithShortFgs.add(pid); + } else { + mUidsToPidsWithShortFgs.remove(uid, pid); + mPidsWithShortFgs.remove(pid); + } + } + } + + /** + * Whether a UID has a (non-timed-out) short FGS or not. + * It's indirectly called by PowerManager, so we can't hold the AM lock in it. + */ + boolean hasUidShortForegroundService(int uid) { + synchronized (mPidsWithShortFgs) { + final ArraySet<Integer> pids = mUidsToPidsWithShortFgs.get(uid); + if (pids == null || pids.size() == 0) { + return false; + } + for (int i = pids.size() - 1; i >= 0; i--) { + final int pid = pids.valueAt(i); + return mPidsWithShortFgs.contains(pid); + } + } + return false; + } } diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 8ce98894e3f3..b2e4740de5d4 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -1470,7 +1470,11 @@ class UserController implements Handler.Callback { * @param userId the id of the user to start. * @return true if the operation was successful. */ - boolean startProfile(final @UserIdInt int userId) { + boolean startProfile(@UserIdInt int userId) { + return startProfile(userId, /* unlockListener= */ null); + } + + boolean startProfile(@UserIdInt int userId, @Nullable IProgressListener unlockListener) { if (mInjector.checkCallingPermission(android.Manifest.permission.MANAGE_USERS) == PackageManager.PERMISSION_DENIED && mInjector.checkCallingPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) @@ -1491,7 +1495,7 @@ class UserController implements Handler.Callback { } return startUserNoChecks(userId, Display.DEFAULT_DISPLAY, - USER_START_MODE_BACKGROUND_VISIBLE, /* unlockListener= */ null); + USER_START_MODE_BACKGROUND_VISIBLE, unlockListener); } @VisibleForTesting diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index b4992d7f64db..88fc51a34488 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3757,8 +3757,19 @@ public class AudioService extends IAudioService.Stub return false; } - /*package*/ void onSetStreamVolume(int streamType, int index, int flags, int device, - String caller, boolean hasModifyAudioSettings) { + /** + * Update stream volume, ringer mode and mute status after a volume index change + * @param streamType + * @param index + * @param flags + * @param device the device for which the volume is changed + * @param caller + * @param hasModifyAudioSettings + * @param canChangeMute true if the origin of this event is one where the mute state should be + * updated following the change in volume index + */ + /*package*/ void onSetStreamVolume(int streamType, int index, int flags, int device, + String caller, boolean hasModifyAudioSettings, boolean canChangeMute) { final int stream = mStreamVolumeAlias[streamType]; setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings); // setting volume on ui sounds stream type also controls silent mode @@ -3768,10 +3779,8 @@ public class AudioService extends IAudioService.Stub TAG + ".onSetStreamVolume", false /*external*/); } // setting non-zero volume for a muted stream unmutes the stream and vice versa - // (only when changing volume for the current device), // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements - if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO) - && (getDeviceForStream(stream) == device)) { + if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO) && canChangeMute) { // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams. muteAliasStreams(stream, index == 0); } @@ -4494,7 +4503,10 @@ public class AudioService extends IAudioService.Stub if (!mSoundDoseHelper.willDisplayWarningAfterCheckVolume(streamType, index, device, flags)) { - onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings); + onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings, + // ada is non-null when called from setDeviceVolume, + // which shouldn't update the mute state + ada == null /*canChangeMute*/); index = mStreamStates[streamType].getIndex(device); } diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java index 7839ada9d5b2..7af7ed5fff65 100644 --- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java +++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java @@ -37,8 +37,12 @@ import android.util.Pair; import com.android.internal.annotations.GuardedBy; import java.io.PrintWriter; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -68,11 +72,14 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, private String[] mMethodNames = {"getDevicesForAttributes"}; private static final boolean USE_CACHE_FOR_GETDEVICES = true; + private static final Object sDeviceCacheLock = new Object(); private ConcurrentHashMap<Pair<AudioAttributes, Boolean>, ArrayList<AudioDeviceAttributes>> mLastDevicesForAttr = new ConcurrentHashMap<>(); + @GuardedBy("sDeviceCacheLock") private ConcurrentHashMap<Pair<AudioAttributes, Boolean>, ArrayList<AudioDeviceAttributes>> mDevicesForAttrCache; - private final Object mDeviceCacheLock = new Object(); + @GuardedBy("sDeviceCacheLock") + private long mDevicesForAttributesCacheClearTimeMs = System.currentTimeMillis(); private int[] mMethodCacheHit; /** * Map that stores all attributes + forVolume pairs that are registered for @@ -249,9 +256,11 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, AudioSystem.setRoutingCallback(sSingletonDefaultAdapter); AudioSystem.setVolumeRangeInitRequestCallback(sSingletonDefaultAdapter); if (USE_CACHE_FOR_GETDEVICES) { - sSingletonDefaultAdapter.mDevicesForAttrCache = - new ConcurrentHashMap<>(AudioSystem.getNumStreamTypes()); - sSingletonDefaultAdapter.mMethodCacheHit = new int[NB_MEASUREMENTS]; + synchronized (sDeviceCacheLock) { + sSingletonDefaultAdapter.mDevicesForAttrCache = + new ConcurrentHashMap<>(AudioSystem.getNumStreamTypes()); + sSingletonDefaultAdapter.mMethodCacheHit = new int[NB_MEASUREMENTS]; + } } if (ENABLE_GETDEVICES_STATS) { sSingletonDefaultAdapter.mMethodCallCounter = new int[NB_MEASUREMENTS]; @@ -265,8 +274,9 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, if (DEBUG_CACHE) { Log.d(TAG, "---- clearing cache ----------"); } - synchronized (mDeviceCacheLock) { + synchronized (sDeviceCacheLock) { if (mDevicesForAttrCache != null) { + mDevicesForAttributesCacheClearTimeMs = System.currentTimeMillis(); // Save latest cache to determine routing updates mLastDevicesForAttr.putAll(mDevicesForAttrCache); @@ -298,7 +308,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, if (USE_CACHE_FOR_GETDEVICES) { ArrayList<AudioDeviceAttributes> res; final Pair<AudioAttributes, Boolean> key = new Pair(attributes, forVolume); - synchronized (mDeviceCacheLock) { + synchronized (sDeviceCacheLock) { res = mDevicesForAttrCache.get(key); if (res == null) { res = AudioSystem.getDevicesForAttributes(attributes, forVolume); @@ -656,23 +666,31 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, */ public void dump(PrintWriter pw) { pw.println("\nAudioSystemAdapter:"); - pw.println(" mDevicesForAttrCache:"); - if (mDevicesForAttrCache != null) { - for (Map.Entry<Pair<AudioAttributes, Boolean>, ArrayList<AudioDeviceAttributes>> - entry : mDevicesForAttrCache.entrySet()) { - final AudioAttributes attributes = entry.getKey().first; - try { - final int stream = attributes.getVolumeControlStream(); - pw.println("\t" + attributes + " forVolume: " + entry.getKey().second - + " stream: " - + AudioSystem.STREAM_NAMES[stream] + "(" + stream + ")"); - for (AudioDeviceAttributes devAttr : entry.getValue()) { - pw.println("\t\t" + devAttr); + final DateTimeFormatter formatter = DateTimeFormatter + .ofPattern("MM-dd HH:mm:ss:SSS") + .withLocale(Locale.US) + .withZone(ZoneId.systemDefault()); + synchronized (sDeviceCacheLock) { + pw.println(" last cache clear time: " + formatter.format( + Instant.ofEpochMilli(mDevicesForAttributesCacheClearTimeMs))); + pw.println(" mDevicesForAttrCache:"); + if (mDevicesForAttrCache != null) { + for (Map.Entry<Pair<AudioAttributes, Boolean>, ArrayList<AudioDeviceAttributes>> + entry : mDevicesForAttrCache.entrySet()) { + final AudioAttributes attributes = entry.getKey().first; + try { + final int stream = attributes.getVolumeControlStream(); + pw.println("\t" + attributes + " forVolume: " + entry.getKey().second + + " stream: " + + AudioSystem.STREAM_NAMES[stream] + "(" + stream + ")"); + for (AudioDeviceAttributes devAttr : entry.getValue()) { + pw.println("\t\t" + devAttr); + } + } catch (IllegalArgumentException e) { + // dump could fail if attributes do not map to a stream. + pw.println("\t dump failed for attributes: " + attributes); + Log.e(TAG, "dump failed", e); } - } catch (IllegalArgumentException e) { - // dump could fail if attributes do not map to a stream. - pw.println("\t dump failed for attributes: " + attributes); - Log.e(TAG, "dump failed", e); } } } diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java index bc61b3788386..42031c6f8f74 100644 --- a/services/core/java/com/android/server/audio/SoundDoseHelper.java +++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java @@ -404,7 +404,8 @@ public class SoundDoseHelper { mPendingVolumeCommand.mIndex, mPendingVolumeCommand.mFlags, mPendingVolumeCommand.mDevice, - callingPackage, true /*hasModifyAudioSettings*/); + callingPackage, true /*hasModifyAudioSettings*/, + true /*canChangeMute*/); mPendingVolumeCommand = null; } } diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 05464c810061..592daa61f36c 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -402,7 +402,6 @@ class AutomaticBrightnessController { boolean userChangedAutoBrightnessAdjustment, int displayPolicy, boolean shouldResetShortTermModel) { mState = state; - mHbmController.setAutoBrightnessEnabled(mState); // While dozing, the application processor may be suspended which will prevent us from // receiving new information from the light sensor. On some devices, we may be able to // switch to a wake-up light sensor instead but for now we will simply disable the sensor @@ -466,7 +465,6 @@ class AutomaticBrightnessController { mHandler.sendEmptyMessage(MSG_RUN_UPDATE); } - @VisibleForTesting float getAmbientLux() { return mAmbientLux; } diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 42e097832346..3759a8bc61ce 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -2396,7 +2396,9 @@ public final class DisplayManagerService extends SystemService { } // fallthrough default: - Slog.w(TAG, "Display " + info + " does not support input device matching."); + if (DEBUG) { + Slog.w(TAG, "Display " + info + " does not support input device matching."); + } } return Optional.empty(); } diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index f8d6c5f3ea4d..52e20d651458 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -635,7 +635,9 @@ public class DisplayModeDirector { // which is within the render rate range // - 90hz is not in range as none of the even divisors (i.e. 90, 45, 30) // fall within the acceptable render range. - final int divisor = (int) Math.ceil(physicalRefreshRate / summary.maxRenderFrameRate); + final int divisor = + (int) Math.ceil((physicalRefreshRate / summary.maxRenderFrameRate) + - FLOAT_TOLERANCE); float adjustedPhysicalRefreshRate = physicalRefreshRate / divisor; if (adjustedPhysicalRefreshRate < (summary.minRenderFrameRate - FLOAT_TOLERANCE)) { if (mLoggingEnabled) { @@ -3081,10 +3083,10 @@ public class DisplayModeDirector { @Override public boolean supportsFrameRateOverride() { - return SurfaceFlingerProperties.enable_frame_rate_override().orElse(false) + return SurfaceFlingerProperties.enable_frame_rate_override().orElse(true) && !SurfaceFlingerProperties.frame_rate_override_for_native_rates() - .orElse(true) - && SurfaceFlingerProperties.frame_rate_override_global().orElse(false); + .orElse(false) + && SurfaceFlingerProperties.frame_rate_override_global().orElse(true); } private DisplayManager getDisplayManager() { diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index fc2a4e509bf5..abb0ff625ef3 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -719,7 +719,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } @Override - public void setBrightnessToFollow(float leadDisplayBrightness, float nits) { + public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) { + mHbmController.onAmbientLuxChange(ambientLux); if (mAutomaticBrightnessController == null || nits < 0) { mBrightnessToFollow = leadDisplayBrightness; } else { @@ -751,7 +752,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } for (int i = 0; i < followers.size(); i++) { DisplayPowerControllerInterface follower = followers.valueAt(i); - follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1); + follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1, + /* ambientLux= */ 0); } } @@ -1523,6 +1525,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mShouldResetShortTermModel); mShouldResetShortTermModel = false; } + mHbmController.setAutoBrightnessEnabled(mUseAutoBrightness + ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED + : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED); if (mBrightnessTracker != null) { mBrightnessTracker.setBrightnessConfiguration(mBrightnessConfiguration); @@ -1634,9 +1639,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mAppliedThrottling = false; } + float ambientLux = mAutomaticBrightnessController == null ? 0 + : mAutomaticBrightnessController.getAmbientLux(); for (int i = 0; i < displayBrightnessFollowers.size(); i++) { DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i); - follower.setBrightnessToFollow(rawBrightnessState, convertToNits(rawBrightnessState)); + follower.setBrightnessToFollow(rawBrightnessState, convertToNits(rawBrightnessState), + ambientLux); } if (updateScreenBrightnessSetting) { diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java index a7444151510f..2e91bdb66072 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController2.java +++ b/services/core/java/com/android/server/display/DisplayPowerController2.java @@ -1236,6 +1236,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mShouldResetShortTermModel); mShouldResetShortTermModel = false; } + mHbmController.setAutoBrightnessEnabled(mUseAutoBrightness + ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED + : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED); if (mBrightnessTracker != null) { mBrightnessTracker.setBrightnessConfiguration(mBrightnessConfiguration); @@ -1347,9 +1350,12 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mAppliedThrottling = false; } + float ambientLux = mAutomaticBrightnessController == null ? 0 + : mAutomaticBrightnessController.getAmbientLux(); for (int i = 0; i < displayBrightnessFollowers.size(); i++) { DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i); - follower.setBrightnessToFollow(rawBrightnessState, convertToNits(rawBrightnessState)); + follower.setBrightnessToFollow(rawBrightnessState, convertToNits(rawBrightnessState), + ambientLux); } if (updateScreenBrightnessSetting) { @@ -2138,7 +2144,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } @Override - public void setBrightnessToFollow(float leadDisplayBrightness, float nits) { + public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) { + mHbmController.onAmbientLuxChange(ambientLux); if (mAutomaticBrightnessController == null || nits < 0) { mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness); } else { @@ -2219,7 +2226,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } for (int i = 0; i < followers.size(); i++) { DisplayPowerControllerInterface follower = followers.valueAt(i); - follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1); + follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1, + /* ambientLux= */ 0); } } diff --git a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java index a95ac74b27c8..4612ec9cf2dc 100644 --- a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java +++ b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java @@ -173,9 +173,11 @@ public interface DisplayPowerControllerInterface { * displays. * @param leadDisplayBrightness The brightness of the lead display in the set of concurrent * displays - * @param nits The brightness value in nits if the device supports nits + * @param nits The brightness value in nits if the device supports nits. Set to a negative + * number otherwise. + * @param ambientLux The lux value that will be passed to {@link HighBrightnessModeController} */ - void setBrightnessToFollow(float leadDisplayBrightness, float nits); + void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux); /** * Add an additional display that will copy the brightness value from this display. This is used diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index f870c0a0e60e..d7306b732785 100644 --- a/services/core/java/com/android/server/dreams/DreamController.java +++ b/services/core/java/com/android/server/dreams/DreamController.java @@ -119,6 +119,8 @@ final class DreamController { // are yet to be delivered. options.setDeliveryGroupMatchingKey( DREAMING_DELIVERY_GROUP_NAMESPACE, DREAMING_DELIVERY_GROUP_KEY); + // This allows the broadcast delivery to be delayed to apps in the Cached state. + options.setDeferUntilActive(true); return options.toBundle(); } diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 8c1329797d12..e2caeec114d0 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -493,7 +493,11 @@ public class InputManagerService extends IInputManager.Stub // Add ourselves to the Watchdog monitors. Watchdog.getInstance().addMonitor(this); - registerPointerSpeedSettingObserver(); + registerMousePointerSpeedSettingObserver(); + registerTouchpadPointerSpeedSettingObserver(); + registerTouchpadNaturalScrollingEnabledObserver(); + registerTouchpadTapToClickEnabledObserver(); + registerTouchpadRightClickZoneEnabledObserver(); registerShowTouchesSettingObserver(); registerAccessibilityLargePointerSettingObserver(); registerLongPressTimeoutObserver(); @@ -502,14 +506,22 @@ public class InputManagerService extends IInputManager.Stub mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - updatePointerSpeedFromSettings(); + updateMousePointerSpeedFromSettings(); + updateTouchpadPointerSpeedFromSettings(); + updateTouchpadNaturalScrollingEnabledFromSettings(); + updateTouchpadTapToClickEnabledFromSettings(); + updateTouchpadRightClickZoneEnabledFromSettings(); updateShowTouchesFromSettings(); updateAccessibilityLargePointerFromSettings(); updateDeepPressStatusFromSettings("user switched"); } }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); - updatePointerSpeedFromSettings(); + updateMousePointerSpeedFromSettings(); + updateTouchpadPointerSpeedFromSettings(); + updateTouchpadNaturalScrollingEnabledFromSettings(); + updateTouchpadTapToClickEnabledFromSettings(); + updateTouchpadRightClickZoneEnabledFromSettings(); updateShowTouchesFromSettings(); updateAccessibilityLargePointerFromSettings(); updateDeepPressStatusFromSettings("just booted"); @@ -1337,8 +1349,8 @@ public class InputManagerService extends IInputManager.Stub setPointerSpeedUnchecked(speed); } - private void updatePointerSpeedFromSettings() { - int speed = getPointerSpeedSetting(); + private void updateMousePointerSpeedFromSettings() { + int speed = getMousePointerSpeedSetting(); setPointerSpeedUnchecked(speed); } @@ -1358,18 +1370,18 @@ public class InputManagerService extends IInputManager.Stub properties -> properties.pointerIconVisible = visible); } - private void registerPointerSpeedSettingObserver() { + private void registerMousePointerSpeedSettingObserver() { mContext.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.POINTER_SPEED), true, new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { - updatePointerSpeedFromSettings(); + updateMousePointerSpeedFromSettings(); } }, UserHandle.USER_ALL); } - private int getPointerSpeedSetting() { + private int getMousePointerSpeedSetting() { int speed = InputManager.DEFAULT_POINTER_SPEED; try { speed = Settings.System.getIntForUser(mContext.getContentResolver(), @@ -1379,6 +1391,77 @@ public class InputManagerService extends IInputManager.Stub return speed; } + private void registerTouchpadPointerSpeedSettingObserver() { + mContext.getContentResolver().registerContentObserver( + Settings.System.getUriFor(Settings.System.TOUCHPAD_POINTER_SPEED), true, + new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange) { + updateTouchpadPointerSpeedFromSettings(); + } + }, UserHandle.USER_ALL); + } + + private void updateTouchpadPointerSpeedFromSettings() { + int speed = Settings.System.getIntForUser(mContext.getContentResolver(), + Settings.System.TOUCHPAD_POINTER_SPEED, InputManager.DEFAULT_POINTER_SPEED, + UserHandle.USER_CURRENT); + speed = Math.min(Math.max(speed, InputManager.MIN_POINTER_SPEED), + InputManager.MAX_POINTER_SPEED); + mNative.setTouchpadPointerSpeed(speed); + } + + private void registerTouchpadNaturalScrollingEnabledObserver() { + mContext.getContentResolver().registerContentObserver( + Settings.System.getUriFor(Settings.System.TOUCHPAD_NATURAL_SCROLLING), true, + new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange) { + updateTouchpadNaturalScrollingEnabledFromSettings(); + } + }, UserHandle.USER_ALL); + } + + private void updateTouchpadNaturalScrollingEnabledFromSettings() { + int setting = Settings.System.getIntForUser(mContext.getContentResolver(), + Settings.System.TOUCHPAD_NATURAL_SCROLLING, 0, UserHandle.USER_CURRENT); + mNative.setTouchpadNaturalScrollingEnabled(setting != 0); + } + + private void registerTouchpadTapToClickEnabledObserver() { + mContext.getContentResolver().registerContentObserver( + Settings.System.getUriFor(Settings.System.TOUCHPAD_TAP_TO_CLICK), true, + new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange) { + updateTouchpadTapToClickEnabledFromSettings(); + } + }, UserHandle.USER_ALL); + } + + private void updateTouchpadTapToClickEnabledFromSettings() { + int setting = Settings.System.getIntForUser(mContext.getContentResolver(), + Settings.System.TOUCHPAD_TAP_TO_CLICK, 0, UserHandle.USER_CURRENT); + mNative.setTouchpadTapToClickEnabled(setting != 0); + } + + private void registerTouchpadRightClickZoneEnabledObserver() { + mContext.getContentResolver().registerContentObserver( + Settings.System.getUriFor(Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE), true, + new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange) { + updateTouchpadRightClickZoneEnabledFromSettings(); + } + }, UserHandle.USER_ALL); + } + + private void updateTouchpadRightClickZoneEnabledFromSettings() { + int setting = Settings.System.getIntForUser(mContext.getContentResolver(), + Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, 0, UserHandle.USER_CURRENT); + mNative.setTouchpadRightClickZoneEnabled(setting != 0); + } + private void updateShowTouchesFromSettings() { int setting = getShowTouchesSetting(0); mNative.setShowTouches(setting != 0); diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java index 6fca9cc4c590..22226e88f15f 100644 --- a/services/core/java/com/android/server/input/NativeInputManagerService.java +++ b/services/core/java/com/android/server/input/NativeInputManagerService.java @@ -120,6 +120,14 @@ interface NativeInputManagerService { void setPointerAcceleration(float acceleration); + void setTouchpadPointerSpeed(int speed); + + void setTouchpadNaturalScrollingEnabled(boolean enabled); + + void setTouchpadTapToClickEnabled(boolean enabled); + + void setTouchpadRightClickZoneEnabled(boolean enabled); + void setShowTouches(boolean enabled); void setInteractive(boolean interactive); @@ -314,6 +322,18 @@ interface NativeInputManagerService { public native void setPointerAcceleration(float acceleration); @Override + public native void setTouchpadPointerSpeed(int speed); + + @Override + public native void setTouchpadNaturalScrollingEnabled(boolean enabled); + + @Override + public native void setTouchpadTapToClickEnabled(boolean enabled); + + @Override + public native void setTouchpadRightClickZoneEnabled(boolean enabled); + + @Override public native void setShowTouches(boolean enabled); @Override diff --git a/services/core/java/com/android/server/location/gnss/ExponentialBackOff.java b/services/core/java/com/android/server/location/gnss/ExponentialBackOff.java index 05a534fa36e9..aab52ce52a0d 100644 --- a/services/core/java/com/android/server/location/gnss/ExponentialBackOff.java +++ b/services/core/java/com/android/server/location/gnss/ExponentialBackOff.java @@ -44,5 +44,14 @@ class ExponentialBackOff { void reset() { mCurrentIntervalMillis = mInitIntervalMillis / MULTIPLIER; } + + @Override + public String toString() { + return "ExponentialBackOff{" + + "mInitIntervalMillis=" + mInitIntervalMillis + + ", mMaxIntervalMillis=" + mMaxIntervalMillis + + ", mCurrentIntervalMillis=" + mCurrentIntervalMillis + + '}'; + } } diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java index 262013ec8d96..e48412ab4029 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -1695,6 +1695,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements pw.println("mFixInterval=" + mFixInterval); pw.print(mGnssMetrics.dumpGnssMetricsAsText()); if (dumpAll) { + mNetworkTimeHelper.dump(pw); pw.println("mSupportsPsds=" + mSupportsPsds); pw.println( "PsdsServerConfigured=" + mGnssConfiguration.isLongTermPsdsServerConfigured()); diff --git a/services/core/java/com/android/server/location/gnss/NetworkTimeHelper.java b/services/core/java/com/android/server/location/gnss/NetworkTimeHelper.java index 72d6f7014515..3a2514604600 100644 --- a/services/core/java/com/android/server/location/gnss/NetworkTimeHelper.java +++ b/services/core/java/com/android/server/location/gnss/NetworkTimeHelper.java @@ -15,9 +15,14 @@ */ package com.android.server.location.gnss; +import android.annotation.CurrentTimeMillisLong; +import android.annotation.ElapsedRealtimeLong; +import android.annotation.NonNull; import android.content.Context; import android.os.Looper; +import java.io.PrintWriter; + /** * An abstraction for use by {@link GnssLocationProvider}. This class allows switching between * implementations with a compile-time constant change, which is less risky than rolling back a @@ -32,15 +37,16 @@ abstract class NetworkTimeHelper { * the looper passed to {@link #create(Context, Looper, InjectTimeCallback)}. */ interface InjectTimeCallback { - void injectTime(long unixEpochTimeMillis, long elapsedRealtimeMillis, - int uncertaintyMillis); + void injectTime(@CurrentTimeMillisLong long unixEpochTimeMillis, + @ElapsedRealtimeLong long elapsedRealtimeMillis, int uncertaintyMillis); } /** * Creates the {@link NetworkTimeHelper} instance for use by {@link GnssLocationProvider}. */ static NetworkTimeHelper create( - Context context, Looper looper, InjectTimeCallback injectTimeCallback) { + @NonNull Context context, @NonNull Looper looper, + @NonNull InjectTimeCallback injectTimeCallback) { return new NtpNetworkTimeHelper(context, looper, injectTimeCallback); } @@ -72,4 +78,8 @@ abstract class NetworkTimeHelper { */ abstract void onNetworkAvailable(); + /** + * Dumps internal state during bugreports useful for debugging. + */ + abstract void dump(@NonNull PrintWriter pw); } diff --git a/services/core/java/com/android/server/location/gnss/NtpNetworkTimeHelper.java b/services/core/java/com/android/server/location/gnss/NtpNetworkTimeHelper.java index 479dbdab8bd5..d682164c988d 100644 --- a/services/core/java/com/android/server/location/gnss/NtpNetworkTimeHelper.java +++ b/services/core/java/com/android/server/location/gnss/NtpNetworkTimeHelper.java @@ -23,12 +23,17 @@ import android.os.Handler; import android.os.Looper; import android.os.PowerManager; import android.os.PowerManager.WakeLock; +import android.os.SystemClock; +import android.util.IndentingPrintWriter; +import android.util.LocalLog; import android.util.Log; import android.util.NtpTrustedTime; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import java.io.PrintWriter; + /** * Handles injecting network time to GNSS by explicitly making NTP requests when needed. */ @@ -60,6 +65,9 @@ class NtpNetworkTimeHelper extends NetworkTimeHelper { private static final long WAKELOCK_TIMEOUT_MILLIS = 60 * 1000; private static final String WAKELOCK_KEY = "NtpTimeHelper"; + private final LocalLog mDumpLog = new LocalLog(10, /*useLocalTimestamps=*/false); + + @GuardedBy("this") private final ExponentialBackOff mNtpBackOff = new ExponentialBackOff(RETRY_INTERVAL, MAX_RETRY_INTERVAL); @@ -103,14 +111,37 @@ class NtpNetworkTimeHelper extends NetworkTimeHelper { @Override void demandUtcTimeInjection() { - retrieveAndInjectNtpTime(); + retrieveAndInjectNtpTime("demandUtcTimeInjection"); } @Override synchronized void onNetworkAvailable() { if (mInjectNtpTimeState == STATE_PENDING_NETWORK) { - retrieveAndInjectNtpTime(); + retrieveAndInjectNtpTime("onNetworkAvailable"); + } + } + + @Override + void dump(PrintWriter pw) { + pw.println("NtpNetworkTimeHelper:"); + + IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); + ipw.increaseIndent(); + synchronized (this) { + ipw.println("mInjectNtpTimeState=" + mInjectNtpTimeState); + ipw.println("mPeriodicTimeInjection=" + mPeriodicTimeInjection); + ipw.println("mNtpBackOff=" + mNtpBackOff); } + + ipw.println("Debug log:"); + ipw.increaseIndent(); + mDumpLog.dump(ipw); + ipw.decreaseIndent(); + + ipw.println("NtpTrustedTime:"); + ipw.increaseIndent(); + mNtpTime.dump(ipw); + ipw.decreaseIndent(); } /** @@ -122,14 +153,14 @@ class NtpNetworkTimeHelper extends NetworkTimeHelper { return activeNetworkInfo != null && activeNetworkInfo.isConnected(); } - private synchronized void retrieveAndInjectNtpTime() { + private synchronized void retrieveAndInjectNtpTime(String reason) { if (mInjectNtpTimeState == STATE_RETRIEVING_AND_INJECTING) { // already downloading data return; } if (!isNetworkConnected()) { // try to inject the cached NTP time - injectCachedNtpTime(); + maybeInjectCachedNtpTime(reason + "[Network not connected]"); // try again when network is up mInjectNtpTimeState = STATE_PENDING_NETWORK; return; @@ -143,7 +174,8 @@ class NtpNetworkTimeHelper extends NetworkTimeHelper { /** {@link NtpTrustedTime#forceRefresh} is a blocking network operation. */ private void blockingGetNtpTimeAndInject() { - long delay; + long debugId = SystemClock.elapsedRealtime(); + long delayMillis; // force refresh NTP cache when outdated boolean refreshSuccess = true; @@ -158,26 +190,30 @@ class NtpNetworkTimeHelper extends NetworkTimeHelper { // only update when NTP time is fresh // If refreshSuccess is false, cacheAge does not drop down. - if (injectCachedNtpTime()) { - delay = NTP_INTERVAL; + String injectReason = "blockingGetNtpTimeAndInject:" + + ", debugId=" + debugId + + ", refreshSuccess=" + refreshSuccess; + if (maybeInjectCachedNtpTime(injectReason)) { + delayMillis = NTP_INTERVAL; mNtpBackOff.reset(); } else { - Log.e(TAG, "requestTime failed"); - delay = mNtpBackOff.nextBackoffMillis(); + logWarn("maybeInjectCachedNtpTime() returned false"); + delayMillis = mNtpBackOff.nextBackoffMillis(); } - if (DEBUG) { - Log.d(TAG, String.format( - "mPeriodicTimeInjection=%s, refreshSuccess=%s, delay=%s", - mPeriodicTimeInjection, - refreshSuccess, - delay)); - } if (mPeriodicTimeInjection || !refreshSuccess) { + String debugMsg = "blockingGetNtpTimeAndInject: Scheduling later NTP retrieval" + + ", debugId=" + debugId + + ", mPeriodicTimeInjection=" + mPeriodicTimeInjection + + ", refreshSuccess=" + refreshSuccess + + ", delayMillis=" + delayMillis; + logDebug(debugMsg); + // Schedule next NTP injection. // Since this is delayed, the wake lock is released right away, and will be held // again when the delayed task runs. - mHandler.postDelayed(this::retrieveAndInjectNtpTime, delay); + String reason = "scheduled: debugId=" + debugId; + mHandler.postDelayed(() -> retrieveAndInjectNtpTime(reason), delayMillis); } } // release wake lock held by task @@ -185,24 +221,41 @@ class NtpNetworkTimeHelper extends NetworkTimeHelper { } /** Returns true if successfully inject cached NTP time. */ - private synchronized boolean injectCachedNtpTime() { + private synchronized boolean maybeInjectCachedNtpTime(String reason) { NtpTrustedTime.TimeResult ntpResult = mNtpTime.getCachedTimeResult(); if (ntpResult == null || ntpResult.getAgeMillis() >= NTP_INTERVAL) { + String debugMsg = "maybeInjectCachedNtpTime: Not injecting latest NTP time" + + ", reason=" + reason + + ", ntpResult=" + ntpResult; + logDebug(debugMsg); + return false; } long unixEpochTimeMillis = ntpResult.getTimeMillis(); + long currentTimeMillis = System.currentTimeMillis(); + String debugMsg = "maybeInjectCachedNtpTime: Injecting latest NTP time" + + ", reason=" + reason + + ", ntpResult=" + ntpResult + + ", System time offset millis=" + (unixEpochTimeMillis - currentTimeMillis); + logDebug(debugMsg); + long timeReferenceMillis = ntpResult.getElapsedRealtimeMillis(); int uncertaintyMillis = ntpResult.getUncertaintyMillis(); - if (DEBUG) { - long currentTimeMillis = System.currentTimeMillis(); - Log.d(TAG, "NTP server returned: " + unixEpochTimeMillis - + " ntpResult: " + ntpResult - + " system time offset: " + (unixEpochTimeMillis - currentTimeMillis)); - } - mHandler.post(() -> mCallback.injectTime(unixEpochTimeMillis, timeReferenceMillis, uncertaintyMillis)); return true; } + + private void logWarn(String logMsg) { + mDumpLog.log(logMsg); + Log.e(TAG, logMsg); + } + + private void logDebug(String debugMsg) { + mDumpLog.log(debugMsg); + if (DEBUG) { + Log.d(TAG, debugMsg); + } + } } diff --git a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java index edb2e5bf3f97..7618419ab0e4 100644 --- a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java +++ b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java @@ -1127,13 +1127,14 @@ public class GnssNative { } @NativeEntryPoint - void setTopHalCapabilities(@GnssCapabilities.TopHalCapabilityFlags int capabilities) { + void setTopHalCapabilities(@GnssCapabilities.TopHalCapabilityFlags int capabilities, + boolean isAdrCapabilityKnown) { // Here the bits specified by 'capabilities' are turned on. It is handled differently from // sub hal because top hal capabilities could be set by HIDL HAL and/or AIDL HAL. Each of // them possesses a different set of capabilities. mTopFlags |= capabilities; GnssCapabilities oldCapabilities = mCapabilities; - mCapabilities = oldCapabilities.withTopHalFlags(mTopFlags); + mCapabilities = oldCapabilities.withTopHalFlags(mTopFlags, isAdrCapabilityKnown); onCapabilitiesChanged(oldCapabilities, mCapabilities); } diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 48e0c300979c..ebc18bcd2369 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -29,6 +29,7 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.PROFILE_ENCRY import static android.content.Context.KEYGUARD_SERVICE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.UserHandle.USER_ALL; +import static android.provider.DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD; @@ -1689,6 +1690,13 @@ public class LockSettingsService extends ILockSettings.Stub { if (newCredential.isPattern()) { setBoolean(LockPatternUtils.PATTERN_EVER_CHOSEN_KEY, true, userHandle); } + if (DeviceConfig.getBoolean(NAMESPACE_AUTO_PIN_CONFIRMATION, + "enable_auto_pin_confirmation", /* defaultValue= */ false)) { + if (newCredential.isPin()) { + setLong(LockPatternUtils.PIN_LENGTH, newCredential.size(), userHandle); + } + } + updatePasswordHistory(newCredential, userHandle); mContext.getSystemService(TrustManager.class).reportEnabledTrustAgentsChanged(userHandle); } diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index 669ea9536568..03e4f09c253d 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -1740,6 +1740,14 @@ abstract public class ManagedServices { return ManagedServices.this; } + public IInterface getService() { + return service; + } + + public boolean isSystem() { + return isSystem; + } + @Override public String toString() { return new StringBuilder("ManagedServiceInfo[") diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b06c4118f9b8..5ab4a426f39b 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -521,6 +521,8 @@ public class NotificationManagerService extends SystemService { private PackageManager mPackageManagerClient; PackageManagerInternal mPackageManagerInternal; private PermissionPolicyInternal mPermissionPolicyInternal; + + private PermissionManagerServiceInternal mPermissionInternal; AudioManager mAudioManager; AudioManagerInternal mAudioManagerInternal; // Can be null for wear @@ -2210,7 +2212,8 @@ public class NotificationManagerService extends SystemService { TelephonyManager telephonyManager, ActivityManagerInternal ami, MultiRateLimiter toastRateLimiter, PermissionHelper permissionHelper, UsageStatsManagerInternal usageStatsManagerInternal, - TelecomManager telecomManager, NotificationChannelLogger channelLogger) { + TelecomManager telecomManager, NotificationChannelLogger channelLogger, + PermissionManagerServiceInternal permInternal) { mHandler = handler; Resources resources = getContext().getResources(); mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(), @@ -2228,6 +2231,7 @@ public class NotificationManagerService extends SystemService { mPackageManagerClient = packageManagerClient; mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class); + mPermissionInternal = permInternal; mUmInternal = LocalServices.getService(UserManagerInternal.class); mUsageStatsManagerInternal = usageStatsManagerInternal; mAppOps = appOps; @@ -2539,7 +2543,8 @@ public class NotificationManagerService extends SystemService { AppGlobals.getPermissionManager()), LocalServices.getService(UsageStatsManagerInternal.class), getContext().getSystemService(TelecomManager.class), - new NotificationChannelLoggerImpl()); + new NotificationChannelLoggerImpl(), + LocalServices.getService(PermissionManagerServiceInternal.class)); publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL); @@ -6689,17 +6694,30 @@ public class NotificationManagerService extends SystemService { (userId == UserHandle.USER_ALL) ? USER_SYSTEM : userId); Notification.addFieldsFromContext(ai, notification); - int canColorize = mPackageManagerClient.checkPermission( - android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, pkg); + int canColorize = mPermissionInternal.checkPermission( + android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, pkg, userId); if (canColorize == PERMISSION_GRANTED) { notification.flags |= Notification.FLAG_CAN_COLORIZE; } else { notification.flags &= ~Notification.FLAG_CAN_COLORIZE; } + if (notification.extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, false)) { + int hasShowDuringSetupPerm = mPermissionInternal.checkPermission( + android.Manifest.permission.NOTIFICATION_DURING_SETUP, pkg, userId); + if (hasShowDuringSetupPerm != PERMISSION_GRANTED) { + notification.extras.remove(Notification.EXTRA_ALLOW_DURING_SETUP); + if (DBG) { + Slog.w(TAG, "warning: pkg " + pkg + " attempting to show during setup" + + " without holding perm " + + Manifest.permission.NOTIFICATION_DURING_SETUP); + } + } + } + if (notification.fullScreenIntent != null && ai.targetSdkVersion >= Build.VERSION_CODES.Q) { - int fullscreenIntentPermission = mPackageManagerClient.checkPermission( - android.Manifest.permission.USE_FULL_SCREEN_INTENT, pkg); + int fullscreenIntentPermission = mPermissionInternal.checkPermission( + android.Manifest.permission.USE_FULL_SCREEN_INTENT, pkg, userId); if (fullscreenIntentPermission != PERMISSION_GRANTED) { notification.fullScreenIntent = null; Slog.w(TAG, "Package " + pkg + @@ -6719,7 +6737,7 @@ public class NotificationManagerService extends SystemService { // Ensure MediaStyle has correct permissions for remote device extras if (notification.isStyle(Notification.MediaStyle.class)) { - int hasMediaContentControlPermission = mPackageManager.checkPermission( + int hasMediaContentControlPermission = mPermissionInternal.checkPermission( android.Manifest.permission.MEDIA_CONTENT_CONTROL, pkg, userId); if (hasMediaContentControlPermission != PERMISSION_GRANTED) { notification.extras.remove(Notification.EXTRA_MEDIA_REMOTE_DEVICE); @@ -6734,7 +6752,7 @@ public class NotificationManagerService extends SystemService { // Ensure only allowed packages have a substitute app name if (notification.extras.containsKey(Notification.EXTRA_SUBSTITUTE_APP_NAME)) { - int hasSubstituteAppNamePermission = mPackageManager.checkPermission( + int hasSubstituteAppNamePermission = mPermissionInternal.checkPermission( permission.SUBSTITUTE_NOTIFICATION_APP_NAME, pkg, userId); if (hasSubstituteAppNamePermission != PERMISSION_GRANTED) { notification.extras.remove(Notification.EXTRA_SUBSTITUTE_APP_NAME); @@ -8338,15 +8356,9 @@ public class NotificationManagerService extends SystemService { } private boolean isExemptFromRateLimiting(String pkg, int userId) { - boolean isExemptFromRateLimiting = false; - try { - isExemptFromRateLimiting = mPackageManager.checkPermission( - android.Manifest.permission.UNLIMITED_TOASTS, pkg, userId) - == PackageManager.PERMISSION_GRANTED; - } catch (RemoteException e) { - Slog.e(TAG, "Failed to connect with package manager"); - } - return isExemptFromRateLimiting; + return mPermissionInternal.checkPermission( + android.Manifest.permission.UNLIMITED_TOASTS, pkg, userId) + == PackageManager.PERMISSION_GRANTED; } /** Reports rate limiting toasts compat change (used when the toast was blocked). */ @@ -9962,8 +9974,9 @@ public class NotificationManagerService extends SystemService { * instance per user, we want to filter out interactions that are not for the user that the * given NAS is bound in. */ - private boolean isInteractionVisibleToListener(ManagedServiceInfo info, int userId) { - boolean isAssistantService = isServiceTokenValid(info.service); + @VisibleForTesting + boolean isInteractionVisibleToListener(ManagedServiceInfo info, int userId) { + boolean isAssistantService = isServiceTokenValid(info.getService()); return !isAssistantService || info.isSameUser(userId); } @@ -9992,13 +10005,9 @@ public class NotificationManagerService extends SystemService { boolean canUseManagedServices(String pkg, Integer userId, String requiredPermission) { boolean canUseManagedServices = true; if (requiredPermission != null) { - try { - if (mPackageManager.checkPermission(requiredPermission, pkg, userId) - != PackageManager.PERMISSION_GRANTED) { - canUseManagedServices = false; - } - } catch (RemoteException e) { - Slog.e(TAG, "can't talk to pm", e); + if (mPermissionInternal.checkPermission(requiredPermission, pkg, userId) + != PackageManager.PERMISSION_GRANTED) { + canUseManagedServices = false; } } @@ -11265,7 +11274,7 @@ public class NotificationManagerService extends SystemService { } BackgroundThread.getHandler().post(() -> { - if (info.isSystem || hasCompanionDevice(info)) { + if (info.isSystem() || hasCompanionDevice(info)) { notifyNotificationChannelGroupChanged( info, pkg, user, group, modificationType); } @@ -11348,7 +11357,7 @@ public class NotificationManagerService extends SystemService { private void notifyNotificationChannelGroupChanged(ManagedServiceInfo info, final String pkg, final UserHandle user, final NotificationChannelGroup group, final int modificationType) { - final INotificationListener listener = (INotificationListener) info.service; + final INotificationListener listener = (INotificationListener) info.getService(); try { listener.onNotificationChannelGroupModification(pkg, user, group, modificationType); } catch (RemoteException ex) { diff --git a/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java b/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java index 6e861232262e..5bdcbb9587ae 100644 --- a/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java +++ b/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java @@ -36,6 +36,7 @@ import android.os.UserManager; import android.util.IndentingPrintWriter; import android.util.Slog; +import com.android.internal.os.RoSystemProperties; import com.android.internal.widget.LockPatternUtils; import com.android.server.LocalServices; import com.android.server.UiThread; @@ -100,6 +101,11 @@ public class UserManagerServiceShellCommand extends ShellCommand { pw.println(" --reboot (which does a full reboot) or"); pw.println(" --no-restart (which requires a manual restart)"); pw.println(); + pw.println(" is-headless-system-user-mode [-v | --verbose]"); + pw.println(" Checks whether the device uses headless system user mode."); + pw.println(" It returns the effective mode, even when using emulation"); + pw.println(" (to get the real mode as well, use -v or --verbose)"); + pw.println(); pw.println(" is-user-visible [--display DISPLAY_ID] <USER_ID>"); pw.println(" Checks if the given user is visible in the given display."); pw.println(" If the display option is not set, it uses the user's context to check"); @@ -121,6 +127,8 @@ public class UserManagerServiceShellCommand extends ShellCommand { return runReportPackageAllowlistProblems(); case "set-system-user-mode-emulation": return runSetSystemUserModeEmulation(); + case "is-headless-system-user-mode": + return runIsHeadlessSystemUserMode(); case "is-user-visible": return runIsUserVisible(); default: @@ -407,6 +415,35 @@ public class UserManagerServiceShellCommand extends ShellCommand { return 0; } + private int runIsHeadlessSystemUserMode() { + PrintWriter pw = getOutPrintWriter(); + + boolean verbose = false; + String opt; + while ((opt = getNextOption()) != null) { + switch (opt) { + case "-v": + case "--verbose": + verbose = true; + break; + default: + pw.println("Invalid option: " + opt); + return -1; + } + } + + boolean isHsum = mService.isHeadlessSystemUserMode(); + if (!verbose) { + // NOTE: do not change output below, as it's used by ITestDevice + // (it's ok to change the verbose option though) + pw.println(isHsum); + } else { + pw.printf("effective=%b real=%b\n", isHsum, + RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER); + } + return 0; + } + /** * Gets the {@link UserManager} associated with the context of the given user. */ diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index e0bcc0e3e883..db939d9a427d 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -3770,6 +3770,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { private boolean setKeyguardOccludedLw(boolean isOccluded, boolean notify) { if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded); mKeyguardOccludedChanged = false; + if (isKeyguardOccluded() == isOccluded) { + return false; + } mKeyguardDelegate.setOccluded(isOccluded, notify); return mKeyguardDelegate.isShowing(); } @@ -5712,44 +5715,53 @@ public class PhoneWindowManager implements WindowManagerPolicy { switch (effectId) { case HapticFeedbackConstants.CONTEXT_CLICK: case HapticFeedbackConstants.GESTURE_END: + case HapticFeedbackConstants.GESTURE_THRESHOLD_ACTIVATE: case HapticFeedbackConstants.ROTARY_SCROLL_TICK: + case HapticFeedbackConstants.SEGMENT_TICK: return VibrationEffect.get(VibrationEffect.EFFECT_TICK); + case HapticFeedbackConstants.TEXT_HANDLE_MOVE: if (!mHapticTextHandleEnabled) { return null; } // fallthrough case HapticFeedbackConstants.CLOCK_TICK: + case HapticFeedbackConstants.SEGMENT_FREQUENT_TICK: return VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK); + case HapticFeedbackConstants.KEYBOARD_RELEASE: case HapticFeedbackConstants.VIRTUAL_KEY_RELEASE: case HapticFeedbackConstants.ENTRY_BUMP: case HapticFeedbackConstants.DRAG_CROSSING: return VibrationEffect.get(VibrationEffect.EFFECT_TICK, false); + case HapticFeedbackConstants.KEYBOARD_TAP: // == KEYBOARD_PRESS case HapticFeedbackConstants.VIRTUAL_KEY: case HapticFeedbackConstants.EDGE_RELEASE: + case HapticFeedbackConstants.CALENDAR_DATE: case HapticFeedbackConstants.CONFIRM: case HapticFeedbackConstants.GESTURE_START: case HapticFeedbackConstants.ROTARY_SCROLL_ITEM_FOCUS: case HapticFeedbackConstants.ROTARY_SCROLL_LIMIT: return VibrationEffect.get(VibrationEffect.EFFECT_CLICK); + case HapticFeedbackConstants.LONG_PRESS: case HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON: + case HapticFeedbackConstants.DRAG_START: case HapticFeedbackConstants.EDGE_SQUEEZE: return VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK); + case HapticFeedbackConstants.REJECT: return VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); - case HapticFeedbackConstants.CALENDAR_DATE: - return VibrationEffect.get(VibrationEffect.EFFECT_CLICK); case HapticFeedbackConstants.SAFE_MODE_ENABLED: pattern = mSafeModeEnabledVibePattern; break; case HapticFeedbackConstants.ASSISTANT_BUTTON: if (mVibrator.areAllPrimitivesSupported( - VibrationEffect.Composition.PRIMITIVE_QUICK_RISE)) { + VibrationEffect.Composition.PRIMITIVE_QUICK_RISE, + VibrationEffect.Composition.PRIMITIVE_TICK)) { // quiet ramp, short pause, then sharp tick return VibrationEffect.startComposition() .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE, 0.25f) @@ -5759,6 +5771,22 @@ public class PhoneWindowManager implements WindowManagerPolicy { // fallback for devices without composition support return VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK); + case HapticFeedbackConstants.GESTURE_THRESHOLD_DEACTIVATE: + return getScaledPrimitiveOrElseEffect( + VibrationEffect.Composition.PRIMITIVE_TICK, 0.4f, + VibrationEffect.EFFECT_TEXTURE_TICK); + + case HapticFeedbackConstants.TOGGLE_ON: + return getScaledPrimitiveOrElseEffect( + VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f, + VibrationEffect.EFFECT_TICK); + + case HapticFeedbackConstants.TOGGLE_OFF: + return getScaledPrimitiveOrElseEffect( + VibrationEffect.Composition.PRIMITIVE_LOW_TICK, 0.2f, + VibrationEffect.EFFECT_TEXTURE_TICK); + + case HapticFeedbackConstants.NO_HAPTICS: default: return null; } @@ -5774,6 +5802,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + private VibrationEffect getScaledPrimitiveOrElseEffect(int primitiveId, float scale, + int elseEffectId) { + if (mVibrator.areAllPrimitivesSupported(primitiveId)) { + return VibrationEffect.startComposition() + .addPrimitive(primitiveId, scale) + .compose(); + } else { + return VibrationEffect.get(elseEffectId); + } + } + private VibrationAttributes getVibrationAttributes(int effectId) { switch (effectId) { case HapticFeedbackConstants.EDGE_SQUEEZE: diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java index ed6a46f9b43f..da7aaa4fd478 100644 --- a/services/core/java/com/android/server/power/Notifier.java +++ b/services/core/java/com/android/server/power/Notifier.java @@ -240,6 +240,8 @@ public class Notifier { options.setDeliveryGroupMatchingKey( UUID.randomUUID().toString(), Intent.ACTION_SCREEN_ON); + // This allows the broadcast delivery to be delayed to apps in the Cached state. + options.setDeferUntilActive(true); return options.toBundle(); } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index c29ab09fa386..e8cb4e207629 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -40,6 +40,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.UserIdInt; import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.SynchronousUserSwitchObserver; import android.content.BroadcastReceiver; @@ -311,6 +312,7 @@ public final class PowerManagerService extends SystemService private SettingsObserver mSettingsObserver; private DreamManagerInternal mDreamManager; private LogicalLight mAttentionLight; + private ActivityManagerInternal mAmInternal; private final InattentiveSleepWarningController mInattentiveSleepWarningOverlayController; private final AmbientDisplaySuppressionController mAmbientDisplaySuppressionController; @@ -1237,6 +1239,7 @@ public final class PowerManagerService extends SystemService mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class); mPolicy = getLocalService(WindowManagerPolicy.class); mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class); + mAmInternal = getLocalService(ActivityManagerInternal.class); mAttentionDetector.systemReady(mContext); SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper()); @@ -4077,9 +4080,8 @@ public final class PowerManagerService extends SystemService final UidState state = wakeLock.mUidState; if (Arrays.binarySearch(mDeviceIdleWhitelist, appid) < 0 && Arrays.binarySearch(mDeviceIdleTempWhitelist, appid) < 0 && - state.mProcState != ActivityManager.PROCESS_STATE_NONEXISTENT && - state.mProcState > - ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { + (mAmInternal != null && !mAmInternal.canHoldWakeLocksInDeepDoze( + state.mUid, state.mProcState))) { disabled = true; } } diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java index 89c5c9efff8a..bc90c8941376 100644 --- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java +++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java @@ -3925,6 +3925,7 @@ public class BatteryStatsImpl extends BatteryStats { private final HistoryStepDetails mDetails = new HistoryStepDetails(); private boolean mHasHistoryStepDetails; + private boolean mUpdateRequested; /** * Total time (in milliseconds) spent executing in user code. @@ -3954,15 +3955,20 @@ public class BatteryStatsImpl extends BatteryStats { @Override public HistoryStepDetails getHistoryStepDetails() { - // Perform a CPU update right after we do this collection, so we have started - // collecting good data for the next step. - requestImmediateCpuUpdate(); - - if (mPlatformIdleStateCallback != null) { - mDetails.statSubsystemPowerState = - mPlatformIdleStateCallback.getSubsystemLowPowerStats(); - if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" + - mDetails.statSubsystemPowerState); + if (!mUpdateRequested) { + mUpdateRequested = true; + // Perform a CPU update right after we do this collection, so we have started + // collecting good data for the next step. + requestImmediateCpuUpdate(); + + if (mPlatformIdleStateCallback != null) { + mDetails.statSubsystemPowerState = + mPlatformIdleStateCallback.getSubsystemLowPowerStats(); + if (DEBUG) { + Slog.i(TAG, + "WRITE SubsystemPowerState:" + mDetails.statSubsystemPowerState); + } + } } if (!mHasHistoryStepDetails) { @@ -4072,7 +4078,11 @@ public class BatteryStatsImpl extends BatteryStats { mCurStepStatIrqTimeMs += statIrqTimeMs; mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs; mCurStepStatIdleTimeMs += statIdleTimeMs; + } + + public void finishAddingCpuLocked() { mHasHistoryStepDetails = true; + mUpdateRequested = false; } @Override @@ -4953,13 +4963,13 @@ public class BatteryStatsImpl extends BatteryStats { } @GuardedBy("this") - public boolean startAddingCpuLocked() { + public boolean startAddingCpuStatsLocked() { mExternalSync.cancelCpuSyncDueToWakelockChange(); return mOnBatteryInternal; } @GuardedBy("this") - public void finishAddingCpuLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, + public void addCpuStatsLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, int statSoftIrqTimeMs, int statIdleTimeMs) { mStepDetailsCalculator.addCpuStats(totalUTimeMs, totalSTimeMs, statUserTimeMs, @@ -4967,6 +4977,14 @@ public class BatteryStatsImpl extends BatteryStats { statSoftIrqTimeMs, statIdleTimeMs); } + /** + * Called after {@link #addCpuStatsLocked} has been invoked for all active apps. + */ + @GuardedBy("this") + public void finishAddingCpuStatsLocked() { + mStepDetailsCalculator.finishAddingCpuLocked(); + } + public void noteProcessDiedLocked(int uid, int pid) { uid = mapUid(uid); Uid u = mUidStats.get(uid); diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java index 13218731af70..9d5173a8da09 100644 --- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java @@ -36,7 +36,7 @@ import android.content.Context; import android.content.IntentSender; import android.content.SharedPreferences; import android.content.pm.PackageManager; -import android.hardware.boot.V1_0.IBootControl; +import android.hardware.boot.IBootControl; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.Binder; @@ -48,6 +48,7 @@ import android.os.Process; import android.os.RecoverySystem; import android.os.RemoteException; import android.os.ResultReceiver; +import android.os.ServiceManager; import android.os.ShellCallback; import android.os.SystemProperties; import android.provider.DeviceConfig; @@ -66,6 +67,7 @@ import com.android.internal.widget.RebootEscrowListener; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.pm.ApexManager; +import com.android.server.recoverysystem.hal.BootControlHIDL; import libcore.io.IoUtils; @@ -155,18 +157,20 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo /** * The action to perform upon new resume on reboot prepare request for a given client. */ - @IntDef({ ROR_NEED_PREPARATION, + @IntDef({ROR_NEED_PREPARATION, ROR_SKIP_PREPARATION_AND_NOTIFY, - ROR_SKIP_PREPARATION_NOT_NOTIFY }) - private @interface ResumeOnRebootActionsOnRequest {} + ROR_SKIP_PREPARATION_NOT_NOTIFY}) + private @interface ResumeOnRebootActionsOnRequest { + } /** * The action to perform upon resume on reboot clear request for a given client. */ - @IntDef({ ROR_NOT_REQUESTED, + @IntDef({ROR_NOT_REQUESTED, ROR_REQUESTED_NEED_CLEAR, - ROR_REQUESTED_SKIP_CLEAR }) - private @interface ResumeOnRebootActionsOnClear {} + ROR_REQUESTED_SKIP_CLEAR}) + private @interface ResumeOnRebootActionsOnClear { + } /** * Fatal arm escrow errors from lock settings that means the RoR is in a bad state. So clients @@ -306,19 +310,26 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo * Throws remote exception if there's an error getting the boot control HAL. * Returns null if the boot control HAL's version is older than V1_2. */ - public android.hardware.boot.V1_2.IBootControl getBootControl() throws RemoteException { - IBootControl bootControlV10 = IBootControl.getService(true); - if (bootControlV10 == null) { - throw new RemoteException("Failed to get boot control HAL V1_0."); + public IBootControl getBootControl() throws RemoteException { + String serviceName = IBootControl.DESCRIPTOR + "/default"; + if (ServiceManager.isDeclared(serviceName)) { + Slog.i(TAG, + "AIDL version of BootControl HAL present, using instance " + serviceName); + return IBootControl.Stub.asInterface( + ServiceManager.waitForDeclaredService(serviceName)); } - android.hardware.boot.V1_2.IBootControl bootControlV12 = - android.hardware.boot.V1_2.IBootControl.castFrom(bootControlV10); - if (bootControlV12 == null) { + IBootControl bootcontrol = BootControlHIDL.getService(); + if (!BootControlHIDL.isServicePresent()) { + Slog.e(TAG, "Neither AIDL nor HIDL version of the BootControl HAL is present."); + return null; + } + + if (!BootControlHIDL.isV1_2ServicePresent()) { Slog.w(TAG, "Device doesn't implement boot control HAL V1_2."); return null; } - return bootControlV12; + return bootcontrol; } public void threadSleep(long millis) throws InterruptedException { @@ -526,7 +537,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.RECOVERY) != PackageManager.PERMISSION_GRANTED && mContext.checkCallingOrSelfPermission(android.Manifest.permission.REBOOT) - != PackageManager.PERMISSION_GRANTED) { + != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Caller must have " + android.Manifest.permission.RECOVERY + " or " + android.Manifest.permission.REBOOT + " for resume on reboot."); } @@ -738,7 +749,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo return true; } - android.hardware.boot.V1_2.IBootControl bootControl; + IBootControl bootControl; try { bootControl = mInjector.getBootControl(); } catch (RemoteException e) { @@ -972,8 +983,8 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo CompressedApexInfoList apexInfoList = getCompressedApexInfoList(packageFile); if (apexInfoList == null) { Log.i(TAG, "apex_info.pb not present in OTA package. " - + "Assuming device doesn't support compressed" - + "APEX, continueing without allocating space."); + + "Assuming device doesn't support compressed" + + "APEX, continueing without allocating space."); return true; } ApexManager apexManager = ApexManager.getInstance(); @@ -1160,6 +1171,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo /** * Reads the status from the uncrypt service which is usually represented as a percentage. + * * @return an integer representing the percentage completed * @throws IOException if there was an error reading the socket */ @@ -1169,6 +1181,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo /** * Sends a confirmation to the uncrypt service. + * * @throws IOException if there was an error writing to the socket */ public void sendAck() throws IOException { diff --git a/services/core/java/com/android/server/recoverysystem/hal/BootControlHIDL.java b/services/core/java/com/android/server/recoverysystem/hal/BootControlHIDL.java new file mode 100644 index 000000000000..65325c297719 --- /dev/null +++ b/services/core/java/com/android/server/recoverysystem/hal/BootControlHIDL.java @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.recoverysystem.hal; + +import android.hardware.boot.IBootControl; +import android.hardware.boot.V1_0.CommandResult; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Slog; + +public class BootControlHIDL implements IBootControl { + private static final String TAG = "BootControlHIDL"; + + final android.hardware.boot.V1_0.IBootControl v1_hal; + final android.hardware.boot.V1_1.IBootControl v1_1_hal; + final android.hardware.boot.V1_2.IBootControl v1_2_hal; + + public static boolean isServicePresent() { + try { + android.hardware.boot.V1_0.IBootControl.getService(true); + } catch (RemoteException e) { + return false; + } + return true; + } + + public static boolean isV1_2ServicePresent() { + try { + android.hardware.boot.V1_2.IBootControl.getService(true); + } catch (RemoteException e) { + return false; + } + return true; + } + + public static BootControlHIDL getService() throws RemoteException { + android.hardware.boot.V1_0.IBootControl v1_hal = + android.hardware.boot.V1_0.IBootControl.getService(true); + android.hardware.boot.V1_1.IBootControl v1_1_hal = + android.hardware.boot.V1_1.IBootControl.castFrom(v1_hal); + android.hardware.boot.V1_2.IBootControl v1_2_hal = + android.hardware.boot.V1_2.IBootControl.castFrom(v1_hal); + return new BootControlHIDL(v1_hal, v1_1_hal, v1_2_hal); + } + + private BootControlHIDL(android.hardware.boot.V1_0.IBootControl v1_hal, + android.hardware.boot.V1_1.IBootControl v1_1_hal, + android.hardware.boot.V1_2.IBootControl v1_2_hal) throws RemoteException { + this.v1_hal = v1_hal; + this.v1_1_hal = v1_1_hal; + this.v1_2_hal = v1_2_hal; + if (v1_hal == null) { + throw new RemoteException("Failed to find V1.0 BootControl HIDL"); + } + if (v1_2_hal != null) { + Slog.i(TAG, "V1.2 version of BootControl HIDL HAL available, using V1.2"); + } else if (v1_1_hal != null) { + Slog.i(TAG, "V1.1 version of BootControl HIDL HAL available, using V1.1"); + } else { + Slog.i(TAG, "V1.0 version of BootControl HIDL HAL available, using V1.0"); + } + } + + @Override + public IBinder asBinder() { + return null; + } + + @Override + public int getActiveBootSlot() throws RemoteException { + if (v1_2_hal == null) { + throw new RemoteException("getActiveBootSlot() requires V1.2 BootControl HAL"); + } + return v1_2_hal.getActiveBootSlot(); + } + + @Override + public int getCurrentSlot() throws RemoteException { + return v1_hal.getCurrentSlot(); + } + + @Override + public int getNumberSlots() throws RemoteException { + return v1_hal.getNumberSlots(); + } + + @Override + public int getSnapshotMergeStatus() throws RemoteException { + if (v1_1_hal == null) { + throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL"); + } + return v1_1_hal.getSnapshotMergeStatus(); + } + + @Override + public String getSuffix(int slot) throws RemoteException { + return v1_hal.getSuffix(slot); + } + + @Override + public boolean isSlotBootable(int slot) throws RemoteException { + int ret = v1_hal.isSlotBootable(slot); + if (ret == -1) { + throw new RemoteException( + "isSlotBootable() failed, Slot %d might be invalid.".formatted(slot)); + } + return ret != 0; + } + + @Override + public boolean isSlotMarkedSuccessful(int slot) throws RemoteException { + int ret = v1_hal.isSlotMarkedSuccessful(slot); + if (ret == -1) { + throw new RemoteException( + "isSlotMarkedSuccessful() failed, Slot %d might be invalid.".formatted(slot)); + } + return ret != 0; + } + + @Override + public void markBootSuccessful() throws RemoteException { + CommandResult res = v1_hal.markBootSuccessful(); + if (!res.success) { + throw new RemoteException("Error markBootSuccessful() " + res.errMsg); + } + } + + @Override + public void setActiveBootSlot(int slot) throws RemoteException { + CommandResult res = v1_hal.setActiveBootSlot(slot); + if (!res.success) { + throw new RemoteException("Error setActiveBootSlot(%d) %s".formatted(slot, res.errMsg)); + } + } + + @Override + public void setSlotAsUnbootable(int slot) throws RemoteException { + CommandResult res = v1_hal.setSlotAsUnbootable(slot); + if (!res.success) { + throw new RemoteException( + "Error setSlotAsUnbootable(%d) %s".formatted(slot, res.errMsg)); + } + } + + @Override + public void setSnapshotMergeStatus(int status) throws RemoteException { + if (v1_1_hal == null) { + throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL"); + } + if (!v1_1_hal.setSnapshotMergeStatus(status)) { + throw new RemoteException("Error setSnapshotMergeStatus(%d)".formatted(status)); + } + } + + @Override + public int getInterfaceVersion() throws RemoteException { + return 1; + } + + @Override + public String getInterfaceHash() throws RemoteException { + return v1_hal.interfaceDescriptor(); + } +} diff --git a/services/core/java/com/android/server/security/FileIntegrityService.java b/services/core/java/com/android/server/security/FileIntegrityService.java index 6c0e1a43f938..5ae697315ed1 100644 --- a/services/core/java/com/android/server/security/FileIntegrityService.java +++ b/services/core/java/com/android/server/security/FileIntegrityService.java @@ -18,7 +18,6 @@ package com.android.server.security; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; @@ -60,7 +59,6 @@ import java.util.ArrayList; * A {@link SystemService} that provides file integrity related operations. * @hide */ -@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) public class FileIntegrityService extends SystemService { private static final String TAG = "FileIntegrityService"; @@ -73,10 +71,7 @@ public class FileIntegrityService extends SystemService { private final ArrayList<X509Certificate> mTrustedCertificates = new ArrayList<X509Certificate>(); - /** - * Gets the instance of the service. - * @hide - */ + /** Gets the instance of the service */ public static FileIntegrityService getService() { return LocalServices.getService(FileIntegrityService.class); } @@ -144,7 +139,6 @@ public class FileIntegrityService extends SystemService { } }; - /** @hide */ public FileIntegrityService(final Context context) { super(context); try { @@ -155,7 +149,6 @@ public class FileIntegrityService extends SystemService { LocalServices.addService(FileIntegrityService.class, this); } - /** @hide */ @Override public void onStart() { loadAllCertificates(); @@ -165,7 +158,6 @@ public class FileIntegrityService extends SystemService { /** * Returns whether the signature over the file's fs-verity digest can be verified by one of the * known certiticates. - * @hide */ public boolean verifyPkcs7DetachedSignature(String signaturePath, String filePath) throws IOException { @@ -191,16 +183,6 @@ public class FileIntegrityService extends SystemService { return false; } - /** - * Enables fs-verity, if supported by the filesystem. - * @see <a href="https://www.kernel.org/doc/html/latest/filesystems/fsverity.html"> - * @hide - */ - @SystemApi(client = SystemApi.Client.SYSTEM_SERVER) - public static void setUpFsVerity(@NonNull String filePath) throws IOException { - VerityUtils.setUpFsverity(filePath); - } - private void loadAllCertificates() { // A better alternative to load certificates would be to read from .fs-verity kernel // keyring, which fsverity_init loads to during earlier boot time from the same sources diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index 29b37cea8eeb..0928bef5c6ec 100755..100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -24,6 +24,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; +import android.content.AttributionSource; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; @@ -43,6 +44,7 @@ import android.content.pm.UserInfo; import android.graphics.Rect; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiDeviceInfo; +import android.media.AudioPresentation; import android.media.PlaybackParams; import android.media.tv.AdBuffer; import android.media.tv.AdRequest; @@ -91,7 +93,6 @@ import android.util.Slog; import android.util.SparseArray; import android.view.InputChannel; import android.view.Surface; - import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; @@ -102,9 +103,7 @@ import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.server.IoThread; import com.android.server.SystemService; - import dalvik.annotation.optimization.NeverCompile; - import java.io.File; import java.io.FileDescriptor; import java.io.FileNotFoundException; @@ -814,7 +813,7 @@ public final class TvInputManagerService extends SystemService { @GuardedBy("mLock") private boolean createSessionInternalLocked(ITvInputService service, IBinder sessionToken, - int userId) { + int userId, AttributionSource tvAppAttributionSource) { UserState userState = getOrCreateUserStateLocked(userId); SessionState sessionState = userState.sessionStateMap.get(sessionToken); if (DEBUG) { @@ -833,8 +832,8 @@ public final class TvInputManagerService extends SystemService { service.createRecordingSession( callback, sessionState.inputId, sessionState.sessionId); } else { - service.createSession( - channels[1], callback, sessionState.inputId, sessionState.sessionId); + service.createSession(channels[1], callback, sessionState.inputId, + sessionState.sessionId, tvAppAttributionSource); } } catch (RemoteException e) { Slog.e(TAG, "error in createSession", e); @@ -1486,7 +1485,8 @@ public final class TvInputManagerService extends SystemService { @Override public void createSession(final ITvInputClient client, final String inputId, - boolean isRecordingSession, int seq, int userId) { + AttributionSource tvAppAttributionSource, boolean isRecordingSession, int seq, + int userId) { final int callingUid = Binder.getCallingUid(); final int callingPid = Binder.getCallingPid(); final int resolvedUserId = resolveCallingUserId(callingPid, callingUid, @@ -1557,7 +1557,7 @@ public final class TvInputManagerService extends SystemService { if (serviceState.service != null) { if (!createSessionInternalLocked(serviceState.service, sessionToken, - resolvedUserId)) { + resolvedUserId, tvAppAttributionSource)) { removeSessionStateLocked(sessionToken, resolvedUserId); } } else { @@ -1836,6 +1836,28 @@ public final class TvInputManagerService extends SystemService { } @Override + public void selectAudioPresentation(IBinder sessionToken, int presentationId, + int programId, int userId) { + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "selectAudioPresentation"); + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + getSessionLocked(sessionToken, callingUid, + resolvedUserId).selectAudioPresentation( + presentationId, programId); + } catch (RemoteException | SessionNotFoundException e) { + Slog.e(TAG, "error in selectAudioPresentation", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override public void selectTrack(IBinder sessionToken, int type, String trackId, int userId) { final int callingUid = Binder.getCallingUid(); final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, @@ -3137,7 +3159,8 @@ public final class TvInputManagerService extends SystemService { // And create sessions, if any. for (IBinder sessionToken : serviceState.sessionTokens) { - if (!createSessionInternalLocked(serviceState.service, sessionToken, mUserId)) { + if (!createSessionInternalLocked( + serviceState.service, sessionToken, mUserId, null)) { tokensToBeRemoved.add(sessionToken); } } @@ -3360,6 +3383,43 @@ public final class TvInputManagerService extends SystemService { } @Override + public void onAudioPresentationsChanged(List<AudioPresentation> audioPresentations) { + synchronized (mLock) { + if (DEBUG) { + Slog.d(TAG, "onAudioPresentationChanged(" + audioPresentations + ")"); + } + if (mSessionState.session == null || mSessionState.client == null) { + return; + } + try { + mSessionState.client.onAudioPresentationsChanged(audioPresentations, + mSessionState.seq); + } catch (RemoteException e) { + Slog.e(TAG, "error in onAudioPresentationsChanged", e); + } + } + } + + @Override + public void onAudioPresentationSelected(int presentationId, int programId) { + synchronized (mLock) { + if (DEBUG) { + Slog.d(TAG, "onAudioPresentationSelected(presentationId=" + presentationId + + ", programId=" + programId + ")"); + } + if (mSessionState.session == null || mSessionState.client == null) { + return; + } + try { + mSessionState.client.onAudioPresentationSelected(presentationId, programId, + mSessionState.seq); + } catch (RemoteException e) { + Slog.e(TAG, "error in onAudioPresentationSelected", e); + } + } + } + + @Override public void onTracksChanged(List<TvTrackInfo> tracks) { synchronized (mLock) { if (DEBUG) { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 24fe5186dbde..0c97d7d837e6 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -444,6 +444,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // finished destroying itself. private static final int DESTROY_TIMEOUT = 10 * 1000; + // Rounding tolerance to be used in aspect ratio computations + private static final float ASPECT_RATIO_ROUNDING_TOLERANCE = 0.005f; + final ActivityTaskManagerService mAtmService; @NonNull final ActivityInfo info; // activity info provided by developer in AndroidManifest @@ -8325,8 +8328,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (screenResolvedBounds.width() <= parentAppBounds.width()) { float positionMultiplier = mLetterboxUiController.getHorizontalPositionMultiplier( newParentConfiguration); - offsetX = (int) Math.ceil((parentAppBounds.width() - screenResolvedBounds.width()) - * positionMultiplier); + offsetX = Math.max(0, (int) Math.ceil((parentAppBounds.width() + - screenResolvedBounds.width()) * positionMultiplier) + // This is added to make sure that insets added inside + // CompatDisplayInsets#getContainerBounds() do not break the alignment + // provided by the positionMultiplier + - screenResolvedBounds.left + parentAppBounds.left); } } @@ -8336,8 +8343,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (screenResolvedBounds.height() <= parentAppBounds.height()) { float positionMultiplier = mLetterboxUiController.getVerticalPositionMultiplier( newParentConfiguration); - offsetY = (int) Math.ceil((parentAppBounds.height() - screenResolvedBounds.height()) - * positionMultiplier); + offsetY = Math.max(0, (int) Math.ceil((parentAppBounds.height() + - screenResolvedBounds.height()) * positionMultiplier) + // This is added to make sure that insets added inside + // CompatDisplayInsets#getContainerBounds() do not break the alignment + // provided by the positionMultiplier + - screenResolvedBounds.top + parentAppBounds.top); } } @@ -9037,7 +9048,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A int activityWidth = containingAppWidth; int activityHeight = containingAppHeight; - if (containingRatio > desiredAspectRatio) { + if (containingRatio - desiredAspectRatio > ASPECT_RATIO_ROUNDING_TOLERANCE) { if (containingAppWidth < containingAppHeight) { // Width is the shorter side, so we use that to figure-out what the max. height // should be given the aspect ratio. @@ -9047,7 +9058,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // should be given the aspect ratio. activityWidth = (int) ((activityHeight * desiredAspectRatio) + 0.5f); } - } else if (containingRatio < desiredAspectRatio) { + } else if (desiredAspectRatio - containingRatio > ASPECT_RATIO_ROUNDING_TOLERANCE) { boolean adjustWidth; switch (getRequestedConfigurationOrientation()) { case ORIENTATION_LANDSCAPE: @@ -10129,6 +10140,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A isLandscape ? shortSide : longSide); } + // TODO(b/267151420): Explore removing getContainerBounds() from CompatDisplayInsets. /** Gets the horizontal centered container bounds for size compatibility mode. */ void getContainerBounds(Rect outAppBounds, Rect outBounds, int rotation, int orientation, boolean orientationRequested, boolean isFixedToUserRotation) { diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index cfcf459fc72e..d759ff555512 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -1804,7 +1804,8 @@ public class DisplayPolicy { dc.getDisplayPolicy().simulateLayoutDisplay(df); final InsetsState insetsState = df.mInsetsState; final Rect displayFrame = insetsState.getDisplayFrame(); - final Insets decor = calculateDecorInsetsWithInternalTypes(insetsState); + final Insets decor = insetsState.calculateInsets(displayFrame, DECOR_TYPES, + true /* ignoreVisibility */); final Insets statusBar = insetsState.calculateInsets(displayFrame, Type.statusBars(), true /* ignoreVisibility */); mNonDecorInsets.set(decor.left, decor.top, decor.right, decor.bottom); @@ -1836,17 +1837,8 @@ public class DisplayPolicy { } } - // TODO (b/235842600): Use public type once we can treat task bar as navigation bar. - static final int[] INTERNAL_DECOR_TYPES; - static { - final ArraySet<Integer> decorTypes = InsetsState.toInternalType( - Type.displayCutout() | Type.navigationBars()); - decorTypes.remove(ITYPE_EXTRA_NAVIGATION_BAR); - INTERNAL_DECOR_TYPES = new int[decorTypes.size()]; - for (int i = 0; i < INTERNAL_DECOR_TYPES.length; i++) { - INTERNAL_DECOR_TYPES[i] = decorTypes.valueAt(i); - } - } + + static final int DECOR_TYPES = Type.displayCutout() | Type.navigationBars(); private final DisplayContent mDisplayContent; private final Info[] mInfoForRotation = new Info[4]; @@ -1873,20 +1865,6 @@ public class DisplayPolicy { info.mNeedUpdate = true; } } - - // TODO (b/235842600): Remove this method once we can treat task bar as navigation bar. - private static Insets calculateDecorInsetsWithInternalTypes(InsetsState state) { - final Rect frame = state.getDisplayFrame(); - Insets insets = Insets.NONE; - for (int i = INTERNAL_DECOR_TYPES.length - 1; i >= 0; i--) { - final InsetsSource source = state.peekSource(INTERNAL_DECOR_TYPES[i]); - if (source != null) { - insets = Insets.max(source.calculateInsets(frame, true /* ignoreVisibility */), - insets); - } - } - return insets; - } } /** diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index 6f7ff5c21d94..3404279d2c59 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -249,11 +249,13 @@ public class DisplayRotation { mDeskDockRotation = readRotation(R.integer.config_deskDockRotation); mUndockedHdmiRotation = readRotation(R.integer.config_undockedHdmiRotation); - mRotation = readDefaultDisplayRotation(displayAddress); + int defaultRotation = readDefaultDisplayRotation(displayAddress); + mRotation = defaultRotation; if (isDefaultDisplay) { final Handler uiHandler = UiThread.getHandler(); - mOrientationListener = new OrientationListener(mContext, uiHandler); + mOrientationListener = + new OrientationListener(mContext, uiHandler, defaultRotation); mOrientationListener.setCurrentRotation(mRotation); mSettingsObserver = new SettingsObserver(uiHandler); mSettingsObserver.observe(); @@ -1735,8 +1737,9 @@ public class DisplayRotation { private class OrientationListener extends WindowOrientationListener implements Runnable { transient boolean mEnabled; - OrientationListener(Context context, Handler handler) { - super(context, handler); + OrientationListener(Context context, Handler handler, + @Surface.Rotation int defaultRotation) { + super(context, handler, defaultRotation); } @Override diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index 718a9e3f0ffd..e9badefe1bb1 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -20,63 +20,47 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.WindowManager.KEYGUARD_STATE_AOD_SHOWN; -import static android.view.WindowManager.KEYGUARD_STATE_DREAMING; -import static android.view.WindowManager.KEYGUARD_STATE_GOING_AWAY; -import static android.view.WindowManager.KEYGUARD_STATE_KEYGUARD_TOP; -import static android.view.WindowManager.KEYGUARD_STATE_LOCKSCREEN_SHOWN; -import static android.view.WindowManager.KEYGUARD_STATE_OCCLUDED; -import static android.view.WindowManager.KEYGUARD_STATE_OFF; -import static android.view.WindowManager.KEYGUARD_STATE_ON; -import static android.view.WindowManager.KEYGUARD_STATE_ROOT; -import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; +import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; +import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION; +import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT; +import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; -import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED; import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE; import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE; 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_WAKE; -import static android.view.WindowManager.keyguardStateToString; -import static android.view.WindowManager.transitTypeToString; -import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD; - +import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS; +import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS; +import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT; +import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE; +import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.KeyguardControllerProto.AOD_SHOWING; +import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_GOING_AWAY; import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_PER_DISPLAY; import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_SHOWING; -import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.ActivityManager; -import android.app.ActivityOptions; -import android.os.Debug; import android.os.IBinder; import android.os.RemoteException; import android.os.Trace; import android.util.Slog; import android.util.SparseArray; import android.util.proto.ProtoOutputStream; +import android.view.Display; import android.view.WindowManager; -import android.view.WindowManager.KeyguardState; -import android.window.TransitionInfo; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.policy.WindowManagerPolicy; -import com.android.server.wm.utils.StateMachine; import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; /** * Controls Keyguard occluding, dismissing and transitions depending on what kind of activities are @@ -85,285 +69,171 @@ import java.util.Optional; * Note that everything in this class should only be accessed with the AM lock being held. */ class KeyguardController { - private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardController" : TAG_ATM; - private static final boolean DEBUG = true; + private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardController" : TAG_ATM; static final String KEYGUARD_SLEEP_TOKEN_TAG = "keyguard"; private static final int DEFER_WAKE_TRANSITION_TIMEOUT_MS = 5000; - private final ActivityTaskManagerService mService; private final ActivityTaskSupervisor mTaskSupervisor; - private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer; - private boolean mWaitingForWakeTransition; private WindowManagerService mWindowManager; + private final SparseArray<KeyguardDisplayState> mDisplayStates = new SparseArray<>(); + private final ActivityTaskManagerService mService; private RootWindowContainer mRootWindowContainer; - - private final SparseArray<DisplayState> mDisplayStates = new SparseArray<>(); - - @NonNull private final ServiceDelegate mServiceDelegate = new ServiceDelegate(); + private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer; + private boolean mWaitingForWakeTransition; KeyguardController(ActivityTaskManagerService service, ActivityTaskSupervisor taskSupervisor) { mService = service; mTaskSupervisor = taskSupervisor; - mSleepTokenAcquirer = service.new SleepTokenAcquirerImpl(KEYGUARD_SLEEP_TOKEN_TAG); + mSleepTokenAcquirer = mService.new SleepTokenAcquirerImpl(KEYGUARD_SLEEP_TOKEN_TAG); } void setWindowManager(WindowManagerService windowManager) { mWindowManager = windowManager; mRootWindowContainer = mService.mRootWindowContainer; - mService.getTransitionController().registerLegacyListener( - new WindowManagerInternal.AppTransitionListener() { - @Override - public int onAppTransitionStartingLocked(TransitionInfo info) { - final List<TransitionInfo.Change> changes = info.getChanges(); - if (changes.size() == 0) { - Slog.e(TAG, "TransitionInfo doesn't contain change: " + info); - return 0; - } - final ActivityManager.RunningTaskInfo taskInfo = - changes.get(0).getTaskInfo(); - if (taskInfo == null) { - Slog.e(TAG, "No RunningTaskInfo: " + info); - return 0; - } - - // TODO(b/242856311): Filtering condition is defined here and in SysUI - // Keyguard service, which need to be in sync. For a long term, we should - // define a new API for notifying occlude status from WMS to SysUI, and - // the filtering logic should only exist in WM Shell. - if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) == 0) { - return 0; - } - - boolean occludeOpeningApp = false; - boolean occludeClosingApp = false; - for (int i = 0; i < changes.size(); ++i) { - final TransitionInfo.Change change = changes.get(i); - if (change.hasFlags(FLAG_OCCLUDES_KEYGUARD)) { - if (change.getMode() == TRANSIT_OPEN - || change.getMode() == TRANSIT_TO_FRONT) { - occludeOpeningApp = true; - } - if (change.getMode() == TRANSIT_CLOSE - || change.getMode() == TRANSIT_TO_BACK) { - occludeClosingApp = true; - } - } - } - final DisplayState state = getDisplayState(taskInfo.displayId); - if (occludeOpeningApp && !occludeClosingApp) { - state.commitOccludedStatus(true /* occluded */); - } else if (!occludeOpeningApp && occludeClosingApp) { - state.commitOccludedStatus(false /* occluded */); - } - return 0; - } - }); } boolean isAodShowing(int displayId) { - return getDisplayState(displayId).isIn(KEYGUARD_STATE_AOD_SHOWN); + return getDisplayState(displayId).mAodShowing; } /** - * @return {@code true} if either Keyguard or AOD are showing. + * @return true if either Keyguard or AOD are showing, not going away, and not being occluded + * on the given display, false otherwise. */ boolean isKeyguardOrAodShowing(int displayId) { - return getDisplayState(displayId).isIn(KEYGUARD_STATE_KEYGUARD_TOP); + final KeyguardDisplayState state = getDisplayState(displayId); + return (state.mKeyguardShowing || state.mAodShowing) + && !state.mKeyguardGoingAway + && !isDisplayOccluded(displayId); } /** - * @return {@codd true} if lock screen is showing. + * @return {@code true} for default display when AOD is showing, not going away. Otherwise, same + * as {@link #isKeyguardOrAodShowing(int)} + * TODO(b/125198167): Replace isKeyguardOrAodShowing() by this logic. */ - boolean isLocksScreenShowing(int displayId) { - // NOTE: This is only used by WindowManagerService#notifyKeyguardTrustedChanged - return getDisplayState(displayId).isIn(KEYGUARD_STATE_LOCKSCREEN_SHOWN); + boolean isKeyguardUnoccludedOrAodShowing(int displayId) { + final KeyguardDisplayState state = getDisplayState(displayId); + if (displayId == DEFAULT_DISPLAY && state.mAodShowing) { + return !state.mKeyguardGoingAway; + } + return isKeyguardOrAodShowing(displayId); } /** - * @return {@code true} if Keyguard is either showing or occluded. + * @return true if Keyguard is showing, not going away, and not being occluded on the given + * display, false otherwise + */ + boolean isKeyguardShowing(int displayId) { + final KeyguardDisplayState state = getDisplayState(displayId); + return state.mKeyguardShowing && !state.mKeyguardGoingAway + && !isDisplayOccluded(displayId); + } + + /** + * @return true if Keyguard is either showing or occluded, but not going away */ boolean isKeyguardLocked(int displayId) { - return getDisplayState(displayId).isIn(KEYGUARD_STATE_ON); + final KeyguardDisplayState state = getDisplayState(displayId); + return state.mKeyguardShowing && !state.mKeyguardGoingAway; } /** + * * @return true if the activity is controlling keyguard state. */ boolean topActivityOccludesKeyguard(ActivityRecord r) { - return getDisplayState(r.getDisplayId()).topActivityOccludesKeyguard(r); + return getDisplayState(r.getDisplayId()).mTopOccludesActivity == r; } /** * @return {@code true} if the keyguard is going away, {@code false} otherwise. */ boolean isKeyguardGoingAway(int displayId) { - return getDisplayState(displayId).isIn(KEYGUARD_STATE_GOING_AWAY); + final KeyguardDisplayState state = getDisplayState(displayId); + // Also check keyguard showing in case value is stale. + return state.mKeyguardGoingAway && state.mKeyguardShowing; } /** - * Checks whether the top activity occludes the keyguard. - */ - boolean isDisplayOccluded(int displayId) { - return getDisplayState(displayId).isIn(KEYGUARD_STATE_OCCLUDED); - } - - /** - * @return Whether the dream activity is on top of default display. - */ - boolean isShowingDream() { - return getDisplayState(DEFAULT_DISPLAY).isIn(KEYGUARD_STATE_DREAMING); - } - - /** - * Checks whether {@param r} should be visible depending on Keyguard state. - * - * @return true if {@param r} is visible taken Keyguard state into account, false otherwise + * Update the Keyguard showing state. */ - boolean checkKeyguardVisibility(@NonNull ActivityRecord r) { - if (r.mDisplayContent.canShowWithInsecureKeyguard() && canDismissKeyguard()) { - return true; - } - return getDisplayState(r.mDisplayContent.getDisplayId()).checkKeyguardVisibility(r); - } - - void onDisplayRemoved(int displayId) { - final DisplayState state = mDisplayStates.get(displayId); - if (state != null) { - state.onRemoved(); - mDisplayStates.remove(displayId); + void setKeyguardShown(int displayId, boolean keyguardShowing, boolean aodShowing) { + if (mRootWindowContainer.getDisplayContent(displayId).isKeyguardAlwaysUnlocked()) { + Slog.i(TAG, "setKeyguardShown ignoring always unlocked display " + displayId); + return; } - } - private final Runnable mResetWaitTransition = () -> { - synchronized (mWindowManager.mGlobalLock) { + final KeyguardDisplayState state = getDisplayState(displayId); + final boolean aodChanged = aodShowing != state.mAodShowing; + final boolean aodRemoved = state.mAodShowing && !aodShowing; + // If keyguard is going away, but SystemUI aborted the transition, need to reset state. + // Do not reset keyguardChanged status when only AOD is removed. + final boolean keyguardChanged = (keyguardShowing != state.mKeyguardShowing) + || (state.mKeyguardGoingAway && keyguardShowing && !aodRemoved); + if (aodRemoved) { updateDeferTransitionForAod(false /* waiting */); } - }; - - /** - * Update if app transition should be deferred until AOD state changes. - * - * <p>Note: This is used for defer app transition before the device fully wakes up, since during - * wake up process, activities life cycle can be messed up due to a display sleep token. - * - * @param waiting {@code true} to defer an app transition, {@code false} to continue an app - * transition. - */ - void updateDeferTransitionForAod(boolean waiting) { - if (waiting == mWaitingForWakeTransition) { - return; - } - if (!mService.getTransitionController().isCollecting()) { + if (!keyguardChanged && !aodChanged) { + setWakeTransitionReady(); return; } - // if AOD is showing, defer the wake transition until AOD state changed. - if (waiting && isAodShowing(DEFAULT_DISPLAY)) { - mWaitingForWakeTransition = true; - mService.getTransitionController().deferTransitionReady(); - mWindowManager.mH.postDelayed(mResetWaitTransition, DEFER_WAKE_TRANSITION_TIMEOUT_MS); - } else if (!waiting) { - // dismiss the deferring if the AOD state change or cancel awake. - mWaitingForWakeTransition = false; - mService.getTransitionController().continueTransitionReady(); - mWindowManager.mH.removeCallbacks(mResetWaitTransition); - } - } - - /** - * TODO(b/242851358): Remove this function once SysUI migrate to the new API. - */ - @KeyguardState private static int convertToState(int displayId, boolean keyguardShowing, - boolean aodShowing) { - if (displayId == DEFAULT_DISPLAY) { - if (aodShowing) { - return KEYGUARD_STATE_AOD_SHOWN; - } else if (keyguardShowing) { - return KEYGUARD_STATE_LOCKSCREEN_SHOWN; - } else { - return KEYGUARD_STATE_OFF; - } - } else { - if (keyguardShowing || aodShowing) { - return KEYGUARD_STATE_LOCKSCREEN_SHOWN; - } else { - return KEYGUARD_STATE_OFF; - } - } - } - - /** - * Update the Keyguard showing state. - * - * @deprecated Use {@link #setKeyguardState(int, int)} instead. See b/242851358 - */ - @Deprecated - void setKeyguardShown(int displayId, boolean keyguardShowing, boolean aodShowing) { - final DisplayState state = getDisplayState(displayId); EventLogTags.writeWmSetKeyguardShown( displayId, keyguardShowing ? 1 : 0, aodShowing ? 1 : 0, - state.isIn(KEYGUARD_STATE_GOING_AWAY) ? 1 : 0, + state.mKeyguardGoingAway ? 1 : 0, "setKeyguardShown"); - setKeyguardState(displayId, convertToState(displayId, keyguardShowing, aodShowing)); - } - /** - * Set keyguard state. - */ - private void setKeyguardState(int displayId, @KeyguardState int newState) { - if (mRootWindowContainer.getDisplayContent(displayId).isKeyguardAlwaysUnlocked()) { - Slog.i(TAG, "setKeyguardShown ignoring always unlocked display " + displayId); - return; - } - if (newState != KEYGUARD_STATE_LOCKSCREEN_SHOWN - && newState != KEYGUARD_STATE_AOD_SHOWN - && newState != KEYGUARD_STATE_OFF - && newState != KEYGUARD_STATE_GOING_AWAY) { - Slog.i(TAG, "Invalid state is requested: displayId=" + displayId - + ", state=" + keyguardStateToString(newState) - + ", stack=" + Debug.getCallers(30)); - return; - } - if (isKeyguardLocked(displayId) && newState == KEYGUARD_STATE_OFF) { - newState = KEYGUARD_STATE_GOING_AWAY; + // 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, + // the later one can be skipped to avoid taking snapshot again. While it still accepts + // if both of them change to show at the same time. + // - Keyguard was not going away. Because if it was, the closing transition is able to + // handle the snapshot. + // - The display state is ON. Because if AOD is not on or pulsing, the display state will + // be OFF or DOZE (the path of screen off may have handled it). + if (((aodShowing ^ keyguardShowing) || (aodShowing && aodChanged && keyguardChanged)) + && !state.mKeyguardGoingAway && Display.isOnState( + mRootWindowContainer.getDefaultDisplay().getDisplayInfo().state)) { + mWindowManager.mTaskSnapshotController.snapshotForSleeping(DEFAULT_DISPLAY); + } + + state.mKeyguardShowing = keyguardShowing; + state.mAodShowing = aodShowing; + + if (keyguardChanged) { + // Irrelevant to AOD. + state.mKeyguardGoingAway = false; + if (keyguardShowing) { + state.mDismissalRequested = false; + } } - final DisplayState state = getDisplayState(displayId); - // SysUI requests to show LOCKSCREEN, but the keyguard is already occluded. Ignore the - // requests. - if (state.isIn(KEYGUARD_STATE_OCCLUDED) - && StateMachine.isIn(newState, KEYGUARD_STATE_LOCKSCREEN_SHOWN)) { - Slog.w(TAG, "Ignore setKeyguardState request: OCCLUDE -> LOCK_SCREEN_SHOWN"); - return; - } - // SysUI requests to show AOD_SHOWN again. This can happen when SysUI still uses the old - // API and enables AOD first, then lock screen, i.e. #setLockScreenShown(false, true), then - // #setLockScreenShown(true, true) - if (state.isIn(KEYGUARD_STATE_AOD_SHOWN) - && StateMachine.isIn(newState, KEYGUARD_STATE_AOD_SHOWN)) { - Slog.w(TAG, "Ignore setKeyguardState request: AOD_SHOWN -> AOD_SHOWN"); - return; + // Update the sleep token first such that ensureActivitiesVisible has correct sleep token + // state when evaluating visibilities. + updateKeyguardSleepToken(); + mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); + InputMethodManagerInternal.get().updateImeWindowStatus(false /* disableImeIcon */); + setWakeTransitionReady(); + if (aodChanged) { + // Ensure the new state takes effect. + mWindowManager.mWindowPlacerLocked.performSurfacePlacement(); } - if (state.isIn(KEYGUARD_STATE_OFF) - && StateMachine.isIn(newState, KEYGUARD_STATE_GOING_AWAY)) { - Slog.w(TAG, "Ignore setKeyguardState request: OFF -> GOING_AWAY"); - return; - } - if (state.isIn(KEYGUARD_STATE_AOD_SHOWN) - && StateMachine.isIn(newState, KEYGUARD_STATE_LOCKSCREEN_SHOWN)) { - ActivityRecord top = getTopNonFinishingActivity(displayId); - if (canOcclude(top)) { - newState = isTopActivityDreaming(displayId) ? KEYGUARD_STATE_DREAMING - : KEYGUARD_STATE_OCCLUDED; - } + } + + private void setWakeTransitionReady() { + if (mWindowManager.mAtmService.getTransitionController().getCollectingTransitionType() + == WindowManager.TRANSIT_WAKE) { + mWindowManager.mAtmService.getTransitionController().setReady( + mRootWindowContainer.getDefaultDisplay()); } - state.setKeyguardState(newState); } /** @@ -371,1008 +241,520 @@ class KeyguardController { * * @param flags See {@link WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE} * etc. - * - * @deprecated Use {@link #setKeyguardState(int, int)} */ void keyguardGoingAway(int displayId, int flags) { - // TODO(b/242851358): Remove IActivityTaskManagerService#keyguardGoingAway and SysUI should - // request the state change via #setKeyguardState. - final DisplayState state = getDisplayState(displayId); - EventLogTags.writeWmSetKeyguardShown( - displayId, - state.isIn(KEYGUARD_STATE_LOCKSCREEN_SHOWN) ? 1 : 0, - state.isIn(KEYGUARD_STATE_AOD_SHOWN) ? 1 : 0, - 1 /* keyguardGoingAway */, - "keyguardGoingAway"); - setKeyguardState(displayId, KEYGUARD_STATE_GOING_AWAY); - } - - /** - * Makes sure to update lockscreen state if needed before completing set all visibility - * ({@link ActivityTaskSupervisor#beginActivityVisibilityUpdate}). - */ - void updateVisibility() { - for (int displayNdx = mRootWindowContainer.getChildCount() - 1; - displayNdx >= 0; displayNdx--) { - final DisplayContent display = mRootWindowContainer.getChildAt(displayNdx); - if (display.isRemoving() || display.isRemoved()) continue; - final DisplayState state = getDisplayState(display.mDisplayId); - state.updateVisibility(); + final KeyguardDisplayState state = getDisplayState(displayId); + if (!state.mKeyguardShowing || state.mKeyguardGoingAway) { + return; + } + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "keyguardGoingAway"); + mService.deferWindowLayout(); + state.mKeyguardGoingAway = true; + try { + EventLogTags.writeWmSetKeyguardShown( + displayId, + 1 /* keyguardShowing */, + state.mAodShowing ? 1 : 0, + 1 /* keyguardGoingAway */, + "keyguardGoingAway"); + final int transitFlags = convertTransitFlags(flags); + final DisplayContent dc = mRootWindowContainer.getDefaultDisplay(); + dc.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, transitFlags); + // We are deprecating TRANSIT_KEYGUARD_GOING_AWAY for Shell transition and use + // TRANSIT_FLAG_KEYGUARD_GOING_AWAY to indicate that it should animate keyguard going + // away. + dc.mAtmService.getTransitionController().requestTransitionIfNeeded( + TRANSIT_TO_BACK, transitFlags, null /* trigger */, dc); + updateKeyguardSleepToken(); + + // Some stack visibility might change (e.g. docked stack) + mRootWindowContainer.resumeFocusedTasksTopActivities(); + mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); + mRootWindowContainer.addStartingWindowsForVisibleActivities(); + mWindowManager.executeAppTransition(); + } finally { + mService.continueWindowLayout(); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } } void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, CharSequence message) { - boolean ok; - final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r == null) { - ok = false; - } else { - final DisplayState state = getDisplayState(r.getDisplayId()); - ok = state.dismissKeyguard(r, callback, message); + final ActivityRecord activityRecord = ActivityRecord.forTokenLocked(token); + if (activityRecord == null || !activityRecord.visibleIgnoringKeyguard) { + failCallback(callback); + return; } + Slog.i(TAG, "Activity requesting to dismiss Keyguard: " + activityRecord); - if (!ok) { - try { - callback.onDismissError(); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to call callback", e); - } + // If the client has requested to dismiss the keyguard and the Activity has the flag to + // turn the screen on, wakeup the screen if it's the top Activity. + if (activityRecord.getTurnScreenOnFlag() && activityRecord.isTopRunningActivity()) { + mTaskSupervisor.wakeUp("dismissKeyguard"); } - } - private boolean isKeyguardSecure() { - return mWindowManager.isKeyguardSecure(mService.getCurrentUserId()); + mWindowManager.dismissKeyguard(callback, message); } - /** - * @return true if Keyguard can be currently dismissed without entering credentials. - */ - private boolean canDismissKeyguard() { - return mWindowManager.mPolicy.isKeyguardTrustedLw() || !isKeyguardSecure(); + private void failCallback(IKeyguardDismissCallback callback) { + try { + callback.onDismissError(); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to call callback", e); + } } - private boolean canOcclude(@Nullable ActivityRecord r) { - if (r == null) { - return false; + private int convertTransitFlags(int keyguardGoingAwayFlags) { + int result = TRANSIT_FLAG_KEYGUARD_GOING_AWAY; + if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0) { + result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; } - // FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD only apply for secondary display. - if (r.getDisplayId() != DEFAULT_DISPLAY) { - final DisplayContent dc = r.getDisplayContent(); - if (dc != null && dc.canShowWithInsecureKeyguard() && canDismissKeyguard()) { - return true; - } + if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0) { + result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; } - // FLAG_DISMISS_KEYGUARD activity - // Insecure: Treat as FLAG_SHOW_WHEN_LOCKED - // Trusted: Actually dismiss Keyguard. - // Secure: Show bouncer. - return r.canShowWhenLocked() || (r.containsDismissKeyguardWindow() && !isKeyguardSecure()); - } - - private boolean isTopActivityDreaming(int displayId) { - final DisplayContent dc = mRootWindowContainer.getDisplayContent(displayId); - final ActivityRecord top = getTopNonFinishingActivity(displayId); - return dc.getDisplayPolicy().isShowingDreamLw() - && top != null && top.getActivityType() == ACTIVITY_TYPE_DREAM; - } - - @Nullable private ActivityRecord getTopNonFinishingActivity(int displayId) { - final DisplayContent dc = mRootWindowContainer.getDisplayContent(displayId); - final Task rootTask = dc == null ? null : dc.getRootTask(t -> - t != null && t.isFocusableAndVisible() && !t.inPinnedWindowingMode()); - return rootTask != null ? rootTask.getTopNonFinishingActivity() : null; - } - - private DisplayState getDisplayState(int displayId) { - DisplayState state = mDisplayStates.get(displayId); - if (state == null) { - state = new DisplayState(displayId, mServiceDelegate); - mDisplayStates.append(displayId, state); + if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0) { + result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; } - return state; - } - - void dumpDebug(ProtoOutputStream proto, long fieldId) { - final DisplayState default_state = getDisplayState(DEFAULT_DISPLAY); - final long token = proto.start(fieldId); - proto.write(AOD_SHOWING, default_state.isIn(KEYGUARD_STATE_AOD_SHOWN)); - proto.write(KEYGUARD_SHOWING, default_state.isIn(KEYGUARD_STATE_LOCKSCREEN_SHOWN)); - writeDisplayStatesToProto(proto, KEYGUARD_PER_DISPLAY); - proto.end(token); - } - - private void writeDisplayStatesToProto(ProtoOutputStream proto, long fieldId) { - for (int i = 0; i < mDisplayStates.size(); i++) { - mDisplayStates.valueAt(i).dumpDebug(proto, fieldId); + if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS) != 0) { + result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION; } - } - - void dump(PrintWriter pw, String prefix) { - pw.print(prefix); - pw.println("KeyguardController:"); - for (int i = 0; i < mDisplayStates.size(); i++) { - mDisplayStates.valueAt(i).dump(pw, prefix); + if ((keyguardGoingAwayFlags + & KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT) != 0) { + result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT; } - pw.println(); + return result; } /** - * Interface for {@link DisplayState} to access non-local information. - * <p> - * Keep this interface as small as possible, and don't let {@link DisplayState} access arbitrary - * large classes such as ActivityTaskSupervisor, which makes managing dependency complicated. + * @return True if we may show an activity while Keyguard is showing because we are in the + * process of dismissing it anyways, false otherwise. */ - private final class ServiceDelegate { - boolean isKeyguardSecure() { - return KeyguardController.this.isKeyguardSecure(); - } - - boolean canOcclude(@Nullable ActivityRecord r) { - return KeyguardController.this.canOcclude(r); - } - - boolean canDismissKeyguard() { - return KeyguardController.this.canDismissKeyguard(); - } - - boolean isDeviceInteractive() { - return mService.mWindowManager.mPowerManager.isInteractive(); - } - - void dismissKeyguard(IKeyguardDismissCallback callback, CharSequence message) { - mWindowManager.dismissKeyguard(callback, message); - } - - @Nullable - ActivityRecord getTopNonFinishingActivity(int displayId) { - return KeyguardController.this.getTopNonFinishingActivity(displayId); - } - - boolean isTopActivityDreaming(int displayId) { - return KeyguardController.this.isTopActivityDreaming(displayId); - } - - void wakeUp(String reason) { - mTaskSupervisor.wakeUp(reason); - } - - void forceSyncOccludedStatus(boolean occluded) { - if (DEBUG) { - Slog.d(TAG, "forceSyncOccludedStatus: occluded=" + occluded); - } - mWindowManager.mPolicy.onKeyguardOccludedChangedLw(occluded); - mWindowManager.mPolicy.applyKeyguardOcclusionChange(true /* notify */); - } - - void snapshotForSleeping(int displayId) { - if (displayId == DEFAULT_DISPLAY) { - mWindowManager.mTaskSnapshotController.snapshotForSleeping(displayId); - } - } + boolean canShowActivityWhileKeyguardShowing(ActivityRecord r) { + // Allow to show it when we are about to dismiss Keyguard. This isn't allowed if r is + // already the dismissing activity, in which case we don't allow it to repeatedly dismiss + // Keyguard. + final KeyguardDisplayState state = getDisplayState(r.getDisplayId()); + return r.containsDismissKeyguardWindow() && canDismissKeyguard() && !state.mAodShowing + && (state.mDismissalRequested + || (r.canShowWhenLocked() && state.mDismissingKeyguardActivity != r)); + } - void notifyKeyguardOccludeChanged(boolean occluded) { - // TODO: This updates status of KeyguardDelegate. Once we delete occlude status from - // KeyguardDelegate, we should remove WindowManagerPolicy#onKeyguardOccludedChangedLw. - mWindowManager.mPolicy.onKeyguardOccludedChangedLw(occluded); - } + /** + * @return True if we may show an activity while Keyguard is occluded, false otherwise. + */ + boolean canShowWhileOccluded(boolean dismissKeyguard, boolean showWhenLocked) { + return showWhenLocked || dismissKeyguard + && !mWindowManager.isKeyguardSecure(mService.getCurrentUserId()); + } - void collect(@NonNull WindowContainer wc) { - mService.getTransitionController().collect(wc); + /** + * Checks whether {@param r} should be visible depending on Keyguard state. + * + * @return true if {@param r} is visible taken Keyguard state into account, false otherwise + */ + boolean checkKeyguardVisibility(ActivityRecord r) { + if (r.mDisplayContent.canShowWithInsecureKeyguard() && canDismissKeyguard()) { + return true; } - void requestTransitionIfNeeded(int displayId, @WindowManager.TransitionType int transit, - @WindowManager.TransitionFlags int flags) { - if (displayId != DEFAULT_DISPLAY) { - return; - } - if (DEBUG) { - Slog.d(TAG, "requestTransitionIfNeeded: display=" + displayId + ", transit=" - + transitTypeToString(transit)); - } - - final DisplayContent dc = mRootWindowContainer.getDisplayContent(displayId); - if (dc == null) { - Slog.e(TAG, "No DisplayContent exists: displayId=" + displayId); - return; - } - - if (transit == TRANSIT_KEYGUARD_GOING_AWAY) { - dc.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, flags); - // We are deprecating TRANSIT_KEYGUARD_GOING_AWAY for Shell transition and use - // TRANSIT_FLAG_KEYGUARD_GOING_AWAY to indicate that it should animate keyguard - // going away. - mService.getTransitionController().requestTransitionIfNeeded( - TRANSIT_TO_BACK, flags, null /* trigger */, dc); - } else { - dc.requestTransitionAndLegacyPrepare(transit, flags); - } + if (isKeyguardOrAodShowing(r.mDisplayContent.getDisplayId())) { + // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard + // right away and AOD isn't visible. + return canShowActivityWhileKeyguardShowing(r); + } else if (isKeyguardLocked(r.getDisplayId())) { + return canShowWhileOccluded(r.containsDismissKeyguardWindow(), r.canShowWhenLocked()); + } else { + return true; } + } - void acquireSleepToken(int displayId, boolean ensureActivitiesVisible) { - mSleepTokenAcquirer.acquire(displayId); - if (ensureActivitiesVisible) { - mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); + /** + * Makes sure to update lockscreen occluded/dismiss/turnScreenOn state if needed before + * completing set all visibility + * ({@link ActivityTaskSupervisor#beginActivityVisibilityUpdate}). + */ + void updateVisibility() { + for (int displayNdx = mRootWindowContainer.getChildCount() - 1; + displayNdx >= 0; displayNdx--) { + final DisplayContent display = mRootWindowContainer.getChildAt(displayNdx); + if (display.isRemoving() || display.isRemoved()) continue; + final KeyguardDisplayState state = getDisplayState(display.mDisplayId); + state.updateVisibility(this, display); + if (state.mRequestDismissKeyguard) { + handleDismissKeyguard(display.getDisplayId()); } } + } - void releaseSleepToken(int displayId, boolean resumeTopActivities) { - mSleepTokenAcquirer.release(displayId); - if (resumeTopActivities) { - mRootWindowContainer.resumeFocusedTasksTopActivities(); - mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); - mRootWindowContainer.addStartingWindowsForVisibleActivities(); - - } + /** + * Called when occluded state changed. + * + * @param topActivity the activity that controls the state whether keyguard should + * be occluded. That is the activity to be shown on top of keyguard if it requests so. + */ + private void handleOccludedChanged(int displayId, @Nullable ActivityRecord topActivity) { + // TODO(b/113840485): Handle app transition for individual display, and apply occluded + // state change to secondary displays. + // For now, only default display fully supports occluded change. Other displays only + // updates keyguard sleep token on that display. + if (displayId != DEFAULT_DISPLAY) { + updateKeyguardSleepToken(displayId); + return; } - void deferWindowLayout() { + mWindowManager.mPolicy.onKeyguardOccludedChangedLw(isDisplayOccluded(DEFAULT_DISPLAY)); + if (isKeyguardLocked(displayId)) { mService.deferWindowLayout(); - } - - void continueWindowLayout() { - mService.continueWindowLayout(); - } - - void executeAppTransition() { - mWindowManager.executeAppTransition(); - } - - private void updateDeferTransitionForAod(boolean waiting) { - KeyguardController.this.updateDeferTransitionForAod(waiting); - } - - private void setWakeTransitionReady() { - if (mService.getTransitionController().getCollectingTransitionType() == TRANSIT_WAKE) { - mService.getTransitionController().setReady( - mRootWindowContainer.getDefaultDisplay()); - } - } - - void requestLayoutRedoWallpaper(int displayId) { - final DisplayContent dc = mRootWindowContainer.getDisplayContent(displayId); - if (!dc.isSleeping() && dc.mWallpaperController.getWallpaperTarget() != null) { - dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; + try { + mRootWindowContainer.getDefaultDisplay() + .requestTransitionAndLegacyPrepare( + isDisplayOccluded(DEFAULT_DISPLAY) + ? TRANSIT_KEYGUARD_OCCLUDE + : TRANSIT_KEYGUARD_UNOCCLUDE, 0 /* flags */); + updateKeyguardSleepToken(DEFAULT_DISPLAY); + mWindowManager.executeAppTransition(); + } finally { + mService.continueWindowLayout(); } } - }; + dismissMultiWindowModeForTaskIfNeeded(displayId, topActivity != null + ? topActivity.getRootTask() : null); + } - private static class KeyguardDisplayStateMachine extends StateMachine { - static final int EVENT_DISMISS_KEYGUARD_ACTIVITY = 1; - static final int EVENT_SHOW_WHEN_LOCKED_ACTIVITY = 2; - static final int EVENT_CHECK_KEYGUARD_VISIBILITY = 3; - static final int EVENT_TOP_ACTIVITY_OCCLUDES_KEYGUARD = 4; - static final int EVENT_LAYOUT_CHANGES = 5; - static final int EVENT_DUMP = 6; - static final int EVENT_DISMISS_KEYGUARD_API = 7; - static final int EVENT_TURN_SCREEN_ON_ACTIVITY = 8; - final int mDisplayId; - - static final class CheckKeyguardVisibilityParam { - boolean mRet; - @NonNull final ActivityRecord mActivity; - - CheckKeyguardVisibilityParam(@NonNull ActivityRecord activity) { - mActivity = activity; - } + /** + * Called when keyguard going away state changed. + */ + private void handleKeyguardGoingAwayChanged(DisplayContent dc) { + mService.deferWindowLayout(); + try { + dc.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, 0 /* transitFlags */); + // We are deprecating TRANSIT_KEYGUARD_GOING_AWAY for Shell transition and use + // TRANSIT_FLAG_KEYGUARD_GOING_AWAY to indicate that it should animate keyguard going + // away. + dc.mAtmService.getTransitionController().requestTransitionIfNeeded( + TRANSIT_OPEN, TRANSIT_FLAG_KEYGUARD_GOING_AWAY, null /* trigger */, dc); + updateKeyguardSleepToken(); + mWindowManager.executeAppTransition(); + } finally { + mService.continueWindowLayout(); } + } - static final class DismissKeyguardParam { - boolean mRet; - @NonNull final ActivityRecord mActivity; - @Nullable final IKeyguardDismissCallback mCallback; - @Nullable final CharSequence mMessage; - - DismissKeyguardParam(@NonNull ActivityRecord activity, - @Nullable IKeyguardDismissCallback callback, @Nullable CharSequence message) { - mActivity = activity; - mCallback = callback; - mMessage = message; - } + /** + * Called when somebody wants to dismiss the Keyguard via the flag. + */ + private void handleDismissKeyguard(int displayId) { + // We only allow dismissing Keyguard via the flag when Keyguard is secure for legacy + // reasons, because that's how apps used to dismiss Keyguard in the secure case. In the + // insecure case, we actually show it on top of the lockscreen. See #canShowWhileOccluded. + if (!mWindowManager.isKeyguardSecure(mService.getCurrentUserId())) { + return; } - static final class TopActivityOccludesKeyguardParam { - boolean mRet; - @NonNull final ActivityRecord mActivity; + mWindowManager.dismissKeyguard(null /* callback */, null /* message */); + final KeyguardDisplayState state = getDisplayState(displayId); + state.mDismissalRequested = true; - TopActivityOccludesKeyguardParam(@NonNull ActivityRecord activity) { - mActivity = activity; - } + // If we are about to unocclude the Keyguard, but we can dismiss it without security, + // we immediately dismiss the Keyguard so the activity gets shown without a flicker. + final DisplayContent dc = mRootWindowContainer.getDefaultDisplay(); + if (state.mKeyguardShowing && canDismissKeyguard() + && dc.mAppTransition.containsTransitRequest(TRANSIT_KEYGUARD_UNOCCLUDE)) { + mWindowManager.executeAppTransition(); } + } - static final class DumpParam { - ArrayList<String> mRet = new ArrayList<>(); - String mPrefix; - - DumpParam(@NonNull String prefix) { - mPrefix = prefix; - } - } + boolean isDisplayOccluded(int displayId) { + return getDisplayState(displayId).mOccluded; + } - KeyguardDisplayStateMachine(int displayId, @KeyguardState int initialState) { - super(initialState); - mDisplayId = displayId; - } + /** + * @return true if Keyguard can be currently dismissed without entering credentials. + */ + boolean canDismissKeyguard() { + return mWindowManager.mPolicy.isKeyguardTrustedLw() + || !mWindowManager.isKeyguardSecure(mService.getCurrentUserId()); + } - @Nullable - @Override - public Handler addStateHandler(int state, Handler handler) { - Handler prevHandler = super.addStateHandler(state, handler); - if (prevHandler != null) { - throw new IllegalStateException( - "Duplicate state handler registration: display=" + mDisplayId - + ", state=" + state); - } - return null; - } + /** + * @return Whether the dream activity is on top of default display. + */ + boolean isShowingDream() { + return getDisplayState(DEFAULT_DISPLAY).mShowingDream; + } - @Override - public void transit(@KeyguardState int newState) { - if (DEBUG) { - StringBuilder sb = new StringBuilder(); - sb.append("[ "); - for (Command cmd : getCommands()) { - sb.append(cmd); - sb.append(' '); - } - sb.append(" ]"); - Slog.d(TAG, "State change: display=" + mDisplayId - + ", current=" + keyguardStateToString(getCurrentState()) - + ", lastRequested=" + keyguardStateToString(getState()) - + ", newState=" + keyguardStateToString(newState) - + ", command=" + sb - + ", stack=" + Debug.getCallers(30)); - } - super.transit(newState); + private void dismissMultiWindowModeForTaskIfNeeded(int displayId, + @Nullable Task currentTaskControllingOcclusion) { + // TODO(b/113840485): Handle docked stack for individual display. + if (!getDisplayState(displayId).mKeyguardShowing || !isDisplayOccluded(DEFAULT_DISPLAY)) { + return; } - @Override - public void enter(@KeyguardState int state) { - if (DEBUG) { - Slog.d(TAG, "enter: display=" + mDisplayId + ", state=" - + keyguardStateToString(state)); - } - super.enter(state); + // Dismiss freeform windowing mode + if (currentTaskControllingOcclusion == null) { + return; } - - @Override - public void exit(@KeyguardState int state) { - if (DEBUG) { - Slog.d(TAG, "exit: display=" + mDisplayId + ", state=" - + keyguardStateToString(state)); - } - super.exit(state); + if (currentTaskControllingOcclusion.inFreeformWindowingMode()) { + currentTaskControllingOcclusion.setWindowingMode(WINDOWING_MODE_FULLSCREEN); } + } - void handleDismissKeyguardActivity() { - handle(EVENT_DISMISS_KEYGUARD_ACTIVITY, null /* param */); + private void updateKeyguardSleepToken() { + for (int displayNdx = mRootWindowContainer.getChildCount() - 1; + displayNdx >= 0; displayNdx--) { + final DisplayContent display = mRootWindowContainer.getChildAt(displayNdx); + updateKeyguardSleepToken(display.mDisplayId); } + } - void handleTurnScreenOnActivity() { - handle(EVENT_TURN_SCREEN_ON_ACTIVITY, null /* param */); + private void updateKeyguardSleepToken(int displayId) { + final KeyguardDisplayState state = getDisplayState(displayId); + if (isKeyguardUnoccludedOrAodShowing(displayId)) { + state.mSleepTokenAcquirer.acquire(displayId); + } else { + state.mSleepTokenAcquirer.release(displayId); } + } - boolean handleDismissKeyguard(@NonNull ActivityRecord r, - @Nullable IKeyguardDismissCallback callback, @Nullable CharSequence message) { - DismissKeyguardParam param = new DismissKeyguardParam(r, callback, message); - handle(EVENT_DISMISS_KEYGUARD_API, param); - return param.mRet; + private KeyguardDisplayState getDisplayState(int displayId) { + KeyguardDisplayState state = mDisplayStates.get(displayId); + if (state == null) { + state = new KeyguardDisplayState(mService, displayId, mSleepTokenAcquirer); + mDisplayStates.append(displayId, state); } + return state; + } - void handleShowWhenLockedActivity() { - handle(EVENT_SHOW_WHEN_LOCKED_ACTIVITY, null /* param */); + void onDisplayRemoved(int displayId) { + final KeyguardDisplayState state = mDisplayStates.get(displayId); + if (state != null) { + state.onRemoved(); + mDisplayStates.remove(displayId); } + } - void handleLayoutChanges() { - handle(EVENT_LAYOUT_CHANGES, null /* param */); + private final Runnable mResetWaitTransition = () -> { + synchronized (mWindowManager.mGlobalLock) { + updateDeferTransitionForAod(false /* waiting */); } + }; - boolean checkKeyguardVisibility(@NonNull ActivityRecord r) { - final CheckKeyguardVisibilityParam param = new CheckKeyguardVisibilityParam(r); - handle(EVENT_CHECK_KEYGUARD_VISIBILITY, param); - return param.mRet; + // Defer transition until AOD dismissed. + void updateDeferTransitionForAod(boolean waiting) { + if (waiting == mWaitingForWakeTransition) { + return; } - - boolean topActivityOccludesKeyguard(@NonNull ActivityRecord r) { - final TopActivityOccludesKeyguardParam param = new TopActivityOccludesKeyguardParam(r); - handle(EVENT_TOP_ACTIVITY_OCCLUDES_KEYGUARD, param); - return param.mRet; + if (!mService.getTransitionController().isCollecting()) { + return; } - - ArrayList<String> handleDump(String prefix) { - final DumpParam param = new DumpParam(prefix); - handle(EVENT_DUMP, param); - return param.mRet; + // if AOD is showing, defer the wake transition until AOD state changed. + if (waiting && isAodShowing(DEFAULT_DISPLAY)) { + mWaitingForWakeTransition = true; + mWindowManager.mAtmService.getTransitionController().deferTransitionReady(); + mWindowManager.mH.postDelayed(mResetWaitTransition, DEFER_WAKE_TRANSITION_TIMEOUT_MS); + } else if (!waiting) { + // dismiss the deferring if the AOD state change or cancel awake. + mWaitingForWakeTransition = false; + mWindowManager.mAtmService.getTransitionController().continueTransitionReady(); + mWindowManager.mH.removeCallbacks(mResetWaitTransition); } } - /** - * Helper class for implementing handler in type-safe way. - */ - private abstract static class Handler implements StateMachine.Handler { - @Override - public final boolean handle(int event, @Nullable Object param) { - switch (event) { - case KeyguardDisplayStateMachine.EVENT_DISMISS_KEYGUARD_ACTIVITY: - return handleDismissKeyguardActivity(); - case KeyguardDisplayStateMachine.EVENT_TURN_SCREEN_ON_ACTIVITY: - return handleTurnScreenOnActivity(); - case KeyguardDisplayStateMachine.EVENT_DISMISS_KEYGUARD_API: { - final KeyguardDisplayStateMachine.DismissKeyguardParam typedParam = - (KeyguardDisplayStateMachine.DismissKeyguardParam) param; - Optional<Boolean> ret = handleDismissKeyguard(typedParam.mActivity, - typedParam.mCallback, typedParam.mMessage); - if (ret.isPresent()) { - typedParam.mRet = ret.get(); - return true; - } - return false; - } - case KeyguardDisplayStateMachine.EVENT_SHOW_WHEN_LOCKED_ACTIVITY: - return handleShowWhenLockedActivity(); - case KeyguardDisplayStateMachine.EVENT_CHECK_KEYGUARD_VISIBILITY: { - final KeyguardDisplayStateMachine.CheckKeyguardVisibilityParam typedParam = - (KeyguardDisplayStateMachine.CheckKeyguardVisibilityParam) param; - Optional<Boolean> ret = checkKeyguardVisibility(typedParam.mActivity); - if (ret.isPresent()) { - typedParam.mRet = ret.get(); - return true; - } - return false; - } - case KeyguardDisplayStateMachine.EVENT_TOP_ACTIVITY_OCCLUDES_KEYGUARD: { - final KeyguardDisplayStateMachine.TopActivityOccludesKeyguardParam typedParam = - (KeyguardDisplayStateMachine.TopActivityOccludesKeyguardParam) param; - Optional<Boolean> ret = topActivityOccludesKeyguardParam(typedParam.mActivity); - if (ret.isPresent()) { - typedParam.mRet = ret.get(); - return true; - } - return false; - } - case KeyguardDisplayStateMachine.EVENT_LAYOUT_CHANGES: - return handleLayoutChanges(); - case KeyguardDisplayStateMachine.EVENT_DUMP: - final KeyguardDisplayStateMachine.DumpParam typedParam = - (KeyguardDisplayStateMachine.DumpParam) param; - String dumpInfo = handleDump(typedParam.mPrefix); - if (dumpInfo != null) { - typedParam.mRet.add(dumpInfo); - } - // keep collecting information for dump up to top status. - return false; - default: - Slog.e(TAG, "Handler.handle(): Unknown event(" + event + ")"); - return false; - } - } - - Optional<Boolean> checkKeyguardVisibility(@NonNull ActivityRecord activity) { - return Optional.empty(); - } - Optional<Boolean> topActivityOccludesKeyguardParam(@NonNull ActivityRecord r) { - return Optional.empty(); - } - - /** - * Handle flags in the activity which request to dismiss the keyguard. - * - * @see ActivityOptions#setDismissKeyguard() - * @see WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD - */ - boolean handleDismissKeyguardActivity() { - return false; - } - - /** - * Handle flags in the activity which request to turn the screen on. This must be called - * after dismiss keyguard flag is handled. - */ - boolean handleTurnScreenOnActivity() { - return false; - } - /** - * Handle flags in the activity which decides if the activity can be shown on top of the - * keyguard. - * - * @see android.app.Activity#setShowWhenLocked(boolean) - * @see android.app.Activity#setInheritShowWhenLocked(boolean) - */ - boolean handleShowWhenLockedActivity() { - return false; + /** Represents Keyguard state per individual display. */ + private static class KeyguardDisplayState { + private final int mDisplayId; + private boolean mKeyguardShowing; + private boolean mAodShowing; + private boolean mKeyguardGoingAway; + private boolean mDismissalRequested; + private boolean mOccluded; + private boolean mShowingDream; + + private ActivityRecord mTopOccludesActivity; + private ActivityRecord mDismissingKeyguardActivity; + private ActivityRecord mTopTurnScreenOnActivity; + + private boolean mRequestDismissKeyguard; + private final ActivityTaskManagerService mService; + private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer; + + KeyguardDisplayState(ActivityTaskManagerService service, int displayId, + ActivityTaskManagerInternal.SleepTokenAcquirer acquirer) { + mService = service; + mDisplayId = displayId; + mSleepTokenAcquirer = acquirer; } - /** - * Request relayout if necessary. - */ - boolean handleLayoutChanges() { - return false; + void onRemoved() { + mTopOccludesActivity = null; + mDismissingKeyguardActivity = null; + mTopTurnScreenOnActivity = null; + mSleepTokenAcquirer.release(mDisplayId); } /** - * Called when the activity requests to dismiss the keyguard via KeyguardManager APIs. - * - * @param r The activity which requested to dismiss the keyguard. - * @return Present if the state handles, delegate to its parent state otherwise. When the - * value is present, the value is {@code true} if the keyguard dismiss request is - * processed, {@code false} otherwise. + * Updates keyguard status if the top task could be visible. The top task may occlude + * keyguard, request to dismiss keyguard or make insecure keyguard go away based on its + * properties. */ - Optional<Boolean> handleDismissKeyguard(@NonNull ActivityRecord r, - @Nullable IKeyguardDismissCallback callback, @Nullable CharSequence message) { - return Optional.empty(); - } - - @Nullable String handleDump(@NonNull String prefix) { - return null; - } - } - - private static class DisplayState { - private final int mDisplayId; - @NonNull private final ServiceDelegate mServiceDelegate; - private final KeyguardDisplayStateMachine mStateMachine; - - // TODO: Set watchdog timer to sync mLastNotifiedOccludedState == isIn(OCCLUDED) - private boolean mLastNotifiedOccludedState = false; - - // Top activity which has a window with FLAG_DISMISS_KEYGUARD flag. Valid only when the - // current state is KEYGUARD_STATE_ON or one of its sub states. - @Nullable private ActivityRecord mDismissingKeyguardActivity; - - // KeyguardController has requested to dismiss keyguard via IWindowManager#dismissKeyguard. - // Reset this to false again, once the KeyguardController status is updated. - private boolean mDismissalRequested = false; - - DisplayState(int displayId, @NonNull ServiceDelegate serviceDelegate) { - mDisplayId = displayId; - mServiceDelegate = serviceDelegate; - mStateMachine = new KeyguardDisplayStateMachine(displayId, KEYGUARD_STATE_OFF); - - mStateMachine.addStateHandler(KEYGUARD_STATE_ROOT, new Handler() { - @Override - Optional<Boolean> checkKeyguardVisibility(@NonNull ActivityRecord activity) { - return Optional.of(false); + void updateVisibility(KeyguardController controller, DisplayContent display) { + final boolean lastOccluded = mOccluded; + final boolean lastKeyguardGoingAway = mKeyguardGoingAway; + + final ActivityRecord lastDismissKeyguardActivity = mDismissingKeyguardActivity; + final ActivityRecord lastTurnScreenOnActivity = mTopTurnScreenOnActivity; + + mRequestDismissKeyguard = false; + mOccluded = false; + mShowingDream = false; + + mTopOccludesActivity = null; + mDismissingKeyguardActivity = null; + mTopTurnScreenOnActivity = null; + + boolean occludedByActivity = false; + final Task task = getRootTaskForControllingOccluding(display); + final ActivityRecord top = task != null ? task.getTopNonFinishingActivity() : null; + if (top != null) { + if (top.containsDismissKeyguardWindow()) { + mDismissingKeyguardActivity = top; } - - @Override - Optional<Boolean> topActivityOccludesKeyguardParam(@NonNull ActivityRecord r) { - return Optional.of(false); + if (top.getTurnScreenOnFlag() && top.currentLaunchCanTurnScreenOn()) { + mTopTurnScreenOnActivity = top; } - }); - mStateMachine.addStateHandler(KEYGUARD_STATE_OFF, new Handler() { - @Override - public Optional<Boolean> checkKeyguardVisibility(@NonNull ActivityRecord r) { - return Optional.of(true); + if (top.mDismissKeyguard && mKeyguardShowing) { + mKeyguardGoingAway = true; + } else if (top.canShowWhenLocked()) { + mTopOccludesActivity = top; } - - @Override - Optional<Boolean> handleDismissKeyguard( - @NonNull ActivityRecord r, @Nullable IKeyguardDismissCallback callback, - @Nullable CharSequence message) { - // Keyguard is not shown, so we don't handle the request to dismiss the - // keyguard. - return Optional.of(false); - } - }); - - mStateMachine.addStateHandler(KEYGUARD_STATE_GOING_AWAY, new Handler() { - @Override - public void enter() { - mServiceDelegate.deferWindowLayout(); - try { - mServiceDelegate.requestTransitionIfNeeded(mDisplayId, - TRANSIT_KEYGUARD_GOING_AWAY, - TRANSIT_FLAG_KEYGUARD_GOING_AWAY - | TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER); - // Some stack visibility might change (e.g. docked stack) - mServiceDelegate.releaseSleepToken(mDisplayId, - true /* resumeTopActivities */); - mServiceDelegate.executeAppTransition(); - } finally { - mServiceDelegate.continueWindowLayout(); - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - } - } - }); - - mStateMachine.addStateHandler(KEYGUARD_STATE_ON, new Handler() { - public boolean handleDismissKeyguardActivity() { - final ActivityRecord lastDismissingKeyguardActivity = - mDismissingKeyguardActivity; - final ActivityRecord top = mServiceDelegate.getTopNonFinishingActivity( - mDisplayId); - mDismissingKeyguardActivity = - (top != null && top.containsDismissKeyguardWindow()) ? top : null; - if (lastDismissingKeyguardActivity != mDismissingKeyguardActivity - && mDismissingKeyguardActivity != null - && mServiceDelegate.isKeyguardSecure()) { - // We only allow dismissing Keyguard via the flag when Keyguard is secure - // for legacy reasons, because that's how apps used to dismiss Keyguard in - // the secure case. In the insecure case, we actually show it on top of the - // lockscreen. See #canShowWhileOccluded. - mDismissalRequested = true; - mServiceDelegate.dismissKeyguard(null, null); - } - return true; - } - - @Override - Optional<Boolean> handleDismissKeyguard(@NonNull ActivityRecord r, - @Nullable IKeyguardDismissCallback callback, - @Nullable CharSequence message) { - if (!r.visibleIgnoringKeyguard) { - return Optional.of(false); - } - if (DEBUG) { - Slog.d(TAG, "Activity requesting to dismiss Keyguard: " + r); - } - // If the client has requested to dismiss the keyguard and the Activity has the - // flag to turn the screen on, wakeup the screen if it's the top Activity. - // Note that it's possible that the client requests to dismiss the keyguard - // before the activity adds a window. In this case the flag set on the window - // is not yet visible from ActivityRecord, so we need to check the flag again - // when the activity adds a window later. See #handleTurnScreenOnActivity(). - if (r.getTurnScreenOnFlag() && r.isTopRunningActivity()) { - mServiceDelegate.wakeUp("ON/handleDismissKeyguard"); - r.setCurrentLaunchCanTurnScreenOn(false); - } - mDismissalRequested = true; - mServiceDelegate.dismissKeyguard(callback, message); - return Optional.of(true); - } - - @Override - public void enter() { - // Update the task snapshot if the screen will not be turned off. To make sure - // that the unlocking animation can animate consistent content. - mServiceDelegate.snapshotForSleeping(mDisplayId); + top.mDismissKeyguard = false; + + // Only the top activity may control occluded, as we can't occlude the Keyguard + // if the top app doesn't want to occlude it. + occludedByActivity = mTopOccludesActivity != null + || (mDismissingKeyguardActivity != null + && task.topRunningActivity() == mDismissingKeyguardActivity + && controller.canShowWhileOccluded( + true /* dismissKeyguard */, false /* showWhenLocked */)); + // FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD only apply for secondary display. + if (mDisplayId != DEFAULT_DISPLAY) { + occludedByActivity |= display.canShowWithInsecureKeyguard() + && controller.canDismissKeyguard(); } + } - @Nullable - @Override - String handleDump(@NonNull String prefix) { - StringBuffer sb = new StringBuffer(); - sb.append(prefix) - .append(" mDismissingKeyguardActivity=") - .append(mDismissingKeyguardActivity) - .append("\n"); - return sb.toString(); - } - }); - - mStateMachine.addStateHandler(KEYGUARD_STATE_OCCLUDED, new Handler() { - ActivityRecord mTopOccludesActivity; - - @Override - Optional<Boolean> checkKeyguardVisibility(@NonNull ActivityRecord activity) { - return Optional.of(mServiceDelegate.canOcclude(activity)); - } - - @Override - public boolean handleShowWhenLockedActivity() { - final ActivityRecord top = mServiceDelegate.getTopNonFinishingActivity( - mDisplayId); - final ActivityRecord topOccludesActivity = mServiceDelegate.canOcclude(top) - ? top : null; - if (mTopOccludesActivity == topOccludesActivity) { - return true; - } - // Launch SHOW_WHEN_LOCKED or INHERIT_SHOW_WHEN_LOCKED activity on top of an - // occluding activity. - mTopOccludesActivity = topOccludesActivity; - if (mServiceDelegate.isTopActivityDreaming(mDisplayId)) { - // Dream activity is launched on top of the previous SHOW_WHEN_LOCKED - // activity. - setKeyguardState(KEYGUARD_STATE_DREAMING); - } else if (topOccludesActivity == null) { - // SHOW_WHEN_LOCKED activity finishes. - setKeyguardState(KEYGUARD_STATE_LOCKSCREEN_SHOWN); - } - return true; - } - - @Override - boolean handleLayoutChanges() { - // The occluding activity may be translucent or not fill screen. Then let - // wallpaper to check whether it should set itself as target to avoid blank - // background. - if (!mTopOccludesActivity.fillsParent()) { - mServiceDelegate.requestLayoutRedoWallpaper(mDisplayId); - } - return true; - } - - @Override - Optional<Boolean> topActivityOccludesKeyguardParam(@NonNull ActivityRecord r) { - return Optional.of(mTopOccludesActivity == r); - } - - @Override - public void enter() { - mTopOccludesActivity = mServiceDelegate.getTopNonFinishingActivity(mDisplayId); - if (!mServiceDelegate.canOcclude(mTopOccludesActivity)) { - Slog.e(TAG, "enter(OCCLUDE): no occluding activity"); - setKeyguardState(KEYGUARD_STATE_LOCKSCREEN_SHOWN); - return; - } - - if (DEBUG) { - Slog.d(TAG, "handleOccludedChanged: display=" + mDisplayId - + ", topActivity=" + mTopOccludesActivity); - } - // Collect the participates for shell transition, so that transition won't - // happen too early since the transition was set ready. - mServiceDelegate.collect(mTopOccludesActivity); - // TODO(b/113840485): Handle app transition for individual display, and apply - // occluded state change to secondary displays. For now, only default display - // fully supports occluded change. Other displays only updates keyguard sleep - // token on that display. - if (mDisplayId != DEFAULT_DISPLAY) { - mServiceDelegate.releaseSleepToken(mDisplayId, - false /* resumeTopActivities */); - return; - } - - if (mTopOccludesActivity.getTurnScreenOnFlag() - && mTopOccludesActivity.currentLaunchCanTurnScreenOn() - && !mServiceDelegate.isDeviceInteractive()) { - mServiceDelegate.wakeUp("OCCLUDE/enter"); - mTopOccludesActivity.setCurrentLaunchCanTurnScreenOn(false); - } - - mServiceDelegate.notifyKeyguardOccludeChanged(true /* occluded */); - mServiceDelegate.deferWindowLayout(); - try { - mServiceDelegate.requestTransitionIfNeeded(mDisplayId, - TRANSIT_KEYGUARD_OCCLUDE, 0 /* flags */); - mServiceDelegate.releaseSleepToken(mDisplayId, - false /* resumeTopActivities */); - mServiceDelegate.executeAppTransition(); - } finally { - mServiceDelegate.continueWindowLayout(); - } - // Dismiss freeform windowing mode - final Task currentTaskControllingOcclusion = mTopOccludesActivity.getRootTask(); - if (currentTaskControllingOcclusion != null - && currentTaskControllingOcclusion.inFreeformWindowingMode()) { - currentTaskControllingOcclusion.setWindowingMode(WINDOWING_MODE_FULLSCREEN); - } - } - - @Override - public void exit() { - mTopOccludesActivity = null; - if (DEBUG) { - Slog.d(TAG, "handleOccludedChanged: topActivity=" + null); - } - // TODO(b/113840485): Handle app transition for individual display, and apply - // occluded state change to secondary displays. - // For now, only default display fully supports occluded change. Other displays - // only updates keyguard sleep token on that display. - if (mDisplayId != DEFAULT_DISPLAY) { - mServiceDelegate.acquireSleepToken( - mDisplayId, false /* ensureActivitiesVisible */); - return; - } - - mServiceDelegate.notifyKeyguardOccludeChanged(false /* occluded */); - mServiceDelegate.deferWindowLayout(); - try { - mServiceDelegate.requestTransitionIfNeeded(mDisplayId, - TRANSIT_KEYGUARD_UNOCCLUDE, 0 /* flags */); - mServiceDelegate.acquireSleepToken( - mDisplayId, false /* ensureActivitiesVisible */); - mServiceDelegate.executeAppTransition(); - } finally { - mServiceDelegate.continueWindowLayout(); - } - } - - @Nullable - @Override - String handleDump(@NonNull String prefix) { - StringBuffer sb = new StringBuffer(); - sb.append(prefix) - .append(" mTopOccludesActivity=") - .append(mTopOccludesActivity) - .append("\n"); - return sb.toString(); - } - }); - - mStateMachine.addStateHandler(KEYGUARD_STATE_KEYGUARD_TOP, new Handler() { - @Override - public boolean handleDismissKeyguardActivity() { - final ActivityRecord top = mServiceDelegate.getTopNonFinishingActivity( - mDisplayId); - if (top != null && top.mDismissKeyguard) { - // Top activity has been launched with ActivityOptions#setDismissKeyguard. - // Authentication has already been passed, so we can turn off the keyguard - // immediately. - top.mDismissKeyguard = false; - setKeyguardState(KEYGUARD_STATE_GOING_AWAY); - // Collect the participates for shell transition, so that transition won't - // happen too early since the transition was set ready. - mServiceDelegate.collect(top); - return true; - } - return false; - } - - @Override - public void enter() { - mServiceDelegate.acquireSleepToken(mDisplayId, - true /* ensureActivitiesVisible */); - InputMethodManagerInternal.get().updateImeWindowStatus( - false /* disableImeIcon */); - mServiceDelegate.setWakeTransitionReady(); - } - - @Override - public void exit() { - // Sleep token is released in enter() action in other states, since we need - // to call requestTransition() before updating visibility of the activities. - } - }); - - mStateMachine.addStateHandler(KEYGUARD_STATE_LOCKSCREEN_SHOWN, new Handler() { - @Override - public Optional<Boolean> checkKeyguardVisibility(@NonNull ActivityRecord r) { - // If lock screen is showing, nothing is visible, except if we are able to - // dismiss Keyguard right away. This isn't allowed if r is already the - // dismissing activity, in which case we don't allow it to repeatedly - // dismiss Keyguard. - return Optional.of(r.containsDismissKeyguardWindow() - && mServiceDelegate.canDismissKeyguard() - && (mDismissalRequested - || (r.canShowWhenLocked() && mDismissingKeyguardActivity != r))); - } - - @Override - public boolean handleShowWhenLockedActivity() { - final ActivityRecord top = mServiceDelegate.getTopNonFinishingActivity( - mDisplayId); - final ActivityRecord topOccludesActivity = mServiceDelegate.canOcclude(top) - ? top : null; - if (topOccludesActivity != null) { - setKeyguardState(mServiceDelegate.isTopActivityDreaming(mDisplayId) - ? KEYGUARD_STATE_DREAMING : KEYGUARD_STATE_OCCLUDED); - } - return true; - } - }); - - mStateMachine.addStateHandler(KEYGUARD_STATE_AOD_SHOWN, new Handler() { - // Top activity which has FLAG_TURN_SCREEN_ON flag. - @Nullable private ActivityRecord mTopTurnScreenOnActivity; - - @Override - public Optional<Boolean> checkKeyguardVisibility(@NonNull ActivityRecord r) { - return Optional.of(false); - } - - @Override - boolean handleTurnScreenOnActivity() { - final ActivityRecord lastTopTurnScreenOnActivity = mTopTurnScreenOnActivity; - final ActivityRecord top = mServiceDelegate.getTopNonFinishingActivity( - mDisplayId); - mTopTurnScreenOnActivity = (top != null && top.getTurnScreenOnFlag() - && top.currentLaunchCanTurnScreenOn()) ? top : null; - if (mTopTurnScreenOnActivity != lastTopTurnScreenOnActivity - && mTopTurnScreenOnActivity != null - && !mServiceDelegate.isDeviceInteractive() - && mDismissalRequested) { - mServiceDelegate.wakeUp("AOD_SHOWN/handleTurnScreenOnActivity"); - mTopTurnScreenOnActivity.setCurrentLaunchCanTurnScreenOn(false); - } - return true; - } - - @Override - public void enter() { - if (mLastNotifiedOccludedState) { - if (mDisplayId == DEFAULT_DISPLAY) { - mServiceDelegate.forceSyncOccludedStatus(false); - } - commitOccludedStatus(false); - } - } - - @Override - public void exit() { - mServiceDelegate.updateDeferTransitionForAod(false /* waiting */); - } - - @Nullable - @Override - String handleDump(@NonNull String prefix) { - StringBuffer sb = new StringBuffer(); - sb.append(prefix) - .append(" mTopTurnScreenOnActivity=") - .append(mTopTurnScreenOnActivity) - .append("\n"); - return sb.toString(); - } - }); - } - - void onRemoved() { - mServiceDelegate.releaseSleepToken(mDisplayId, false /* resumeTopActivities */); - } - - void updateVisibility() { - mStateMachine.handleDismissKeyguardActivity(); - mStateMachine.handleTurnScreenOnActivity(); - mStateMachine.handleShowWhenLockedActivity(); - mStateMachine.handleLayoutChanges(); - } - - boolean dismissKeyguard(@NonNull ActivityRecord r, - @Nullable IKeyguardDismissCallback callback, - @Nullable CharSequence message) { - return mStateMachine.handleDismissKeyguard(r, callback, message); - } - - void commitOccludedStatus(boolean occluded) { - mLastNotifiedOccludedState = occluded; - } - - void setKeyguardState(@KeyguardState int newState) { - mDismissalRequested = false; - mStateMachine.transit(newState); - } - - boolean isKeyguardTop() { - return mStateMachine.isIn(KEYGUARD_STATE_KEYGUARD_TOP); - } + mShowingDream = display.getDisplayPolicy().isShowingDreamLw() && (top != null + && top.getActivityType() == ACTIVITY_TYPE_DREAM); + mOccluded = mShowingDream || occludedByActivity; + mRequestDismissKeyguard = lastDismissKeyguardActivity != mDismissingKeyguardActivity + && !mOccluded && !mKeyguardGoingAway + && mDismissingKeyguardActivity != null; + if (mOccluded && mKeyguardShowing && !display.isSleeping() && !top.fillsParent() + && display.mWallpaperController.getWallpaperTarget() == null) { + // The occluding activity may be translucent or not fill screen. Then let wallpaper + // to check whether it should set itself as target to avoid blank background. + display.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; + } - boolean isIn(@KeyguardState int category) { - return mStateMachine.isIn(category); - } + if (mTopTurnScreenOnActivity != lastTurnScreenOnActivity + && mTopTurnScreenOnActivity != null + && !mService.mWindowManager.mPowerManager.isInteractive() + && (mRequestDismissKeyguard || occludedByActivity)) { + controller.mTaskSupervisor.wakeUp("handleTurnScreenOn"); + mTopTurnScreenOnActivity.setCurrentLaunchCanTurnScreenOn(false); + } - boolean topActivityOccludesKeyguard(@NonNull ActivityRecord r) { - return mStateMachine.topActivityOccludesKeyguard(r); + boolean hasChange = false; + if (lastOccluded != mOccluded) { + controller.handleOccludedChanged(mDisplayId, mTopOccludesActivity); + hasChange = true; + } else if (!lastKeyguardGoingAway && mKeyguardGoingAway) { + controller.handleKeyguardGoingAwayChanged(display); + hasChange = true; + } + // Collect the participates for shell transition, so that transition won't happen too + // early since the transition was set ready. + if (hasChange && top != null && (mOccluded || mKeyguardGoingAway)) { + display.mTransitionController.collect(top); + } } - boolean checkKeyguardVisibility(@NonNull ActivityRecord r) { - return mStateMachine.checkKeyguardVisibility(r); + /** + * Gets the stack used to check the occluded state. + * <p> + * Only the top non-pinned activity of the focusable stack on each display can control its + * occlusion state. + */ + @Nullable + private Task getRootTaskForControllingOccluding(DisplayContent display) { + return display.getRootTask(task -> + task != null && task.isFocusableAndVisible() && !task.inPinnedWindowingMode()); + } + + void dumpStatus(PrintWriter pw, String prefix) { + final StringBuilder sb = new StringBuilder(); + sb.append(prefix); + sb.append(" KeyguardShowing=") + .append(mKeyguardShowing) + .append(" AodShowing=") + .append(mAodShowing) + .append(" KeyguardGoingAway=") + .append(mKeyguardGoingAway) + .append(" DismissalRequested=") + .append(mDismissalRequested) + .append(" Occluded=") + .append(mOccluded) + .append(" DismissingKeyguardActivity=") + .append(mDismissingKeyguardActivity) + .append(" TurnScreenOnActivity=") + .append(mTopTurnScreenOnActivity) + .append(" at display=") + .append(mDisplayId); + pw.println(sb.toString()); } void dumpDebug(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); proto.write(KeyguardPerDisplayProto.DISPLAY_ID, mDisplayId); - proto.write(KeyguardPerDisplayProto.KEYGUARD_SHOWING, - isIn(KEYGUARD_STATE_LOCKSCREEN_SHOWN)); - proto.write(KeyguardPerDisplayProto.AOD_SHOWING, isIn(KEYGUARD_STATE_AOD_SHOWN)); - proto.write(KeyguardPerDisplayProto.KEYGUARD_OCCLUDED, isIn(KEYGUARD_STATE_OCCLUDED)); + proto.write(KeyguardPerDisplayProto.KEYGUARD_SHOWING, mKeyguardShowing); + proto.write(KeyguardPerDisplayProto.AOD_SHOWING, mAodShowing); + proto.write(KeyguardPerDisplayProto.KEYGUARD_OCCLUDED, mOccluded); + proto.write(KeyguardPerDisplayProto.KEYGUARD_GOING_AWAY, mKeyguardGoingAway); proto.end(token); } + } - void dump(PrintWriter pw, String prefix) { - StringBuffer sb = new StringBuffer(); - sb.append(prefix) - .append("* display=") - .append(mDisplayId) - .append("\n"); - sb.append(prefix) - .append(" state=") - .append(keyguardStateToString(mStateMachine.getState())) - .append("\n"); - sb.append(prefix) - .append(" mLastNotifiedOccludedState=") - .append(mLastNotifiedOccludedState) - .append("\n"); - sb.append(prefix) - .append(" mDismissalRequested=") - .append(mDismissalRequested) - .append("\n"); - pw.print(sb.toString()); + void dump(PrintWriter pw, String prefix) { + final KeyguardDisplayState default_state = getDisplayState(DEFAULT_DISPLAY); + pw.println(prefix + "KeyguardController:"); + pw.println(prefix + " mKeyguardShowing=" + default_state.mKeyguardShowing); + pw.println(prefix + " mAodShowing=" + default_state.mAodShowing); + pw.println(prefix + " mKeyguardGoingAway=" + default_state.mKeyguardGoingAway); + dumpDisplayStates(pw, prefix); + pw.println(prefix + " mDismissalRequested=" + default_state.mDismissalRequested); + pw.println(); + } - ArrayList<String> dumpInfo = mStateMachine.handleDump(prefix); - for (int i = dumpInfo.size() - 1; i >= 0; --i) { - pw.print(dumpInfo.get(i)); - } + void dumpDebug(ProtoOutputStream proto, long fieldId) { + final KeyguardDisplayState default_state = getDisplayState(DEFAULT_DISPLAY); + final long token = proto.start(fieldId); + proto.write(AOD_SHOWING, default_state.mAodShowing); + proto.write(KEYGUARD_SHOWING, default_state.mKeyguardShowing); + proto.write(KEYGUARD_GOING_AWAY, default_state.mKeyguardGoingAway); + writeDisplayStatesToProto(proto, KEYGUARD_PER_DISPLAY); + proto.end(token); + } + + private void dumpDisplayStates(PrintWriter pw, String prefix) { + for (int i = 0; i < mDisplayStates.size(); i++) { + mDisplayStates.valueAt(i).dumpStatus(pw, prefix); + } + } + + private void writeDisplayStatesToProto(ProtoOutputStream proto, long fieldId) { + for (int i = 0; i < mDisplayStates.size(); i++) { + mDisplayStates.valueAt(i).dumpDebug(proto, fieldId); } } } diff --git a/services/core/java/com/android/server/wm/SurfaceSyncGroupController.java b/services/core/java/com/android/server/wm/SurfaceSyncGroupController.java index 75691caad246..1711845247f9 100644 --- a/services/core/java/com/android/server/wm/SurfaceSyncGroupController.java +++ b/services/core/java/com/android/server/wm/SurfaceSyncGroupController.java @@ -63,7 +63,7 @@ class SurfaceSyncGroupController { if (callback == null) { return false; } - outAddToSyncGroupResult.mParentSyncGroup = root; + outAddToSyncGroupResult.mParentSyncGroup = root.mISurfaceSyncGroup; outAddToSyncGroupResult.mTransactionReadyCallback = callback; 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 80965a78bc9b..5e116baa3fae 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -730,7 +730,7 @@ class TransitionController { void dispatchLegacyAppTransitionStarting(TransitionInfo info, long statusBarTransitionDelay) { for (int i = 0; i < mLegacyListeners.size(); ++i) { - mLegacyListeners.get(i).onAppTransitionStartingLocked(info); + // TODO(shell-transitions): handle (un)occlude transition. mLegacyListeners.get(i).onAppTransitionStartingLocked( SystemClock.uptimeMillis() + statusBarTransitionDelay, AnimationAdapter.STATUS_BAR_TRANSITION_DURATION); diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index ad6bd3c6ccf6..1282acbc9e5a 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -44,7 +44,6 @@ import android.view.SurfaceControlViewHost; import android.view.WindowInfo; import android.view.WindowManager.DisplayImePolicy; import android.view.inputmethod.ImeTracker; -import android.window.TransitionInfo; import com.android.internal.policy.KeyInterceptionInfo; import com.android.server.input.InputManagerService; @@ -213,7 +212,7 @@ public abstract class WindowManagerInternal { * Abstract class to be notified about {@link com.android.server.wm.AppTransition} events. Held * as an abstract class so a listener only needs to implement the methods of its interest. */ - public abstract static class AppTransitionListener { + public static abstract class AppTransitionListener { /** * Called when an app transition is being setup and about to be executed. @@ -252,20 +251,6 @@ public abstract class WindowManagerInternal { } /** - * Called when an app transition gets started when WM shell is enabled. - * - * @param info Information about what is changing during a transition. - * - * @return Return any bit set of {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_LAYOUT}, - * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_CONFIG}, - * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_WALLPAPER}, - * or {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_ANIM}. - */ - public int onAppTransitionStartingLocked(TransitionInfo info) { - return 0; - } - - /** * Called when an app transition is finished running. * * @param token the token for app whose transition has finished diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f6cb06866cf3..a596eed2a500 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -3132,7 +3132,7 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void notifyKeyguardTrustedChanged() { synchronized (mGlobalLock) { - if (mAtmService.mKeyguardController.isLocksScreenShowing(DEFAULT_DISPLAY)) { + if (mAtmService.mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) { mRoot.ensureActivitiesVisible(null, 0, false /* preserveWindows */); } } diff --git a/services/core/java/com/android/server/wm/WindowOrientationListener.java b/services/core/java/com/android/server/wm/WindowOrientationListener.java index 3e165e442d79..14c816db0dbb 100644 --- a/services/core/java/com/android/server/wm/WindowOrientationListener.java +++ b/services/core/java/com/android/server/wm/WindowOrientationListener.java @@ -88,14 +88,19 @@ public abstract class WindowOrientationListener { private final Object mLock = new Object(); + @Surface.Rotation + private final int mDefaultRotation; + /** * Creates a new WindowOrientationListener. * * @param context for the WindowOrientationListener. * @param handler Provides the Looper for receiving sensor updates. + * @param defaultRotation Default rotation of the display. */ - public WindowOrientationListener(Context context, Handler handler) { - this(context, handler, SensorManager.SENSOR_DELAY_UI); + public WindowOrientationListener(Context context, Handler handler, + @Surface.Rotation int defaultRotation) { + this(context, handler, defaultRotation, SensorManager.SENSOR_DELAY_UI); } /** @@ -103,7 +108,7 @@ public abstract class WindowOrientationListener { * * @param context for the WindowOrientationListener. * @param handler Provides the Looper for receiving sensor updates. - * @param wmService WindowManagerService to read the device config from. + * @param defaultRotation Default rotation of the display. * @param rate at which sensor events are processed (see also * {@link android.hardware.SensorManager SensorManager}). Use the default * value of {@link android.hardware.SensorManager#SENSOR_DELAY_NORMAL @@ -111,10 +116,11 @@ public abstract class WindowOrientationListener { * * This constructor is private since no one uses it. */ - private WindowOrientationListener( - Context context, Handler handler, int rate) { + private WindowOrientationListener(Context context, Handler handler, + @Surface.Rotation int defaultRotation, int rate) { mContext = context; mHandler = handler; + mDefaultRotation = defaultRotation; mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); mRate = rate; List<Sensor> l = mSensorManager.getSensorList(Sensor.TYPE_DEVICE_ORIENTATION); @@ -1159,7 +1165,7 @@ public abstract class WindowOrientationListener { "Reusing the last rotation resolution: " + mLastRotationResolution); finalizeRotation(mLastRotationResolution); } else { - finalizeRotation(Surface.ROTATION_0); + finalizeRotation(mDefaultRotation); } return; } diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 7c737680e226..f4d1d1ef88d1 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -292,6 +292,10 @@ public: void setPointerDisplayId(int32_t displayId); void setPointerSpeed(int32_t speed); void setPointerAcceleration(float acceleration); + void setTouchpadPointerSpeed(int32_t speed); + void setTouchpadNaturalScrollingEnabled(bool enabled); + void setTouchpadTapToClickEnabled(bool enabled); + void setTouchpadRightClickZoneEnabled(bool enabled); void setInputDeviceEnabled(uint32_t deviceId, bool enabled); void setShowTouches(bool enabled); void setInteractive(bool interactive); @@ -409,6 +413,20 @@ private: // True if stylus button reporting through motion events is enabled. bool stylusButtonMotionEventsEnabled{true}; + + // The touchpad pointer speed, as a number from -7 (slowest) to 7 (fastest). + int32_t touchpadPointerSpeed{0}; + + // True to invert the touchpad scrolling direction, so that moving two fingers downwards on + // the touchpad scrolls the content upwards. + bool touchpadNaturalScrollingEnabled{true}; + + // True to enable tap-to-click on touchpads. + bool touchpadTapToClickEnabled{true}; + + // True to enable a zone on the right-hand side of touchpads where clicks will be turned + // into context (a.k.a. "right") clicks. + bool touchpadRightClickZoneEnabled{false}; } mLocked GUARDED_BY(mLock); std::atomic<bool> mInteractive; @@ -657,6 +675,11 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon outConfig->defaultPointerDisplayId = mLocked.pointerDisplayId; + outConfig->touchpadPointerSpeed = mLocked.touchpadPointerSpeed; + outConfig->touchpadNaturalScrollingEnabled = mLocked.touchpadNaturalScrollingEnabled; + outConfig->touchpadTapToClickEnabled = mLocked.touchpadTapToClickEnabled; + outConfig->touchpadRightClickZoneEnabled = mLocked.touchpadRightClickZoneEnabled; + outConfig->disabledDevices = mLocked.disabledInputDevices; outConfig->stylusButtonMotionEventsEnabled = mLocked.stylusButtonMotionEventsEnabled; @@ -1099,6 +1122,70 @@ void NativeInputManager::setPointerAcceleration(float acceleration) { InputReaderConfiguration::CHANGE_POINTER_SPEED); } +void NativeInputManager::setTouchpadPointerSpeed(int32_t speed) { + { // acquire lock + AutoMutex _l(mLock); + + if (mLocked.touchpadPointerSpeed == speed) { + return; + } + + ALOGI("Setting touchpad pointer speed to %d.", speed); + mLocked.touchpadPointerSpeed = speed; + } // release lock + + mInputManager->getReader().requestRefreshConfiguration( + InputReaderConfiguration::CHANGE_TOUCHPAD_SETTINGS); +} + +void NativeInputManager::setTouchpadNaturalScrollingEnabled(bool enabled) { + { // acquire lock + AutoMutex _l(mLock); + + if (mLocked.touchpadNaturalScrollingEnabled == enabled) { + return; + } + + ALOGI("Setting touchpad natural scrolling to %s.", toString(enabled)); + mLocked.touchpadNaturalScrollingEnabled = enabled; + } // release lock + + mInputManager->getReader().requestRefreshConfiguration( + InputReaderConfiguration::CHANGE_TOUCHPAD_SETTINGS); +} + +void NativeInputManager::setTouchpadTapToClickEnabled(bool enabled) { + { // acquire lock + AutoMutex _l(mLock); + + if (mLocked.touchpadTapToClickEnabled == enabled) { + return; + } + + ALOGI("Setting touchpad tap to click to %s.", toString(enabled)); + mLocked.touchpadTapToClickEnabled = enabled; + } // release lock + + mInputManager->getReader().requestRefreshConfiguration( + InputReaderConfiguration::CHANGE_TOUCHPAD_SETTINGS); +} + +void NativeInputManager::setTouchpadRightClickZoneEnabled(bool enabled) { + { // acquire lock + AutoMutex _l(mLock); + + if (mLocked.touchpadRightClickZoneEnabled == enabled) { + return; + } + + ALOGI("Setting touchpad right click zone to %s.", toString(enabled)); + mLocked.touchpadRightClickZoneEnabled = enabled; + } // release lock + + mInputManager->getReader().requestRefreshConfiguration( + InputReaderConfiguration::CHANGE_TOUCHPAD_SETTINGS); +} + void NativeInputManager::setInputDeviceEnabled(uint32_t deviceId, bool enabled) { { // acquire lock AutoMutex _l(mLock); @@ -1944,6 +2031,33 @@ static void nativeSetPointerAcceleration(JNIEnv* env, jobject nativeImplObj, jfl im->setPointerAcceleration(acceleration); } +static void nativeSetTouchpadPointerSpeed(JNIEnv* env, jobject nativeImplObj, jint speed) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); + + im->setTouchpadPointerSpeed(speed); +} + +static void nativeSetTouchpadNaturalScrollingEnabled(JNIEnv* env, jobject nativeImplObj, + jboolean enabled) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); + + im->setTouchpadNaturalScrollingEnabled(enabled); +} + +static void nativeSetTouchpadTapToClickEnabled(JNIEnv* env, jobject nativeImplObj, + jboolean enabled) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); + + im->setTouchpadTapToClickEnabled(enabled); +} + +static void nativeSetTouchpadRightClickZoneEnabled(JNIEnv* env, jobject nativeImplObj, + jboolean enabled) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); + + im->setTouchpadRightClickZoneEnabled(enabled); +} + static void nativeSetShowTouches(JNIEnv* env, jobject nativeImplObj, jboolean enabled) { NativeInputManager* im = getNativeInputManager(env, nativeImplObj); @@ -2463,6 +2577,11 @@ static const JNINativeMethod gInputManagerMethods[] = { {"transferTouch", "(Landroid/os/IBinder;I)Z", (void*)nativeTransferTouch}, {"setPointerSpeed", "(I)V", (void*)nativeSetPointerSpeed}, {"setPointerAcceleration", "(F)V", (void*)nativeSetPointerAcceleration}, + {"setTouchpadPointerSpeed", "(I)V", (void*)nativeSetTouchpadPointerSpeed}, + {"setTouchpadNaturalScrollingEnabled", "(Z)V", + (void*)nativeSetTouchpadNaturalScrollingEnabled}, + {"setTouchpadTapToClickEnabled", "(Z)V", (void*)nativeSetTouchpadTapToClickEnabled}, + {"setTouchpadRightClickZoneEnabled", "(Z)V", (void*)nativeSetTouchpadRightClickZoneEnabled}, {"setShowTouches", "(Z)V", (void*)nativeSetShowTouches}, {"setInteractive", "(Z)V", (void*)nativeSetInteractive}, {"reloadCalibration", "()V", (void*)nativeReloadCalibration}, diff --git a/services/core/jni/gnss/GnssCallback.cpp b/services/core/jni/gnss/GnssCallback.cpp index 3c1ac1e4144e..60eed8e6d716 100644 --- a/services/core/jni/gnss/GnssCallback.cpp +++ b/services/core/jni/gnss/GnssCallback.cpp @@ -95,7 +95,7 @@ void Gnss_class_init_once(JNIEnv* env, jclass& clazz) { method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F[F)V"); method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); - method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V"); + method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(IZ)V"); method_setSignalTypeCapabilities = env->GetMethodID(clazz, "setSignalTypeCapabilities", "(Ljava/util/List;)V"); method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V"); @@ -120,8 +120,10 @@ void Gnss_class_init_once(JNIEnv* env, jclass& clazz) { Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) { ALOGD("%s: %du\n", __func__, capabilities); + bool isAdrCapabilityKnown = (getInterfaceVersion() >= 3) ? true : false; JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities); + env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities, + isAdrCapabilityKnown); checkAndClearExceptionFromCallback(env, __FUNCTION__); return Status::ok(); } @@ -409,7 +411,8 @@ Return<void> GnssCallbackHidl::gnssSetCapabilitesCb(uint32_t capabilities) { ALOGD("%s: %du\n", __func__, capabilities); JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities); + env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities, + /* isAdrCapabilityKnown= */ false); checkAndClearExceptionFromCallback(env, __FUNCTION__); return Void(); } diff --git a/services/core/jni/gnss/GnssMeasurementCallback.cpp b/services/core/jni/gnss/GnssMeasurementCallback.cpp index a1c570812682..2982546bfa47 100644 --- a/services/core/jni/gnss/GnssMeasurementCallback.cpp +++ b/services/core/jni/gnss/GnssMeasurementCallback.cpp @@ -58,7 +58,7 @@ jmethodID method_gnssAgcBuilderSetCarrierFrequencyHz; jmethodID method_gnssAgcBuilderBuild; jmethodID method_gnssMeasurementsEventBuilderCtor; jmethodID method_gnssMeasurementsEventBuilderSetClock; -jmethodID method_gnssMeasurementsEventBuilderSetFullTracking; +jmethodID method_gnssMeasurementsEventBuilderSetIsFullTracking; jmethodID method_gnssMeasurementsEventBuilderSetMeasurements; jmethodID method_gnssMeasurementsEventBuilderSetGnssAutomaticGainControls; jmethodID method_gnssMeasurementsEventBuilderBuild; @@ -110,8 +110,8 @@ void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz) { env->GetMethodID(class_gnssMeasurementsEventBuilder, "setGnssAutomaticGainControls", "([Landroid/location/GnssAutomaticGainControl;)" "Landroid/location/GnssMeasurementsEvent$Builder;"); - method_gnssMeasurementsEventBuilderSetFullTracking = - env->GetMethodID(class_gnssMeasurementsEventBuilder, "setFullTracking", + method_gnssMeasurementsEventBuilderSetIsFullTracking = + env->GetMethodID(class_gnssMeasurementsEventBuilder, "setIsFullTracking", "(Z)" "Landroid/location/GnssMeasurementsEvent$Builder;"); method_gnssMeasurementsEventBuilderBuild = @@ -234,7 +234,7 @@ void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz) { void setMeasurementData(JNIEnv* env, jobject& callbacksObj, jobject clock, jobjectArray measurementArray, jobjectArray gnssAgcArray, - bool hasFullTracking, jboolean isFullTracking) { + bool hasIsFullTracking, jboolean isFullTracking) { jobject gnssMeasurementsEventBuilderObject = env->NewObject(class_gnssMeasurementsEventBuilder, method_gnssMeasurementsEventBuilderCtor); @@ -246,9 +246,9 @@ void setMeasurementData(JNIEnv* env, jobject& callbacksObj, jobject clock, callObjectMethodIgnoringResult(env, gnssMeasurementsEventBuilderObject, method_gnssMeasurementsEventBuilderSetGnssAutomaticGainControls, gnssAgcArray); - if (hasFullTracking) { + if (hasIsFullTracking) { callObjectMethodIgnoringResult(env, gnssMeasurementsEventBuilderObject, - method_gnssMeasurementsEventBuilderSetFullTracking, + method_gnssMeasurementsEventBuilderSetIsFullTracking, isFullTracking); } jobject gnssMeasurementsEventObject = @@ -394,10 +394,10 @@ void GnssMeasurementCallbackAidl::translateAndSetGnssData(const GnssData& data) gnssAgcArray = translateAllGnssAgcs(env, data.gnssAgcs); if (this->getInterfaceVersion() >= 3) { setMeasurementData(env, mCallbacksObj, clock, measurementArray, gnssAgcArray, - /*hasFullTracking=*/true, data.isFullTracking); + /*hasIsFullTracking=*/true, data.isFullTracking); } else { setMeasurementData(env, mCallbacksObj, clock, measurementArray, gnssAgcArray, - /*hasFullTracking=*/false, + /*hasIsFullTracking=*/false, /*isFullTracking=*/JNI_FALSE); } diff --git a/services/core/jni/gnss/GnssMeasurementCallback.h b/services/core/jni/gnss/GnssMeasurementCallback.h index fde56881d854..b3de486e6fa9 100644 --- a/services/core/jni/gnss/GnssMeasurementCallback.h +++ b/services/core/jni/gnss/GnssMeasurementCallback.h @@ -49,7 +49,7 @@ void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz); void setMeasurementData(JNIEnv* env, jobject& callbacksObj, jobject clock, jobjectArray measurementArray, jobjectArray gnssAgcArray, - bool hasFullTracking, jboolean isFullTracking); + bool hasIsFullTracking, jboolean isFullTracking); class GnssMeasurementCallbackAidl : public hardware::gnss::BnGnssMeasurementCallback { public: @@ -142,7 +142,7 @@ void GnssMeasurementCallbackHidl::translateAndSetGnssData(const T& data) { jobjectArray measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count); setMeasurementData(env, mCallbacksObj, clock, measurementArray, /*gnssAgcArray=*/nullptr, - /*hasFullTracking=*/false, + /*hasIsFullTracking=*/false, /*isFullTracking=*/JNI_FALSE); env->DeleteLocalRef(clock); diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp index f915298ae84a..101498aef183 100644 --- a/services/tests/mockingservicestests/Android.bp +++ b/services/tests/mockingservicestests/Android.bp @@ -92,7 +92,10 @@ android_test { certificate: "platform", platform_apis: true, - test_suites: ["device-tests"], + test_suites: [ + "device-tests", + "automotive-tests", + ], optimize: { enabled: false, diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java index 57c5a6efa099..ef470fe14f4b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -208,6 +208,7 @@ public class AlarmManagerServiceTest { private static final String TAG = AlarmManagerServiceTest.class.getSimpleName(); private static final int SYSTEM_UI_UID = 12345; private static final int TEST_CALLING_USER = UserHandle.getUserId(TEST_CALLING_UID); + private static final int TEST_CALLING_UID_2 = TEST_CALLING_UID + 1; private long mAppStandbyWindow; private long mAllowWhileIdleWindow; @@ -3412,10 +3413,40 @@ public class AlarmManagerServiceTest { final int type = ((i & 1) == 0) ? ELAPSED_REALTIME : ELAPSED_REALTIME_WAKEUP; setTestAlarm(type, mNowElapsedTest + i, getNewMockPendingIntent()); } + for (int i = 0; i < 4; i++) { + final int type = ((i & 1) == 0) ? ELAPSED_REALTIME : ELAPSED_REALTIME_WAKEUP; + setTestAlarm( + type, + mNowElapsedTest + i, + getNewMockPendingIntent(), + 0, + FLAG_STANDALONE, + TEST_CALLING_UID_2); + } mNowElapsedTest += 100; mTestTimer.expire(); - verify(() -> MetricsHelper.pushAlarmBatchDelivered(10, 5)); + final ArgumentCaptor<int[]> uidsCaptor = ArgumentCaptor.forClass(int[].class); + final ArgumentCaptor<int[]> alarmsPerUidCaptor = ArgumentCaptor.forClass(int[].class); + final ArgumentCaptor<int[]> wakeupAlarmsPerUidCaptor = ArgumentCaptor.forClass(int[].class); + + verify(() -> MetricsHelper.pushAlarmBatchDelivered( + eq(14), + eq(7), + uidsCaptor.capture(), + alarmsPerUidCaptor.capture(), + wakeupAlarmsPerUidCaptor.capture())); + assertEquals(2, uidsCaptor.getValue().length); + assertEquals(2, alarmsPerUidCaptor.getValue().length); + assertEquals(2, wakeupAlarmsPerUidCaptor.getValue().length); + final int uid1Idx = uidsCaptor.getValue()[0] == TEST_CALLING_UID ? 0 : 1; + final int uid2Idx = 1 - uid1Idx; + assertEquals(TEST_CALLING_UID, uidsCaptor.getValue()[uid1Idx]); + assertEquals(TEST_CALLING_UID_2, uidsCaptor.getValue()[uid2Idx]); + assertEquals(10, alarmsPerUidCaptor.getValue()[uid1Idx]); + assertEquals(5, wakeupAlarmsPerUidCaptor.getValue()[uid1Idx]); + assertEquals(4, alarmsPerUidCaptor.getValue()[uid2Idx]); + assertEquals(2, wakeupAlarmsPerUidCaptor.getValue()[uid2Idx]); } @Test diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java index 7281fafc93f2..ed78e720df73 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java @@ -30,7 +30,9 @@ import static com.android.server.job.JobSchedulerService.RARE_INDEX; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -95,6 +97,8 @@ public class JobSchedulerServiceTest { private ActivityManagerInternal mActivityMangerInternal; @Mock private Context mContext; + @Mock + private PackageManagerInternal mPackageManagerInternal; private class TestJobSchedulerService extends JobSchedulerService { TestJobSchedulerService(Context context) { @@ -121,6 +125,8 @@ public class JobSchedulerServiceTest { .when(() -> LocalServices.getService(AppStandbyInternal.class)); doReturn(mock(BatteryManagerInternal.class)) .when(() -> LocalServices.getService(BatteryManagerInternal.class)); + doReturn(mPackageManagerInternal) + .when(() -> LocalServices.getService(PackageManagerInternal.class)); doReturn(mock(UsageStatsManagerInternal.class)) .when(() -> LocalServices.getService(UsageStatsManagerInternal.class)); when(mContext.getString(anyInt())).thenReturn("some_test_string"); @@ -138,9 +144,6 @@ public class JobSchedulerServiceTest { // Used in JobConcurrencyManager. doReturn(mock(UserManagerInternal.class)) .when(() -> LocalServices.getService(UserManagerInternal.class)); - // Used in JobStatus. - doReturn(mock(PackageManagerInternal.class)) - .when(() -> LocalServices.getService(PackageManagerInternal.class)); // Called via IdleController constructor. when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class)); when(mContext.getResources()).thenReturn(mock(Resources.class)); @@ -197,8 +200,13 @@ public class JobSchedulerServiceTest { private JobStatus createJobStatus(String testTag, JobInfo.Builder jobInfoBuilder, int callingUid) { + return createJobStatus(testTag, jobInfoBuilder, callingUid, "com.android.test"); + } + + private JobStatus createJobStatus(String testTag, JobInfo.Builder jobInfoBuilder, + int callingUid, String sourcePkg) { return JobStatus.createFromJobInfo( - jobInfoBuilder.build(), callingUid, "com.android.test", 0, "JSSTest", testTag); + jobInfoBuilder.build(), callingUid, sourcePkg, 0, "JSSTest", testTag); } private void grantRunLongJobsPermission(boolean grant) { @@ -1238,4 +1246,57 @@ public class JobSchedulerServiceTest { 0, "JSSTest", "")); } } + + /** Tests that jobs are removed from the pending list if the user stops the app. */ + @Test + public void testUserStopRemovesPending() { + spyOn(mService); + + JobStatus job1a = createJobStatus("testUserStopRemovesPending", + createJobInfo(1), 1, "pkg1"); + JobStatus job1b = createJobStatus("testUserStopRemovesPending", + createJobInfo(2), 1, "pkg1"); + JobStatus job2a = createJobStatus("testUserStopRemovesPending", + createJobInfo(1), 2, "pkg2"); + JobStatus job2b = createJobStatus("testUserStopRemovesPending", + createJobInfo(2), 2, "pkg2"); + doReturn(1).when(mPackageManagerInternal).getPackageUid("pkg1", 0, 0); + doReturn(11).when(mPackageManagerInternal).getPackageUid("pkg1", 0, 1); + doReturn(2).when(mPackageManagerInternal).getPackageUid("pkg2", 0, 0); + + mService.getPendingJobQueue().clear(); + mService.getPendingJobQueue().add(job1a); + mService.getPendingJobQueue().add(job1b); + mService.getPendingJobQueue().add(job2a); + mService.getPendingJobQueue().add(job2b); + mService.getJobStore().add(job1a); + mService.getJobStore().add(job1b); + mService.getJobStore().add(job2a); + mService.getJobStore().add(job2b); + + mService.stopUserVisibleJobsInternal("pkg1", 1); + assertEquals(4, mService.getPendingJobQueue().size()); + assertTrue(mService.getPendingJobQueue().contains(job1a)); + assertTrue(mService.getPendingJobQueue().contains(job1b)); + assertTrue(mService.getPendingJobQueue().contains(job2a)); + assertTrue(mService.getPendingJobQueue().contains(job2b)); + + mService.stopUserVisibleJobsInternal("pkg1", 0); + assertEquals(2, mService.getPendingJobQueue().size()); + assertFalse(mService.getPendingJobQueue().contains(job1a)); + assertEquals(JobScheduler.PENDING_JOB_REASON_USER, mService.getPendingJobReason(job1a)); + assertFalse(mService.getPendingJobQueue().contains(job1b)); + assertEquals(JobScheduler.PENDING_JOB_REASON_USER, mService.getPendingJobReason(job1b)); + assertTrue(mService.getPendingJobQueue().contains(job2a)); + assertTrue(mService.getPendingJobQueue().contains(job2b)); + + mService.stopUserVisibleJobsInternal("pkg2", 0); + assertEquals(0, mService.getPendingJobQueue().size()); + assertFalse(mService.getPendingJobQueue().contains(job1a)); + assertFalse(mService.getPendingJobQueue().contains(job1b)); + assertFalse(mService.getPendingJobQueue().contains(job2a)); + assertEquals(JobScheduler.PENDING_JOB_REASON_USER, mService.getPendingJobReason(job2a)); + assertFalse(mService.getPendingJobQueue().contains(job2b)); + assertEquals(JobScheduler.PENDING_JOB_REASON_USER, mService.getPendingJobReason(job2b)); + } } diff --git a/services/tests/mockingservicestests/src/com/android/server/power/OWNERS b/services/tests/mockingservicestests/src/com/android/server/power/OWNERS index d68066bb8c40..fb62520ff57b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/power/OWNERS +++ b/services/tests/mockingservicestests/src/com/android/server/power/OWNERS @@ -1 +1,3 @@ include /services/core/java/com/android/server/power/OWNERS + +per-file ThermalManagerServiceMockingTest.java=wvw@google.com,xwxw@google.com diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java index de54537bbabe..9b48114fafec 100644 --- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java @@ -201,7 +201,7 @@ public class WallpaperManagerServiceTests { public void setUp() { MockitoAnnotations.initMocks(this); - ExtendedMockito.doAnswer(invocation -> { + ExtendedMockito.doAnswer(invocation -> { int userId = (invocation.getArgument(0)); return getWallpaperTestDir(userId); }).when(() -> WallpaperUtils.getWallpaperDir(anyInt())); @@ -315,7 +315,8 @@ public class WallpaperManagerServiceTests { spyOn(mService.mWallpaperDisplayHelper); doReturn(true).when(mService.mWallpaperDisplayHelper) - .isUsableDisplay(any(Display.class), mService.mLastWallpaper.connection.mClientUid); + .isUsableDisplay(any(Display.class), + eq(mService.mLastWallpaper.connection.mClientUid)); mService.mLastWallpaper.connection.attachEngine(mock(IWallpaperEngine.class), DEFAULT_DISPLAY); diff --git a/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java b/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java index 8cbed2c7ffb8..4412cfe4a3b5 100644 --- a/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java +++ b/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java @@ -305,4 +305,60 @@ public class OomAdjusterTests { assertEquals("Interaction event time was not updated correctly.", interactionEventTime, mProcessRecord.mState.getInteractionEventTime()); } + + private void updateShortFgsOwner(int uid, int pid, boolean add) { + sService.mOomAdjuster.updateShortFgsOwner(uid, pid, add); + } + + private void assertHasUidShortForegroundService(int uid, boolean expected) { + assertEquals(expected, sService.mOomAdjuster.hasUidShortForegroundService(uid)); + } + + @Test + public void testHasUidShortForegroundService() { + assertHasUidShortForegroundService(1, false); + assertHasUidShortForegroundService(2, false); + assertHasUidShortForegroundService(3, false); + assertHasUidShortForegroundService(100, false); + assertHasUidShortForegroundService(101, false); + + updateShortFgsOwner(1, 100, true); + assertHasUidShortForegroundService(1, true); + assertHasUidShortForegroundService(100, false); + assertHasUidShortForegroundService(2, false); + + updateShortFgsOwner(1, 101, true); + assertHasUidShortForegroundService(1, true); + assertHasUidShortForegroundService(101, false); + assertHasUidShortForegroundService(2, false); + + updateShortFgsOwner(2, 200, true); + assertHasUidShortForegroundService(1, true); + assertHasUidShortForegroundService(2, true); + assertHasUidShortForegroundService(200, false); + + updateShortFgsOwner(1, 101, false); + assertHasUidShortForegroundService(1, true); + assertHasUidShortForegroundService(2, true); + + updateShortFgsOwner(1, 99, false); // unused PID + assertHasUidShortForegroundService(1, true); + assertHasUidShortForegroundService(2, true); + + updateShortFgsOwner(1, 100, false); + assertHasUidShortForegroundService(1, false); + assertHasUidShortForegroundService(2, true); + + updateShortFgsOwner(1, 100, true); + assertHasUidShortForegroundService(1, true); + assertHasUidShortForegroundService(2, true); + + updateShortFgsOwner(2, 200, false); + assertHasUidShortForegroundService(1, true); + assertHasUidShortForegroundService(2, false); + + updateShortFgsOwner(2, 201, true); + assertHasUidShortForegroundService(1, true); + assertHasUidShortForegroundService(2, true); + } } diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java index 69a0b870ee8f..3a3a5078aac7 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java @@ -298,6 +298,18 @@ public class DisplayModeDirectorTest { assertThat(desiredSpecs.primary.physical.min).isWithin(FLOAT_TOLERANCE).of(60); assertThat(desiredSpecs.primary.physical.max).isWithin(FLOAT_TOLERANCE).of(60); assertThat(desiredSpecs.baseModeId).isEqualTo(60); + + votes.clear(); + votes.put(Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE, + Vote.forRenderFrameRates(0, 60 - error)); + votes.put(Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE, + Vote.forRenderFrameRates(60 + error, Float.POSITIVE_INFINITY)); + director.injectVotesByDisplay(votesByDisplay); + desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID); + + assertThat(desiredSpecs.primary.render.min).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.primary.render.max).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.baseModeId).isEqualTo(60); } @Test diff --git a/services/tests/servicestests/src/com/android/server/dreams/DreamOverlayServiceTest.java b/services/tests/servicestests/src/com/android/server/dreams/DreamOverlayServiceTest.java new file mode 100644 index 000000000000..6c73f716493c --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/dreams/DreamOverlayServiceTest.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.dreams; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import android.content.ComponentName; +import android.content.Intent; +import android.os.IBinder; +import android.os.RemoteException; +import android.service.dreams.DreamOverlayService; +import android.service.dreams.IDreamOverlay; +import android.service.dreams.IDreamOverlayCallback; +import android.service.dreams.IDreamOverlayClient; +import android.service.dreams.IDreamOverlayClientCallback; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +/** + * A collection of tests to exercise {@link DreamOverlayService}. + */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class DreamOverlayServiceTest { + private static final ComponentName FIRST_DREAM_COMPONENT = + ComponentName.unflattenFromString("com.foo.bar/.DreamService"); + private static final ComponentName SECOND_DREAM_COMPONENT = + ComponentName.unflattenFromString("com.foo.baz/.DreamService"); + + @Mock + WindowManager.LayoutParams mLayoutParams; + + @Mock + IDreamOverlayCallback mOverlayCallback; + + /** + * {@link TestDreamOverlayService} is a simple {@link DreamOverlayService} implementation for + * tracking interactions across {@link IDreamOverlay} binder interface. The service reports + * interactions to a {@link Monitor} instance provided at construction. + */ + private static class TestDreamOverlayService extends DreamOverlayService { + /** + * An interface implemented to be informed when the corresponding methods in + * {@link TestDreamOverlayService} are invoked. + */ + interface Monitor { + void onStartDream(); + void onEndDream(); + void onWakeUp(); + } + + private final Monitor mMonitor; + + TestDreamOverlayService(Monitor monitor) { + super(); + mMonitor = monitor; + } + + @Override + public void onStartDream(@NonNull WindowManager.LayoutParams layoutParams) { + mMonitor.onStartDream(); + } + + @Override + public void onEndDream() { + mMonitor.onEndDream(); + super.onEndDream(); + } + + @Override + public void onWakeUp(@NonNull Runnable onCompleteCallback) { + mMonitor.onWakeUp(); + super.onWakeUp(onCompleteCallback); + } + } + + /** + * A {@link IDreamOverlayClientCallback} implementation that captures the requested client. + */ + private static class OverlayClientCallback extends IDreamOverlayClientCallback.Stub { + public IDreamOverlayClient retrievedClient; + @Override + public void onDreamOverlayClient(IDreamOverlayClient client) throws RemoteException { + retrievedClient = client; + } + } + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + } + + /** + * Verifies that only the currently started dream is able to affect the overlay. + */ + @Test + public void testOverlayClientInteraction() throws RemoteException { + final TestDreamOverlayService.Monitor monitor = Mockito.mock( + TestDreamOverlayService.Monitor.class); + final TestDreamOverlayService service = new TestDreamOverlayService(monitor); + final IBinder binder = service.onBind(new Intent()); + final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(binder); + + // Create two overlay clients and ensure they are unique. + final IDreamOverlayClient firstClient = getClient(overlay); + assertThat(firstClient).isNotNull(); + + final IDreamOverlayClient secondClient = getClient(overlay); + assertThat(secondClient).isNotNull(); + + assertThat(firstClient).isNotEqualTo(secondClient); + + // Start a dream with the first client and ensure the dream is now active from the + // overlay's perspective. + firstClient.startDream(mLayoutParams, mOverlayCallback, + FIRST_DREAM_COMPONENT.flattenToString(), false); + + + verify(monitor).onStartDream(); + assertThat(service.getDreamComponent()).isEqualTo(FIRST_DREAM_COMPONENT); + + Mockito.clearInvocations(monitor); + + // Start a dream from the second client and verify that the overlay has both cycled to + // the new dream (ended/started). + secondClient.startDream(mLayoutParams, mOverlayCallback, + SECOND_DREAM_COMPONENT.flattenToString(), false); + + verify(monitor).onEndDream(); + verify(monitor).onStartDream(); + assertThat(service.getDreamComponent()).isEqualTo(SECOND_DREAM_COMPONENT); + + Mockito.clearInvocations(monitor); + + // Verify that interactions with the first, now inactive client don't affect the overlay. + firstClient.endDream(); + verify(monitor, never()).onEndDream(); + + firstClient.wakeUp(); + verify(monitor, never()).onWakeUp(); + } + + private static IDreamOverlayClient getClient(IDreamOverlay overlay) throws RemoteException { + final OverlayClientCallback callback = new OverlayClientCallback(); + overlay.getClient(callback); + return callback.retrievedClient; + } +} diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java index 9b9cb4d8cfa0..c760efdae263 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -144,7 +144,9 @@ public final class UserManagerTest { @Test public void testCloneUser() throws Exception { - + assumeCloneEnabled(); + UserHandle mainUser = mUserManager.getMainUser(); + assumeTrue("Main user is null", mainUser != null); // Get the default properties for clone user type. final UserTypeDetails userTypeDetails = UserTypeFactory.getUserTypes().get(UserManager.USER_TYPE_PROFILE_CLONE); @@ -153,7 +155,7 @@ public final class UserManagerTest { final UserProperties typeProps = userTypeDetails.getDefaultUserPropertiesReference(); // Test that only one clone user can be created - final int mainUserId = mUserManager.getMainUser().getIdentifier(); + final int mainUserId = mainUser.getIdentifier(); UserInfo userInfo = createProfileForUser("Clone user1", UserManager.USER_TYPE_PROFILE_CLONE, mainUserId); @@ -536,6 +538,7 @@ public final class UserManagerTest { @Test public void testRemoveUserWhenPossible_withProfiles() throws Exception { assumeHeadlessModeEnabled(); + assumeCloneEnabled(); final UserInfo parentUser = createUser("Human User", /* flags= */ 0); final UserInfo cloneProfileUser = createProfileForUser("Clone Profile user", UserManager.USER_TYPE_PROFILE_CLONE, @@ -1539,6 +1542,12 @@ public final class UserManagerTest { UserManager.isHeadlessSystemUserMode()); } + private void assumeCloneEnabled() { + // assume clone profile is supported on the device + assumeTrue("Device doesn't support clone profiles ", + mUserManager.isUserTypeEnabled(UserManager.USER_TYPE_PROFILE_CLONE)); + } + private boolean isAutomotive() { return mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); } diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java index a0fb3deeb131..d71deaf3a88d 100644 --- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java @@ -16,6 +16,7 @@ package com.android.server.power; +import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP; import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; import static android.app.AppOpsManager.MODE_ALLOWED; @@ -29,6 +30,8 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.AdditionalMatchers.gt; +import static org.mockito.AdditionalMatchers.leq; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -150,6 +153,9 @@ public class PowerManagerServiceTest { @Mock private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock; + @Mock + private ActivityManagerInternal mActivityManagerInternal; + private PowerManagerService mService; private ContextWrapper mContextSpy; private BatteryReceiver mBatteryReceiver; @@ -205,6 +211,7 @@ public class PowerManagerServiceTest { addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock); addLocalServiceMock(AttentionManagerInternal.class, mAttentionManagerInternalMock); addLocalServiceMock(DreamManagerInternal.class, mDreamManagerInternalMock); + addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternal); mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); mResourcesSpy = spy(mContextSpy.getResources()); @@ -221,6 +228,14 @@ public class PowerManagerServiceTest { mClock = new OffsettableClock.Stopped(); mTestLooper = new TestLooper(mClock::now); + + // Set up canHoldWakeLocksInDeepDoze. + // - procstate <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE -> true + // - procstate > PROCESS_STATE_BOUND_FOREGROUND_SERVICE -> false + when(mActivityManagerInternal.canHoldWakeLocksInDeepDoze( + anyInt(), leq(PROCESS_STATE_BOUND_FOREGROUND_SERVICE))).thenReturn(true); + when(mActivityManagerInternal.canHoldWakeLocksInDeepDoze( + anyInt(), gt(PROCESS_STATE_BOUND_FOREGROUND_SERVICE))).thenReturn(false); } private PowerManagerService createService() { diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java b/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java index 74189fdd604a..4fde73bd8408 100644 --- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java +++ b/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java @@ -41,10 +41,10 @@ import java.util.concurrent.Future; public class BatteryStatsHistoryIteratorTest { private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; - private MockClock mMockClock = new MockClock(); + private final MockClock mMockClock = new MockClock(); private MockBatteryStatsImpl mBatteryStats; - private Random mRandom = new Random(); - private MockExternalStatsSync mExternalStatsSync = new MockExternalStatsSync(); + private final Random mRandom = new Random(); + private final MockExternalStatsSync mExternalStatsSync = new MockExternalStatsSync(); @Before public void setup() { @@ -184,29 +184,27 @@ public class BatteryStatsHistoryIteratorTest { 100, /* plugType */ 0, 90, 72, 3700, 3_600_000, 4_000_000, 0, 1_000_000, 1_000_000, 1_000_000); - assertThat(mExternalStatsSync.mSyncScheduled).isTrue(); - mBatteryStats.finishAddingCpuLocked(100, 0, 0, 0, 0, 0, 0, 0); - mExternalStatsSync.mSyncScheduled = false; + mExternalStatsSync.updateCpuStats(100, 1_100_000, 1_100_000); // Device was suspended for 3_000 seconds, note the difference in elapsed time and uptime mBatteryStats.setBatteryStateLocked(BatteryManager.BATTERY_STATUS_DISCHARGING, 100, /* plugType */ 0, 80, 72, 3700, 2_400_000, 4_000_000, 0, 5_000_000, 2_000_000, 5_000_000); - assertThat(mExternalStatsSync.mSyncScheduled).isTrue(); - mBatteryStats.finishAddingCpuLocked(200, 0, 0, 0, 0, 0, 0, 0); - mExternalStatsSync.mSyncScheduled = false; + mExternalStatsSync.updateCpuStats(200, 5_100_000, 2_100_000); // Battery level is unchanged, so we don't write battery level details in history mBatteryStats.noteAlarmStartLocked("wakeup", null, APP_UID, 6_000_000, 3_000_000); - assertThat(mExternalStatsSync.mSyncScheduled).isFalse(); + assertThat(mExternalStatsSync.isSyncScheduled()).isFalse(); // Battery level drops, so we write the accumulated battery level details mBatteryStats.setBatteryStateLocked(BatteryManager.BATTERY_STATUS_DISCHARGING, 100, /* plugType */ 0, 79, 72, 3700, 2_000_000, 4_000_000, 0, 7_000_000, 4_000_000, 6_000_000); + mExternalStatsSync.updateCpuStats(300, 7_100_000, 4_100_000); + final BatteryStatsHistoryIterator iterator = mBatteryStats.iterateBatteryStatsHistory(); BatteryStats.HistoryItem item; @@ -220,6 +218,10 @@ public class BatteryStatsHistoryIteratorTest { assertThat(item = iterator.next()).isNotNull(); assertThat(item.batteryLevel).isEqualTo(90); + assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS); + + assertThat(item = iterator.next()).isNotNull(); + assertThat(item.batteryLevel).isEqualTo(90); assertThat(item.states & BatteryStats.HistoryItem.STATE_CPU_RUNNING_FLAG).isEqualTo(0); assertThat(item.stepDetails.userTime).isEqualTo(100); @@ -230,6 +232,10 @@ public class BatteryStatsHistoryIteratorTest { assertThat(item = iterator.next()).isNotNull(); assertThat(item.batteryLevel).isEqualTo(80); + assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS); + + assertThat(item = iterator.next()).isNotNull(); + assertThat(item.batteryLevel).isEqualTo(80); assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_ALARM_START); assertThat(item.stepDetails).isNull(); @@ -238,6 +244,10 @@ public class BatteryStatsHistoryIteratorTest { assertThat(item.states & BatteryStats.HistoryItem.STATE_CPU_RUNNING_FLAG).isNotEqualTo(0); assertThat(item.stepDetails.userTime).isEqualTo(200); + assertThat(item = iterator.next()).isNotNull(); + assertThat(item.batteryLevel).isEqualTo(79); + assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS); + assertThat(item = iterator.next()).isNull(); } @@ -258,7 +268,7 @@ public class BatteryStatsHistoryIteratorTest { assertThat(item.time).isEqualTo(elapsedTimeMs); } - private static class MockExternalStatsSync extends MockBatteryStatsImpl.DummyExternalStatsSync { + private class MockExternalStatsSync extends MockBatteryStatsImpl.DummyExternalStatsSync { private boolean mSyncScheduled; @Override @@ -266,5 +276,18 @@ public class BatteryStatsHistoryIteratorTest { mSyncScheduled = true; return null; } + + public boolean isSyncScheduled() { + return mSyncScheduled; + } + + public void updateCpuStats(int totalUTimeMs, long elapsedRealtime, long uptime) { + assertThat(mExternalStatsSync.mSyncScheduled).isTrue(); + mBatteryStats.recordHistoryEventLocked(elapsedRealtime, uptime, + BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS, "wakelock-update", 0); + mBatteryStats.addCpuStatsLocked(totalUTimeMs, 0, 0, 0, 0, 0, 0, 0); + mBatteryStats.finishAddingCpuStatsLocked(); + mExternalStatsSync.mSyncScheduled = false; + } } } diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java index 5234bb725a8f..63d676800512 100644 --- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java @@ -46,7 +46,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.IntentSender; import android.content.pm.PackageManager; -import android.hardware.boot.V1_2.IBootControl; +import android.hardware.boot.IBootControl; import android.os.Handler; import android.os.IPowerManager; import android.os.IRecoverySystemProgressListener; diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java index 27e953f30fa0..f1cf48bc5f20 100644 --- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java @@ -17,7 +17,7 @@ package com.android.server.recoverysystem; import android.content.Context; -import android.hardware.boot.V1_2.IBootControl; +import android.hardware.boot.IBootControl; import android.os.PowerManager; import com.android.internal.widget.LockSettingsInternal; diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java index 3de65c19a1a4..1b3a19954d7f 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java @@ -132,6 +132,19 @@ public class WindowOrientationListenerTest { assertThat(mFinalizedRotation).isEqualTo(DEFAULT_SENSOR_ROTATION); } + @Test + public void testOnSensorChanged_screenLocked_doNotCallRotationResolverReturnDefaultRotation() { + mWindowOrientationListener = new TestableWindowOrientationListener(mMockContext, + mHandler, /* defaultRotation */ Surface.ROTATION_180); + mWindowOrientationListener.mRotationResolverService = mFakeRotationResolverInternal; + mWindowOrientationListener.mIsScreenLocked = true; + + mWindowOrientationListener.mOrientationJudge.onSensorChanged(mFakeSensorEvent); + + assertThat(mWindowOrientationListener.mIsOnProposedRotationChangedCalled).isFalse(); + assertThat(mFinalizedRotation).isEqualTo(Surface.ROTATION_180); + } + static final class TestableRotationResolver extends RotationResolverInternal { @Surface.Rotation RotationResolverCallbackInternal mCallback; @@ -166,21 +179,17 @@ public class WindowOrientationListenerTest { } } - @Test - public void testOnSensorChanged_inLockScreen_doNotCallRotationResolver() { - mWindowOrientationListener.mIsScreenLocked = true; - - mWindowOrientationListener.mOrientationJudge.onSensorChanged(mFakeSensorEvent); - - assertThat(mWindowOrientationListener.mIsOnProposedRotationChangedCalled).isFalse(); - } - final class TestableWindowOrientationListener extends WindowOrientationListener { private boolean mIsOnProposedRotationChangedCalled = false; private boolean mIsScreenLocked; TestableWindowOrientationListener(Context context, Handler handler) { - super(context, handler); + this(context, handler, Surface.ROTATION_0); + } + + TestableWindowOrientationListener(Context context, Handler handler, + @Surface.Rotation int defaultRotation) { + super(context, handler, defaultRotation); this.mOrientationJudge = new OrientationSensorJudge(); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java index 581cf430d359..90d148856fff 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java @@ -28,24 +28,29 @@ import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.intThat; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.INotificationManager; import android.app.Notification; import android.app.NotificationChannel; +import android.app.NotificationChannelGroup; import android.app.NotificationManager; import android.content.ComponentName; import android.content.pm.IPackageManager; @@ -54,7 +59,10 @@ import android.content.pm.ServiceInfo; import android.content.pm.VersionedPackage; import android.content.res.Resources; import android.os.Bundle; +import android.os.Parcel; +import android.os.RemoteException; import android.os.UserHandle; +import android.service.notification.INotificationListener; import android.service.notification.NotificationListenerFilter; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationRankingUpdate; @@ -63,10 +71,10 @@ import android.service.notification.StatusBarNotification; import android.testing.TestableContext; import android.util.ArraySet; import android.util.Pair; -import android.util.Xml; - import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; +import android.util.Xml; + import com.android.server.UiServiceTestCase; import com.google.common.collect.ImmutableList; @@ -113,6 +121,8 @@ public class NotificationListenersTest extends UiServiceTestCase { getContext().setMockPackageManager(mPm); doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any()); + when(mNm.isInteractionVisibleToListener(any(), anyInt())).thenReturn(true); + mListeners = spy(mNm.new NotificationListeners( mContext, new Object(), mock(ManagedServices.UserProfiles.class), miPm)); when(mNm.getBinderService()).thenReturn(mINm); @@ -596,4 +606,44 @@ public class NotificationListenersTest extends UiServiceTestCase { verify(mPmi).grantImplicitAccess(sbn.getUserId(), null, UserHandle.getAppId(33), sbn.getUid(), false, false); } + + @Test + public void testUpdateGroup_notifyTwoListeners() throws Exception { + final NotificationChannelGroup updated = new NotificationChannelGroup("id", "name"); + updated.setChannels(ImmutableList.of( + new NotificationChannel("a", "a", 1), new NotificationChannel("b", "b", 2))); + updated.setBlocked(true); + + ManagedServices.ManagedServiceInfo i1 = getParcelingListener(updated); + ManagedServices.ManagedServiceInfo i2= getParcelingListener(updated); + when(mListeners.getServices()).thenReturn(ImmutableList.of(i1, i2)); + NotificationChannelGroup existing = new NotificationChannelGroup("id", "name"); + + mListeners.notifyNotificationChannelGroupChanged("pkg", UserHandle.of(0), updated, 0); + Thread.sleep(500); + + verify(((INotificationListener) i1.getService()), times(1)) + .onNotificationChannelGroupModification(anyString(), any(), any(), anyInt()); + } + + private ManagedServices.ManagedServiceInfo getParcelingListener( + final NotificationChannelGroup toParcel) + throws RemoteException { + ManagedServices.ManagedServiceInfo i1 = mock(ManagedServices.ManagedServiceInfo.class); + when(i1.isSystem()).thenReturn(true); + INotificationListener l1 = mock(INotificationListener.class); + when(i1.enabledAndUserMatches(anyInt())).thenReturn(true); + doAnswer(invocationOnMock -> { + try { + toParcel.writeToParcel(Parcel.obtain(), 0); + } catch (Exception e) { + fail("Failed to parcel group to listener"); + return e; + + } + return null; + }).when(l1).onNotificationChannelGroupModification(anyString(), any(), any(), anyInt()); + when(i1.getService()).thenReturn(l1); + return i1; + } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 5f8a2b5027ef..20e8cd4671ba 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -19,6 +19,7 @@ package com.android.server.notification; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; import static android.app.ActivityTaskManager.INVALID_TASK_ID; +import static android.app.Notification.EXTRA_ALLOW_DURING_SETUP; import static android.app.Notification.FLAG_AUTO_CANCEL; import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_CAN_COLORIZE; @@ -217,6 +218,7 @@ import com.android.server.notification.NotificationManagerService.NotificationAs import com.android.server.notification.NotificationManagerService.NotificationListeners; import com.android.server.pm.PackageManagerService; import com.android.server.pm.UserManagerInternal; +import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.UriGrantsManagerInternal; @@ -305,6 +307,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { ActivityManager mActivityManager; @Mock TelecomManager mTelecomManager; + + @Mock + PermissionManagerServiceInternal mPermissionInternal; @Mock Resources mResources; @Mock @@ -518,7 +523,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mAppOpsManager, mAppOpsService, mUm, mHistoryManager, mStatsManager, mock(TelephonyManager.class), mAmi, mToastRateLimiter, mPermissionHelper, mock(UsageStatsManagerInternal.class), - mTelecomManager, mLogger); + mTelecomManager, mLogger, mPermissionInternal); // Return first true for RoleObserver main-thread check when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false); mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper); @@ -4168,8 +4173,35 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testNoNotificationDuringSetupPermission() throws Exception { + when(mPermissionInternal.checkPermission(any(), any(), anyInt())) + .thenReturn(PERMISSION_DENIED); + Bundle extras = new Bundle(); + extras.putBoolean(EXTRA_ALLOW_DURING_SETUP, true); + Notification.Builder nb = new Notification.Builder(mContext, + mTestNotificationChannel.getId()) + .setContentTitle("foo") + .addExtras(extras) + .setSmallIcon(android.R.drawable.sym_def_app_icon); + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, + "testNoNotificationDuringSetupPermission", mUid, 0, + nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); + NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(), + nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); + waitForIdle(); + + NotificationRecord posted = mService.findNotificationLocked( + PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId()); + + assertFalse(posted.getNotification().extras.containsKey(EXTRA_ALLOW_DURING_SETUP)); + } + + @Test public void testNoFakeColorizedPermission() throws Exception { - when(mPackageManagerClient.checkPermission(any(), any())).thenReturn(PERMISSION_DENIED); + when(mPermissionInternal.checkPermission(any(), any(), anyInt())) + .thenReturn(PERMISSION_DENIED); Notification.Builder nb = new Notification.Builder(mContext, mTestNotificationChannel.getId()) .setContentTitle("foo") @@ -4194,7 +4226,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testMediaStyleRemote_hasPermission() throws RemoteException { String deviceName = "device"; - when(mPackageManager.checkPermission( + when(mPermissionInternal.checkPermission( eq(android.Manifest.permission.MEDIA_CONTENT_CONTROL), any(), anyInt())) .thenReturn(PERMISSION_GRANTED); Notification.MediaStyle style = new Notification.MediaStyle(); @@ -4223,7 +4255,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testMediaStyleRemote_noPermission() throws RemoteException { String deviceName = "device"; - when(mPackageManager.checkPermission( + when(mPermissionInternal.checkPermission( eq(android.Manifest.permission.MEDIA_CONTENT_CONTROL), any(), anyInt())) .thenReturn(PERMISSION_DENIED); Notification.MediaStyle style = new Notification.MediaStyle(); @@ -4251,7 +4283,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testSubstituteAppName_hasPermission() throws RemoteException { String subName = "Substitute Name"; - when(mPackageManager.checkPermission( + when(mPermissionInternal.checkPermission( eq(android.Manifest.permission.SUBSTITUTE_NOTIFICATION_APP_NAME), any(), anyInt())) .thenReturn(PERMISSION_GRANTED); Bundle extras = new Bundle(); @@ -4278,7 +4310,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testSubstituteAppName_noPermission() throws RemoteException { - when(mPackageManager.checkPermission( + when(mPermissionInternal.checkPermission( eq(android.Manifest.permission.SUBSTITUTE_NOTIFICATION_APP_NAME), any(), anyInt())) .thenReturn(PERMISSION_DENIED); Bundle extras = new Bundle(); @@ -5788,7 +5820,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCanUseManagedServices_hasPermission() throws Exception { - when(mPackageManager.checkPermission("perm", "pkg", 0)) + when(mPermissionInternal.checkPermission("perm", "pkg", 0)) .thenReturn(PackageManager.PERMISSION_GRANTED); assertEquals(true, mService.canUseManagedServices("pkg", 0, "perm")); @@ -5796,7 +5828,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCanUseManagedServices_noPermission() throws Exception { - when(mPackageManager.checkPermission("perm", "pkg", 0)) + when(mPermissionInternal.checkPermission("perm", "pkg", 0)) .thenReturn(PackageManager.PERMISSION_DENIED); assertEquals(false, mService.canUseManagedServices("pkg", 0, "perm")); @@ -6751,7 +6783,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private void setIfPackageHasPermissionToAvoidToastRateLimiting( String pkg, boolean hasPermission) throws Exception { - when(mPackageManager.checkPermission(android.Manifest.permission.UNLIMITED_TOASTS, + when(mPermissionInternal.checkPermission(android.Manifest.permission.UNLIMITED_TOASTS, pkg, UserHandle.getUserId(mUid))) .thenReturn(hasPermission ? PERMISSION_GRANTED : PERMISSION_DENIED); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index 19f31896d6a8..f0f9204c4e4e 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -93,6 +93,7 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.os.Parcel; import android.os.RemoteCallback; import android.os.RemoteException; import android.os.UserHandle; @@ -2449,6 +2450,35 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test + public void testGetNotificationChannelGroup() throws Exception { + NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted"); + NotificationChannel base = + new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT); + base.setGroup("not"); + NotificationChannel convo = + new NotificationChannel("convo", "belongs to notDeleted", IMPORTANCE_DEFAULT); + convo.setGroup("not"); + convo.setConversationId("not deleted", "banana"); + + mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true); + mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, base, true, false); + mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, convo, true, false); + mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true); + + NotificationChannelGroup g + = mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG_N_MR1, UID_N_MR1); + Parcel parcel = Parcel.obtain(); + g.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + NotificationChannelGroup g2 + = mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG_N_MR1, UID_N_MR1); + Parcel parcel2 = Parcel.obtain(); + g2.writeToParcel(parcel2, 0); + parcel2.setDataPosition(0); + } + + @Test public void testOnUserRemoved() throws Exception { int[] user0Uids = {98, 235, 16, 3782}; int[] user1Uids = new int[user0Uids.length]; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java index 98c156e6f3b5..3a01c2d26e50 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java @@ -72,6 +72,7 @@ import com.android.server.UiServiceTestCase; import com.android.server.lights.LightsManager; import com.android.server.notification.NotificationManagerService.NotificationAssistants; import com.android.server.notification.NotificationManagerService.NotificationListeners; +import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.utils.quota.MultiRateLimiter; import com.android.server.wm.ActivityTaskManagerInternal; @@ -168,8 +169,9 @@ public class RoleObserverTest extends UiServiceTestCase { mock(StatsManager.class), mock(TelephonyManager.class), mock(ActivityManagerInternal.class), mock(MultiRateLimiter.class), mock(PermissionHelper.class), - mock(UsageStatsManagerInternal.class), mock (TelecomManager.class), - mock(NotificationChannelLogger.class)); + mock(UsageStatsManagerInternal.class), mock(TelecomManager.class), + mock(NotificationChannelLogger.class), + mock(PermissionManagerServiceInternal.class)); } catch (SecurityException e) { if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { throw e; diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml index b51feb3ac5c7..593ee4a7fa1a 100644 --- a/services/tests/wmtests/AndroidManifest.xml +++ b/services/tests/wmtests/AndroidManifest.xml @@ -90,9 +90,6 @@ android:foregroundServiceType="mediaProjection" android:enabled="true"> </service> - - <service android:name="com.android.server.wm.scvh.EmbeddedSCVHService" - android:process="com.android.server.wm.scvh.embedded_process" /> </application> <instrumentation diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 9fda2043c5d2..e663245157cf 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -1475,6 +1475,7 @@ public class ActivityRecordTests extends WindowTestsBase { // Make keyguard locked and set the top activity show-when-locked. KeyguardController keyguardController = activity.mTaskSupervisor.getKeyguardController(); int displayId = activity.getDisplayId(); + doReturn(true).when(keyguardController).isKeyguardLocked(eq(displayId)); final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(task).build(); topActivity.setVisibleRequested(true); topActivity.nowVisible = true; @@ -1484,24 +1485,18 @@ public class ActivityRecordTests extends WindowTestsBase { anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */); topActivity.setShowWhenLocked(true); - try { - keyguardController.setKeyguardShown(displayId, true, false); - - // Verify the stack-top activity is occluded keyguard. - assertEquals(topActivity, task.topRunningActivity()); - assertTrue(keyguardController.isDisplayOccluded(DEFAULT_DISPLAY)); + // Verify the stack-top activity is occluded keyguard. + assertEquals(topActivity, task.topRunningActivity()); + assertTrue(keyguardController.isDisplayOccluded(DEFAULT_DISPLAY)); - // Finish the top activity - topActivity.setState(PAUSED, "true"); - topActivity.finishing = true; - topActivity.completeFinishing("test"); + // Finish the top activity + topActivity.setState(PAUSED, "true"); + topActivity.finishing = true; + topActivity.completeFinishing("test"); - // Verify new top activity does not occlude keyguard. - assertEquals(activity, task.topRunningActivity()); - assertFalse(keyguardController.isDisplayOccluded(DEFAULT_DISPLAY)); - } finally { - keyguardController.setKeyguardShown(displayId, false, false); - } + // Verify new top activity does not occlude keyguard. + assertEquals(activity, task.topRunningActivity()); + assertFalse(keyguardController.isDisplayOccluded(DEFAULT_DISPLAY)); } /** diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index 305260b23d12..3dcae91f5c89 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -252,12 +252,7 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { mAtm.setLockScreenShown(true, true); mRootWindowContainer.forAllDisplays(displayContent -> { assertTrue(displayContent.isKeyguardLocked()); - // Only default display supports AOD. - if (displayContent.isDefaultDisplay) { - assertTrue(displayContent.isAodShowing()); - } else { - assertFalse(displayContent.isAodShowing()); - } + assertTrue(displayContent.isAodShowing()); }); // Check setLockScreenShown unlocking both displays 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 91e875f47440..1ab8c1fbf640 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -2926,6 +2926,39 @@ public class SizeCompatTests extends WindowTestsBase { } @Test + public void testUpdateResolvedBoundsHorizontalPosition_leftInsets_appCentered() { + // Set up folded display + final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1100, 2100) + .setCanRotate(true) + .build(); + display.setIgnoreOrientationRequest(true); + final DisplayPolicy policy = display.getDisplayPolicy(); + DisplayPolicy.DecorInsets.Info decorInfo = policy.getDecorInsetsInfo(ROTATION_90, + display.mBaseDisplayHeight, display.mBaseDisplayWidth); + decorInfo.mNonDecorInsets.set(130, 0, 60, 0); + spyOn(policy); + doReturn(decorInfo).when(policy).getDecorInsetsInfo(ROTATION_90, + display.mBaseDisplayHeight, display.mBaseDisplayWidth); + mWm.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f); + + setUpApp(display); + prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); + + // Resize the display to simulate unfolding in portrait + resizeDisplay(mTask.mDisplayContent, 2200, 1800); + assertTrue(mActivity.inSizeCompatMode()); + + // Simulate real display not taking non-decor insets into consideration + display.getWindowConfiguration().setAppBounds(0, 0, 2200, 1800); + + // Rotate display to landscape + rotateDisplay(mActivity.mDisplayContent, ROTATION_90); + + // App is centered + assertEquals(mActivity.getBounds(), new Rect(350, 50, 1450, 2150)); + } + + @Test public void testUpdateResolvedBoundsHorizontalPosition_left() { // Display configured as (2800, 1400). assertHorizontalPositionForDifferentDisplayConfigsForPortraitActivity( @@ -3071,6 +3104,20 @@ public class SizeCompatTests extends WindowTestsBase { } @Test + public void testApplyAspectRatio_containingRatioAlmostEqualToMaxRatio_boundsUnchanged() { + setUpDisplaySizeWithApp(1981, 2576); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + mWm.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f); + + final Rect originalBounds = new Rect(mActivity.getBounds()); + prepareUnresizable(mActivity, 1.3f, SCREEN_ORIENTATION_UNSPECIFIED); + + // The containing aspect ratio is now 1.3003534, while the desired aspect ratio is 1.3. The + // bounds of the activity should not be changed as the difference is too small + assertEquals(mActivity.getBounds(), originalBounds); + } + + @Test public void testUpdateResolvedBoundsHorizontalPosition_activityFillParentWidth() { // When activity width equals parent width, multiplier shouldn't have any effect. assertHorizontalPositionForDifferentDisplayConfigsForLandscapeActivity( @@ -3082,6 +3129,39 @@ public class SizeCompatTests extends WindowTestsBase { } @Test + public void testUpdateResolvedBoundsVerticalPosition_topInsets_appCentered() { + // Set up folded display + final DisplayContent display = new TestDisplayContent.Builder(mAtm, 2100, 1100) + .setCanRotate(true) + .build(); + display.setIgnoreOrientationRequest(true); + final DisplayPolicy policy = display.getDisplayPolicy(); + DisplayPolicy.DecorInsets.Info decorInfo = policy.getDecorInsetsInfo(ROTATION_90, + display.mBaseDisplayHeight, display.mBaseDisplayWidth); + decorInfo.mNonDecorInsets.set(0, 130, 0, 60); + spyOn(policy); + doReturn(decorInfo).when(policy).getDecorInsetsInfo(ROTATION_90, + display.mBaseDisplayHeight, display.mBaseDisplayWidth); + mWm.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f); + + setUpApp(display); + prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); + + // Resize the display to simulate unfolding in portrait + resizeDisplay(mTask.mDisplayContent, 1800, 2200); + assertTrue(mActivity.inSizeCompatMode()); + + // Simulate real display not taking non-decor insets into consideration + display.getWindowConfiguration().setAppBounds(0, 0, 1800, 2200); + + // Rotate display to landscape + rotateDisplay(mActivity.mDisplayContent, ROTATION_90); + + // App is centered + assertEquals(mActivity.getBounds(), new Rect(50, 350, 2150, 1450)); + } + + @Test public void testUpdateResolvedBoundsVerticalPosition_top() { // Display configured as (1400, 2800). assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity( diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java index f655242afac8..22d72ed3d361 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java @@ -55,7 +55,7 @@ public class SurfaceSyncGroupTest { SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG); syncGroup.addSyncCompleteCallback(mExecutor, finishedLatch::countDown); SyncTarget syncTarget = new SyncTarget(); - syncGroup.addToSync(syncTarget, false /* parentSyncGroupMerge */); + syncGroup.add(syncTarget, null /* runnable */); syncGroup.markSyncReady(); syncTarget.onBufferReady(); @@ -73,9 +73,9 @@ public class SurfaceSyncGroupTest { SyncTarget syncTarget2 = new SyncTarget(); SyncTarget syncTarget3 = new SyncTarget(); - syncGroup.addToSync(syncTarget1, false /* parentSyncGroupMerge */); - syncGroup.addToSync(syncTarget2, false /* parentSyncGroupMerge */); - syncGroup.addToSync(syncTarget3, false /* parentSyncGroupMerge */); + syncGroup.add(syncTarget1, null /* runnable */); + syncGroup.add(syncTarget2, null /* runnable */); + syncGroup.add(syncTarget3, null /* runnable */); syncGroup.markSyncReady(); syncTarget1.onBufferReady(); @@ -97,11 +97,11 @@ public class SurfaceSyncGroupTest { SyncTarget syncTarget1 = new SyncTarget(); SyncTarget syncTarget2 = new SyncTarget(); - assertTrue(syncGroup.addToSync(syncTarget1, false /* parentSyncGroupMerge */)); + assertTrue(syncGroup.add(syncTarget1, null /* runnable */)); syncGroup.markSyncReady(); // Adding to a sync that has been completed is also invalid since the sync id has been // cleared. - assertFalse(syncGroup.addToSync(syncTarget2, false /* parentSyncGroupMerge */)); + assertFalse(syncGroup.add(syncTarget2, null /* runnable */)); } @Test @@ -117,8 +117,8 @@ public class SurfaceSyncGroupTest { SyncTarget syncTarget1 = new SyncTarget(); SyncTarget syncTarget2 = new SyncTarget(); - assertTrue(syncGroup1.addToSync(syncTarget1, false /* parentSyncGroupMerge */)); - assertTrue(syncGroup2.addToSync(syncTarget2, false /* parentSyncGroupMerge */)); + assertTrue(syncGroup1.add(syncTarget1, null /* runnable */)); + assertTrue(syncGroup2.add(syncTarget2, null /* runnable */)); syncGroup1.markSyncReady(); syncGroup2.markSyncReady(); @@ -147,10 +147,10 @@ public class SurfaceSyncGroupTest { SyncTarget syncTarget1 = new SyncTarget(); SyncTarget syncTarget2 = new SyncTarget(); - assertTrue(syncGroup1.addToSync(syncTarget1, false /* parentSyncGroupMerge */)); - assertTrue(syncGroup2.addToSync(syncTarget2, false /* parentSyncGroupMerge */)); + assertTrue(syncGroup1.add(syncTarget1, null /* runnable */)); + assertTrue(syncGroup2.add(syncTarget2, null /* runnable */)); syncGroup1.markSyncReady(); - syncGroup2.addToSync(syncGroup1, false /* parentSyncGroupMerge */); + syncGroup2.add(syncGroup1, null /* runnable */); syncGroup2.markSyncReady(); // Finish syncTarget2 first to test that the syncGroup is not complete until the merged sync @@ -183,8 +183,8 @@ public class SurfaceSyncGroupTest { SyncTarget syncTarget1 = new SyncTarget(); SyncTarget syncTarget2 = new SyncTarget(); - assertTrue(syncGroup1.addToSync(syncTarget1, false /* parentSyncGroupMerge */)); - assertTrue(syncGroup2.addToSync(syncTarget2, false /* parentSyncGroupMerge */)); + assertTrue(syncGroup1.add(syncTarget1, null /* runnable */)); + assertTrue(syncGroup2.add(syncTarget2, null /* runnable */)); syncGroup1.markSyncReady(); syncTarget1.onBufferReady(); @@ -192,7 +192,7 @@ public class SurfaceSyncGroupTest { finishedLatch1.await(5, TimeUnit.SECONDS); assertEquals(0, finishedLatch1.getCount()); - syncGroup2.addToSync(syncGroup1, false /* parentSyncGroupMerge */); + syncGroup2.add(syncGroup1, null /* runnable */); syncGroup2.markSyncReady(); syncTarget2.onBufferReady(); @@ -216,12 +216,12 @@ public class SurfaceSyncGroupTest { SyncTarget syncTarget2 = new SyncTarget(); SyncTarget syncTarget3 = new SyncTarget(); - assertTrue(syncGroup1.addToSync(syncTarget1, false /* parentSyncGroupMerge */)); - assertTrue(syncGroup1.addToSync(syncTarget2, false /* parentSyncGroupMerge */)); + assertTrue(syncGroup1.add(syncTarget1, null /* runnable */)); + assertTrue(syncGroup1.add(syncTarget2, null /* runnable */)); // Add syncTarget1 to syncGroup2 so it forces syncGroup1 into syncGroup2 - assertTrue(syncGroup2.addToSync(syncTarget1, false /* parentSyncGroupMerge */)); - assertTrue(syncGroup2.addToSync(syncTarget3, false /* parentSyncGroupMerge */)); + assertTrue(syncGroup2.add(syncTarget1, null /* runnable */)); + assertTrue(syncGroup2.add(syncTarget3, null /* runnable */)); syncGroup1.markSyncReady(); syncGroup2.markSyncReady(); @@ -261,13 +261,13 @@ public class SurfaceSyncGroupTest { SyncTarget syncTarget2 = new SyncTarget(); SyncTarget syncTarget3 = new SyncTarget(); - assertTrue(syncGroup1.addToSync(syncTarget1, false /* parentSyncGroupMerge */)); - assertTrue(syncGroup1.addToSync(syncTarget2, false /* parentSyncGroupMerge */)); + assertTrue(syncGroup1.add(syncTarget1, null /* runnable */)); + assertTrue(syncGroup1.add(syncTarget2, null /* runnable */)); syncTarget2.onBufferReady(); // Add syncTarget1 to syncGroup2 so it forces syncGroup1 into syncGroup2 - assertTrue(syncGroup2.addToSync(syncTarget1, false /* parentSyncGroupMerge */)); - assertTrue(syncGroup2.addToSync(syncTarget3, false /* parentSyncGroupMerge */)); + assertTrue(syncGroup2.add(syncTarget1, null /* runnable */)); + assertTrue(syncGroup2.add(syncTarget3, null /* runnable */)); syncGroup1.markSyncReady(); syncGroup2.markSyncReady(); @@ -303,7 +303,9 @@ public class SurfaceSyncGroupTest { SurfaceSyncGroup.setTransactionFactory(() -> targetTransaction); SyncTarget syncTarget = new SyncTarget(); - assertTrue(syncGroup.addToSync(syncTarget, true /* parentSyncGroupMerge */)); + assertTrue( + syncGroup.add(syncTarget.mISurfaceSyncGroup, true /* parentSyncGroupMerge */, + null /* runnable */)); syncTarget.markSyncReady(); // When parentSyncGroupMerge is true, the transaction passed in merges the main SyncGroup @@ -328,7 +330,7 @@ public class SurfaceSyncGroupTest { SurfaceSyncGroup.setTransactionFactory(() -> targetTransaction); SyncTarget syncTarget = new SyncTarget(); - assertTrue(syncGroup.addToSync(syncTarget, false /* parentSyncGroupMerge */)); + assertTrue(syncGroup.add(syncTarget, null /* runnable */)); syncTarget.markSyncReady(); // When parentSyncGroupMerge is false, the transaction passed in should not merge @@ -343,9 +345,9 @@ public class SurfaceSyncGroupTest { SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG); syncGroup.addSyncCompleteCallback(mExecutor, finishedLatch::countDown); SyncTarget syncTarget = new SyncTarget(); - syncGroup.addToSync(syncTarget, false /* parentSyncGroupMerge */); + syncGroup.add(syncTarget, null /* runnable */); // Add the syncTarget to the same syncGroup and ensure it doesn't crash. - syncGroup.addToSync(syncTarget, false /* parentSyncGroupMerge */); + syncGroup.add(syncTarget, null /* runnable */); syncGroup.markSyncReady(); syncTarget.onBufferReady(); diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupContinuousTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncContinuousTest.java index eef7cc25eee7..ad7314c9bc60 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupContinuousTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncContinuousTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,15 +22,10 @@ import static android.server.wm.WindowManagerState.getLogicalDisplaySize; import android.app.KeyguardManager; import android.os.PowerManager; -import android.platform.test.annotations.Presubmit; -import android.view.SurfaceControl; import android.view.cts.surfacevalidator.CapturedActivity; -import android.window.SurfaceSyncGroup; import androidx.test.rule.ActivityTestRule; -import com.android.server.wm.scvh.SyncValidatorSCVHTestCase; - import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -38,7 +33,7 @@ import org.junit.rules.TestName; import java.util.Objects; -public class SurfaceSyncGroupContinuousTest { +public class SurfaceViewSyncContinuousTest { @Rule public TestName mName = new TestName(); @@ -59,33 +54,10 @@ public class SurfaceSyncGroupContinuousTest { pressWakeupButton(); pressUnlockButton(); } - SurfaceSyncGroup.setTransactionFactory(SurfaceControl.Transaction::new); } @Test public void testSurfaceViewSyncDuringResize() throws Throwable { - mCapturedActivity.verifyTest(new SurfaceSyncGroupValidatorTestCase(), mName); - } - - @Test - public void testSurfaceControlViewHostIPCSync_Fast() throws Throwable { - mCapturedActivity.verifyTest( - new SyncValidatorSCVHTestCase(0 /* delayMs */, false /* overrideDefaultDuration */), - mName); - } - - @Test - public void testSurfaceControlViewHostIPCSync_Slow() throws Throwable { - mCapturedActivity.verifyTest(new SyncValidatorSCVHTestCase(100 /* delayMs */, - false /* overrideDefaultDuration */), mName); - } - - @Test - @Presubmit - public void testSurfaceControlViewHostIPCSync_Short() throws Throwable { - mCapturedActivity.setMinimumCaptureDurationMs(5000); - mCapturedActivity.verifyTest( - new SyncValidatorSCVHTestCase(0 /* delayMs */, true /* overrideDefaultDuration */), - mName); + mCapturedActivity.verifyTest(new SurfaceViewSyncValidatorTestCase(), mName); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupValidatorTestCase.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncValidatorTestCase.java index 1fa0c2300173..93c1badd5e78 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupValidatorTestCase.java +++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncValidatorTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ import androidx.annotation.NonNull; * never an empty area (black color). The test uses {@link SurfaceSyncGroup} class to gather the * content it wants to synchronize. */ -public class SurfaceSyncGroupValidatorTestCase implements ISurfaceValidatorTestCase { +public class SurfaceViewSyncValidatorTestCase implements ISurfaceValidatorTestCase { private static final String TAG = "SurfaceSyncGroupValidatorTestCase"; private final Runnable mRunnable = new Runnable() { @@ -76,7 +76,7 @@ public class SurfaceSyncGroupValidatorTestCase implements ISurfaceValidatorTestC public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { if (mSyncGroup != null) { - mSyncGroup.addToSync(mSurfaceView, frameCallback -> + mSyncGroup.add(mSurfaceView, frameCallback -> mRenderingThread.setFrameCallback(frameCallback)); mSyncGroup.markSyncReady(); mSyncGroup = null; @@ -133,7 +133,7 @@ public class SurfaceSyncGroupValidatorTestCase implements ISurfaceValidatorTestC mRenderingThread.pauseRendering(); mSyncGroup = new SurfaceSyncGroup(TAG); - mSyncGroup.addToSync(mParent.getRootSurfaceControl()); + mSyncGroup.add(mParent.getRootSurfaceControl(), null /* runanble */); ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams(); svParams.height = height; diff --git a/services/tests/wmtests/src/com/android/server/wm/scvh/EmbeddedSCVHService.java b/services/tests/wmtests/src/com/android/server/wm/scvh/EmbeddedSCVHService.java deleted file mode 100644 index 3bd577cb1d64..000000000000 --- a/services/tests/wmtests/src/com/android/server/wm/scvh/EmbeddedSCVHService.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm.scvh; - -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; - -import android.annotation.Nullable; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.graphics.Color; -import android.graphics.PixelFormat; -import android.hardware.display.DisplayManager; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.RemoteException; -import android.view.Display; -import android.view.SurfaceControl.Transaction; -import android.view.SurfaceControlViewHost; -import android.view.View; -import android.view.WindowManager; -import android.widget.FrameLayout; - -import androidx.annotation.NonNull; - -public class EmbeddedSCVHService extends Service { - private static final String TAG = "SCVHEmbeddedService"; - private SurfaceControlViewHost mVr; - - private Handler mHandler; - - @Override - public void onCreate() { - super.onCreate(); - mHandler = new Handler(Looper.getMainLooper()); - } - - @Nullable - @Override - public IBinder onBind(Intent intent) { - // Return the interface - return new AttachEmbeddedWindow(); - } - - public static class SlowView extends View { - private long mDelayMs; - public SlowView(Context context) { - super(context); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - try { - Thread.sleep(mDelayMs); - } catch (InterruptedException e) { - } - } - - public void setDelay(long delayMs) { - mDelayMs = delayMs; - } - } - - private class AttachEmbeddedWindow extends IAttachEmbeddedWindow.Stub { - @Override - public void attachEmbedded(IBinder hostToken, int width, - int height, int displayId, long delayMs, IAttachEmbeddedWindowCallback callback) { - mHandler.post(() -> { - Context context = EmbeddedSCVHService.this; - Display display = getApplicationContext().getSystemService( - DisplayManager.class).getDisplay(displayId); - mVr = new SurfaceControlViewHost(context, display, hostToken); - FrameLayout content = new FrameLayout(context); - - SlowView slowView = new SlowView(context); - slowView.setDelay(delayMs); - slowView.setBackgroundColor(Color.BLUE); - content.addView(slowView); - WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height, - TYPE_APPLICATION, 0, PixelFormat.OPAQUE); - lp.setTitle("EmbeddedWindow"); - mVr.setView(content, lp); - - content.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { - @Override - public void onViewAttachedToWindow(@NonNull View v) { - // First frame isn't included in the sync so don't notify the host about the - // surface package until the first draw has completed. - Transaction transaction = new Transaction().addTransactionCommittedListener( - getMainExecutor(), () -> { - try { - callback.onEmbeddedWindowAttached(mVr.getSurfacePackage()); - } catch (RemoteException e) { - } - }); - v.getRootSurfaceControl().applyTransactionOnDraw(transaction); - } - - @Override - public void onViewDetachedFromWindow(@NonNull View v) { - } - }); - }); - } - - @Override - public void relayout(WindowManager.LayoutParams lp) { - mHandler.post(() -> mVr.relayout(lp)); - } - } -} diff --git a/services/tests/wmtests/src/com/android/server/wm/scvh/SyncValidatorSCVHTestCase.java b/services/tests/wmtests/src/com/android/server/wm/scvh/SyncValidatorSCVHTestCase.java deleted file mode 100644 index 07dac8d7fcc3..000000000000 --- a/services/tests/wmtests/src/com/android/server/wm/scvh/SyncValidatorSCVHTestCase.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm.scvh; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNotNull; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.graphics.Color; -import android.graphics.PixelFormat; -import android.graphics.Point; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.RemoteException; -import android.util.Log; -import android.view.Gravity; -import android.view.SurfaceControlViewHost.SurfacePackage; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.view.cts.surfacevalidator.ISurfaceValidatorTestCase; -import android.view.cts.surfacevalidator.PixelChecker; -import android.widget.FrameLayout; -import android.window.SurfaceSyncGroup; - -import androidx.annotation.NonNull; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -public class SyncValidatorSCVHTestCase implements ISurfaceValidatorTestCase { - private static final String TAG = "SCVHSyncValidatorTestCase"; - - private final Point[] mSizes = new Point[]{new Point(500, 500), new Point(700, 400), - new Point(300, 800), new Point(200, 200)}; - private int mLastSizeIndex = 1; - - private final long mDelayMs; - private final boolean mOverrideDefaultDuration; - - public SyncValidatorSCVHTestCase(long delayMs, boolean overrideDefaultDuration) { - mDelayMs = delayMs; - mOverrideDefaultDuration = overrideDefaultDuration; - } - - private final Runnable mRunnable = new Runnable() { - @Override - public void run() { - Point size = mSizes[mLastSizeIndex % mSizes.length]; - Runnable svResizeRunnable = () -> { - ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams(); - svParams.width = size.x; - svParams.height = size.y; - mSurfaceView.setLayoutParams(svParams); - }; - Runnable resizeRunnable = () -> { - try { - final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(size.x, - size.y, - WindowManager.LayoutParams.TYPE_APPLICATION, 0, - PixelFormat.TRANSPARENT); - mIAttachEmbeddedWindow.relayout(lp); - } catch (RemoteException e) { - } - }; - - SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG); - syncGroup.addToSync(mSurfaceView.getRootSurfaceControl(), svResizeRunnable); - syncGroup.addToSync(mSurfacePackage, resizeRunnable); - syncGroup.markSyncReady(); - - mLastSizeIndex++; - - mHandler.postDelayed(this, mDelayMs + 50); - } - }; - - private Handler mHandler; - private SurfaceView mSurfaceView; - - private final CountDownLatch mReadyLatch = new CountDownLatch(1); - private boolean mSurfaceCreated; - private boolean mIsAttached; - private final Object mLock = new Object(); - private int mDisplayId; - private IAttachEmbeddedWindow mIAttachEmbeddedWindow; - private SurfacePackage mSurfacePackage; - - final SurfaceHolder.Callback mCallback = new SurfaceHolder.Callback() { - @Override - public void surfaceCreated(@NonNull SurfaceHolder holder) { - synchronized (mLock) { - mSurfaceCreated = true; - } - if (isReadyToAttach()) { - attachEmbedded(); - } - } - - @Override - public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, - int height) { - } - - @Override - public void surfaceDestroyed(@NonNull SurfaceHolder holder) { - } - }; - - @Override - public PixelChecker getChecker() { - return new PixelChecker(Color.BLACK) { - @Override - public boolean checkPixels(int matchingPixelCount, int width, int height) { - // Content has been set up yet. - if (mReadyLatch.getCount() > 0) { - return true; - } - return matchingPixelCount == 0; - } - }; - } - - private final ServiceConnection mConnection = new ServiceConnection() { - // Called when the connection with the service is established - public void onServiceConnected(ComponentName className, IBinder service) { - Log.d(TAG, "Service Connected"); - synchronized (mLock) { - mIAttachEmbeddedWindow = IAttachEmbeddedWindow.Stub.asInterface(service); - } - if (isReadyToAttach()) { - attachEmbedded(); - } - } - - public void onServiceDisconnected(ComponentName className) { - Log.d(TAG, "Service Disconnected"); - mIAttachEmbeddedWindow = null; - synchronized (mLock) { - mIsAttached = false; - } - } - }; - - private boolean isReadyToAttach() { - synchronized (mLock) { - if (!mSurfaceCreated) { - Log.d(TAG, "surface is not created"); - } - if (mIAttachEmbeddedWindow == null) { - Log.d(TAG, "Service is not attached"); - } - if (mIsAttached) { - Log.d(TAG, "Already attached"); - } - - return mSurfaceCreated && mIAttachEmbeddedWindow != null && !mIsAttached; - } - } - - private void attachEmbedded() { - synchronized (mLock) { - mIsAttached = true; - } - try { - mIAttachEmbeddedWindow.attachEmbedded(mSurfaceView.getHostToken(), mSizes[0].x, - mSizes[0].y, mDisplayId, mDelayMs, new IAttachEmbeddedWindowCallback.Stub() { - @Override - public void onEmbeddedWindowAttached(SurfacePackage surfacePackage) { - mHandler.post(() -> { - mSurfacePackage = surfacePackage; - mSurfaceView.setChildSurfacePackage(surfacePackage); - mReadyLatch.countDown(); - }); - } - }); - } catch (RemoteException e) { - } - } - - @Override - public void start(Context context, FrameLayout parent) { - mDisplayId = context.getDisplayId(); - mHandler = new Handler(Looper.getMainLooper()); - - Intent intent = new Intent(context, EmbeddedSCVHService.class); - intent.setAction(EmbeddedSCVHService.class.getName()); - context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - - mSurfaceView = new SurfaceView(context); - mSurfaceView.getHolder().addCallback(mCallback); - - FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(mSizes[0].x, - mSizes[0].y); - layoutParams.gravity = Gravity.CENTER; - parent.addView(mSurfaceView, layoutParams); - } - - @Override - public void waitForReady() { - - try { - mReadyLatch.await(5, TimeUnit.SECONDS); - } catch (InterruptedException e) { - } - - assertEquals("Timed out waiting for setup", 0, mReadyLatch.getCount()); - assertNotNull("SurfacePackage is null", mSurfacePackage); - - mHandler.post(mRunnable); - } - - @Override - public void end() { - mHandler.removeCallbacks(mRunnable); - } - - @Override - public boolean hasAnimation() { - return !mOverrideDefaultDuration; - } -} diff --git a/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java b/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java index 55cbc7261e64..f5f9b846c38b 100644 --- a/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java +++ b/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java @@ -83,7 +83,7 @@ final class TextToSpeechManagerPerUserService extends ServiceConnector.Impl<ITextToSpeechService> { private final String mEngine; - private final ITextToSpeechSessionCallback mCallback; + private ITextToSpeechSessionCallback mCallback; private final DeathRecipient mUnbindOnDeathHandler; static void start(Context context, @UserIdInt int userId, String engine, @@ -156,6 +156,7 @@ final class TextToSpeechManagerPerUserService extends } catch (NoSuchElementException ex) { Slog.d(TAG, "The death recipient was not linked."); } + mCallback = null; } } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java index 220ef21413db..445446e8ee10 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java @@ -705,8 +705,7 @@ final class HotwordDetectionConnection { } boolean bindResult = mContext.bindIsolatedService( mIntent, - Context.BIND_SHARED_ISOLATED_PROCESS | Context.BIND_AUTO_CREATE - | Context.BIND_FOREGROUND_SERVICE | mBindingFlags, + Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE | mBindingFlags, "hotword_detector_" + mInstanceNumber, mExecutor, serviceConnection); diff --git a/telecomm/java/android/telecom/CallEndpointException.java b/telecomm/java/android/telecom/CallEndpointException.java index e223892847bc..994e1c9f9412 100644 --- a/telecomm/java/android/telecom/CallEndpointException.java +++ b/telecomm/java/android/telecom/CallEndpointException.java @@ -92,25 +92,12 @@ public final class CallEndpointException extends RuntimeException implements Par public @interface CallEndpointErrorCode { } - public CallEndpointException(@Nullable String message) { - super(getMessage(message, ERROR_UNSPECIFIED)); - mMessage = message; - } - public CallEndpointException(@Nullable String message, @CallEndpointErrorCode int code) { super(getMessage(message, code)); mCode = code; mMessage = message; } - public CallEndpointException(@Nullable String message, @CallEndpointErrorCode int code, - @Nullable Throwable cause) { - super(getMessage(message, code), cause); - mCode = code; - mMessage = message; - } - - public @CallEndpointErrorCode int getCode() { return mCode; } diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 189a08c3bfc2..7404adb96e6c 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -160,6 +160,10 @@ public class SubscriptionManager { private static final String CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY = "cache_key.telephony.subscription_manager_service"; + /** The temporarily cache key to indicate whether subscription manager service is enabled. */ + private static final String CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_ENABLED_PROPERTY = + "cache_key.telephony.subscription_manager_service_enabled"; + /** @hide */ public static final String GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME = "getSimSpecificSettings"; @@ -340,6 +344,12 @@ public class SubscriptionManager { CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY, INVALID_PHONE_INDEX); + //TODO: Removed before U AOSP public release. + private static VoidPropertyInvalidatedCache<Boolean> sIsSubscriptionManagerServiceEnabled = + new VoidPropertyInvalidatedCache<>(ISub::isSubscriptionManagerServiceEnabled, + CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_ENABLED_PROPERTY, + false); + /** * Generates a content {@link Uri} used to receive updates on simInfo change * on the given subscriptionId @@ -1358,8 +1368,6 @@ public class SubscriptionManager { private final Context mContext; - private static boolean sIsSubscriptionManagerServiceEnabled = false; - // Cache of Resource that has been created in getResourcesForSubId. Key is a Pair containing // the Context and subId. private static final Map<Pair<Context, Integer>, Resources> sResourcesCache = @@ -1445,9 +1453,6 @@ public class SubscriptionManager { public SubscriptionManager(Context context) { if (DBG) logd("SubscriptionManager created"); mContext = context; - - sIsSubscriptionManagerServiceEnabled = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_using_subscription_manager_service); } /** @@ -1456,8 +1461,9 @@ public class SubscriptionManager { * * @hide */ + //TODO: Removed before U AOSP public release. public static boolean isSubscriptionManagerServiceEnabled() { - return sIsSubscriptionManagerServiceEnabled; + return sIsSubscriptionManagerServiceEnabled.query(null); } private NetworkPolicyManager getNetworkPolicyManager() { @@ -3971,6 +3977,13 @@ public class SubscriptionManager { PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY); } + /** @hide */ + //TODO: Removed before U AOSP public release. + public static void invalidateSubscriptionManagerServiceEnabledCaches() { + PropertyInvalidatedCache.invalidateCache( + CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_ENABLED_PROPERTY); + } + /** * Allows a test process to disable client-side caching operations. * @@ -3992,6 +4005,8 @@ public class SubscriptionManager { sGetSlotIndexCache.disableLocal(); sGetSubIdCache.disableLocal(); sGetPhoneIdCache.disableLocal(); + + sIsSubscriptionManagerServiceEnabled.disableLocal(); } /** @@ -4014,6 +4029,8 @@ public class SubscriptionManager { sGetSlotIndexCache.clear(); sGetSubIdCache.clear(); sGetPhoneIdCache.clear(); + + sIsSubscriptionManagerServiceEnabled.clear(); } /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 83b909852d8f..0921834436bd 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -16355,6 +16355,7 @@ public class TelephonyManager { /** * Setup sIPhoneSubInfo for testing. + * * @hide */ @VisibleForTesting @@ -16365,9 +16366,21 @@ public class TelephonyManager { } /** - * Whether device can connect to 5G network when two SIMs are active. + * Setup sISub for testing. + * * @hide - * TODO b/153669716: remove or make system API. + */ + @VisibleForTesting + public static void setupISubForTest(ISub iSub) { + synchronized (sCacheLock) { + sISub = iSub; + } + } + + /** + * Whether device can connect to 5G network when two SIMs are active. + * + * @hide TODO b/153669716: remove or make system API. */ public boolean canConnectTo5GInDsdsMode() { ITelephony telephony = getITelephony(); diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl index 25a714a4bb81..defa046da503 100644 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -356,4 +356,11 @@ interface ISub { * @hide */ List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(in UserHandle userHandle); + + /** + * @return {@code true} if using SubscriptionManagerService instead of + * SubscriptionController. + */ + //TODO: Removed before U AOSP public release. + boolean isSubscriptionManagerServiceEnabled(); } diff --git a/tests/BinaryTransparencyHostTest/Android.bp b/tests/BinaryTransparencyHostTest/Android.bp new file mode 100644 index 000000000000..142e3ddf9fe7 --- /dev/null +++ b/tests/BinaryTransparencyHostTest/Android.bp @@ -0,0 +1,42 @@ +// Copyright (C) 2023 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // 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_applicable_licenses: ["frameworks_base_license"], +} + +java_test_host { + name: "BinaryTransparencyHostTest", + srcs: ["src/**/*.java"], + libs: [ + "tradefed", + "compatibility-tradefed", + "compatibility-host-util", + ], + static_libs: [ + "truth-prebuilt", + ], + data: [ + ":BinaryTransparencyTestApp", + ":EasterEgg", + ], + test_suites: [ + "general-tests", + ], +} diff --git a/tests/BinaryTransparencyHostTest/AndroidTest.xml b/tests/BinaryTransparencyHostTest/AndroidTest.xml new file mode 100644 index 000000000000..e0d11c0c1097 --- /dev/null +++ b/tests/BinaryTransparencyHostTest/AndroidTest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2023 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<configuration description="Binary Transparency integration test"> + <option name="test-suite-tag" value="apct" /> + + <!-- Service is not exposed to apps. Disable SELinux for testing purpose. --> + <target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer" /> + + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="BinaryTransparencyTestApp.apk" /> + </target_preparer> + + <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" > + <option name="jar" value="BinaryTransparencyHostTest.jar" /> + <option name="runtime-hint" value="1m" /> + </test> +</configuration> diff --git a/tests/BinaryTransparencyHostTest/OWNERS b/tests/BinaryTransparencyHostTest/OWNERS new file mode 100644 index 000000000000..ca84550c76a4 --- /dev/null +++ b/tests/BinaryTransparencyHostTest/OWNERS @@ -0,0 +1 @@ +include /core/java/android/transparency/OWNERS diff --git a/tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java b/tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java new file mode 100644 index 000000000000..84bed92f5117 --- /dev/null +++ b/tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.transparency.test; + +import static org.junit.Assert.assertTrue; + +import com.android.tradefed.device.DeviceNotAvailableException; +import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; +import com.android.tradefed.testtype.junit4.DeviceTestRunOptions; +import com.android.tradefed.util.CommandResult; +import com.android.tradefed.util.CommandStatus; + +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; + +// TODO: Add @Presubmit +@RunWith(DeviceJUnit4ClassRunner.class) +public final class BinaryTransparencyHostTest extends BaseHostJUnit4Test { + private static final String PACKAGE_NAME = "android.transparency.test.app"; + + @After + public void tearDown() throws Exception { + uninstallPackage("com.android.egg"); + } + + @Test + public void testCollectAllApexInfo() throws Exception { + var options = new DeviceTestRunOptions(PACKAGE_NAME); + options.setTestClassName(PACKAGE_NAME + ".BinaryTransparencyTest"); + options.setTestMethodName("testCollectAllApexInfo"); + + // Collect APEX package names from /apex, then pass them as expectation to be verified. + CommandResult result = getDevice().executeShellV2Command( + "ls -d /apex/*/ |grep -v @ |grep -v /apex/sharedlibs |cut -d/ -f3"); + assertTrue(result.getStatus() == CommandStatus.SUCCESS); + String[] packageNames = result.getStdout().split("\n"); + for (var i = 0; i < packageNames.length; i++) { + options.addInstrumentationArg("apex-" + String.valueOf(i), packageNames[i]); + } + options.addInstrumentationArg("apex-number", Integer.toString(packageNames.length)); + runDeviceTests(options); + } + + @Test + public void testCollectAllUpdatedPreloadInfo() throws Exception { + installPackage("EasterEgg.apk"); + runDeviceTest("testCollectAllUpdatedPreloadInfo"); + } + + @Test + public void testMeasureMbas() throws Exception { + // TODO(265244016): figure out a way to install an MBA + } + + private void runDeviceTest(String method) throws DeviceNotAvailableException { + var options = new DeviceTestRunOptions(PACKAGE_NAME); + options.setTestClassName(PACKAGE_NAME + ".BinaryTransparencyTest"); + options.setTestMethodName(method); + runDeviceTests(options); + } +} diff --git a/tests/BinaryTransparencyHostTest/test-app/Android.bp b/tests/BinaryTransparencyHostTest/test-app/Android.bp new file mode 100644 index 000000000000..b5193ddf7c2c --- /dev/null +++ b/tests/BinaryTransparencyHostTest/test-app/Android.bp @@ -0,0 +1,40 @@ +// Copyright (C) 2023 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // 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_applicable_licenses: ["frameworks_base_license"], +} + +android_test_helper_app { + name: "BinaryTransparencyTestApp", + manifest: "AndroidManifest.xml", + srcs: ["src/**/*.java"], + static_libs: [ + "androidx.test.core", + "compatibility-device-util-axt", + "junit", + ], + test_suites: [ + "general-tests", + ], + platform_apis: true, + dex_preopt: { + enabled: false, + }, +} diff --git a/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindow.aidl b/tests/BinaryTransparencyHostTest/test-app/AndroidManifest.xml index 343956759f09..42e616e24eb9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindow.aidl +++ b/tests/BinaryTransparencyHostTest/test-app/AndroidManifest.xml @@ -1,5 +1,6 @@ -/* - * Copyright (C) 2022 The Android Open Source Project +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,16 +13,15 @@ * 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.scvh; +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.transparency.test.app"> + <application> + <uses-library android:name="android.test.runner" /> + </application> -import android.view.SurfaceControlViewHost.SurfacePackage; -import android.os.IBinder; -import com.android.server.wm.scvh.IAttachEmbeddedWindowCallback; -import android.view.WindowManager.LayoutParams; - -interface IAttachEmbeddedWindow { - void attachEmbedded(IBinder hostToken, int width, int height, int displayId, long delayMs, IAttachEmbeddedWindowCallback callback); - void relayout(in LayoutParams lp); -}
\ No newline at end of file + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:label="APCT tests for binary transparency" + android:targetPackage="android.transparency.test.app" /> +</manifest> diff --git a/tests/BinaryTransparencyHostTest/test-app/src/android/transparency/test/app/BinaryTransparencyTest.java b/tests/BinaryTransparencyHostTest/test-app/src/android/transparency/test/app/BinaryTransparencyTest.java new file mode 100644 index 000000000000..aedb3666a574 --- /dev/null +++ b/tests/BinaryTransparencyHostTest/test-app/src/android/transparency/test/app/BinaryTransparencyTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.transparency.test.app; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import android.content.Context; +import android.os.Bundle; +import android.transparency.BinaryTransparencyManager; +import android.util.Log; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import com.android.internal.os.IBinaryTransparencyService.AppInfo; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.HashSet; +import java.util.HexFormat; +import java.util.stream.Collectors; + +@RunWith(AndroidJUnit4.class) +public class BinaryTransparencyTest { + private static final String TAG = "BinaryTransparencyTest"; + + private BinaryTransparencyManager mBt; + + @Before + public void setUp() { + Context context = InstrumentationRegistry.getInstrumentation().getContext(); + mBt = context.getSystemService(BinaryTransparencyManager.class); + } + + @Test + public void testCollectAllApexInfo() { + // Prepare the expectation received from host's shell command + Bundle args = InstrumentationRegistry.getArguments(); + assertThat(args).isNotNull(); + int number = Integer.valueOf(args.getString("apex-number")); + assertThat(number).isGreaterThan(0); + var expectedApexNames = new HashSet<String>(); + for (var i = 0; i < number; i++) { + String moduleName = args.getString("apex-" + Integer.toString(i)); + expectedApexNames.add(moduleName); + } + + // Action + var apexInfoList = mBt.collectAllApexInfo(/* includeTestOnly */ true); + + // Verify actual apex names + var actualApexesNames = apexInfoList.stream().map((apex) -> apex.moduleName) + .collect(Collectors.toList()); + assertThat(actualApexesNames).containsExactlyElementsIn(expectedApexNames); + + // Perform more valitidy checks + var digestsSeen = new HashSet<String>(); + var hexFormatter = HexFormat.of(); + for (var apex : apexInfoList) { + Log.d(TAG, "Verifying " + apex.packageName + " / " + apex.moduleName); + + assertThat(apex.longVersion).isGreaterThan(0); + assertThat(apex.digestAlgorithm).isGreaterThan(0); + assertThat(apex.signerDigests).asList().containsNoneOf(null, ""); + + assertThat(apex.digest).isNotNull(); + String digestHex = hexFormatter.formatHex(apex.digest); + boolean isNew = digestsSeen.add(digestHex); + assertWithMessage( + "Digest should be unique, but received a dup: " + digestHex) + .that(isNew).isTrue(); + } + } + + @Test + public void testCollectAllUpdatedPreloadInfo() { + var preloadInfoList = mBt.collectAllUpdatedPreloadInfo(new Bundle()); + assertThat(preloadInfoList).isNotEmpty(); // because we just installed from the host side + AppInfo updatedPreload = null; + for (var preload : preloadInfoList) { + Log.d(TAG, "Received " + preload.packageName); + if (preload.packageName.equals("com.android.egg")) { + assertWithMessage("Received the same package").that(updatedPreload).isNull(); + updatedPreload = preload; + } + } + + // Verify + assertThat(updatedPreload.longVersion).isGreaterThan(0); + assertThat(updatedPreload.digestAlgorithm).isGreaterThan(0); + assertThat(updatedPreload.digest).isNotEmpty(); + assertThat(updatedPreload.mbaStatus).isEqualTo(/* MBA_STATUS_UPDATED_PRELOAD */ 2); + assertThat(updatedPreload.signerDigests).asList().containsNoneOf(null, ""); + } +} diff --git a/tests/Input/src/com/android/test/input/MotionPredictorTest.kt b/tests/Input/src/com/android/test/input/MotionPredictorTest.kt index bc363b01ea4b..8b1b06fe40e8 100644 --- a/tests/Input/src/com/android/test/input/MotionPredictorTest.kt +++ b/tests/Input/src/com/android/test/input/MotionPredictorTest.kt @@ -102,9 +102,9 @@ class MotionPredictorTest { * a prediction. Here, we send 2 events to the predictor and check the returned event. * Input: * t = 0 x = 0 y = 0 - * t = 1 x = 1 y = 2 + * t = 4 x = 10 y = 20 * Output (expected): - * t = 3 x = 3 y = 6 + * t = 12 x = 30 y = 60 ± error * * Historical data is ignored for simplicity. */ @@ -118,19 +118,20 @@ class MotionPredictorTest { // ACTION_DOWN t=0 x=0 y=0 predictor.record(downEvent) - eventTime += Duration.ofMillis(1) - val moveEvent = getStylusMotionEvent(eventTime, ACTION_MOVE, /*x=*/1f, /*y=*/2f) + eventTime += Duration.ofMillis(4) + val moveEvent = getStylusMotionEvent(eventTime, ACTION_MOVE, /*x=*/10f, /*y=*/20f) // ACTION_MOVE t=1 x=1 y=2 predictor.record(moveEvent) - val predicted = predictor.predict(Duration.ofMillis(2).toNanos()) + val predicted = predictor.predict(Duration.ofMillis(8).toNanos()) assertEquals(1, predicted.size) val event = predicted[0] assertNotNull(event) - // Prediction will happen for t=3 (2 + 1, since offset is 1 and present time is 2) - assertEquals(3, event.eventTime) - assertEquals(3f, event.x, /*delta=*/0.001f) - assertEquals(6f, event.y, /*delta=*/0.001f) + // Prediction will happen for t=12 (since it is the next input interval after the requested + // time, 8, plus the model offset, 1). + assertEquals(12, event.eventTime) + assertEquals(30f, event.x, /*delta=*/5f) + assertEquals(60f, event.y, /*delta=*/15f) } } diff --git a/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostSyncTest.java b/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostSyncTest.java index ea727b91768d..359eb35384c7 100644 --- a/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostSyncTest.java +++ b/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostSyncTest.java @@ -131,8 +131,8 @@ public class SurfaceControlViewHostSyncTest extends Activity implements SurfaceH if (mSync) { SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG); - syncGroup.addToSync(getWindow().getRootSurfaceControl(), svResizeRunnable); - syncGroup.addToSync(mSurfacePackage, resizeRunnable); + syncGroup.add(getWindow().getRootSurfaceControl(), svResizeRunnable); + syncGroup.add(mSurfacePackage, resizeRunnable); syncGroup.markSyncReady(); } else { svResizeRunnable.run(); diff --git a/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java b/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java index d5983d064c80..d1f2112f649d 100644 --- a/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java +++ b/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java @@ -90,7 +90,7 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C if (mEnableSyncSwitch.isChecked()) { mSyncGroup = new SurfaceSyncGroup(TAG); - mSyncGroup.addToSync(container.getRootSurfaceControl()); + mSyncGroup.add(container.getRootSurfaceControl(), null /* runnable */); } ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams(); @@ -114,7 +114,7 @@ public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.C mRenderingThread.renderFrame(null, width, height); return; } - mSyncGroup.addToSync(mSurfaceView, frameCallback -> + mSyncGroup.add(mSurfaceView, frameCallback -> mRenderingThread.renderFrame(frameCallback, width, height)); mSyncGroup.markSyncReady(); mSyncGroup = null; |