Merge "Remove blocking call on binder thread to check account features."
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 7bd5921..b71d596 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 @@
/** 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 2533a0f..d7163d8 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 @@
}
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 @@
}
rescheduleKernelAlarmsLocked();
updateNextAlarmClockLocked();
- MetricsHelper.pushAlarmBatchDelivered(triggerList.size(), wakeUps);
+ logAlarmBatchDelivered(
+ triggerList.size(), wakeUps, countsPerUid, wakeupCountsPerUid);
}
}
@@ -4850,6 +4855,32 @@
}
}
+ 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 @@
}
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 28acb45..eb1848d 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 @@
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 299cb6c..e8fcdd2 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 @@
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 @@
}
}
- 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 @@
// 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 e87487a..bca9913 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -20181,6 +20181,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 a40d97e..c098adb 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -303,6 +303,7 @@
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 @@
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 ce29937..0fa1a37 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -955,4 +955,12 @@
* @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 9dc8ce6..058c389 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -795,7 +795,7 @@
// 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 @@
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 3bd86c1..92db8b3 100644
--- a/core/java/android/app/NotificationChannelGroup.java
+++ b/core/java/android/app/NotificationChannelGroup.java
@@ -20,6 +20,7 @@
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 @@
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 @@
} 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 @@
} 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 577c8a3..42aa608 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -902,8 +902,8 @@
* <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 3fc44f8..86c453b 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -1225,14 +1225,6 @@
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 @@
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 3ccc940..657541c 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -51,6 +51,7 @@
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 @@
*
* @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 @@
* @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 @@
*
* @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 @@
* @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 @@
*
* @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 @@
* @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 @@
*
* @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 @@
* @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 @@
*
* @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 a35b088..0307c10 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -7828,8 +7828,8 @@
}
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 07212a2..b2d89962 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5665,6 +5665,44 @@
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 @@
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 bf5b970..6e4535b 100644
--- a/core/java/android/service/dreams/DreamOverlayService.java
+++ b/core/java/android/service/dreams/DreamOverlayService.java
@@ -36,39 +36,101 @@
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 wakeUp() {
+ mService.wakeUp(this, () -> {
+ try {
+ mDreamOverlayCallback.onWakeUpComplete();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not notify dream of wakeUp", e);
+ }
+ });
}
@Override
public void endDream() {
- onEndDream();
+ 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 wakeUp() {
- onWakeUp(() -> {
- try {
- mDreamOverlayCallback.onWakeUpComplete();
- } catch (RemoteException e) {
- Log.e(TAG, "Could not notify dream of wakeUp:" + e);
- }
- });
+ 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);
+ }
}
};
- IDreamOverlayCallback mDreamOverlayCallback;
-
public DreamOverlayService() {
}
@@ -110,18 +172,23 @@
* 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 @@
* @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 d378886..6a4710f 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -248,25 +248,39 @@
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 @@
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 @@
* </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 @@
}
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 @@
mWindow.getDecorView().addOnAttachStateChangeListener(
new View.OnAttachStateChangeListener() {
- private Consumer<IDreamOverlay> mDreamStartOverlayConsumer;
+ private Consumer<IDreamOverlayClient> mDreamStartOverlayConsumer;
@Override
public void onViewAttachedToWindow(View v) {
@@ -1389,17 +1417,6 @@
@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 @@
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 0e4bd3b..7ec75a5 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 @@
*/
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 0000000..78b7280
--- /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 0000000..244d999
--- /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 7e8622a..21b14f4 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -2422,6 +2422,7 @@
@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 f6d7c61..d77bbcc 100644
--- a/core/java/android/transparency/BinaryTransparencyManager.java
+++ b/core/java/android/transparency/BinaryTransparencyManager.java
@@ -19,6 +19,7 @@
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 @@
}
}
+ /**
+ * 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 45b65e5..6551a18 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -25,6 +25,13 @@
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 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 fa86a4c..4d32efe 100644
--- a/core/java/android/view/MotionPredictor.java
+++ b/core/java/android/view/MotionPredictor.java
@@ -22,26 +22,27 @@
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 @@
/**
* 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 fedb098..54e1a53 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -280,7 +280,12 @@
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 @@
@GuardedBy("mLock")
private int mHeight;
+ private TrustedPresentationCallback mTrustedPresentationCallback;
+
private WeakReference<View> mLocalOwnerView;
static GlobalTransactionWrapper sGlobalTransaction;
@@ -2400,6 +2407,79 @@
}
/**
+ * 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 @@
}
/**
+ * 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 490091b..f7bdd09 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -97,7 +97,8 @@
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 e559a71..1eb87c9 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -1091,7 +1091,7 @@
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 7b53843..9fa6c05 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -25829,10 +25829,6 @@
* @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 @@
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 @@
* @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 9f5015c..0e4ac01 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -4631,7 +4631,7 @@
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 84ed845..9119ea4 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3768,7 +3768,7 @@
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 @@
// 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 @@
mBlastBufferQueue.syncNextTransaction(new Consumer<Transaction>() {
@Override
public void accept(Transaction transaction) {
- surfaceSyncGroup.addTransactionToSync(transaction);
+ surfaceSyncGroup.addTransaction(transaction);
surfaceSyncGroup.markSyncReady();
}
});
@@ -11391,7 +11391,7 @@
// 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 @@
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 40898d0..9bec409 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -629,114 +629,6 @@
@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 f2f4557..f4a8639 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1637,6 +1637,10 @@
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 12cd340..2e55041 100644
--- a/core/java/android/window/SurfaceSyncGroup.java
+++ b/core/java/android/window/SurfaceSyncGroup.java
@@ -42,14 +42,18 @@
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 @@
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 @@
}
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 @@
/**
* 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 @@
/**
* 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 @@
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 @@
}
@GuardedBy("mLock")
- private void invokeSyncCompleteListeners() {
+ private void invokeSyncCompleteCallbacks() {
mSyncCompleteCallbacks.forEach(
executorRunnablePair -> executorRunnablePair.first.execute(
executorRunnablePair.second));
@@ -188,6 +204,7 @@
*
* @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 @@
}
/**
- * 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 @@
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 @@
}
/**
- * Add an AttachedSurfaceControl to a sync set.
+ * 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.
- * @return true if the View was successfully added to the SyncGroup, false otherwise.
- * @see #addToSync(AttachedSurfaceControl, Runnable)
+ * @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) {
- 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.
- *
- * @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)
- */
- @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 @@
+ "SCVH returned null SurfaceSyncGroup");
return false;
}
- return addToSync(surfaceSyncGroup, false /* parentSyncGroupMerge */, runnable);
- }
-
- @Override
- public boolean addToSync(ISurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge) {
- return addToSync(surfaceSyncGroup, parentSyncGroupMerge, null);
+ return add(surfaceSyncGroup, 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 SurfaceSyncGroup to the current SurfaceSyncGroup.
*
- * @param surfaceSyncGroup A SyncableSurface that implements how to handle syncing
- * buffers.
+ * @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 ISurfaceSyncGroup} to a SurfaceSyncGroup.
+ *
+ * @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 @@
* @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 @@
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 @@
@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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
} 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 @@
} 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 @@
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 @@
/**
* 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 @@
* 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 @@
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 @@
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 406c230..04577a2 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 5b0abd3..b8446da 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 @@
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 void setStateDescription(CharSequence stateDescription) {
+ mStateDescription = stateDescription;
+ }
+
/**
* Gets the state description of this feature target.
*
@@ -113,7 +118,7 @@
*/
@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 469d10f..41a0ba2 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 @@
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 @@
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 ebdaed6..d2124a0 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 @@
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 @@
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 ca7b83e..e782aa7 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 @@
byte[] digest;
int digestAlgorithm;
String[] signerDigests;
+
+ // Test only
+ String moduleName;
}
parcelable AppInfo {
@@ -51,4 +56,8 @@
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 d9cb72a..cee8c1a 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -178,7 +178,14 @@
* 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 @@
? 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 5adbc58..e56c381 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 @@
@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 86fd956..2f51479 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.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 @@
@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 @@
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 @@
}
/**
+ * 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 @@
|| 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 eca85ff..82f414b 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -266,7 +266,6 @@
"av-types-aidl-cpp",
"android.hardware.camera.device@3.2",
"libandroid_net",
- "libandroidicu",
"libbattery",
"libnetdutils",
"libmemtrack",
@@ -287,6 +286,7 @@
"libPlatformProperties",
"libsensor",
"libinput",
+ "libicu",
"libcamera_client",
"libcamera_metadata",
"libprocinfo",
@@ -326,6 +326,7 @@
"libdl",
"libdl_android",
"libtimeinstate",
+ "libtflite",
"server_configurable_flags",
"libimage_io",
"libjpegdecoder",
@@ -343,7 +344,9 @@
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 225ed2c..97a0f50 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -246,6 +246,17 @@
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 @@
}
};
+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 @@
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 @@
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 @@
(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 @@
(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 @@
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 664e964..6a92581 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -353,6 +353,7 @@
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 @@
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 e56d55e..146ac9d 100644
--- a/core/proto/android/providers/settings/system.proto
+++ b/core/proto/android/providers/settings/system.proto
@@ -195,6 +195,17 @@
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 @@
// 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 b112e7a..82e1777 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -117,7 +117,7 @@
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 @@
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 7d69d56..81c7fba 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 2652da6..76a4da0 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 d47bcab..39e010e 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 b443e45..5a64dbe 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 e39a783..608e628 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 73bf38b..40af5eb 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 237aea2..0f39f41 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 aae5f56..6d1135f 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 f4d6749..cfe18d4 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 e669b6d..e02d75d 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 1e88766..3c1925b 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 5843095..41496a5 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 7e864a4..2e2c3e2 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 29cb818..7bd5556 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 29703a5..bf79e13 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 185308f..e17f78f 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 94bdb01..04cdfd9 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 599d6fc..cbe8013 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 b52f527..a43067a 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 dce46b4..02bea3d 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 b18ee98..d111611 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 93b4dc8..dad0231 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 caefd2c..abec04b 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 611c4c0..f246539 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 ccf7308..86e804c 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 8d0e8b1..e1a8322 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 f327cea..297278e 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 2019938..adc0f98 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 b58d375..ea481cd 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 d998add..735a4d5d 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 3be37c9..00bddbb 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 06a7b5e..65b1242 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 135a7c70..85a4c45 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 c4a0a9b..0c9a6cd 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 db6046c..3c2b686 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 c22480a..ce78f79 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 eadd87c..cba0380 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 e0fa0f4..bfa9666 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 e84252f..7315331 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 c384e99..52d018c 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 5e96865..c0fa6a0 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 eba758a..68ebba9 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 85247df..ee39924 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 2ad0200..d23a53e 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 ad429ba..a52259a 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 d4c4c07..67a890d 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 13a88ca..e890cc6 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 6a66751..0c43543 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 2bb12db..47233ff 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 52019e4..6c4bcb1 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 88ce780..9652af5 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 0dc530d..5f9c268 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 1b899a5..e6dd0bb 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 7419995..364c325 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 8d78806..0a8990c 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 1835ceb..d646c76 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 9492433..d300beb 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 8de5fe4..9b6b896 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 2dc96a7..c2560da 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 a2f3b11..4086ab7 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 d0857f5..f57ec7e 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 8c03ed9..6fc8ce5 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 fc91fb4..f7b9e69 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 8c03ed9..6fc8ce5 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 77206a1..b9c90b1 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 650fc71..b7a3f60 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 d686d82..edb7dc2 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 123b63c4..af6cc59 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 ce19c52..e33b67d 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 4964349..b3e3108 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 914e36c..fd55aa2e 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 c45c847..eec2656 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 cc7aa19..f0bb94b 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 149f895..80a9ee9 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 709be1a..e0e232f 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 3d46e4d..6c6b406 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 ff08592..21f8e39 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 79ba5b5..f62560e 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 cd8762f..322929f 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 88cf716..50e79a1 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 6a88112..ddcb6e1 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 eeb799f..9ae3290 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 820d692..118c520 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 b0e5f60..2e44412 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 79b8bce..2155790 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 55b5e9a..c81ab5e 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 d3aee43..a07d85e 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 f7ed38c..0ec3ef7 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 1c0e39d..0000000
--- 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 51e530a..0000000
--- 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 396fd12..0000000
--- 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 b2914d8..0000000
--- 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 6536e43..cb75779 100644
--- a/keystore/java/android/security/KeyStoreException.java
+++ b/keystore/java/android/security/KeyStoreException.java
@@ -265,7 +265,7 @@
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 @@
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 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 @@
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 @@
@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 @@
? 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 @@
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 f615ad6..0f45219 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -47,6 +47,7 @@
"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 904ae86..a93f090 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 8b46704..032767e 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 635334d..9bbee53 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 788fd5c..f7ea139 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 a56918d..86b7714 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 dcb03aa..4a1ee7a 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 f6b285a..1986699 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 044f2a7..b8a0316 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 1fb0292..40395fa 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 8e52d78..daef1a0 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 6bc4f99..85edc20 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 b638b0e..ce11197 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 e0b7a8c..38acf45 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 caca8b4..d455fc6 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 ffb4fb0..051a20d 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 c71011d..68f5de9 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 05091fb..204a24f 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 c71011d..68f5de9 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 c71011d..68f5de9 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 2993fe7..81e6e05 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 0eaca8b..7b569f2 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 9c8fed1..b9ee866 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 e8cbe53..de569e6 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 4417668..c05b3c7 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 7375faf..f7d52f9 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 7729d1c..91120d4 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 6348800..59bd339 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 1842213..41de4db 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 2e05d4c..573e17e 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 e680298..35e9607 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 9a926d8..173029a 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 23a5970..c45bb56 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 1bbbdb7..7c45113 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 6eef4af..c26c540 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 61a9558..8247309 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 0b873bc..b64f2d5 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 da4d0bb..ffb5f30 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 e9a53dd..5f204b2 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 2930cc3..8c70341 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 848be3f..82048c9 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 8d08ccab..ed4a14b 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 7c4ea57e..e705301 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 7290617..bebf0c0 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 59b405f..6c58c31 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 6919a8e..9f4dbb5 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 d5ea3cf..97a7344 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 922f5b5..5fc2592 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 08ac928..a89545d 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 ae71ae9..1aab9ef 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 0923312..f74738b 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 c1950a1..51c4584 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 29821f6..cbde558 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 c3db19d..23f7e52 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 b2bb37d..2fae552 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 90b9dfc..b34e134 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 15f22f7..7bcca1a 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 f9f4ef4..6ec4739 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 5a76a6f..0f27984 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 617c95e..2baec3c 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 4a17ec7..ecf6b4d 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 69be68e..847573b 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 13e83ac..b684c6c 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 69be68e..847573b 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 c112a9d..5342dfb 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 489adc0..71925a1 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 3237114..188a137 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 a753021..0aa4f30 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 b5d8733..a4eb3d0 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 ebd644c..cc4b7a4 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 d051ca3..80f7aa6 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 cd46039..4a4b6c9 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 345fbf8..ad33144 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 525f2ea..52f5e22 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 0c0114a..2eb739d 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 9f3a146..e0b1bb1 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 c20a07f..a49ed27 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 aeb86da..c19e083 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 b589ed8..6869401 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 81672bf..e3a22eb 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 d0384e9..d12dac3 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 49986b5..39de38c 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 acdb252..c787f61 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 b1a957e5..395b2a9 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 bb3dba1..8a84f15 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 51a23ff..fca5a7a 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 94e01e9..5d451a5 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.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 @@
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.
+ * 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 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.
- */
- 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 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();
}
- 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 Rect getCurrentBoundsOnScreen() {
+ getBoundsOnScreen(mTmpRect);
+ return mTmpRect;
+ }
+
+ @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 @@
* 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 @@
/** 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 0000000..3d0a8fd
--- /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 42844b5..735d9bc 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 @@
/** 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 0000000..69ce35f
--- /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 07d5012..aab257e 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 @@
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 @@
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 @@
// 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 @@
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 @@
* 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
} 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 e85b3c7..1feff18 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.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 @@
private AlphaOptimizedButton mManageButton;
private TaskView mTaskView;
+ private TaskViewTaskController mTaskViewTaskController;
private BubbleOverflowContainerView mOverflowView;
private int mTaskId = INVALID_TASK_ID;
@@ -409,8 +411,10 @@
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 c14704d..fe95d04 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 @@
: 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 7096a64..283b1ec 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 @@
}
}
+ @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 36ce0a6..a3e05f2 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.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 @@
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 @@
} 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 6af81f1..1549355 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.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 @@
/** 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 @@
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 @@
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 f77ac81..476a7ec 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 @@
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 @@
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 @@
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 f94fbfc..060dc4e 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 @@
private View.OnClickListener mOnCaptionButtonClickListener;
private View.OnTouchListener mOnCaptionTouchListener;
- private DragResizeCallback mDragResizeCallback;
+ private DragPositioningCallback mDragPositioningCallback;
private DragResizeInputListener mDragResizeListener;
private DragDetector mDragDetector;
@@ -78,8 +78,8 @@
mOnCaptionTouchListener = onCaptionTouchListener;
}
- void setDragResizeCallback(DragResizeCallback dragResizeCallback) {
- mDragResizeCallback = dragResizeCallback;
+ void setDragPositioningCallback(DragPositioningCallback dragPositioningCallback) {
+ mDragPositioningCallback = dragPositioningCallback;
}
void setDragDetector(DragDetector dragDetector) {
@@ -151,7 +151,7 @@
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 c0c0ab9..606cf28 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 @@
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 @@
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 @@
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 @@
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 31b56d3..744c18f 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 @@
private View.OnClickListener mOnCaptionButtonClickListener;
private View.OnTouchListener mOnCaptionTouchListener;
- private DragResizeCallback mDragResizeCallback;
+ private DragPositioningCallback mDragPositioningCallback;
private DragResizeInputListener mDragResizeListener;
private DragDetector mDragDetector;
@@ -90,8 +90,8 @@
mOnCaptionTouchListener = onCaptionTouchListener;
}
- void setDragResizeCallback(DragResizeCallback dragResizeCallback) {
- mDragResizeCallback = dragResizeCallback;
+ void setDragPositioningCallback(DragPositioningCallback dragPositioningCallback) {
+ mDragPositioningCallback = dragPositioningCallback;
}
void setDragDetector(DragDetector dragDetector) {
@@ -179,7 +179,7 @@
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
similarity index 76%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeCallback.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java
index ee160a1..0191c60 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 @@
/**
* 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 ea417b1..3d1edc9 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 @@
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 @@
Choreographer choreographer,
int displayId,
SurfaceControl decorationSurface,
- DragResizeCallback callback) {
+ DragPositioningCallback callback) {
mInputManager = context.getSystemService(InputManager.class);
mHandler = handler;
mChoreographer = choreographer;
@@ -294,7 +294,7 @@
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 @@
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 @@
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 8cd2a59..d3f9227 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 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 @@
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 @@
}
@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 @@
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 @@
}
@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 @@
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;
+ // |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 - mResizeStartPoint.x;
- final float deltaY = y - mResizeStartPoint.y;
- mResizeTaskBounds.set(mTaskBoundsAtDragStart);
+ 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 d5bb901..62bfd17 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 @@
Context mContext;
TaskView mTaskView;
TaskViewTransitions mTaskViewTransitions;
+ TaskViewTaskController mTaskViewTaskController;
@Before
public void setUp() {
@@ -125,7 +126,9 @@
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 @@
@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 @@
@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 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 @@
@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 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 @@
@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 @@
@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 @@
@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 @@
@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 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 @@
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 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 @@
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 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 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 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 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 f24a7f2..f3f615d9 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.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 @@
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 804c416..f185a8a 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 @@
@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 @@
@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 @@
@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 @@
}
})
- taskPositioner.onDragResizeEnd(
+ taskPositioner.onDragPositioningEnd(
STARTING_BOUNDS.left.toFloat() + 10,
STARTING_BOUNDS.top.toFloat() + 10
)
@@ -150,7 +150,7 @@
@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 @@
// 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 @@
@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 @@
// 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 b563627..13357fa 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 232fd71..63d3f83 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 @@
///////////////////////////////////////////////////////////////////////////////
+#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
}
+#else
+// 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 312b60b..bbdd98e 100644
--- a/libs/hwui/tests/common/BitmapAllocationTestUtils.h
+++ b/libs/hwui/tests/common/BitmapAllocationTestUtils.h
@@ -56,10 +56,11 @@
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 11b5833..c6f32c2 100644
--- a/location/java/android/location/GnssCapabilities.java
+++ b/location/java/android/location/GnssCapabilities.java
@@ -129,21 +129,26 @@
* @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 @@
*
* @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 @@
if (mMeasurementCorrectionsFlags == flags) {
return this;
} else {
- return new GnssCapabilities(mTopFlags, flags, mPowerFlags,
+ return new GnssCapabilities(mTopFlags, mIsAdrCapabilityKnown, flags, mPowerFlags,
mGnssSignalTypes);
}
}
@@ -189,8 +195,8 @@
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 @@
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 @@
* 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 @@
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 @@
@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 @@
@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 @@
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 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 Builder(@NonNull GnssCapabilities capabilities) {
mTopFlags = capabilities.mTopFlags;
+ mIsAdrCapabilityKnown = capabilities.mIsAdrCapabilityKnown;
mMeasurementCorrectionsFlags = capabilities.mMeasurementCorrectionsFlags;
mPowerFlags = capabilities.mPowerFlags;
mGnssSignalTypes = capabilities.mGnssSignalTypes;
@@ -768,12 +796,22 @@
* 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 @@
* 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 d4b861f..4fc2ee8 100644
--- a/location/java/android/location/GnssMeasurementsEvent.java
+++ b/location/java/android/location/GnssMeasurementsEvent.java
@@ -43,7 +43,7 @@
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 @@
* 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 @@
/**
* 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 @@
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 @@
* 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 @@
* 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
similarity index 74%
rename from services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindowCallback.aidl
rename to media/java/android/media/AudioPresentation.aidl
index 92abfc8..3fb5a5b 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 05f3c5a..a413545 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 @@
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 @@
* 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 @@
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 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 @@
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 @@
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 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 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 @@
* @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 @@
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 948fef4..194da21 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -272,15 +272,19 @@
@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 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 b03653c0..ff0a492 100644
--- a/media/java/android/media/RouteListingPreference.java
+++ b/media/java/android/media/RouteListingPreference.java
@@ -32,6 +32,7 @@
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 @@
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 @@
* 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 @@
@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 @@
mDisableReason = in.readInt();
mSessionParticipantCount = in.readInt();
Preconditions.checkArgument(mSessionParticipantCount >= 0);
+ mCustomDisableReasonMessage = in.readCharSequence();
+ validateCustomDisableReasonMessage();
}
/**
@@ -346,6 +362,7 @@
* @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 @@
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 @@
dest.writeInt(mFlags);
dest.writeInt(mDisableReason);
dest.writeInt(mSessionParticipantCount);
+ dest.writeCharSequence(mCustomDisableReasonMessage);
}
// Equals and hashCode.
@@ -392,12 +429,28 @@
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 @@
private int mFlags;
private int mDisableReason;
private int mSessionParticipantCount;
+ private CharSequence mCustomDisableReasonMessage;
/**
* Constructor.
@@ -444,6 +498,14 @@
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 d55d287..c4f60c3 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 @@
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 f7c1e3c..746cfa2 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 @@
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 @@
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 64a23a2..be73c0c 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 @@
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 326b98d..e6c09a9 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 @@
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 8216622..0111f09 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 @@
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 634f102..847762f 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -30,7 +30,6 @@
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 @@
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 @@
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 @@
+ "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 @@
}
@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 @@
}
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 e8127df..a4e2212 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -26,11 +26,13 @@
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.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 @@
}
/**
+ * 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 @@
});
}
+ 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 @@
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 @@
* 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 @@
* @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 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 @@
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 @@
* @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 @@
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 @@
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 @@
}
/**
+ * 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
old mode 100755
new mode 100644
index 15f511b..b769757
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -26,11 +26,13 @@
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.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 @@
@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 @@
args.arg2 = cb;
args.arg3 = inputId;
args.arg4 = sessionId;
+ args.arg5 = tvAppAttributionSource;
mServiceHandler.obtainMessage(ServiceHandler.DO_CREATE_SESSION,
args).sendToTarget();
}
@@ -370,6 +371,24 @@
}
/**
+ * 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 @@
}
/**
+ * 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 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 @@
}
/**
- * called when broadcast info is removed.
+ * Called when broadcast info is removed.
*/
public void onRemoveBroadcastInfo(int requestId) {
}
@@ -1246,6 +1333,23 @@
}
/**
+ * 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 @@
}
/**
+ * 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 @@
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 @@
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 2fdbc3b..c7a63ac 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -21,6 +21,7 @@
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.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.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 @@
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 @@
mDefStyleAttr = defStyleAttr;
resetSurfaceView();
mTvInputManager = (TvInputManager) getContext().getSystemService(Context.TV_INPUT_SERVICE);
+ mTvAppAttributionSource = getContext().getAttributionSource();
}
/**
@@ -304,6 +308,22 @@
}
/**
+ * 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 @@
// 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 @@
}
/**
+ * 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 @@
resetInternal();
mSessionCallback = new MySessionCallback(inputId, recordedProgramUri);
if (mTvInputManager != null) {
- mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+ mTvInputManager.createSession(
+ inputId, mTvAppAttributionSource, mSessionCallback, mHandler);
}
}
}
@@ -977,6 +1028,27 @@
}
/**
+ * 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 @@
}
@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 ac920d2..7d08b81 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -1297,6 +1297,13 @@
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 35ee3ee9..625e842 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::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 @@
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 @@
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 @@
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 @@
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 55a7c0f..c2e5ba8 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 755d28d..8881940 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 f055acc..a37e0a3 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 5eb9e16..f78449c 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 40181ef..54c9e6e 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 b1d6b08..cd411c9 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 2124253..d20a1e8 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 58a8490..0759011 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 5a405a9..85642b8 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 9435c29..769f240 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 e47e5fe..7274bce 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 60f8dbb..2cbe297 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 d4c612b..1a388cd 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 5ae71fd..ad6c794 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 bd711cc..92b47be 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 36f48e0..2c1be52 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 bd75210..a841cb2 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 ef04781..170bd76 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 2a38941..8684ee6 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 a3f0017..ea88457 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 2ce3285..4a895f4 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 6608570..51a51ff 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 dcf800e..1fefe92 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 ee8cbf7..a48c605 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 8abf26be..6a4642c 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 48ce1c7..f7349f9 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 aca2a38..540a54c 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 7f4a089..de957a9 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 943d806..166af5a 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 950c789..a58bd06 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 7029c86..618e335 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 1eac728..ac044ec 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 b6c5d96..1c72f30 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 7c24542..cfc46e8 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 8484fdd..c8fb73b 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 5e553b4..9927ea0 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 48cc440..563117f 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 53b71ab..7ed0c3c 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 723f21c..f62b72d 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 3d482f9..5a35369 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 47e41a7..7244489 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 2cea9c8..6f68adb 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 a987b66..bb35963 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 5a52190..3182c13 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 6cad43d..2979cff 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 163398e..759f2d46 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 408ccb1..17905ee 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 6d3a184..e8d8ecc 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 5d59484..300c95f 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 86135b0..b214c04 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 8da48c1..91afe23 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 f99b5f0..2797b37 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 5ea787f..c096d13 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 c685bc2..c6e67cf 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 30a823d..875460d 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 0ca9df7..a037d78 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 47325b5..c833024 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 6dff909..08dd739 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 c501178..445284d 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 05a0601..cc39214 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 6cc26c5..71ee22b 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 f9efc85..71e8cb3 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 790ee8f..66aa664 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 b3d42d0..8171335 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 d13c991..2e5218c 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 1637a94..2082e7e 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 88c3cb6..7daf552 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 f40ddfb..dce384d 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 beef76f..4af16b3 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 6afbb08..ac15c5b 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 b061db4..30d9219 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 1ba1ef1..d18dd15 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 1be7ca5..a75dbc2 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 309a10b..2e4ed38 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 fffcf00..8626790 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 d4afb28..047f738 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 8627030..bee211e 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 b8d63e1..ce33822 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 6d8af5f..7e6d10a 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 c77130c..cbf199e 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 9f857d1..bf7a09e 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 7deefbb..7a8e50a 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 7deefbb..7a8e50a 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 73bddea..b0a008f 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 a8561f4..eeb4a96 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 897450e..28e8716 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 375d97dc..0474277 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 d1a043d..fe13124 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 68af50b..3c50151 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 9857215..77beb85 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 1c78fb8..d75ac57 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 5a3bcba..4ee0b51 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 46e7649..bd10f42 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 f815f67..43ece9a 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 0fe35b1..f2b9476 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 78a3d22..daffaca 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 54fe97c..5255b92 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 0be95d2..274ed21 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 f281c0d..d6624f0 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 bc3a9c8..fd2aeb1 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 de53a5e..4ebcd33 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 f41115b..88fd1a5 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 08758a1..401ffdb 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 d6e117f..7d46f9d 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 13bd74b..9837d15 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 9e7a0af..052750f 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 140cd2f..abbd499 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 ec64f9b..6104121 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 2f849a2..2f03d02 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 9b75fe3..369c33b 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 c556952..85fcfbe 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 7f47029..b2219a78 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 dea95e8..0e59529 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 3c3eae8..11cd8f4 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 beec7c7..7bcc90f 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 054506c..1c3197d 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 beec7c7..7bcc90f 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 beec7c7..7bcc90f 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 d8df532..a0aaabb 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 9d44fcc..9808e2a 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 bedb822..de337d3 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 38a6fbf..555c8bf 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 ad2a5be..1a50a26 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 2725afa..1c636c7 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 0a7486d..e117dfb 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 1377f25..8e19690 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 5eaea19..b3e76f9 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 205cb26..b3d9973 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 ab752e6..0831270 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 3bb636d..43e6e4d 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 2eb3434..8e7f6fe 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 fc2d34b..79b1f3d 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 8a6f3af..4b0b549 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 56b47ad..a50bf0c 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 08fa6a0..7bfaff4 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 939b1f4..b3eb19b 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 906043f..2542f0e 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 d114bb2..cacd022 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 82ca5a7..c100740 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 562898d..b973362 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 938aa3be..7b65679 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 e70d75d..ab00502 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 b5adf3f..c401430 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 34c6293..d3d82c3 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 45cd47a..7ab33a9 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 a58fc8e17..9ffa09c 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 b802fa2..c3e1a88 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 c038506..e100257 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 68bb819..ca1ae38 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 6a95f54..3be98b5 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 fb271b3..ffd6610 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 4e9daa7..1c369bc 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 35e82fe..08135d2 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 3b145d1..ad49d525 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 4efd35a..034c6f6 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 3e85971..1a73282 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 f457a2d..95ad470 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 e8977d1..9e6b9b8 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 e06dea6..6784325 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 98a75cf..8514aeb 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 07bd2de..248c366 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 98a75cf..8514aeb 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 7a18b2a..2dc2b0c 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 3bc40c3..e811b4e 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 9d400ef..dfd88ef 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 cb3cdae..8620d60 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 654fba1..f083ec2 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 b967259..271a7b3 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 8858ef5..3ac1995 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 43f3d4c..8681392 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 978f667..849a042 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 eaa8711..564606a 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 a6cd3e7..b1662eb 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 fd1af0b..c0fe2ed 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 f46be7f..f194e86 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 7548c5d..fb64517 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 48ff554..1b805d3 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 1327d48..03ee46a 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 ef8f6b3..aeb00cc 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 2d49c9b..7fbc74c 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 eb13321..b5f3cba 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 d7fb07e..74e8bea 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 a825d20..a338015 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 62c8a9a..9298cbd 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 ded6251..9117524a 100644
--- a/packages/SettingsLib/Spa/build.gradle
+++ b/packages/SettingsLib/Spa/build.gradle
@@ -19,12 +19,12 @@
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 bf4ad75..e035615 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle
+++ b/packages/SettingsLib/Spa/spa/build.gradle
@@ -75,9 +75,9 @@
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 f7cbdae..72f662f 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 @@
/**
* 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 ae88ed7..e8b5b19 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.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.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 @@
actions = actions,
colors = topAppBarColors(),
windowInsets = TopAppBarDefaults.windowInsets,
- maxHeight = 176.dp,
+ maxHeightWithoutTitle = 120.dp,
pinnedHeight = ContainerHeight,
scrollBehavior = scrollBehavior,
)
@@ -258,8 +261,8 @@
* 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 @@
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 @@
)
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 7c75bc4..c9d840a 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 @@
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 bd43606..c2a3ada 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 @@
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 75d28d5..25b9906 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 @@
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 2779fa2..0664061 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 c729b09..17a94b86 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.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 @@
* 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 e91a671..b8d78fb 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.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 @@
* 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 @@
}
?: 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 @@
}
// 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 @@
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 @@
// 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 26aa0e8..23e3a01 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.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 @@
* 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 @@
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 0000000..2eb503b
--- /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 9257f99..46d5a5c 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 @@
/** 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 fd9355d..e4f6db5 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 @@
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 0e3d41c..7897934 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 @@
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 9058510..4322d53 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 @@
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 @@
"""
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 @@
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 @@
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 @@
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 b37c734..bc4796a 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 @@
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 @@
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 @@
}
// 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 de96e97..446bb01 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 5588fd3..a64c9ae 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 6f33623..07c428b 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 0000000..101fad9
--- /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 0000000..65fc19c
--- /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 abc8337..f2e114b 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 c949ba0..18d231c 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 496eb6e..7e8bc2c 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 0000000..c794d91
--- /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 7f12066..6bb51bbb 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 822f156..45e83c0 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 3daba41..eeaf5d7 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 16c9935..56f7e8e 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 0646697..6b5ad2a 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 9b8bbec..3f9f3ec 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 3a476f4..d4dc17b 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 de24b94..2141a47 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 a72733c..691293c 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 d82e269..57c0a23 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 308ea11..e5563c0 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 2a01318..c099f66 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 d7467b00..c50202d 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 0b01f15..0ac3f4b 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 0db8cfb..eb0abea 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 8f6b9b9..cad3b47 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 8c4e66c..c41a164 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 8f6b9b9..cad3b47 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 8f6b9b9..cad3b47 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 34bf569..059a5fa 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 d4bbb3f..706248b 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 db0b4b0..458cd38 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 8171ddd9..82bb481 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 6f49d06..ebbc8db 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 f46d67b..ab78224 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 ffb420d..b84ca4f 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 006cce8..a60d961 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 d9267c9..1a37657 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 a06ddd7..cb1a8cb 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 687d1af..78aa0f5 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 555b3d7..c0d89f9 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 7e0ba00..cdf6e57 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 4c8c988..c411a0a 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 370ce823..9186f12 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 bd1f48b..1d0d3d6 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 cd924f2..aabae2f 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 531ac20..ced316f 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 926e2aa..dba7c4e 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 8cd79df..f88eb8b 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 fe0a8a0..dd4f03dc 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 b2274c8..f4575f0 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 d33b439..d5e31aa 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 e9dc769..687fa28 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 c9d70a1..3631973 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 54a073e..f5b4a26 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 fc386d6..8754166 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 753b8b7..d42fc7a 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 f2af1c1..d01cab9 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 1517c23..f8e0151 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 365e660..96ebfd0 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 a6194c9..5a552ad 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 bbcd720..a9e57f7 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 9b9e72c..9ffe823 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 21ebda9..3ccac95 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 30fa917..44d97aa 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 4cc7c2f..b5ffc21 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 8f0d864..221a9d8 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 b179bc5..e3314b3 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 d8ffabf..be4e149 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 f25f1a6..b9c3fa6 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 fd5328f..8bb3e7d 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 5efafc7..19e9194 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 fd5328f..8bb3e7d 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 c23098a..2473153 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 0f1b895..830b0c1 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 9ad90af..bee211a 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 a646e5b..beb0ee07 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 48c4a66..72eddd3 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 0713019..0cbd9cd 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 864b861..4c685a9 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 24c939c..94cd420 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 1c1d71e..9fbaf92 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 07f90ba..dd99594 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 824fd11..655f2f9 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 ff1bf35..1d62202 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 a287d20..e29fc9e 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 de21f2c..d421610 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 61fc89c..43c212d 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 bec50f1..c9e1ee4 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 939cb5c..d31f3f8 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 2326813..2a4989a 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 bfc6cc5..431146b 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 3f14f5e..ac27be2 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 e02597f..56fc01d 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 a68b214..eda7571 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 d01bc4a..f5db5ec 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 ade75cb..9e001e0 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 d14207a..575dc94 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 f8f5e83..dd87e91 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 0000000..d3be3c7
--- /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 0000000..88c7055
--- /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 196f7f0..c9a25b0 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 @@
val resourceId: Int
}
-interface DeviceConfigFlag<T> : Flag<T> {
- val default: T
-}
-
interface SysPropFlag<T> : Flag<T> {
val default: T
}
@@ -80,8 +76,8 @@
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 @@
) : 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 @@
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 @@
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 @@
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 @@
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 @@
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 195ba465..72a4fab 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 @@
/** 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 d85292a..da1641c 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 @@
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 @@
* 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 @@
* 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 @@
}
}
- 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 @@
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 @@
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 742bb0b..6beb851 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 @@
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 857cc462..5d036fb 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.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 @@
private final int mTaskbarBottomMarginResource;
@DimenRes
private final int mButtonDiameterResource;
+ @BoolRes
+ private final int mFloatingRotationBtnPositionLeftResource;
private AnimatedVectorDrawable mAnimatedDrawable;
private boolean mIsShowing;
@@ -84,7 +87,7 @@
@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 @@
mTaskbarLeftMarginResource = taskbarLeftMargin;
mTaskbarBottomMarginResource = taskbarBottomMargin;
mButtonDiameterResource = buttonDiameter;
+ mFloatingRotationBtnPositionLeftResource = floatingRotationBtnPositionLeftResource;
updateDimensionResources();
}
@@ -116,8 +120,11 @@
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 ec3c073..40e43a9 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 @@
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 @@
taskbarVisible: Boolean,
taskbarStashed: Boolean
): Position {
-
val isTaskbarSide = currentRotation == Surface.ROTATION_0
|| currentRotation == Surface.ROTATION_90
val useTaskbarMargin = isTaskbarSide && taskbarVisible && !taskbarStashed
@@ -55,11 +55,21 @@
)
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 05372fe..31234cf 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 @@
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 @@
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 @@
resourceId = resourceId,
teamfood = teamfood
)
- FlagsFactory.checkForDupesAndAdd(flag)
+ checkForDupesAndAdd(flag)
return flag
}
@@ -77,18 +77,13 @@
): 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 1680b47..3a940e9 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.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 @@
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 7da27b1..baaef19 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
@@ -103,6 +103,7 @@
@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 6d9c5df..0685794 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.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 @@
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 @@
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 @@
}
}
+ 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 @@
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 02776a2..ec8fa92 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 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 @@
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 @@
private final SparseArray<Presentation> mPresentations = new SparseArray<>();
- private final DisplayManager.DisplayListener mDisplayListener =
- new DisplayManager.DisplayListener() {
+ 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 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) {
-
- }
-
- @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 @@
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 @@
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 @@
// 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 d1c9a30..b143c5b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
@@ -121,6 +121,7 @@
@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 0b2b121..e3de8c7 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.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 @@
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 @@
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 @@
}
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 @@
@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 9ac45b3..227f0ace 100644
--- a/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt
+++ b/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt
@@ -34,7 +34,7 @@
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 e6f559b..71f98fa 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.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.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 @@
R.id.display_cutout_bottom
};
- private DisplayManager mDisplayManager;
+ private DisplayTracker mDisplayTracker;
@VisibleForTesting
protected boolean mIsRegistered;
private final Context mContext;
@@ -128,7 +129,7 @@
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 @@
SecureSettings secureSettings,
TunerService tunerService,
UserTracker userTracker,
+ DisplayTracker displayTracker,
PrivacyDotViewController dotViewController,
ThreadFactory threadFactory,
PrivacyDotDecorProviderFactory dotFactory,
@@ -311,6 +313,7 @@
mSecureSettings = secureSettings;
mTunerService = tunerService;
mUserTracker = userTracker;
+ mDisplayTracker = displayTracker;
mDotViewController = dotViewController;
mThreadFactory = threadFactory;
mDotFactory = dotFactory;
@@ -376,7 +379,6 @@
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 @@
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 @@
}
}
};
-
- 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 46cc894..00f5ac2 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.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.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 @@
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 @@
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 @@
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 348c2ee..3653bc8 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.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 @@
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 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 @@
mModeSwitchesController = modeSwitchesController;
mSysUiState = sysUiState;
mOverviewProxyService = overviewProxyService;
+ mDisplayTracker = displayTracker;
mMagnificationControllerSupplier = new ControllerSupplier(context,
mHandler, this, context.getSystemService(DisplayManager.class), sysUiState,
secureSettings);
@@ -144,14 +147,14 @@
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 7fedf16..2c413a2 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.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 @@
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 @@
AccessibilityButtonModeObserver accessibilityButtonModeObserver,
KeyguardUpdateMonitor keyguardUpdateMonitor,
FeatureFlags featureFlags,
- SecureSettings secureSettings) {
+ SecureSettings secureSettings,
+ DisplayTracker displayTracker) {
mContext = context;
mWindowManager = windowManager;
mDisplayManager = displayManager;
@@ -115,6 +117,7 @@
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mFeatureFlags = featureFlags;
mSecureSettings = secureSettings;
+ mDisplayTracker = displayTracker;
mIsKeyguardVisible = false;
}
@@ -185,7 +188,8 @@
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 ee09c62..ecfe4ca 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 @@
@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 c2bc140..7f4e7844 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 @@
* {@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 @@
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 e2a9d54..105de16c 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 @@
}
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 aad708a..0538e7d 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.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 @@
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 @@
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 8a31142..d01590f 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 @@
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 0000000..849b79a
--- /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 28269d9..47770fa 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 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 @@
}
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 86f0d06..665a398 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.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 @@
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 @@
AssistLogger assistLogger,
@Main Handler uiHandler,
UserTracker userTracker,
+ DisplayTracker displayTracker,
SecureSettings secureSettings) {
mContext = context;
mDeviceProvisionedController = controller;
@@ -150,6 +151,7 @@
mPhoneStateMonitor = phoneStateMonitor;
mAssistLogger = assistLogger;
mUserTracker = userTracker;
+ mDisplayTracker = displayTracker;
mSecureSettings = secureSettings;
registerVoiceInteractionSessionListener();
@@ -214,7 +216,7 @@
.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 e42f051..3e5d16a 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 @@
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 04a2689..53ab6d6 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 @@
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 @@
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 @@
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 @@
}
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 9bccafb..2d0d52e 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.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 @@
) {
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 @@
)
}
}
- /**
- * 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 @@
}
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 @@
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 @@
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 @@
} else {
keyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false)
}
- updateBouncerHiddenAmount()
updateAlpha()
updatePauseAuth()
return true
@@ -425,19 +409,11 @@
}
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 @@
}
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 @@
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 f97d6af..8c8ee8a 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.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 @@
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 @@
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 @@
}
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 2244813..09b2e44 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 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 @@
*/
@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 0000000..9763665
--- /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 ddde628..2edac52 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.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 31cc0bd..c3f24f0 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.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 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 @@
@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 @@
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 4382757..e1d0339 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 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 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 267e036..61e4c32 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 @@
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 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 @@
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 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 @@
}
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 @@
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 @@
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 @@
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 id " + id);
+ 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 name " + name);
}
@Override
@@ -340,13 +386,13 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
};
- 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 8bddacc..7e14237 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 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 @@
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 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 @@
@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 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 @@
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 b7fc0e4..daf9429 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 @@
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 @@
@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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 a6977e1..fa0ce24 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 @@
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 @@
// 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 8442230..0054d26 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 @@
@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 ae05c46..a02b795 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 @@
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 d9bcb50..418aeca 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 @@
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 @@
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 9c7411b..6a27ee7 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 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.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 @@
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 @@
@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 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 fe945fb..d302b13a 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 @@
*/
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 @@
@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 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 4a3071d..7a891b0 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.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 @@
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 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 @@
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 e9d7a5b..3319f9d 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.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 @@
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 @@
.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 @@
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 5e46c5d..c1731e0 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 @@
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 c6002d6..737c35d 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 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 @@
/** 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 1a10b18..8c1ec16 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.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 @@
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 @@
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 @@
* @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 @@
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 e7f7647..b2ad155 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.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 @@
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 @@
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 39dd733..2fd4f27 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 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 @@
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 @@
});
}
+ 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 @@
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 @@
// 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 @@
recommendation.getTitle(), artistName, appName));
}
-
// Set up title
CharSequence title = recommendation.getTitle();
hasTitle |= !TextUtils.isEmpty(title);
@@ -1356,6 +1429,10 @@
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 2ec7be6..1e6002c 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.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 @@
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 @@
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 ab03930..81efa36 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 @@
* 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 4e08050..dc75538 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.TextView;
import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
import androidx.recyclerview.widget.RecyclerView;
import com.android.settingslib.Utils;
@@ -142,11 +143,12 @@
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 @@
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 1587e62..5f5c686 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 @@
@VisibleForTesting
LocalMediaManager mLocalMediaManager;
@VisibleForTesting
- private MediaOutputMetricLogger mMetricLogger;
+ MediaOutputMetricLogger mMetricLogger;
private int mCurrentState;
private int mColorItemContent;
@@ -870,12 +870,15 @@
}
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 f8785fc..f1acae8 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 @@
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 1edb837..e665d83 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.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 @@
@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 @@
): 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 0000000..829b0dd
--- /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 0000000..13b71a7
--- /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 0000000..6bd33e7
--- /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 0000000..a6b3da0
--- /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 3ecf154..8d80990 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 @@
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 @@
}
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 32dee92..79b4b3a 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.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.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 @@
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 @@
@Override
public void onStartedWakingUp() {
notifyScreenStateChanged(true);
- if (isGesturalModeOnDefaultDisplay(getContext(), mNavBarMode)) {
+ if (isGesturalModeOnDefaultDisplay(getContext(), mDisplayTracker,
+ mNavBarMode)) {
mRegionSamplingHelper.start(mSamplingBounds);
}
}
@@ -557,7 +559,8 @@
Optional<BackAnimation> backAnimation,
UserContextProvider userContextProvider,
WakefulnessLifecycle wakefulnessLifecycle,
- TaskStackChangeListeners taskStackChangeListeners) {
+ TaskStackChangeListeners taskStackChangeListeners,
+ DisplayTracker displayTracker) {
super(navigationBarView);
mFrame = navigationBarFrame;
mContext = context;
@@ -597,6 +600,7 @@
mUserContextProvider = userContextProvider;
mWakefulnessLifecycle = wakefulnessLifecycle;
mTaskStackChangeListeners = taskStackChangeListeners;
+ mDisplayTracker = displayTracker;
mNavColorSampleMargin = getResources()
.getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin);
@@ -644,12 +648,14 @@
@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 @@
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 @@
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 046a284..3c17465 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 @@
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.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 @@
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 @@
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 @@
// 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 @@
}
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 @@
/** @return {@link NavigationBarView} on the default display. */
public @Nullable NavigationBarView getDefaultNavigationBarView() {
- return getNavigationBarView(DEFAULT_DISPLAY);
+ return getNavigationBarView(mDisplayTracker.getDefaultDisplayId());
}
/**
@@ -433,7 +437,8 @@
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 @@
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 @@
/** @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 43cf623..20b5032 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.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 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 @@
@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 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 @@
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 void destroy() {
try {
mWindowManagerService.unregisterWallpaperVisibilityListener(mWallpaperVisibilityListener,
- Display.DEFAULT_DISPLAY);
+ mDisplayTracker.getDefaultDisplayId());
} catch (RemoteException e) {
}
mLightTransitionsController.destroy();
@@ -150,7 +153,10 @@
@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 @@
@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 88c4fd5..63fb499 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.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 @@
private int mDarkIconColor;
private EdgeBackGestureHandler mEdgeBackGestureHandler;
+ private DisplayTracker mDisplayTracker;
private final DeadZone mDeadZone;
private NavigationBarTransitions mBarTransitions;
@Nullable
@@ -303,7 +301,8 @@
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 @@
mBgExecutor = bgExecutor;
}
+ public void setDisplayTracker(DisplayTracker displayTracker) {
+ mDisplayTracker = displayTracker;
+ }
+
public void setTouchHandler(Gefingerpoken touchHandler) {
mTouchHandler = touchHandler;
}
@@ -558,7 +561,8 @@
}
public void setBehavior(@Behavior int behavior) {
- mRotationButtonController.onBehaviorChanged(Display.DEFAULT_DISPLAY, behavior);
+ mRotationButtonController.onBehaviorChanged(mDisplayTracker.getDefaultDisplayId(),
+ behavior);
}
@Override
@@ -678,7 +682,7 @@
@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 4a07159..de0f9b2 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.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 @@
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 @@
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 2a6ca1a..8ad2f86 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 @@
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 @@
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 100853c..98af9df 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 @@
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 @@
}
}
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 @@
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 cfda9fd..7c2536d 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.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 @@
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 @@
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 @@
mServiceManager = tileServices.getTileWrapper(this);
mService = mServiceManager.getTileService();
mCustomTileStatePersister = customTileStatePersister;
+ mDisplayTracker = displayTracker;
}
@Override
@@ -310,7 +313,7 @@
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 @@
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 @@
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 @@
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 @@
final QSLogger mQSLogger;
final CustomTileStatePersister mCustomTileStatePersister;
private TileServices mTileServices;
+ final DisplayTracker mDisplayTracker;
Context mUserContext;
String mSpec = "";
@@ -581,7 +586,8 @@
ActivityStarter activityStarter,
QSLogger qsLogger,
CustomTileStatePersister customTileStatePersister,
- TileServices tileServices
+ TileServices tileServices,
+ DisplayTracker displayTracker
) {
mQSHostLazy = hostLazy;
mBackgroundLooper = backgroundLooper;
@@ -593,6 +599,7 @@
mQSLogger = qsLogger;
mCustomTileStatePersister = customTileStatePersister;
mTileServices = tileServices;
+ mDisplayTracker = displayTracker;
}
Builder setSpec(@NonNull String spec) {
@@ -623,7 +630,8 @@
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 dd7ea76..a979e5a 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.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 @@
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 @@
@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 @@
UserTracker userTracker,
ScreenLifecycle screenLifecycle,
UiEventLogger uiEventLogger,
+ DisplayTracker displayTracker,
KeyguardUnlockAnimationController sysuiUnlockAnimationController,
AssistUtils assistUtils,
DumpManager dumpManager) {
@@ -535,6 +537,7 @@
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 01e32b7a..aa8e2c0 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.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.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 @@
@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 @@
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 814b8e9..4f5cb72 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.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 @@
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 @@
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 0000000..1e531ba
--- /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 adff6e1..ab13962 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.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 @@
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 @@
};
private ScreenshotView mScreenshotView;
+ private MessageContainerController mMessageContainerController;
private Bitmap mScreenBitmap;
private SaveImageInBackgroundTask mSaveInBgTask;
private boolean mScreenshotTakenInPortrait;
@@ -331,7 +333,8 @@
ActionIntentExecutor actionExecutor,
UserManager userManager,
WorkProfileMessageController workProfileMessageController,
- AssistContentRequester assistContentRequester
+ AssistContentRequester assistContentRequester,
+ DisplayTracker displayTracker
) {
mScreenshotSmartActions = screenshotSmartActions;
mNotificationsController = screenshotNotificationsController;
@@ -357,6 +360,7 @@
});
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 @@
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 @@
// 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 @@
setWindowFocusable(false);
}
}, mActionExecutor, mFlags);
+ mScreenshotView.setDefaultDisplay(mDisplayTracker.getDefaultDisplayId());
mScreenshotView.setDefaultTimeoutMillis(mScreenshotHandler.getDefaultTimeoutMillis());
mScreenshotView.setOnKeyListener((v, keyCode, event) -> {
@@ -700,7 +707,8 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
}
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 3a35286..21a7310 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.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 @@
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 @@
)
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 bd4ea11..80f2717 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.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.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.TextView;
import androidx.constraintlayout.widget.ConstraintLayout;
@@ -104,8 +102,7 @@
* 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 @@
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 @@
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 @@
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 @@
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 @@
}
}
- /**
- * 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 @@
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 5d7e56f..b4a07d4 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 @@
) {
/**
- * 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 @@
val badgedLabel =
packageManager.getUserBadgedLabel(label ?: defaultFileAppName(), userHandle)
- messageDisplay.showWorkProfileMessage(badgedLabel, badgedIcon) { onMessageDismissed() }
+ messageContainer.showWorkProfileMessage(badgedLabel, badgedIcon) {
+ onMessageDismissed()
+ }
}
}
@@ -89,15 +91,6 @@
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 0000000..bb7f721
--- /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 0000000..5169f88
--- /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 b69786e..9594ba3 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.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.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 @@
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 @@
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 @@
Context context,
ToggleSlider control,
UserTracker userTracker,
+ DisplayTracker displayTracker,
@Main Executor mainExecutor,
@Background Handler bgHandler) {
mContext = context;
@@ -290,6 +287,7 @@
mMainExecutor = mainExecutor;
mBackgroundHandler = bgHandler;
mUserTracker = userTracker;
+ mDisplayTracker = displayTracker;
mBrightnessObserver = new BrightnessObserver(mHandler);
mDisplayId = mContext.getDisplayId();
@@ -424,6 +422,7 @@
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 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 @@
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 e208be9..8879501 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.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 @@
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 @@
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 809fa29..e9a1dd7 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 @@
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.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 @@
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 7ed6e3e..60fa865 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 @@
// 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 85b259e..de02115 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.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 @@
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 @@
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 @@
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 02316b7..f73dde6 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.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 @@
}
@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 b02a45a..393279b 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 @@
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 @@
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 @@
* 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 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 87c12c2..6577cf6 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.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 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 a0a7586..3aaad87 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.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.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.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.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.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 @@
* 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 @@
* 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 @@
}
/**
- * @see DisplayManager.DisplayListener#onDisplayRemoved(int)
+ * @see DisplayTracker.Callback#onDisplayRemoved(int)
*/
default void onDisplayRemoved(int displayId) {
}
@@ -500,46 +501,43 @@
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 098c617..d7568a9 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.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 @@
@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 3a4731a..92a8356 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 @@
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 @@
* 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 @@
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 5ab3d7c..693ae66 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 @@
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 @@
@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 5ecc35c..6d60f4a9 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_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 @@
@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 7ffb07a..a901d597 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.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 @@
*/
@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 daed286..5b62d30 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.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 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 @@
@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 @@
}
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 @@
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,12 +219,38 @@
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 weather view and connects it to the smartspace service.
+ */
+ 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, weatherPlugin)
+ connectSession()
+
+ return view
+ }
+
+ /**
* Constructs the smartspace view and connects it to the smartspace service.
*/
fun buildAndConnectView(parent: ViewGroup): View? {
@@ -225,17 +260,17 @@
throw RuntimeException("Cannot build view when not enabled")
}
- val view = buildView(parent)
+ val view = buildView(parent, plugin, configPlugin)
connectSession()
return view
}
- fun requestSmartspaceUpdate() {
- session?.requestSmartspaceUpdate()
- }
-
- 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 @@
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 @@
}
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 @@
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 @@
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 @@
}
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 058042c..0c95eab 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 @@
* 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 b86c243..e595ddf 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 @@
// 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 @@
}
protected QS createDefaultQSFragment() {
- return FragmentHostManager.get(mNotificationShadeWindowView).create(QSFragment.class);
+ return mFragmentService
+ .getFragmentHostManager(mNotificationShadeWindowView)
+ .create(QSFragment.class);
}
private void setUpPresenter() {
@@ -3773,6 +3780,9 @@
});
} 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 4d14542..fe2a913 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.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 @@
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 @@
mNavigationMode = mode;
});
- if (ctx.getDisplayId() == DEFAULT_DISPLAY) {
+ if (ctx.getDisplayId() == displayTracker.getDefaultDisplayId()) {
dumpManager.registerDumpable(getClass().getSimpleName(), this);
}
}
@@ -317,24 +318,27 @@
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 2c8677d..2d80edb 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 @@
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 afcf7a9..853de7b 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.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 @@
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 @@
WindowManager windowManager,
IWindowManager iWindowManager,
StatusBarContentInsetsProvider contentInsetsProvider,
+ FragmentService fragmentService,
@Main Resources resources,
Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider) {
mContext = context;
@@ -98,6 +101,7 @@
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 @@
/** 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 6e3cb48..9dbc4b3 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 @@
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 @@
*/
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 933c060..b1be404 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.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 @@
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 79811c5..2475890 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.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 @@
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 @@
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 0069bb5..19a0866 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 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 @@
@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 @@
.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 d54de3fa..c2727fc 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 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 @@
* {@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 08ee0af..56c5d3b 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.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 @@
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 @@
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 @@
}
}
- 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 @@
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 8ef98f0..bd60401 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.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 @@
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 @@
ProtoTracer protoTracer,
WakefulnessLifecycle wakefulnessLifecycle,
UserTracker userTracker,
+ DisplayTracker displayTracker,
NoteTaskInitializer noteTaskInitializer,
@Main Executor sysUiMainExecutor) {
mContext = context;
@@ -203,6 +204,7 @@
mWakefulnessLifecycle = wakefulnessLifecycle;
mProtoTracer = protoTracer;
mUserTracker = userTracker;
+ mDisplayTracker = displayTracker;
mNoteTaskInitializer = noteTaskInitializer;
mSysUiMainExecutor = sysUiMainExecutor;
}
@@ -268,7 +270,7 @@
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 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 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 @@
@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 @@
@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 00b2fbe..b9c23d4 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.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.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.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 1059543..50645e5 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 @@
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 01365b4..30e3d09 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.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 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 @@
@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 @@
@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 @@
@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 @@
@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 06082b6..68dc6c0 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.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 @@
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 @@
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 81d0034..32edf8f 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 @@
// 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 @@
// 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 @@
// 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 0627fc6..e918c1c 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.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 @@
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 @@
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 47dff51..213ce9e 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 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 @@
private IWindowMagnificationConnection mIWindowMagnificationConnection;
private WindowMagnification mWindowMagnification;
+ private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
@Before
public void setUp() throws Exception {
@@ -91,7 +93,8 @@
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 89ab835..201f020 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.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 @@
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 @@
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 14b00ca..583f2db 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 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 @@
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 @@
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 15a3145..aac0b51 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.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 @@
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 a61cd23..578e1d4 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.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.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 @@
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 cac4a0e..1e62fd23 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.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 @@
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 3696ec5..0798d73 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 498cc29..dbbc266 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 @@
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 b4e85c0..ca5b7af 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.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 @@
private ClipboardOverlayUtils mClipboardUtils;
@Mock
private UiEventLogger mUiEventLogger;
+ private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
private FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
@Mock
@@ -116,7 +118,8 @@
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 b73bfc3..9d4bef6 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.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.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@SmallTest
@@ -189,13 +192,25 @@
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 @@
@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 @@
@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 @@
.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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 @@
// 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 @@
@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 89c7280..a4cf15c 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.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 @@
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 170a70f..35f0f6c 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 @@
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 @@
flags.set(stringFlag, "Test")
flags.set(stringFlag, "Test")
- listener.verifyInOrder(stringFlag.id)
+ listener.verifyInOrder(stringFlag.name)
}
@Test
@@ -149,7 +149,7 @@
flags.removeListener(listener)
flags.set(unreleasedFlag, false)
- listener.verifyInOrder(unreleasedFlag.id)
+ listener.verifyInOrder(unreleasedFlag.name)
}
@Test
@@ -162,7 +162,7 @@
flags.removeListener(listener)
flags.set(stringFlag, "Other")
- listener.verifyInOrder(stringFlag.id)
+ listener.verifyInOrder(stringFlag.name)
}
@Test
@@ -175,7 +175,7 @@
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 @@
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 @@
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 @@
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 7592cc5..d8bbd04 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.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 @@
@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 @@
@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 @@
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 @@
mFeatureFlagsDebug.isEnabled(
ReleasedFlag(
4,
- name = "3",
+ name = "4",
namespace = "test"
)
)
@@ -150,7 +150,7 @@
mFeatureFlagsDebug.isEnabled(
UnreleasedFlag(
5,
- name = "4",
+ name = "5",
namespace = "test"
)
)
@@ -159,7 +159,8 @@
@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 @@
@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 @@
@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 @@
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 @@
@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 @@
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 @@
@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 @@
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 @@
// 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 @@
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 @@
val flag = UnreleasedFlag(100, name = "100", namespace = "test")
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
-
assertThat(mFeatureFlagsDebug.isEnabled(flag)).isTrue()
}
@@ -503,26 +505,26 @@
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 d5b5a4a..4c6028c 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.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 @@
@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 @@
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 fea91c5..28131b5 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 @@
@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 @@
(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 fca7e96..e679d47 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 @@
@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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 77c837b..a2dc1eb 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 @@
@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 @@
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 e4e95e5..5e5dc8b 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.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 @@
@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 @@
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 b35dd26..ce22b19 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 @@
@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 @@
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 @@
}
@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 4ed6d7c..2f7eac2 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 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 @@
@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 @@
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 77daa3f..5564774 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.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 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 @@
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 @@
}
@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 117751c..7c36e46 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 @@
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 @@
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 @@
}
@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 0000000..e8b6f9b
--- /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 9bcfd5b..1a93adc 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 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 @@
@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 92652a7..3eb7329 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.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 @@
private ImageReader mReader;
private NavigationBarView mNavBar;
private VirtualDisplay mVirtualDisplay;
+ private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
@Before
public void setup() {
@@ -83,6 +85,7 @@
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 8058b85..2212bbd 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.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 @@
private NavigationBar mDefaultNavBar;
private NavigationBar mSecondaryNavBar;
private StaticMockitoSession mMockitoSession;
+ private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
@Mock
private CommandQueue mCommandQueue;
@@ -110,7 +112,8 @@
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 2ad865e..764ddc4 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.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 @@
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 cafd2cf..54e6509 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.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 @@
IWindowManager mIWindowManager;
private NavigationBarTransitions mTransitions;
+ private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
@Before
public void setup() {
@@ -86,7 +88,7 @@
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 36e02cb..bc67df6 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 @@
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 @@
)
),
TestCase(
+ calculator = posLeftCalculator,
rotation = Surface.ROTATION_90,
taskbarVisible = false,
taskbarStashed = false,
@@ -70,6 +81,7 @@
)
),
TestCase(
+ calculator = posLeftCalculator,
rotation = Surface.ROTATION_180,
taskbarVisible = false,
taskbarStashed = false,
@@ -80,6 +92,7 @@
)
),
TestCase(
+ calculator = posLeftCalculator,
rotation = Surface.ROTATION_270,
taskbarVisible = false,
taskbarStashed = false,
@@ -90,6 +103,7 @@
)
),
TestCase(
+ calculator = posLeftCalculator,
rotation = Surface.ROTATION_0,
taskbarVisible = true,
taskbarStashed = false,
@@ -100,6 +114,7 @@
)
),
TestCase(
+ calculator = posLeftCalculator,
rotation = Surface.ROTATION_0,
taskbarVisible = true,
taskbarStashed = true,
@@ -110,6 +125,7 @@
)
),
TestCase(
+ calculator = posLeftCalculator,
rotation = Surface.ROTATION_90,
taskbarVisible = true,
taskbarStashed = false,
@@ -118,11 +134,86 @@
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 42ef9c2..4caa50f 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.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 @@
@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 2bd068a..d6dfc85 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 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 @@
@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 @@
activityStarter,
qsLogger,
customTileStatePersister,
- tileServices
+ tileServices,
+ displayTracker
)
customTile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext)
@@ -339,7 +343,7 @@
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 e1eda11..7d58325 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 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 @@
private PendingIntent mMockPendingIntent;
private Intent mIntent;
+ private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
@Before
public void setup() throws InterruptedException, ExecutionException, TimeoutException {
@@ -135,10 +137,11 @@
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 17396b1..ee61f57 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.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 @@
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 bd04b3c..e8905ab 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 @@
@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 0000000..ae976a0
--- /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 9d1802a..7646193 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.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 @@
@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 @@
override fun create(intent: Intent?): TestDialog {
return TestDialog(
userTracker,
+ displayTracker,
brightnessSliderControllerFactory,
mainExecutor,
backgroundHandler
@@ -105,12 +109,14 @@
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 bdafc7d..c915502a 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 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.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 @@
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 @@
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 @@
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 @@
largeScreenShadeHeaderController,
shadeExpansionStateManager,
featureFlags,
+ fragmentService,
delayableExecutor
)
@@ -114,9 +127,10 @@
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 @@
largeScreenShadeHeaderController,
shadeExpansionStateManager,
featureFlags,
+ fragmentService,
delayableExecutor
)
controller.updateConstraints()
@@ -426,6 +441,17 @@
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 4c76825..e5d5e3b 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.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 @@
@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 @@
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 @@
@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 d435624..5cc3ef1 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.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 @@
@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 @@
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 0000c32..b1ca1c0 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.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 @@
};
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 @@
@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 ea06647..746544a 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.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 @@
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 @@
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 43b6e41..2423f13 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 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 @@
private lateinit var handler: Handler
@Mock
+ private lateinit var weatherPlugin: BcSmartspaceDataPlugin
+
+ @Mock
private lateinit var plugin: BcSmartspaceDataPlugin
@Mock
@@ -151,6 +155,7 @@
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 @@
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 @@
executor,
bgExecutor,
handler,
+ Optional.of(weatherPlugin),
Optional.of(plugin),
Optional.of(configPlugin),
)
@@ -218,11 +230,22 @@
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 @@
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 @@
}
@Test
- fun testListenersAreRegistered() {
+ fun testAddListener_registersListenersForPlugin() {
// GIVEN a listener is added after a session is created
connectSession()
@@ -252,10 +275,12 @@
// 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 @@
// 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 @@
// 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 @@
}
@Test
- fun testSettingsChangeReloadsSmartspace() {
+ fun testSettingsChange_reloadsSmartspace() {
// GIVEN a connected smartspace session
connectSession()
@@ -306,7 +335,7 @@
}
@Test
- fun testThemeChangeUpdatesTextColor() {
+ fun testThemeChange_updatesTextColor() {
// GIVEN a connected smartspace session
connectSession()
@@ -318,7 +347,22 @@
}
@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()
@@ -330,7 +374,22 @@
}
@Test
- fun testKeyguardBypassEnabledUpdatesView() {
+ fun testDozeAmountChange_ifDecouplingEnabled_updatesViews() {
+ `when`(featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)).thenReturn(true)
+
+ // 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(weatherSmartspaceView).setDozeAmount(0.7f)
+ verify(smartspaceView).setDozeAmount(0.7f)
+ }
+
+ @Test
+ fun testKeyguardBypassEnabled_updatesView() {
// GIVEN a connected smartspace session
connectSession()
`when`(keyguardBypassController.bypassEnabled).thenReturn(true)
@@ -425,6 +484,27 @@
}
@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 @@
}
@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 @@
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 @@
}
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 @@
.addOnTargetsAvailableListener(any(), capture(sessionListenerCaptor))
sessionListener = sessionListenerCaptor.value
+ verify(smartspaceManager).createSmartspaceSession(any())
+
verify(userTracker).addCallback(capture(userTrackerCaptor), any())
userListener = userTrackerCaptor.value
@@ -578,9 +684,11 @@
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 @@
).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 701cf95..af52459 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 @@
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 @@
// 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 4559a23..9e23d54 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 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 @@
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);
+ }
+
+ @Test
+ 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(group.getCurrentBackgroundTint()).isEqualTo(Color.RED);
+ assertThat(group.getChildNotificationAt(0).getCurrentBackgroundTint())
+ .isEqualTo(Color.GREEN);
+ assertThat(group.getChildNotificationAt(1).getCurrentBackgroundTint())
+ .isEqualTo(Color.BLUE);
+
+ group.updateBackgroundColors();
+
+ int resetTint = group.getCurrentBackgroundTint();
+ assertThat(resetTint).isNotEqualTo(Color.RED);
+ assertThat(group.getChildNotificationAt(0).getCurrentBackgroundTint())
+ .isEqualTo(resetTint);
+ assertThat(group.getChildNotificationAt(1).getCurrentBackgroundTint())
+ .isEqualTo(resetTint);
+ }
+
+ @Test
+ public void testSetSensitiveOnNotifRowNotifiesOfHeightChange() throws Exception {
+ // GIVEN a sensitive notification row that's currently redacted
+ 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);
+ row.setOnHeightChangedListener(listener);
+
+ // WHEN the row is set to no longer be sensitive
+ row.setSensitive(false, true);
+
+ // VERIFY that the height change listener is invoked
+ assertThat(row.getShowingLayout()).isSameInstanceAs(row.getPrivateLayout());
+ assertThat(row.getIntrinsicHeight()).isGreaterThan(0);
+ verify(listener).onHeightChanged(eq(row), eq(false));
+ }
+
+ @Test
+ public void testSetSensitiveOnGroupRowNotifiesOfHeightChange() throws Exception {
+ // GIVEN a sensitive group row that's currently redacted
+ 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);
+ group.setOnHeightChangedListener(listener);
+
+ // WHEN the row is set to no longer be sensitive
+ group.setSensitive(false, true);
+
+ // VERIFY that the height change listener is invoked
+ assertThat(group.getShowingLayout()).isSameInstanceAs(group.getPrivateLayout());
+ assertThat(group.getIntrinsicHeight()).isGreaterThan(0);
+ verify(listener).onHeightChanged(eq(group), eq(false));
+ }
+
+ @Test
+ public void testSetSensitiveOnPublicRowDoesNotNotifyOfHeightChange() throws Exception {
// 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);
+ ExpandableNotificationRow publicRow = mNotificationTestHelper.createRow(publicNotif);
- }
-
- @Test
- public void testUpdateBackgroundColors_isRecursive() {
- mGroupRow.setTintColor(Color.RED);
- mGroupRow.getChildNotificationAt(0).setTintColor(Color.GREEN);
- mGroupRow.getChildNotificationAt(1).setTintColor(Color.BLUE);
-
- assertThat(mGroupRow.getCurrentBackgroundTint()).isEqualTo(Color.RED);
- assertThat(mGroupRow.getChildNotificationAt(0).getCurrentBackgroundTint())
- .isEqualTo(Color.GREEN);
- assertThat(mGroupRow.getChildNotificationAt(1).getCurrentBackgroundTint())
- .isEqualTo(Color.BLUE);
-
- mGroupRow.updateBackgroundColors();
-
- int resetTint = mGroupRow.getCurrentBackgroundTint();
- assertThat(resetTint).isNotEqualTo(Color.RED);
- assertThat(mGroupRow.getChildNotificationAt(0).getCurrentBackgroundTint())
- .isEqualTo(resetTint);
- assertThat(mGroupRow.getChildNotificationAt(1).getCurrentBackgroundTint())
- .isEqualTo(resetTint);
- }
-
- @Test
- public void testSetSensitiveOnNotifRowNotifiesOfHeightChange() throws InterruptedException {
- // 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);
-
- // GIVEN that the row has a height change listener
- OnHeightChangedListener listener = mock(OnHeightChangedListener.class);
- mNotifRow.setOnHeightChangedListener(listener);
-
- // WHEN the row is set to no longer be sensitive
- mNotifRow.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));
- }
-
- @Test
- public void testSetSensitiveOnGroupRowNotifiesOfHeightChange() {
- // 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);
-
- // GIVEN that the row has a height change listener
- OnHeightChangedListener listener = mock(OnHeightChangedListener.class);
- mGroupRow.setOnHeightChangedListener(listener);
-
- // WHEN the row is set to no longer be sensitive
- mGroupRow.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));
- }
-
- @Test
- public void testSetSensitiveOnPublicRowDoesNotNotifyOfHeightChange() {
// 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 @@
}
@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 @@
@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 @@
}
@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 @@
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();
- mGroupRow.resetTranslation();
- assertEquals(0, mGroupRow.getEntry().getIcons().getShelfIcon().getScrollX());
+ group.setDismissUsingRowTranslationX(false);
+ group.setTranslation(50);
+ assertEquals(50, -group.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 @@
}
@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 @@
@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 @@
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 e6f6a8d..aca9c56 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.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.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.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.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.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 @@
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 @@
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 b1363a0..0605398 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 @@
}
@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 cc4abfc..529519a 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.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 @@
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 189aa0f..0a68406 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 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 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 eef43bd..8841521 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.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 @@
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 613238f..929099a 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 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 @@
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 a87a950..c539246 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 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 @@
@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 0a1e3e4..9d518ac 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.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 @@
private TestableLooper mTestableLooper;
+ private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -333,7 +336,7 @@
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 7ae47b4..8cae998 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.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 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ FakeDisplayTracker displayTracker = new FakeDisplayTracker(mContext);
mWMShell = new WMShell(
mContext,
mShellInterface,
@@ -100,6 +102,7 @@
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 6c82cef..b94f816e 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 @@
}
}
- 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 @@
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 0000000..6ae7c34
--- /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 9a6fa8e..8a6897c 100644
--- a/rs/jni/Android.bp
+++ b/rs/jni/Android.bp
@@ -51,4 +51,10 @@
"-Wunreachable-code",
"-Wno-deprecated-declarations",
],
+
+ target: {
+ android_riscv64: {
+ enabled: false,
+ },
+ },
}
diff --git a/services/api/current.txt b/services/api/current.txt
index a92ccd4..f7d6ee9 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -225,19 +225,6 @@
}
-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 1e96324..d7a77cd 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 @@
@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 f65ed33..bd072f5 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -148,9 +148,10 @@
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 66fa746..f93f504 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.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 @@
+ " 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 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
if (!packageState.isUpdatedSystemApp()) {
return;
}
- if (packagesToSkip.contains(packageState.getPackageName())) {
+ if (packagesToSkip.containsKey(packageState.getPackageName())) {
return;
}
@@ -413,11 +420,10 @@
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 @@
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 @@
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 10d50c2..57a89e3 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_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 @@
}
mBatteryStatsService.noteProcessDied(app.info.uid, pid);
+ mOomAdjuster.updateShortFgsOwner(app.info.uid, pid, false);
if (!app.isKilled()) {
if (!fromBinderDied) {
@@ -16727,6 +16729,12 @@
}
@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 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 1e97285..3ab1cd7 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.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 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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 e06ce2c9..4ad43fa 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 @@
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 @@
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 114e2c1..e02dda6 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.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 @@
@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 @@
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 @@
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 @@
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 @@
}
}
}
+ 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 @@
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 8ce9889..b2e4740 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 @@
* @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 @@
}
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 b4992d7..88fc51a3 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 @@
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 @@
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 @@
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 7839ada..7af7ed5 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 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 @@
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 @@
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 @@
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 @@
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 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 bc61b37..42031c6 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 @@
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 05464c8..592daa6 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 @@
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 @@
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 42e0978..3759a8b 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 @@
}
// 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 f8d6c5f..52e20d6 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 @@
// 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 @@
@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 fc2a4e5..abb0ff6 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 @@
}
@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 @@
}
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 @@
mShouldResetShortTermModel);
mShouldResetShortTermModel = false;
}
+ mHbmController.setAutoBrightnessEnabled(mUseAutoBrightness
+ ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
+ : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
if (mBrightnessTracker != null) {
mBrightnessTracker.setBrightnessConfiguration(mBrightnessConfiguration);
@@ -1634,9 +1639,12 @@
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 a744415..2e91bdb 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 @@
mShouldResetShortTermModel);
mShouldResetShortTermModel = false;
}
+ mHbmController.setAutoBrightnessEnabled(mUseAutoBrightness
+ ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
+ : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
if (mBrightnessTracker != null) {
mBrightnessTracker.setBrightnessConfiguration(mBrightnessConfiguration);
@@ -1347,9 +1350,12 @@
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 @@
}
@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 @@
}
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 a95ac74..4612ec9 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 @@
* 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 f870c0a..d7306b7 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 @@
// 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 8c13297..e2caeec 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 @@
// Add ourselves to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
- registerPointerSpeedSettingObserver();
+ registerMousePointerSpeedSettingObserver();
+ registerTouchpadPointerSpeedSettingObserver();
+ registerTouchpadNaturalScrollingEnabledObserver();
+ registerTouchpadTapToClickEnabledObserver();
+ registerTouchpadRightClickZoneEnabledObserver();
registerShowTouchesSettingObserver();
registerAccessibilityLargePointerSettingObserver();
registerLongPressTimeoutObserver();
@@ -502,14 +506,22 @@
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 @@
setPointerSpeedUnchecked(speed);
}
- private void updatePointerSpeedFromSettings() {
- int speed = getPointerSpeedSetting();
+ private void updateMousePointerSpeedFromSettings() {
+ int speed = getMousePointerSpeedSetting();
setPointerSpeedUnchecked(speed);
}
@@ -1358,18 +1370,18 @@
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 @@
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 6fca9cc..22226e8 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 @@
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 @@
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 05a534f..aab52ce 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 @@
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 262013e..e48412a 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 @@
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 72d6f70..3a25146 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 @@
* 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 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 479dbda..d682164 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.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 @@
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,16 +111,39 @@
@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();
+ }
+
/**
* @return {@code true} if there is a network available for outgoing connections,
* {@code false} otherwise.
@@ -122,14 +153,14 @@
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 @@
/** {@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 @@
// 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 @@
}
/** 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 edb2e5b..7618419 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 @@
}
@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 48e0c30..ebc18bc 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.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 @@
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 669ea95..03e4f09 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 @@
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 b06c411..5ab4a42 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 @@
private PackageManager mPackageManagerClient;
PackageManagerInternal mPackageManagerInternal;
private PermissionPolicyInternal mPermissionPolicyInternal;
+
+ private PermissionManagerServiceInternal mPermissionInternal;
AudioManager mAudioManager;
AudioManagerInternal mAudioManagerInternal;
// Can be null for wear
@@ -2210,7 +2212,8 @@
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 @@
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 @@
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 @@
(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 @@
// 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 @@
// 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 @@
}
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 @@
* 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 @@
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 @@
}
BackgroundThread.getHandler().post(() -> {
- if (info.isSystem || hasCompanionDevice(info)) {
+ if (info.isSystem() || hasCompanionDevice(info)) {
notifyNotificationChannelGroupChanged(
info, pkg, user, group, modificationType);
}
@@ -11348,7 +11357,7 @@
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 6e86123..5bdcbb9 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.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 @@
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 @@
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 @@
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 e0bcc0e..db939d9 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 @@
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 @@
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 @@
// 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 @@
}
}
+ 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 ed6a46f..da7aaa4 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 @@
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 c29ab09..e8cb4e2 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.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 @@
private SettingsObserver mSettingsObserver;
private DreamManagerInternal mDreamManager;
private LogicalLight mAttentionLight;
+ private ActivityManagerInternal mAmInternal;
private final InattentiveSleepWarningController mInattentiveSleepWarningOverlayController;
private final AmbientDisplaySuppressionController mAmbientDisplaySuppressionController;
@@ -1237,6 +1239,7 @@
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 @@
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 89c5c9e..bc90c89 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 @@
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 @@
@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 (!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 (mPlatformIdleStateCallback != null) {
+ mDetails.statSubsystemPowerState =
+ mPlatformIdleStateCallback.getSubsystemLowPowerStats();
+ if (DEBUG) {
+ Slog.i(TAG,
+ "WRITE SubsystemPowerState:" + mDetails.statSubsystemPowerState);
+ }
+ }
}
if (!mHasHistoryStepDetails) {
@@ -4072,7 +4078,11 @@
mCurStepStatIrqTimeMs += statIrqTimeMs;
mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs;
mCurStepStatIdleTimeMs += statIdleTimeMs;
+ }
+
+ public void finishAddingCpuLocked() {
mHasHistoryStepDetails = true;
+ mUpdateRequested = false;
}
@Override
@@ -4953,13 +4963,13 @@
}
@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 @@
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 1321873..9d5173a 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.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.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.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 @@
/**
* 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 @@
* 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 @@
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 @@
return true;
}
- android.hardware.boot.V1_2.IBootControl bootControl;
+ IBootControl bootControl;
try {
bootControl = mInjector.getBootControl();
} catch (RemoteException e) {
@@ -972,8 +983,8 @@
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 @@
/**
* 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 @@
/**
* 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 0000000..65325c2
--- /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 6c0e1a4..5ae6973 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 @@
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 @@
* 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 @@
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 @@
}
};
- /** @hide */
public FileIntegrityService(final Context context) {
super(context);
try {
@@ -155,7 +149,6 @@
LocalServices.addService(FileIntegrityService.class, this);
}
- /** @hide */
@Override
public void onStart() {
loadAllCertificates();
@@ -165,7 +158,6 @@
/**
* 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 @@
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
old mode 100755
new mode 100644
index 29b37ce..0928bef
--- 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.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.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.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.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 @@
@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 @@
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 @@
@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 @@
if (serviceState.service != null) {
if (!createSessionInternalLocked(serviceState.service, sessionToken,
- resolvedUserId)) {
+ resolvedUserId, tvAppAttributionSource)) {
removeSessionStateLocked(sessionToken, resolvedUserId);
}
} else {
@@ -1836,6 +1836,28 @@
}
@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 @@
// 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 @@
}
@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 24fe518..0c97d7d 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 @@
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
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 cfcf459..d759ff5 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 @@
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 @@
}
}
- // 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 @@
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 6f7ff5c..3404279 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 @@
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 @@
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 718a9e3..e9badef 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.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,138 +69,281 @@
* 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.
+ * Update the Keyguard showing state.
*/
- boolean isDisplayOccluded(int displayId) {
- return getDisplayState(displayId).isIn(KEYGUARD_STATE_OCCLUDED);
+ void setKeyguardShown(int displayId, boolean keyguardShowing, boolean aodShowing) {
+ if (mRootWindowContainer.getDisplayContent(displayId).isKeyguardAlwaysUnlocked()) {
+ Slog.i(TAG, "setKeyguardShown ignoring always unlocked display " + displayId);
+ return;
+ }
+
+ 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 */);
+ }
+ if (!keyguardChanged && !aodChanged) {
+ setWakeTransitionReady();
+ return;
+ }
+ EventLogTags.writeWmSetKeyguardShown(
+ displayId,
+ keyguardShowing ? 1 : 0,
+ aodShowing ? 1 : 0,
+ state.mKeyguardGoingAway ? 1 : 0,
+ "setKeyguardShown");
+
+ // 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;
+ }
+ }
+
+ // 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();
+ }
+ }
+
+ private void setWakeTransitionReady() {
+ if (mWindowManager.mAtmService.getTransitionController().getCollectingTransitionType()
+ == WindowManager.TRANSIT_WAKE) {
+ mWindowManager.mAtmService.getTransitionController().setReady(
+ mRootWindowContainer.getDefaultDisplay());
+ }
}
/**
- * @return Whether the dream activity is on top of default display.
+ * Called when Keyguard is going away.
+ *
+ * @param flags See {@link WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
+ * etc.
*/
- boolean isShowingDream() {
- return getDisplayState(DEFAULT_DISPLAY).isIn(KEYGUARD_STATE_DREAMING);
+ void keyguardGoingAway(int displayId, int flags) {
+ 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) {
+ final ActivityRecord activityRecord = ActivityRecord.forTokenLocked(token);
+ if (activityRecord == null || !activityRecord.visibleIgnoringKeyguard) {
+ failCallback(callback);
+ return;
+ }
+ Slog.i(TAG, "Activity requesting to dismiss Keyguard: " + activityRecord);
+
+ // 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");
+ }
+
+ mWindowManager.dismissKeyguard(callback, message);
+ }
+
+ private void failCallback(IKeyguardDismissCallback callback) {
+ try {
+ callback.onDismissError();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call callback", e);
+ }
+ }
+
+ 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;
+ }
+ if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0) {
+ result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+ }
+ if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0) {
+ result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
+ }
+ if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS) != 0) {
+ result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
+ }
+ if ((keyguardGoingAwayFlags
+ & KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT) != 0) {
+ result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT;
+ }
+ return result;
+ }
+
+ /**
+ * @return True if we may show an activity while Keyguard is showing because we are in the
+ * process of dismissing it anyways, false otherwise.
+ */
+ 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));
+ }
+
+ /**
+ * @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());
}
/**
@@ -224,15 +351,181 @@
*
* @return true if {@param r} is visible taken Keyguard state into account, false otherwise
*/
- boolean checkKeyguardVisibility(@NonNull ActivityRecord r) {
+ boolean checkKeyguardVisibility(ActivityRecord r) {
if (r.mDisplayContent.canShowWithInsecureKeyguard() && canDismissKeyguard()) {
return true;
}
- return getDisplayState(r.mDisplayContent.getDisplayId()).checkKeyguardVisibility(r);
+
+ 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;
+ }
+ }
+
+ /**
+ * 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());
+ }
+ }
+ }
+
+ /**
+ * 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;
+ }
+
+ mWindowManager.mPolicy.onKeyguardOccludedChangedLw(isDisplayOccluded(DEFAULT_DISPLAY));
+ if (isKeyguardLocked(displayId)) {
+ mService.deferWindowLayout();
+ 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);
+ }
+
+ /**
+ * 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();
+ }
+ }
+
+ /**
+ * 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;
+ }
+
+ mWindowManager.dismissKeyguard(null /* callback */, null /* message */);
+ final KeyguardDisplayState state = getDisplayState(displayId);
+ state.mDismissalRequested = true;
+
+ // 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();
+ }
+ }
+
+ boolean isDisplayOccluded(int displayId) {
+ return getDisplayState(displayId).mOccluded;
+ }
+
+ /**
+ * @return true if Keyguard can be currently dismissed without entering credentials.
+ */
+ boolean canDismissKeyguard() {
+ return mWindowManager.mPolicy.isKeyguardTrustedLw()
+ || !mWindowManager.isKeyguardSecure(mService.getCurrentUserId());
+ }
+
+ /**
+ * @return Whether the dream activity is on top of default display.
+ */
+ boolean isShowingDream() {
+ return getDisplayState(DEFAULT_DISPLAY).mShowingDream;
+ }
+
+ 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;
+ }
+
+ // Dismiss freeform windowing mode
+ if (currentTaskControllingOcclusion == null) {
+ return;
+ }
+ if (currentTaskControllingOcclusion.inFreeformWindowingMode()) {
+ currentTaskControllingOcclusion.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ }
+ }
+
+ private void updateKeyguardSleepToken() {
+ for (int displayNdx = mRootWindowContainer.getChildCount() - 1;
+ displayNdx >= 0; displayNdx--) {
+ final DisplayContent display = mRootWindowContainer.getChildAt(displayNdx);
+ updateKeyguardSleepToken(display.mDisplayId);
+ }
+ }
+
+ private void updateKeyguardSleepToken(int displayId) {
+ final KeyguardDisplayState state = getDisplayState(displayId);
+ if (isKeyguardUnoccludedOrAodShowing(displayId)) {
+ state.mSleepTokenAcquirer.acquire(displayId);
+ } else {
+ state.mSleepTokenAcquirer.release(displayId);
+ }
+ }
+
+ 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 onDisplayRemoved(int displayId) {
- final DisplayState state = mDisplayStates.get(displayId);
+ final KeyguardDisplayState state = mDisplayStates.get(displayId);
if (state != null) {
state.onRemoved();
mDisplayStates.remove(displayId);
@@ -245,15 +538,7 @@
}
};
- /**
- * 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.
- */
+ // Defer transition until AOD dismissed.
void updateDeferTransitionForAod(boolean waiting) {
if (waiting == mWaitingForWakeTransition) {
return;
@@ -264,1115 +549,212 @@
// if AOD is showing, defer the wake transition until AOD state changed.
if (waiting && isAodShowing(DEFAULT_DISPLAY)) {
mWaitingForWakeTransition = true;
- mService.getTransitionController().deferTransitionReady();
+ 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;
- mService.getTransitionController().continueTransitionReady();
+ mWindowManager.mAtmService.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,
- "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;
- }
-
- 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;
- }
- 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;
- }
- }
- state.setKeyguardState(newState);
- }
-
- /**
- * Called when Keyguard is going away.
- *
- * @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();
- }
- }
-
- 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);
- }
-
- if (!ok) {
- try {
- callback.onDismissError();
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to call callback", e);
- }
- }
- }
-
- private boolean isKeyguardSecure() {
- return mWindowManager.isKeyguardSecure(mService.getCurrentUserId());
- }
-
- /**
- * @return true if Keyguard can be currently dismissed without entering credentials.
- */
- private boolean canDismissKeyguard() {
- return mWindowManager.mPolicy.isKeyguardTrustedLw() || !isKeyguardSecure();
- }
-
- private boolean canOcclude(@Nullable ActivityRecord r) {
- if (r == null) {
- return false;
- }
- // 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;
- }
- }
- // 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);
- }
- 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);
- }
- }
-
- 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);
- }
- pw.println();
- }
-
- /**
- * 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.
- */
- 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);
- }
- }
-
- 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);
- }
-
- void collect(@NonNull WindowContainer wc) {
- mService.getTransitionController().collect(wc);
- }
-
- 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);
- }
- }
-
- void acquireSleepToken(int displayId, boolean ensureActivitiesVisible) {
- mSleepTokenAcquirer.acquire(displayId);
- if (ensureActivitiesVisible) {
- mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
- }
- }
-
- void releaseSleepToken(int displayId, boolean resumeTopActivities) {
- mSleepTokenAcquirer.release(displayId);
- if (resumeTopActivities) {
- mRootWindowContainer.resumeFocusedTasksTopActivities();
- mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
- mRootWindowContainer.addStartingWindowsForVisibleActivities();
-
- }
- }
-
- void deferWindowLayout() {
- 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;
- }
- }
- };
-
- 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;
- }
- }
-
- 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;
- }
- }
-
- static final class TopActivityOccludesKeyguardParam {
- boolean mRet;
- @NonNull final ActivityRecord mActivity;
-
- TopActivityOccludesKeyguardParam(@NonNull ActivityRecord activity) {
- mActivity = activity;
- }
- }
-
- static final class DumpParam {
- ArrayList<String> mRet = new ArrayList<>();
- String mPrefix;
-
- DumpParam(@NonNull String prefix) {
- mPrefix = prefix;
- }
- }
-
- KeyguardDisplayStateMachine(int displayId, @KeyguardState int initialState) {
- super(initialState);
- mDisplayId = displayId;
- }
-
- @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;
- }
-
- @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);
- }
-
- @Override
- public void enter(@KeyguardState int state) {
- if (DEBUG) {
- Slog.d(TAG, "enter: display=" + mDisplayId + ", state="
- + keyguardStateToString(state));
- }
- super.enter(state);
- }
-
- @Override
- public void exit(@KeyguardState int state) {
- if (DEBUG) {
- Slog.d(TAG, "exit: display=" + mDisplayId + ", state="
- + keyguardStateToString(state));
- }
- super.exit(state);
- }
-
- void handleDismissKeyguardActivity() {
- handle(EVENT_DISMISS_KEYGUARD_ACTIVITY, null /* param */);
- }
-
- void handleTurnScreenOnActivity() {
- handle(EVENT_TURN_SCREEN_ON_ACTIVITY, null /* param */);
- }
-
- 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;
- }
-
- void handleShowWhenLockedActivity() {
- handle(EVENT_SHOW_WHEN_LOCKED_ACTIVITY, null /* param */);
- }
-
- void handleLayoutChanges() {
- handle(EVENT_LAYOUT_CHANGES, null /* param */);
- }
-
- boolean checkKeyguardVisibility(@NonNull ActivityRecord r) {
- final CheckKeyguardVisibilityParam param = new CheckKeyguardVisibilityParam(r);
- handle(EVENT_CHECK_KEYGUARD_VISIBILITY, param);
- return param.mRet;
- }
-
- boolean topActivityOccludesKeyguard(@NonNull ActivityRecord r) {
- final TopActivityOccludesKeyguardParam param = new TopActivityOccludesKeyguardParam(r);
- handle(EVENT_TOP_ACTIVITY_OCCLUDES_KEYGUARD, param);
- return param.mRet;
- }
-
- ArrayList<String> handleDump(String prefix) {
- final DumpParam param = new DumpParam(prefix);
- handle(EVENT_DUMP, param);
- return param.mRet;
- }
- }
-
- /**
- * 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;
- }
-
- /**
- * Request relayout if necessary.
- */
- boolean handleLayoutChanges() {
- return false;
- }
-
- /**
- * 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.
- */
- 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 {
+ /** Represents Keyguard state per individual display. */
+ private static class KeyguardDisplayState {
private final int mDisplayId;
- @NonNull private final ServiceDelegate mServiceDelegate;
- private final KeyguardDisplayStateMachine mStateMachine;
+ private boolean mKeyguardShowing;
+ private boolean mAodShowing;
+ private boolean mKeyguardGoingAway;
+ private boolean mDismissalRequested;
+ private boolean mOccluded;
+ private boolean mShowingDream;
- // TODO: Set watchdog timer to sync mLastNotifiedOccludedState == isIn(OCCLUDED)
- private boolean mLastNotifiedOccludedState = false;
+ private ActivityRecord mTopOccludesActivity;
+ private ActivityRecord mDismissingKeyguardActivity;
+ private ActivityRecord mTopTurnScreenOnActivity;
- // 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;
+ private boolean mRequestDismissKeyguard;
+ private final ActivityTaskManagerService mService;
+ private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer;
- // 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) {
+ KeyguardDisplayState(ActivityTaskManagerService service, int displayId,
+ ActivityTaskManagerInternal.SleepTokenAcquirer acquirer) {
+ mService = service;
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);
- }
-
- @Override
- Optional<Boolean> topActivityOccludesKeyguardParam(@NonNull ActivityRecord r) {
- return Optional.of(false);
- }
- });
-
- mStateMachine.addStateHandler(KEYGUARD_STATE_OFF, new Handler() {
- @Override
- public Optional<Boolean> checkKeyguardVisibility(@NonNull ActivityRecord r) {
- return Optional.of(true);
- }
-
- @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);
- }
-
- @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();
- }
- });
+ mSleepTokenAcquirer = acquirer;
}
void onRemoved() {
- mServiceDelegate.releaseSleepToken(mDisplayId, false /* resumeTopActivities */);
+ mTopOccludesActivity = null;
+ mDismissingKeyguardActivity = null;
+ mTopTurnScreenOnActivity = null;
+ mSleepTokenAcquirer.release(mDisplayId);
}
- void updateVisibility() {
- mStateMachine.handleDismissKeyguardActivity();
- mStateMachine.handleTurnScreenOnActivity();
- mStateMachine.handleShowWhenLockedActivity();
- mStateMachine.handleLayoutChanges();
+ /**
+ * 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.
+ */
+ 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;
+ }
+ if (top.getTurnScreenOnFlag() && top.currentLaunchCanTurnScreenOn()) {
+ mTopTurnScreenOnActivity = top;
+ }
+
+ if (top.mDismissKeyguard && mKeyguardShowing) {
+ mKeyguardGoingAway = true;
+ } else if (top.canShowWhenLocked()) {
+ mTopOccludesActivity = top;
+ }
+ 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();
+ }
+ }
+
+ 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;
+ }
+
+ if (mTopTurnScreenOnActivity != lastTurnScreenOnActivity
+ && mTopTurnScreenOnActivity != null
+ && !mService.mWindowManager.mPowerManager.isInteractive()
+ && (mRequestDismissKeyguard || occludedByActivity)) {
+ controller.mTaskSupervisor.wakeUp("handleTurnScreenOn");
+ mTopTurnScreenOnActivity.setCurrentLaunchCanTurnScreenOn(false);
+ }
+
+ 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 dismissKeyguard(@NonNull ActivityRecord r,
- @Nullable IKeyguardDismissCallback callback,
- @Nullable CharSequence message) {
- return mStateMachine.handleDismissKeyguard(r, callback, message);
+ /**
+ * 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 commitOccludedStatus(boolean occluded) {
- mLastNotifiedOccludedState = occluded;
- }
-
- void setKeyguardState(@KeyguardState int newState) {
- mDismissalRequested = false;
- mStateMachine.transit(newState);
- }
-
- boolean isKeyguardTop() {
- return mStateMachine.isIn(KEYGUARD_STATE_KEYGUARD_TOP);
- }
-
- boolean isIn(@KeyguardState int category) {
- return mStateMachine.isIn(category);
- }
-
- boolean topActivityOccludesKeyguard(@NonNull ActivityRecord r) {
- return mStateMachine.topActivityOccludesKeyguard(r);
- }
-
- boolean checkKeyguardVisibility(@NonNull ActivityRecord r) {
- return mStateMachine.checkKeyguardVisibility(r);
+ 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 75691ca..1711845 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 @@
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 80965a7..5e116ba 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 @@
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 ad6bd3c..1282acb 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.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 @@
* 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 @@
}
/**
- * 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 f6cb068..a596eed 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 @@
@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 3e165e4..14c816d 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 @@
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 @@
*
* @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 @@
*
* 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 @@
"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 7c73768..f4d1d1e 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
{"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 3c1ac1e..60eed8e6 100644
--- a/services/core/jni/gnss/GnssCallback.cpp
+++ b/services/core/jni/gnss/GnssCallback.cpp
@@ -95,7 +95,7 @@
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 @@
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 @@
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 a1c5708..2982546 100644
--- a/services/core/jni/gnss/GnssMeasurementCallback.cpp
+++ b/services/core/jni/gnss/GnssMeasurementCallback.cpp
@@ -58,7 +58,7 @@
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 @@
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 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 @@
callObjectMethodIgnoringResult(env, gnssMeasurementsEventBuilderObject,
method_gnssMeasurementsEventBuilderSetGnssAutomaticGainControls,
gnssAgcArray);
- if (hasFullTracking) {
+ if (hasIsFullTracking) {
callObjectMethodIgnoringResult(env, gnssMeasurementsEventBuilderObject,
- method_gnssMeasurementsEventBuilderSetFullTracking,
+ method_gnssMeasurementsEventBuilderSetIsFullTracking,
isFullTracking);
}
jobject gnssMeasurementsEventObject =
@@ -394,10 +394,10 @@
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 fde56881..b3de486 100644
--- a/services/core/jni/gnss/GnssMeasurementCallback.h
+++ b/services/core/jni/gnss/GnssMeasurementCallback.h
@@ -49,7 +49,7 @@
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 @@
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 f915298..101498a 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -92,7 +92,10 @@
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 57c5a6e..ef470fe 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 @@
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 @@
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 7281fafc..ed78e72 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.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 @@
private ActivityManagerInternal mActivityMangerInternal;
@Mock
private Context mContext;
+ @Mock
+ private PackageManagerInternal mPackageManagerInternal;
private class TestJobSchedulerService extends JobSchedulerService {
TestJobSchedulerService(Context context) {
@@ -121,6 +125,8 @@
.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 @@
// 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 @@
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 @@
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 d68066b..fb62520 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 de54537..9b48114 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 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 @@
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 8cbed2c..4412cfe 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 @@
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 69a0b87..3a3a507 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 @@
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 0000000..6c73f71
--- /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 9b9cb4d..c760efd 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 @@
@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 @@
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 @@
@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 @@
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 a0fb3de..d71deaf 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 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 @@
@Mock
private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock;
+ @Mock
+ private ActivityManagerInternal mActivityManagerInternal;
+
private PowerManagerService mService;
private ContextWrapper mContextSpy;
private BatteryReceiver mBatteryReceiver;
@@ -205,6 +211,7 @@
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 @@
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 74189fd..4fde73b 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 5234bb7..63d6768 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 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 27e953f..f1cf48b 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 3de65c1..1b3a199 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 @@
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 @@
}
}
- @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 581cf43..90d1488 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 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.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.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 @@
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 @@
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 5f8a2b5..20e8cd4 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 @@
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.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 @@
ActivityManager mActivityManager;
@Mock
TelecomManager mTelecomManager;
+
+ @Mock
+ PermissionManagerServiceInternal mPermissionInternal;
@Mock
Resources mResources;
@Mock
@@ -518,7 +523,7 @@
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 @@
}
@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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 @@
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 19f3189..f0f9204 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.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 @@
}
@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 98c156e..3a01c2d 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.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 @@
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 b51feb3..593ee4a 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 9fda204..e663245 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 @@
// 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 @@
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 305260b..3dcae91 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 @@
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 91e875f..1ab8c1f 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 @@
}
@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 @@
}
@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 @@
}
@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 f655242..22d72ed 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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
similarity index 60%
rename from services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupContinuousTest.java
rename to services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncContinuousTest.java
index eef7cc2..ad7314c 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 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 java.util.Objects;
-public class SurfaceSyncGroupContinuousTest {
+public class SurfaceViewSyncContinuousTest {
@Rule
public TestName mName = new TestName();
@@ -59,33 +54,10 @@
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
similarity index 95%
rename from services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupValidatorTestCase.java
rename to services/tests/wmtests/src/com/android/server/wm/SurfaceViewSyncValidatorTestCase.java
index 1fa0c23..93c1bad 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 @@
* 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 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 @@
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 3bd577c..0000000
--- 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/IAttachEmbeddedWindow.aidl b/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindow.aidl
deleted file mode 100644
index 3439567..0000000
--- a/services/tests/wmtests/src/com/android/server/wm/scvh/IAttachEmbeddedWindow.aidl
+++ /dev/null
@@ -1,27 +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 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
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 07dac8d..0000000
--- 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 55cbc72..f5f9b84 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 @@
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 @@
} 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 220ef21..445446e 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 @@
}
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 e2238928..994e1c9 100644
--- a/telecomm/java/android/telecom/CallEndpointException.java
+++ b/telecomm/java/android/telecom/CallEndpointException.java
@@ -92,25 +92,12 @@
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 189a08c..7404adb 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -160,6 +160,10 @@
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 @@
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 @@
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 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 @@
*
* @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 @@
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 @@
sGetSlotIndexCache.disableLocal();
sGetSubIdCache.disableLocal();
sGetPhoneIdCache.disableLocal();
+
+ sIsSubscriptionManagerServiceEnabled.disableLocal();
}
/**
@@ -4014,6 +4029,8 @@
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 83b9098..0921834 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -16355,6 +16355,7 @@
/**
* Setup sIPhoneSubInfo for testing.
+ *
* @hide
*/
@VisibleForTesting
@@ -16365,9 +16366,21 @@
}
/**
- * 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 25a714a..defa046 100644
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -356,4 +356,11 @@
* @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 0000000..142e3dd
--- /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 0000000..e0d11c0
--- /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 0000000..ca84550
--- /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 0000000..84bed92
--- /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 0000000..b5193dd
--- /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/tests/BinaryTransparencyHostTest/test-app/AndroidManifest.xml b/tests/BinaryTransparencyHostTest/test-app/AndroidManifest.xml
new file mode 100644
index 0000000..42e616e
--- /dev/null
+++ b/tests/BinaryTransparencyHostTest/test-app/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.transparency.test.app">
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <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 0000000..aedb366
--- /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 bc363b0..8b1b06f 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 @@
* 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 @@
// 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 ea727b9..359eb35 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 @@
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 d5983d0..d1f2112 100644
--- a/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
+++ b/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
@@ -90,7 +90,7 @@
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 @@
mRenderingThread.renderFrame(null, width, height);
return;
}
- mSyncGroup.addToSync(mSurfaceView, frameCallback ->
+ mSyncGroup.add(mSurfaceView, frameCallback ->
mRenderingThread.renderFrame(frameCallback, width, height));
mSyncGroup.markSyncReady();
mSyncGroup = null;